jmls
jmls

Reputation: 2969

using a virtual attribute as a hash

I want to be able to have a virtual attribute on a non-database model that is a hash. I just can't figure out what the syntax is for adding and removing items from this hash:

If I define:

attr_accessor :foo, :bar

then in a method in the model, I can use:

self.foo = "x"

But I can't say:

self.bar["item"] = "value"

Upvotes: 0

Views: 174

Answers (4)

severin
severin

Reputation: 10268

When you are calling:

attr_accessor :foo, :bar

on your class, Ruby does something like the following behind the curtains:

def foo
  return @foo
end
def foo=(val)
  @foo = val
end

def bar
  return @bar
end
def bar=(val)
  @bar = val
end

The methods #foo and #bar are just returning the instance variables and #foo= and #bar= just set them. So if you want one of them to contain a Hash, you have to assign this Hash somewhere.

My favorite solution would be the following:

class YourModel

  # generate the default accessor methods
  attr_accessor :foo, :bar

  # overwrite #bar so that it always returns a hash
  def bar
    @bar ||= {}
  end

end

Upvotes: 0

Victor Moroz
Victor Moroz

Reputation: 9225

class YourModel
  def bar
    @bar ||= Hash.new
  end

  def foo
    bar["item"] = "value"
  end
end

but classic approach would be:

class YourModel
  def initialize
    @bar = Hash.new
  end

  def foo
    @bar["item"] = "value"
  end
end

Upvotes: 1

Sully
Sully

Reputation: 14943

Try

self.bar = Hash.new
self.bar["item"] = "value"

Upvotes: 2

sheerun
sheerun

Reputation: 1794

Just use OpenStruct, Hash with Indifferent Access or Active Model.

Upvotes: 0

Related Questions