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!

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.

Hi --

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.

"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