A real puzzler: attr_accessor / create incompatibility?

Greetings,

I have a problem with attr_accessor and create seemingly being at odds
with each other in my environment. Here is the setup:

A simple class representing a US State (say, Maine for example):

class State < ActiveRecord::Base
attr_accessor(:name, :code)
end

In an IRB session, I type the following and receive the response
included below:

State.create(:name=>‘Maine’, :code=>‘ME’)
State.create(:name=>‘Maine’, :code=>‘ME’)
=> #<State:0x487be24 @new_record=false, @attributes={“name”=>nil,
“code”=>nil, “id”=>2}, @code=“ME”, @name=“Maine”,
@errors=#<ActiveRecord::Errors:0x487b6cc @errors={}, @base=#<State:
0x487be24 …>>>

This indicates to me that somehow the persistence layer in
ActiveRecord is not accessing the @XXX attributes but is going after
the attributes in the @attributes hash and that these two are
separate. As you can see, the values passed in to the create method
are being passed through and are being assigned to the appropriate
@XXX variables but these variables don’t seem to be used by the
internal persistence logic.

I have tested this as follows: If I remove the attr_accessor line from
the State definition, it all works just fine. In fact, if I replace
the attr_accessor with an attr_reader, that works fine. However, if I
use an attr_accessor or an attr_writer statement, I see this rather
unexpected behavior.

Perhaps this is expected behavior and I am missing something here? Or
perhaps there is something I have in my environment that is causing
this?

Any help here would be appreciated!

Hi –

On 3/21/07, P² [email protected] wrote:

end

This indicates to me that somehow the persistence layer in
ActiveRecord is not accessing the @XXX attributes but is going after
the attributes in the @attributes hash and that these two are
separate. As you can see, the values passed in to the create method
are being passed through and are being assigned to the appropriate
@XXX variables but these variables don’t seem to be used by the
internal persistence logic.

“attr_accessor :code” creates a method called “code=” which, as you
say, has no implications for database persistence (it just sets an
instance variable). When you do create(:code => “NY”), ActiveRecord
honors your initialization request by sending the message “code=” to
your object. If you don’t defined “code=”, it gets handled by
method_missing, which knows how to map “code=” to the @attributes
hash, where it does have database implications. But you have defined
“code=”, so the message is recognized by the object and ActiveRecord
never gets to do its thing.

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

On 3/21/07, P² [email protected] wrote:

end

the State definition, it all works just fine. In fact, if I replace
the attr_accessor with an attr_reader, that works fine. However, if I
use an attr_accessor or an attr_writer statement, I see this rather
unexpected behavior.

Perhaps this is expected behavior and I am missing something here? Or
perhaps there is something I have in my environment that is causing
this?

Any help here would be appreciated!

This is expected behavior. You’re basically creating your own
attribute accessors with attr_accessor. Check out the
ActiveRecord::Base documentation:
http://rails.rubyonrails.org/classes/ActiveRecord/Base.html.


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com