- Read Tutorial
- Watch Guide Video
In this guide you'll learn how to create a seeds file. This file will allow you to dynamically generate sample data to use in the application.
Let's start with our Pivotaltracker dashboard and move the "Data flow for Portfolio Features” Sprint item to our current tab. Click on the tab to open it. The first thing we need to do is add a couple more tasks:
- Create a seeds file for sample data
- Portfolio functionality build out
With those added, we have a total of five tasks for this sprint. Click start in the state section and then let’s open the terminal.
First we will create a branch for this feature, with the imperative:
git checkout -b ‘portfolio_feature’
Feature Branches
So far, we've been creating branches for every guide. However, in a real-world scenario, we're not going to be creating a branch every ten or twenty minutes. It just wouldn't be the most intuitive way of developing a feature. Instead, branches are typically used as feature branches, which means they should be relegated to features. With that in mind, I'm going to work on this branch for this entire section. We are going to work on this branch until we complete our portfolio feature, then we'll merge it into master once this sprint is completed. That is the process you would typically use in a real world environment.
In the earlier guides, I created a branch for every guide because I wanted you to get a feel for the process and be comfortable with the syntax.
Seeds.rb
We need to develop a seeds file. Go to your code in the sublime editor, and open the db/seeds.rb
file. This is where you can create any kind of sample data you want. Here you will see some examples shown as comments.
# This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). # # Examples: # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first)
I love seeds files because they allows you to utilize core Ruby scripts, and you can connect that with Rails scripts.
Let's say, you wanted to create a blog post. We've walked through this, but just to review, in your terminal start up the rails console with the imperative: rails c
Create a blog post with the command Blog.create!(title: ‘catchy phrase’, body:’truly amazing info’)
You can see in your terminal response that a blog was created.
Now, if you type CTRL+D, you can exit the console.
Creating Test Data
We can run similar scripts in our seeds.rb
file. This will require you to call on your Ruby knowledge, as we are going to create some loops. This is important because, while having sample data is great, it makes sense to have more than one item. For example, say we want to have ten blog posts to test our data. We wouldn't want to have to go into the browser and create ten blog posts. That would not be very intuitive. What we can do is use a ruby block to create our data.
10.times do |blog| end
This block will run ten times, and is a really efficient way to build our data.
Let's split the sublime screen by going to view < layout < column:2 and in the right panel go ahead and open the schema.rb
file. It should look like this
ActiveRecord::Schema.define(version: 20170313003558) do #These are extensions that must be enabled in order to support this database enable_extension “plpgsql” create_table "blogs", force: :cascade do |t| t.string "title" t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "portfolios", force: :cascade do |t| t.string "title" t.string "subtitle" t.text "body" t.text "main_image" t.text "thumb_image" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "skills", force: :cascade do |t| t.string "title" t.integer "percent_utilized" t.datetime "created_at", null: false t.datetime "updated_at", null: false end end
Since we are going to create sample data for blogs, portfolios, and skills, having the schema file open gives us convenient access to the attributes of each object.
First, inside our block, I'm going to create the Blog data. We need a title and a body.
Blog.create!( title: “My Blog Post #{blog}”, end
If you notice, I'm not putting all my code on the same line here in the block like I did in the rails console. It makes more sense to do it in that instance, but here in our ruby seeds file, separating the attributes on to different lines makes the code more readable. If we put all the attributes on one line, the script becomes less straightforward, especially when you have an object with many attributes, such as our Portfolio object.
In this code, I'm asking the system to create ten blog posts for me. For the title I can put any string I want, but, I don't want them to all be identical, I want them to have some unique value associated with them. With that in mind, I'm using some string interpolation #{blog}
to display the iteration number.
Keep in mind, the block parameter here |blog|
is just a variable, and it can be called anything we want, for example we could use |x|
. Each time this block loops it creates a block variable and it will be set to whatever number is being looped. Accordingly, the first time it loops, the value of blog
will be 0. Remember this is computer science and in computer science we start at 0, not 1.
Let's run a test and see what happens. Open the rails console rails c
. I'm not going to create ten blog posts, as I just want to show what happens when you run a block of code like this. The code is:
10 times do |blog| puts blog end
Here you can see the block variable was equal to 0
the first time, 1
the second time and so on until the tenth loop where it equaled 9
. At the very end, it returns the count => 10
. So in terms of what the value of the variable was equal to, each time it loops through, the iterator variable value will be incremented by one. That is why we can use the variable, as string interpolation, in our seeds.rb
file, to create unique blog posts.
Next, I'm going to create five records of Skill. Oh before that, let's add some body attribute to our Blog. For this, I'm going to go to a website called www.lipsum.com, and copy a paragraph from there and paste in here. So, the code looks like this:
Blog.create!( title: “My Blog Post #{blog}”, body: “Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?” ) end
This gives an appropriate amount of fabricated data to use as our blog content. Usually you will find this Latin text comes handy when you need place holder data.
Now let's create our Skill. Again, we'll use string interpolation in the title to make each record unique and we'll have a standard value of 15 for our percent_utilized
variable.
5.times do |skill| Skill.create!( title: "Rails #{skill}", percent_utilized: 15 ) end
Usually, I like to add some feedback in the terminal, just to know this code is working. So, I'm going to add a line after our Blog creation block.
puts "10 blog posts created"
Likewise, one after our Skill creation block
puts "5 skills created"
Next, I want to create nine portfolio items. If you're wondering why nine, it's because I want to mimic the grid layout on my portfolio page like this:
But, you can use as many or as few as you want.
Now for the Portfolio item, we have more code than the others because there are more attributes.
To make it easier to create this item, copy and paste each attribute from the schema file followed by a comma.
9.times do |portfolio_item| Portfolio.create!( title: , subtitle: , body: , main_image: , thumb_image: ) end
For the title, I'm going to use string interpolation again "Portfolio title: #{portfolio_item}”
For subtitle, I'm going to have the same content for all nine posts. ”My great service”
For the body, let's copy some more latin from www.lipsum.com, but we will use a shorter paragraph.
9.times do |portfolio_item| Portfolio.create!( title: "Portfolio title: #{portfolio_item}", subtitle: "Ruby on Rails", body: ""Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", main_image: , thumb_image: ) end
One note here: Double quotations marks are required to do string interpolation. If you use single apostrophe like this ’Portfolio title:#{portfolio_item}’
, it will not work. Though it won't throw an error, it will simply print out the code exactly as you have typed it. It would not be dynamic, it would simply print out the brackets and the hash and each item would look the same. So make sure you use double quotes with string interpolation.
Placeholder Images
Now, the next two attributes are images. This is a little tricky because we don't have any images. I'll show you what I like to use for prototypes, and we'll get into how to add real images later on. For now, what I like to use is a service called PLACEHOLD.IT.
If you copy the link http://placehold.it/350x150 and paste it in your browser, it'll generate an image for you.
Notice, how you can make a change in the URL, and it dynamically creates an image based on the size I specify.
Let’s look at the image size of 400 X 200, then try with 350 X 150.
I think a size of 350X200 would be nice for our application. Copy this URL ”http://placehold.it/350x150”
and place it as a string value for your thumb_image
parameter. For the main_image
, I'm going to go with ”http://placehold.it/600x400”
.
Lastly, let's add our message that gets displayed in the terminal after these items are created: puts "9 portfolio items created”
This is how the code for the portfolio item should read.
9.times do |portfolio_item| Portfolio.create!( title: "Portfolio title: #{portfolio_item}", subtitle: "Ruby on Rails", body: ""Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", main_image: "http://placehold.it/600x400", thumb_image: "http://placehold.it/350x200" ) end puts "9 portfolio items created”
That's all we need for our seeds file.
Setting up the New Database
The next thing we need to do is run this in the terminal. Use the command rails db:setup
.
This will wipe all the previous data from our database, so it will remove the test data. Then, it will create new databases. Essentially, it will create everything from ground up, run our migration file and then run our seeds file.
With that it mind, you might think of this as the nuclear option. This is something you will never run in production. You should only run this setup command in your development environment.
When your data is constantly changing, and you simply want to have new, fresh sample data, this is a great tool. For this reason we will be accessing the seeds file quite a bit. In comparison, it is so much easier to update the seeds file than to create items through the browser. Imagine if we added another attribute to our Blog. It would be very annoying to go and edit each record on the browser. Instead, we could update the seeds file by adding the parameters we want, and then run rails db:setup
. All the deprecated data will be removed and replaced with the new updated data. We will be updating our seeds file and recreating the database quite a bit throughout the course, as it is a good practice to do in development.
Obviously you should not do this in production. I want to give you an extra warning because I had a student who actually did wipe his database in production, and it was not a fun process to bring the data back.
Go ahead and run your setup. The last three outputs you should see are:
10 blog posts created 5 skills created 9 portfolio items created
We can test this out, and there are a couple ways to do it.
First, open rails console rails c
and type Blog.count
. This displays a value of =>10
, which means there are ten records. Likewise, we can test for skill.count
which should yield =>5
and portfolio.count
that will return =>9
.
If you run portfolio.last
, the terminal with return all the data for the last portfolio item, including the image placeholder data.
Another way is to view the objects created by the seeds file is to start the rails server rails s
and go to the browser. If you go to localhost:3000/pages/home, you'll see the new Blog data there in Blog Posts and the new Skills data displayed as well.
Eventually, we'll add portfolio items in the section as well. We'll also build out this feature so you can navigate to your portfolios separately.
Now let’s do a git status
. You can see we only changed our seeds.rb file.
Let’s add this to our repository with git add .
Next we will commit with a message git commit -m ‘created seeds file for sample data’
And then push it to our branch with git push origin portfolio_feature
.
The files are now on GitHub, but we are not going to merge them in at this time. We will continue to work on this branch until we have finished this entire section and our feature is done.
Our last item for this guide is to update PivotalTracker by checking off our first task.
So, now you know how to create sample data for your application.