sscirrus
sscirrus

Reputation: 56779

Rails Seed confusion

I'm having trouble seeding my database using seed.rb, specifically where table relationships are concerned.

Here's a sample of the code:

# seed.rb
user = User.find_or_create_by_login(  
  :login => "myname",  
  :email => "[email protected]",  
  :user_type => "Admin",  
  :password => "admin",  
  :password_confirmation => "admin")

project = Project.find_or_create_by_user_id(
  :user_id => user.id,
  :name => "Test Project")

When project is created (along with other unrelated parameters I've left out from above), user_id is empty. How can I get this to work?


This is the strangest behavior I've seen in something so simple. In my seed file, I have about eight tables being created and some are nested 3-4 levels deep (i.e. user has_many projects; projects has_many tasks, etc.).

When I call user user as above and reference user.id multiple times after that, it only works once! I tried adding [user.reload] before each new record is created but to no avail. I don't imagine this will make sense to anyone, but are there any possibilities here? Thanks all.

Upvotes: 4

Views: 2284

Answers (5)

Ross
Ross

Reputation: 1562

try this use User.find_or_create instead of User.find_or_create_by_login. It seems like your user object is not saved. Or before you assign user.id do user.reload

user = User.find_or_create(  
  :login => "myname",  
  :email => "[email protected]",  
  :user_type => "Admin",  
  :password => "admin",  
  :password_confirmation => "admin")

[user.reload]

project = Project.find_or_create_by_user_id(  :user_id => user.id,
  :name => "Test Project")

Upvotes: 0

Heikki
Heikki

Reputation: 15417

Are you sure your user is saved? I think the right syntax for find_or_create_by_XX is Blog.find_or_create_by_title("Some Blog"). If you need to pass more data you need to use find_or_initialize first and set other data after that separately.

Loosely related thread: Rails find_or_create by more than one attribute?

--edit

Passing data as hash to find_or_create_by_XX seems to work too. Docs are under "Dynamic attribute-based finders" here http://apidock.com/rails/v3.0.0/ActiveRecord/Base

Upvotes: 0

sscirrus
sscirrus

Reputation: 56779

I figured out what the problem was. The fields that weren't populating were not listed explicitly in attr_accessible in their respective models. The fields listed were being saved correctly.

Thank you very much for your help everyone.

Upvotes: 5

idlefingers
idlefingers

Reputation: 32067

The code is fine and is the correct syntax for find_or_create. As others have said the most likely problem is that the user is invalid. Trying to call user.reload would make it blow up if the user is invalid and so will kind of make the problem more apparent, but the error you'll get from it will be useless (it'll moan about not being able to find a user without an id).

Unfortunately find_or_create doesn't work as a bang method to raise exceptions if it's invalid, so the best thing to do is probably raising an error and outputting the error after attempting to create the user:

user = User.find_or_create_by_login(:login => "myname")
raise "User is invalid: #{user.errors.full_messages}" unless user.valid?

Upvotes: 3

user162972
user162972

Reputation:

User created with success? if so..try user.reload if not. that is probably the error

Upvotes: 0

Related Questions