Skip to content

Instantly share code, notes, and snippets.

@tansaku
Created February 27, 2014 09:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tansaku/9247099 to your computer and use it in GitHub Desktop.
Save tansaku/9247099 to your computer and use it in GitHub Desktop.
Emily Hill's walkthrough of chapter 4 and HW2 setup for 169 ESaaS
My Rotten Potatoes Setup (walkthrough from Chapter 4)
===========================================
> cd Documents
> rails new myrottenpotatoes -T
Make sure it completed correctly. Some users have reported needing to install additional items such as:
> gem install arel
> cd myrottenpotatoes; ls
> gedit Gemfile &
Add the following lines not in a group (http://pastebin.com/AGMAxaag):
# use Haml for templates
gem 'haml'
# use Ruby debugger
group :development, :test do
gem 'ruby-debug19'
end
> bundle install —without production
> rails server
Open a browser & navigate to http://localhost:3000/movies
You will see an error
Open another terminal tab
> rake routes
> gedit log/development.log &
Keep an eye on this file to see what’s happening in your application.
> gedit config/routes.rb &
Replace contents with (http://pastebin.com/piLDY4eM):
Myrottenpotatoes::Application.routes.draw do
resources :movies
root :to => redirect('/movies')
end
> rm public/index.html
> rake routes
> rails generate migration create_movies
> ls db/migrate/
> gedit db/migrate/*_create_movies.rb &
Paste (http://pastebin.com/tmSkQX8b):
class CreateMovies < ActiveRecord::Migration
def up
create_table 'movies' do |t|
t.string 'title'
t.string 'rating'
t.text 'description'
t.datetime 'release_date'
# Add fields that let Rails automatically keep track
# of when movies are added or modified:
t.timestamps
end
end
def down
drop_table 'movies' # deletes the whole table and all its data!
end
end
> rake db:migrate
[rake db:rollback to undo]
> echo "class Movie < ActiveRecord::Base" >> app/models/movie.rb
> echo "end" >> app/models/movie.rb
Back in main rails server tab, hit ctrl-c and run
> rails console
> Movie.all
Let’s seed some movies by going to a new terminal window:
> gedit db/seeds.rb &
Paste the following (http://pastebin.com/hNB7kpWz):
# Seed the RottenPotatoes DB with some movies.
more_movies = [
{:title => 'Aladdin', :rating => 'G',
:release_date => '25-Nov-1992'},
{:title => 'When Harry Met Sally', :rating => 'R',
:release_date => '21-Jul-1989'},
{:title => 'The Help', :rating => 'PG-13',
:release_date => '10-Aug-2011'},
{:title => 'Raiders of the Lost Ark', :rating => 'PG',
:release_date => '12-Jun-1981'}
]
# NOTE: the following line temporarily allows mass assignment
# (needed if you used attr_accessible/attr_protected in movie.rb)
Movie.send(:attr_accessible, :title, :rating, :release_date)
more_movies.each do |movie|
Movie.create!(movie)
end
> rake db:seed
Back at the rail console:
> Movie.all
> Movie.where(‘id=2’)
> Movie.find(4)
> Movie.find_by_rating('PG')
> Movie.where('release_date < :cutoff and rating = :rating', :cutoff => 'Jan 1, 2000', :rating => 'G')
This allows us to interact with our application and DB and experiment with code without changing our web app implementation.
Get out of the console & let’s start building controllers and views for our actions.
> exit
> rails server
If you reload your browser window (http://localhost:3000/movies), you should get an uninitialized constant for MoviesController.
In another terminal window:
> gedit app/controllers/movies_controller.rb &
Paste the following (http://pastebin.com/KGWiEt09):
# This file is app/controllers/movies_controller.rb
class MoviesController < ApplicationController
def index
@movies = Movie.all
end
end
> mkdir -p app/views/movies
> gedit app/views/movies/index.html.haml &
And paste (http://pastebin.com/Bz9fuk34):
-# This file is app/views/movies/index.html.haml
%h2 All Movies
%table#movies
%thead
%tr
%th Movie Title
%th Rating
%th Release Date
%th More Info
%tbody
- @movies.each do |movie|
%tr
%td= movie.title
%td= movie.rating
%td= movie.release_date
%td= link_to "More about #{movie.title}", movie_path(movie)
Refresh your browser window (http://localhost:3000/movies), and you should see the same list of 4 movies that typing Movie.all gave you in the rails console (with prettier formatting).
Now let’s update the generic application wrapper (written in erg) with one in haml:
> rm app/views/layouts/application.html.erb
> gedit app/views/layouts/application.html.haml &
Paste (http://pastebin.com/0RU47cUy):
!!! 5
%html
%head
%title Rotten Potatoes!
= stylesheet_link_tag 'application'
= javascript_include_tag 'application'
= csrf_meta_tags
%body
= yield
When you reload the page, you should see the page title change from MyRottenPotatoes -> Rotten Potatoes! Check out this screen cast to learn more about how these haml files are used to generate the html source code: http://vimeo.com/34754667
Let’s add the capability to show movie details.
> gedit app/views/movies/show.html.haml &
Paste:
%h2 Details about #{@movie.title}
%ul#details
%li
Rating:
= @movie.rating
%li
Released on:
= @movie.release_date.strftime("%B %d, %Y")
%h3 Description:
%p#description= @movie.description
= link_to 'Back to movie list', movies_path
In app/controllers/movies_controller.rb, add a show method (http://pastebin.com/TESrHmkk):
def show
id = params[:id] # retrieve movie ID from URI route
@movie = Movie.find(id) # look up movie by unique ID
# will render app/views/movies/show.html.haml by default
end
Click on a movie on the list, you should see some details. Now let’s make the movies view a little prettier by pasting a stylesheet (http://pastebin.com/LsLngdin) into:
> gedit app/assets/stylesheets/application.css &
If you refresh the movie listings page, it should look more professional.
Now let’s allow users to add new movies through the web interface, rather than on the command line.
> gedit app/views/movies/index.html.haml &
And paste the following line to the end (http://pastebin.com/6wLiit6M):
= link_to 'Add new movie', new_movie_path
When you refresh the page, you should see a link to add a new movie at the bottom (but it won’t work yet).
> gedit app/views/movies/new.html.haml &
Paste (http://pastebin.com/eu3DFuMX):
%h2 Create New Movie
= form_tag movies_path, :method => :post do
= label :movie, :title, 'Title'
= text_field :movie, :title
= label :movie, :rating, 'Rating'
= select :movie, :rating, ['G', 'PG', 'PG13', 'R', 'NC-17']
= label :movie, :release_date, 'Released On'
= date_select :movie, :release_date
= submit_tag 'Save Changes'
Add a new method inside the Movie class to app/controllers/movies_controller.rb:
def new
# default: render ‘new’ template
end
Now when you click on the link, you should see the “Create a new movie” page. Next we’ll enable the form to create a new movie in our app.
> gedit app/controllers/movies_controller.rb &
Paste the following code inside the MovieController class (http://pastebin.com/FFgBP1Jy):
def create
@movie = Movie.create!(params[:movie])
redirect_to movies_path
end
Add the following line to your app/models/movie.rb file inside the Movie class:
attr_accessible :title, :rating, :description, :release_date
When you submit the form in the browser, it should now create a movie. Wouldn’t it be nice if the web page showed us a status update that our movie was or was not successfully added?
Update the create method in app/controllers/movies_controller.rb with the following flash message (http://pastebin.com/N1n4Pkr0):
# in movies_controller.rb
def create
@movie = Movie.create!(params[:movie])
flash[:notice] = "#{@movie.title} was successfully created."
redirect_to movies_path
end
Now we need to update the haml to get and display the message.
> gedit app/views/layouts/application.html.haml &
Paste the following if statement inside the body, before the yield command, like this:
%body
- if flash[:notice]
#notice.message= flash[:notice]
- elsif flash[:warning]
#warning.message= flash[:warning]
= yield
Remember that haml is VERY fussy about indentation and make sure you are consistent with tabs and spacing. Now when you add a movie, a status message should be displayed.
Exercise: edit app/assets/stylesheets/application.css so that flash messages are red & centered.
Let’s add the ability to edit existing movies, which will require the following changes:
> gedit app/views/movies/show.html.haml &
Modify the last 2 lines to be (http://pastebin.com/ZD1y6TYc):
= link_to 'Edit info', edit_movie_path(@movie)
= link_to 'Back to movie list', movies_path
> gedit app/views/movies/edit.html.haml &
Paste the properly indented haml code (http://pastebin.com/Uqm1AS8Q):
%h2 Edit Movie
= form_tag movie_path(@movie), :method => :put do
= label :movie, :title, 'Title'
= text_field :movie, 'title'
= label :movie, :rating, 'Rating'
= select :movie, :rating, ['G', 'PG', 'PG13', 'R', 'NC-17']
= label :movie, :release_date, 'Released On'
= date_select :movie, :release_date
= submit_tag 'Save Changes'
Add the following edit & update methods to app/controllers/movie_controller.rb (http://pastebin.com/jdTS5P7Q):
def edit
@movie = Movie.find params[:id]
end
def update
@movie = Movie.find params[:id]
@movie.update_attributes!(params[:movie])
flash[:notice] = "#{@movie.title} was successfully updated."
redirect_to movie_path(@movie)
end
Now you should have the ability to edit movies. But what if we want to delete one? Add the following lines to app/controllers/movie_controller.rb (http://pastebin.com/8ZYbFUcb):
def destroy
@movie = Movie.find(params[:id])
@movie.destroy
flash[:notice] = "Movie '#{@movie.title}' deleted."
redirect_to movies_path
end
And then add a delete link to app/views/movies/show.html.haml (http://pastebin.com/Cr8EXQaH):
-# Our Edit link from previous example:
= link_to 'Edit info', edit_movie_path(@movie)
-# This Delete link will not really be a link, but a form:
= link_to 'Delete', movie_path(@movie), :method => :delete
You now should be able to delete a movie after clicking on a “more info” link. However, a destructive action like delete should probably prompt the user to be sure they want to take that action. So let’s change that delete link to a button instead (http://pastebin.com/mTXuE5up):
= button_to 'Delete', movie_path(@movie), :method => :delete, :confirm => 'Are you sure you want to delete?’
That concludes the chapter 4 walk through of a setting up a sample ruby on rails app from scratch. You should now have a better understanding of how the HW2 skeleton is setup.
=============
Before trying HW2, make sure to shut down your rails server from chapter 4 (in myrottenpotatoes) by hitting ctrl-c in the terminal window.
Setup for HW2
=============
In a terminal window, return to your home folder & setup the skeleton code for HW2 by typing:
> cd
> mkdir hw2
> cd hw2
> wget https://edge.edx.org/c4x/MSU/CMPT594-01/asset/rails-intro.zip
> unzip rails-intro.zip
We need to setup this rottenpotatoes skeleton similar to how we deployed our example from Chapter 4, above:
> cd rottenpotatoes
> bundle install
> rails s
Navigate to http://localhost:3000
Now you are ready to complete HW2 parts 1-3 as per the instructions on edx.
Submitting HW2
=============
To submit:
Go back to your home directory.
> cd
> zip -r hw2.zip hw2/rottenpotatoes
Upload hw2.zip to Blackboard to submit
@prudhvirajs
Copy link

line 349+ = button_to 'Delete', movie_path(@movie), :method => :delete, :confirm => 'Are you sure you want to delete?’

should be = button_to 'Delete', movie_path(@movie), :method => :delete, :confirm => 'Are you sure you want to delete?'

’ is used instead of ' causing error to code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment