Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for creating has_many associations #202

Closed
cannikin opened this issue Sep 19, 2011 · 5 comments
Closed

Documentation for creating has_many associations #202

cannikin opened this issue Sep 19, 2011 · 5 comments

Comments

@cannikin
Copy link

I'm sorry to have to revert to the issues list here, but I can't for the life of me find any documentation on creating has_many relationships in FG 2.0. After some experimentation I found the solution below, but I don't know if this is the "right" way to do it:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

FactoryGirl.define do
  factory :comment do
    body 'This is a comment'
  end

  factory :post do
    title 'This is a Post'
    comments { FactoryGirl.create_list(:comment, 2) }
    # or, to create only one =>  comments { [FactoryGirl.create(:comment)] }
  end
end

Factory.create :post

One problem is that I won't know if you called build or create when you factoried (nice, right?) your post, but this will always create the comments. So I played with the syntax a bit to get association in there instead and came up with this:

  factory :post do
    title 'This is a Post'
    comments { [association(:comment)] }
  end

Is that the right way to do it? GETTING_STARTED has a great reference for just about everything you can do with FG except this one case. Thanks!

@cannikin
Copy link
Author

By the way, if that later method is the correct one I'd be happy to update the docs myself an issue a pull request.

@oli-g
Copy link

oli-g commented Sep 22, 2011

+1 something like this is needed

@jferris
Copy link
Member

jferris commented Sep 22, 2011

Creating records for a has_many association is sort of tricky, for a couple reasons:

First, there's always a chicken-and-egg problem doing this in a relational database, because one record has to exist before the other. You can't create records in separate tables simultaneously, and one table has to hold the primary key of the other.

Second, there's no knowing what kind of validations or callbacks are in place on the models in question, so it's hard to know if the collection needs to be saved or unsaved.

If you're validating that at least member is present in the collection, you can try passing in a list of unsaved records (using Factory.build).

If you're not validating anything about the collection, I'd recommend doing it in an after_create callback.

@joshuaclayton
Copy link
Contributor

After talking about this with @jferris, it seems like the ideal syntax may be something like this:

FactoryGirl.define do
  factory :user, :aliases => [:author]

  factory :comment do
    author
    post

    factory :old_comment do
      created_at { 1.year.ago }
    end
  end

  factory :post do
    factory :commented_post do
      comments(2) # this would create two `:comment`s
      # alternatively...
      comments # this would create one `:comment`
      old_comments(2, :body => 'something static') # this would create two `:comment`s, both with body of 'something static'
      old_comments # this would create one `:old_comment`
    end
  end
end

@joshuaclayton
Copy link
Contributor

I've added more documentation in this commit: 9c6c252

It includes tests (since they're a great form of documentation) but the primary example is in the GETTING_STARTED document.

While it's beneficial to discuss syntactical improvements and ways to make this more straightforward, I think that's better handled in a separate pull request when an implementation is started; for now, this focuses on documentation and this commit should handle that request.

Thanks everyone for their contribution to the discussion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants