Hi all,
I am having a weird problem reading a value from my model. basicaly, I
have these two models:
class Category < ActiveRecord::Base
acts_as_tree :order => “name”
belongs_to :item_type
has_many :specific_category_names
end
and
class SpecificCategoryName < ActiveRecord::Base
set_table_name “Specific_category_names”
has_many :products
belongs_to :brand
belongs_to :category
#if there is no name, use the name of the category
def name
if @name.nil?
category.name
else
@name
end
end
end
Then, I start to play in the console… In my DB,
specific_category_names.name for canon is = “WIDER” and the
corresponding category.name = “wide”
canon = Brand.find_by_name(“Canon”)
=>#<Brand:0x2429784 @attributes={“name”=>“Canon”, “id”=>“1”}>
Thats OK
canon.specific_category_names.first
=>#<SpecificCategoryName:0x24235a0 @attributes={“name”=>“WIDER”,
“brand_id”=>“1”, “id”=>“1”, “description”=>nil, “category_id”=>“7”}>
then the strange things:
canon.specific_category_names.first.name
=> “Wide”
This should be “WIDER” since that the value from specific_category_name
and it is not null!!!
And even weirder, if I ask again for the specific_category_name array, I
will get the same one as before but this time there is a @category
added…
canon.specific_category_names.first
=> #<SpecificCategoryName:0x24235a0 @attributes={“name”=>“WIDER”,
“brand_id”=>“1”, “id”=>“1”, “description”=>nil, “category_id”=>“7”},
@category=#<Category:0x241557c @attributes={“name”=>“Wide”, “id”=>“7”,
“description”=>nil, “item_type_id”=>“1”, “parent_id”=>“2”}>>
Anyone can tell me what I am doing wrong?!? This is puzzling me to no
end!
Thanks
“Alain Pilon” [email protected] wrote in
message news:[email protected]…
Hi all,
I am having a weird problem reading a value from my model. basicaly, I
have these two models:
#if there is no name, use the name of the category
def name
if @name.nil?
category.name
else
@name
end
end
end
ActiveRecord attributes aren’t stored as instance variables in the model
so
you don’t need the @. I’m pretty sure AR uses method_missing to return
attribute values, try something like this:
def name
tmp = super
return tmp || category.name
end
I think (ie untested) you should be able to use
def name
self[:name] || category.name
end
See “Overwriting default accessors” in
http://api.rubyonrails.com/classes/ActiveRecord/Base.html
Chris
self[:name] is essentially the rails equivalent of @name.
if you tried to use self.name, you would invoke the name method on the
current instance, from within… the name method on the current
instance; resulting in an infinite loop
Thx Chris, that solved my problem. But why use self[:name] and not
self.name ???
On 7/20/06, Chris R. [email protected] wrote:
self[:name] is essentially the rails equivalent of @name.
In ruby, this isn’t necessarily true, as @name, self[:name] and
self.name can all be different:
irb(main):001:0> class A
irb(main):002:1> def initialize
irb(main):003:2> super
irb(main):004:2> @p = 2
irb(main):005:2> end
irb(main):006:1> def [] y
irb(main):007:2> @x ||= {}
irb(main):008:2> @x[y]
irb(main):009:2> end
irb(main):010:1> def p
irb(main):011:2> 1
irb(main):012:2> end
irb(main):013:1> def test
irb(main):014:2> puts “@p = #{@p}”
irb(main):015:2> puts “self.p = #{self.p}”
irb(main):016:2> puts “self[:p] = #{self[:p]}”
irb(main):017:2> end
irb(main):018:1> def self.test
irb(main):019:2> new.test
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0> A.test
@p = 2
self.p = 1
self[:p] =
=> nil
For ActiveRecord objects, self[:blah] and self.blah are usually the
same if blah is a column in the associated table (since self.blah will
default to self[:blah]), but that can be (and often is) changed.
However, ActiveRecord doesn’t create @blah instance variables for
columns, AFAIK.
Jeremy