# Attr\_accessor puzzle?

**URL:** <https://www.ruby-forum.com/t/attr-accessor-puzzle/127502>\
**Category:** Rails\
**Created:** [January 29, 2008, 9:23pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502 "2008-01-29T21:23:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 29, 2008, 9:23pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/1 "2008-01-29T21:23:56Z")

</div>

Hi,  
I have a “user” model, which has present “attr\_accessor :password”  
in the beginning, by which I wish only the password attribute could be  
read and written from outside of this class. However, by retrieving a  
user instance (e.g @user) by “find(:id)” from database, surprisingly I  
noticed I could read every single attribute in this “user” instance  
from the view, simply say: #{@user.login}, #{@user.email}, etc.  
This is not what I expected, am I misunderstanding something about  
the “attr” helper ?

* * *

The user model’s sexy migration:  
create\_table “users”, :force =\> true do |t|

t.string :login, :email, :remember\_token, :first\_name, :last\_name  
t.string :crypted\_password, :limit =\> 40  
t.string :password\_reset\_code, :limit =\> 40  
t.string :salt, :limit =\> 40  
t.string :activation\_code, :limit =\> 40

t.datetime :remember\_token\_expires\_at, :activated\_at, :deleted\_at  
t.string :state, :null =\> :no, :default =\> ‘passive’

```
  t.timestamps
end
```

---

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 29, 2008, 10:20pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/2 "2008-01-29T22:20:54Z")

</div>

No, you understand attr\_accessor correctly. Under normal  
circumstances, what you did would only expose password and no other  
variables. However, there is some Rails magic going on in the  
background. ActiveRecord automagically creates accessor methods for  
each attribute your model has.

---

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 29, 2008, 10:26pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/3 "2008-01-29T22:26:12Z")

</div>

I found a way to explicitly hide columns. Check out this Rails patch:

[http://dev.rubyonrails.org/ticket/8355](http://dev.rubyonrails.org/ticket/8355)

---

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 30, 2008, 11:33pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/4 "2008-01-30T23:33:08Z")

</div>

On 1/29/08, Wyatt G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> No, you understand attr\_accessor correctly. Under normal  
> circumstances, what you did would only expose password and no other  
> variables. However, there is some Rails magic going on in the  
> background. ActiveRecord automagically creates accessor methods for  
> each attribute your model has.

Actually, you don’t normally want to use attr\_accessor, or  
attr\_writer, or attr\_reader for ActiveRecord attributes, despite the  
name.

These generate methods for accessing instance variables, not database  
columns. And the methods generated for AR attributes get generated  
the first time the object gets a method\_missing, so having an  
attr\_accessor with the same name as an attribute could interfere with  
AR.

I think that the OP is thinking of attr\_accessible which is an  
ActiveRecord::Base class method to “whitelist” attributes for mass  
assignment, and it’s “blacklist brother” attr\_protected

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 30, 2008, 9:10am UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/5 "2008-01-30T09:10:20Z")

</div>

Thank you Wyatt, this is so wired… I dont get why in each tutorial  
book, even DHH’s, it  
says: using attr\_accessor to expose attribute, but actually it isn’t  
like that …

---

<div class="post-metadata">

**Author:** ![myst\_tt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47774/32.png) [@myst\_tt](https://www.ruby-forum.com/u/myst_tt)\
**Post date:** [January 31, 2008, 6:54pm UTC](https://www.ruby-forum.com/t/attr-accessor-puzzle/127502/6 "2008-01-31T18:54:04Z")

</div>

I think that he meant that attr\_accessor is what you’d use in a normal  
Ruby (non-Rails) context to expose an attribute. That’s a fair  
statement. It’s not applicable to these ActiveRecord attributes,  
however, since the Rails team decided to hook method\_missing in ARec  
such that it issues attr\_accessor calls for every content\_column not  
identified in the attr\_protected and attr\_accessible methods you’ve  
mentioned.

The problem with attr\_accessible and attr\_protected is that they still  
allow the attributes to be read, just not written. The original post  
required all the attributes be hidden entirely.
