# Writing a simple accessor ... or so I thought

**URL:** <https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777>\
**Category:** Rails\
**Created:** [February 7, 2007, 5:06pm UTC](https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777 "2007-02-07T17:06:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![carp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a8b319/32.png) [@carp](https://www.ruby-forum.com/u/carp)\
**Post date:** [February 7, 2007, 5:06pm UTC](https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777/1 "2007-02-07T17:06:42Z")

</div>

Hello Rubyists.

What I want is a “write once, then readonly” attribute in a subclass of  
ActiveController::Base. With “write once” in this case I mean that it  
must not be changed once the object has been stored to the database.

The simplified class looks as follows:

class User \< ActiveRecord::Base  
attr\_reader :login

def login=(new\_login)  
@login = new\_login unless !new\_record?  
end  
end

When I tested the method, I noticed that it behaved oddly:

An instance of User is created from the fixtures. Its login attribute is  
set properly (checked it with Object::inspect). However, thatobj.login  
returns nil. I thought it should be covered with the “attr\_reader  
:login” statement in the User class.

What am I missing here? Thanks in advance.

-carp

---

<div class="post-metadata">

**Author:** ![carp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a8b319/32.png) [@carp](https://www.ruby-forum.com/u/carp)\
**Post date:** [February 7, 2007, 5:07pm UTC](https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777/2 "2007-02-07T17:07:55Z")

</div>

> in a subclass of ActiveController::Base.

… must of course be “ActiveRecord::Base”

:-p

---

<div class="post-metadata">

**Author:** ![carp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a8b319/32.png) [@carp](https://www.ruby-forum.com/u/carp)\
**Post date:** [February 7, 2007, 6:45pm UTC](https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777/3 "2007-02-07T18:45:14Z")

</div>

> class User \< ActiveRecord::Base  
> attr\_reader :login
> 
> def login=(new\_login)  
> @login = new\_login unless !new\_record?  
> end  
> end

Try this:  
def login=(new\_login)  
write\_attribute( :login, new\_login ) if new\_record?  
end

For more info take a look at the “Overwriting default accessors”  
section of the ActiveRecord::Base documentation.  
[http://api.rubyonrails.com/classes/ActiveRecord/Base.html](http://api.rubyonrails.com/classes/ActiveRecord/Base.html)

Aaron

---

<div class="post-metadata">

**Author:** ![carp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a8b319/32.png) [@carp](https://www.ruby-forum.com/u/carp)\
**Post date:** [February 8, 2007, 10:29am UTC](https://www.ruby-forum.com/t/writing-a-simple-accessor-or-so-i-thought/84777/4 "2007-02-08T10:29:26Z")

</div>

Aaron wrote:

> For more info take a look at the “Overwriting default accessors”  
> section of the ActiveRecord::Base documentation.  
> [Peak Obsession](http://api.rubyonrails.com/classes/ActiveRecord/Base.html)

I was able to fix it. I’ve been searching the forever, but never got to  
the section you pointed out. Thanks a lot Aaron!

-carp
