Writing a simple accessor ... or so I thought


#1

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


#2

in a subclass of ActiveController::Base.

… must of course be “ActiveRecord::Base”

:-p


#3

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

Aaron


#4

Aaron wrote:

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

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