Despite the intention of seed
-ing - that this is meant to be run once, to populate the database - there is no technical constrain preventing you from running rake db:seed
command couple times. Even without cleaning/recreating your database.
In that case, try following code for db/seeds.rb
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
]
post_attributes.each do |attributes|
Post.create(attributes) unless Post.where(attributes).first
end
First of all, we're defining an array of attributes for each Post
, to be created.
Later, we're iterating through that array (with post_attributes.each do |attributes|
), and trying create a new Post
, unless one with specified attributes found.
In Rails, there is quite fancy method first_or_create
, which does exactly that - queries database for specified attributes (where(attributes)
), and if nothing found - creates new record based on provided attributes.
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
]
post_attributes.each do |attributes|
Post.where(attributes).first_or_create
end
At this point, you can "seed" the database with rake db:seed
and check what is stored in database (after running rails console
) by:
Post.all.map(&:title)
Assuming you had empty database before running rake db:seed
, it should contain only 3 Post
s. The ones specified with attributes in post_attributes
.
Now, if you try to modify your db/seeds.rb again, adding an attributes for one more Post
:
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
{ title: "Another Post", body: "WOW!" },
]
post_attributes.each do |attributes|
Post.where(attributes).first_or_create
end
After running rake db:seed
, and checking in console:
Post.all.map(&:title)
You can see, that only one new Post
has been created. The one with title "Another Post".
In your question I understood, that when creating new Post
, both attributes - title
and body
have be unique, so if you try to perform the same for attributes like:
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 1", body: "Sample body 2" },
]
This will create two separate Post
s, because they have different body
attributes defined.
For Comment
s you can do similar thing.
Again, as jBeas mentioned earlier - seed
-ing has different purpose, but if this is only exercise to play with ActiveRecord
- this is one of ways how you can tackle the problem.
Hope that helps!