# Weird result for a custom attr reader!

**URL:** <https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972>\
**Category:** Rails\
**Created:** [July 19, 2006, 1:49pm UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972 "2006-07-19T13:49:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 19, 2006, 1:49pm UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/1 "2006-07-19T13:49:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 19, 2006, 2:01pm UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/2 "2006-07-19T14:01:31Z")

</div>

“Alain Pilon” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in  
message news:removed\_email\_address@domain.invalid…

> 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

---

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 19, 2006, 3:12pm UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/3 "2006-07-19T15:12:47Z")

</div>

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](http://api.rubyonrails.com/classes/ActiveRecord/Base.html)

Chris

---

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 20, 2006, 11:48am UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/4 "2006-07-20T11:48:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 20, 2006, 5:06am UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/5 "2006-07-20T05:06:04Z")

</div>

Thx Chris, that solved my problem. But why use self[:name] and not  
self.name ???

---

<div class="post-metadata">

**Author:** ![Alain\_Pilon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@Alain\_Pilon](https://www.ruby-forum.com/u/Alain_Pilon)\
**Post date:** [July 20, 2006, 6:27pm UTC](https://www.ruby-forum.com/t/weird-result-for-a-custom-attr-reader/98972/6 "2006-07-20T18:27:16Z")

</div>

On 7/20/06, Chris R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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
