On Seeding Nested Models in Rails 3

Dead Models

So you’re in active development and want some real-ish data in your app, eh?  And you keep making adjustments to your model as you understand the requirements better?  Oh?  Your models are deeply nested, like a proper associative-normalizing ninja?  

So I was struggling mightily with this, and couldn’t find any tutorials that gave me the key.  Here were my (non operational) models (simplified for this post):

class User < ActiveRecord::Base
  attr_accessible :email, :password, :password_confirmation
  has_many :surveys
  accepts_nested_attributes_for :surveys
end

and

class Survey < ActiveRecord::Base
  belongs_to :user
  attr_accessible :name, :active
end

So now you want to see these with a sample user + survey? Should be easy right,

accepts_nested_attributes_for

is set! I expected this would work:

params = { :u => {
  :email => "me@awesome.com", :password => "guessthishackers", :surveys_attributes => [
          { :name => 'Test Survey', :active => true}
        ]
        }}
person = User.create(params[:u])

No dice. Fails with a “can’t mass-assign error” in the development log. A great deal of searching didn’t provide an obvious answer, but points clearly to the model. After a fair amount of googling and head scratching, the answer hit me like a brick:

attr_accessible :surveys_attributes

Duh, the attributes hash is a first-level attribute of User, in-and-of-itself!

Moral of the story — seeds.rb is a ruby file that mass-assigns for breakfast. Tweak your models accordingly.

Tags: , , ,