I was bitten by this recently, and it'd be useful to know precisely what's happening to make this happen, so others avoid this mistake.
I have a model User, with a schema like so:
create_table "users", :force => true do |t|
t.string "user_name"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "location"
t.string "town"
t.string "country"
t.string "postcode"
t.boolean "newsletter"
In the class user.rb, I have a attr_accessor for three methods:
class User < ActiveRecord::Base
# lots of code
attr_protected :admin, :active
# relevant accessor methods
attr_accessor :town, :postcode, :country
end
Now in my user controller, if I have the following method:
def create
@user = User.new params[:user]
end
When when I try to create a new user with the contents in this params hash:
--- !map:HashWithIndifferentAccess
# other values
country: United Kingdom
dob(1i): "1985"
dob(2i): "9"
dob(3i): "19"
town: london
The returned object has empty strings for the country
, town
and postcode postcode
values, like so.
(rdb:53) y user1
--- !ruby/object:User
attributes:
# lots of attributes that aren't relevant for this example, and are filled in okay
postcode:
country:
town:
I can tell that the attr_accessor methods are clobbering Active Record's existing accessor methods, because when I take them out all works fine, so the solution is fairly straightforward - just take them out.
But what exactly is happening when here?
I'm looking here in the Rails API docs for Active Record, and here in Ruby's own docs about attr_accessor
, but I'm still slightly hazy about how attr_accessor
is breaking things here.
Any able to shed some light to stop some other poor soul falling foul of this?