Created
February 27, 2014 09:37
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.