SooDesuNe
SooDesuNe

Reputation: 10030

rails Model.create(:attr=>"value") returns model with uninitialized fields

This is really stumping me. The process works fine if I go about it with #new and then #save, but #create returns a model instance with all the fields set to nil.

e.g: Unexpected behavior:

ruby-1.9.2-p0 > EmailDefault.create(:description=>"hi")
 => #<EmailDefault id: nil, description: nil, created_at: nil, updated_at: nil> 

Expected behaviour:

ruby-1.9.2-p0 > e = EmailDefault.new
 => #<EmailDefault id: nil, description: nil, created_at: nil, updated_at: nil> 
ruby-1.9.2-p0 > e.description = "hi"
 => "hi"
ruby-1.9.2-p0 > e.save
 => true 
ruby-1.9.2-p0 > EmailDefault.last
 => #<EmailDefault id: 4, description: "hi", created_at: "2011-02-27 22:25:33", updated_at: "2011-02-27 22:25:33"> 

What am I doing wrong?

--update-- Turns out I was mis-using attr_accessor. I wanted to add some non-database attributes, so I did it with:

attr_accessible :example_to, :cc_comments

which is wrong, and caused the situation @Heikki mentioned. What I need to do is:

attr_accessor :example_to, :cc_comments

Upvotes: 0

Views: 3965

Answers (1)

Heikki
Heikki

Reputation: 15417

You need to white list those properties with attr_accessible to enable mass-assignment.

http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html#method-i-attr_accessible

--edit

By default all attributes are available for mass-assignment. If attr_accessible is used then mass-assignment will work only for those attributes. Attr_protected works the opposite way ie. those attributes will be protected from mass-assignment. Only one should be used at a time. I prefer the white listing with attr_accessible.

Upvotes: 1

Related Questions