Topics Covered: Putting MVC together; building an API app; taking off the scaffolding training wheels
index
action.For review purposes, here are the list of steps we did today (the order may seem different because we jumped around a bit during class—please check the video if these steps confuse you):
rails new reddit_rails
cd reddit_rails
story.rb
file in app/models
and add the code to create a model (something that looks like class Story < ActiveRecord::Base ... end
stories_controller.rb
controller in app/controllers
(it should have something like class StoriesController < ApplicationController ... end)
index
)config/routes.rb
index.html.erb
in app/views/stories
(you'll have to make a folder called stories
). Why do we name it index
? Because your action is called index
. Rails renders the view with the same name as the action. We'll learn how to change that later.Why are we not using scaffolding? Why do we not want to use it all the time?
Now we're going to write an app that does what our Terminal code for using the data.gov API did. In d8
, start by creating new rails app called petitions_rails
. If you've lost the code from before, you can find it here.
For this app to work, remember that we needed to install the gems 'rest-client' and 'json'. The way Rails manages this is in the Gemfile
, stored right in first directory. Right now, it looks something like
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# ...
At the end of the file, go ahead and add gem 'json'
and gem 'rest-client'
on their own lines. Then, back in Terminal, run bundle install
. What that does is basically run gem install
for each of the gems in the Gemfile.
Now we want to think about what models our application is going to need. One of them should be fairly obvious: a Petition
model. Go ahead and create that.
Follow the steps in today's code along, and create a route that maps the URL /petitions
to a controller (probably the PetitionsController
), and create the necessary action (probably index
). Make sure your route in config/routes.rb
maps to that controller and action.
Now visit localhost:3000
and make sure your link works. Get it so there are no error messages, and it basically shows an empty page.
Now you have to figure out where all the code we wrote last week goes. But this application is unique: we're not pulling data from our database, but from the data.gov API. We're going to create a get_petitions
method that does just that.
class Petition < ActiveRecord::Base
def self.get_petitions
# your code here
end
end
What should your code do? You want to get the data from the API, and return an array of hashes that contain all the information that we want. Your code should not puts
anything—that's what your view is for! If I were to write pseudo-code, it might look like:
def self.get_petitions
# Get JSON from API
# Parse it into a hash
# Get the relevant fields of the hash
# Return an array of petitions
end
Start getting used to this workflow: Rails is a lot of switching between files, putting your code in the right place. What method should we call inside the index
` action? What instance variable should you store that in?
Update your /app/views/petitions/index.html.erb
file to render each of the petitions title, body, URL, deadline, status, created and siganture count. But don't let the date be something ugly like 1403920011
, use some of Rails' built in methods to make it into something nice (this might help).
Now you should have a website that has two pages: a main page (URL /
) that has a link to the /petitions
page, and a petitions page (with URL /petitions
) that shows the first five petitions on data.gov. Congrats, you've built your first somewhat useful website!!
A bit tougher now! Add the UI (user interface) and controller methods to be able to view just a single petition by clicking on it on the petitions page. The URL will probably looks something like /petitions/petition_id
. (Hint: use a show
action.) In order to do this, you'll have to use the params
hash. We'll cover this in more detail next week, but for now, all you need to know is that if you define a route with :id
where you expect the link to include the id number, the id given in the URL will be available as params[:id]
as shown below.
# In config/routes.rb
# :id is a placeholder where the URL will have a number
get '/petitions/:id' => 'petitions#show'
# In app/views/petitions/index.html.erb
# the actual petition id is put in the URL.
<% @petitions.each do |petition| %>
<!-- Show the petition... -->
<!-- Then add a link to see just this one -->
<%= link_to 'Show', '/petitions/' + petition[:id] %>
<% end %>
# Note that in this case, id will look something like 50a3fd762f2c88cd65000015
# Why is it not something nice, like 1 or 8? Because we're not using our
# database yet, and this is how the petitions api works.
# In app/controllers/petitions_controller.rb
# the params hash will now have a key :id which has the value of 1
def show
@petition = Petition.get_petition(params[:id])
end
Note that now we're calling Petition.get_petition
instead of Petition.get_petitions
. get_petitions
takes no arguments, and returns an array of petitions. get_petition
should take one argument (the petition id), and returns one petition. How can we use the data.gov API to get just one petition, instead of an array? Hint—make sure to read thoroughly.
Your website works, but it always gives us just the last 5 petitions. It doesn't let us filter, or search, or any of the nice things the API allows us to do. Let's fix that.
In the same app, add the necessary user interface (meaning HTML/CSS in your views), controller methods and model methods that allow us to search through petitions, filter by status, or see more than 5. Then go sign one of them and participate in America's beautiful democracy.
Using the steps above, turn the group API project you did on Day 4 into a Rails app. It may seem repetitive/redundant to do a third API app, but please trust us: repetition with Rails never hurts. If you feel its easy, start adding CSS in app/assets/stylesheets
so that your website looks pretty!