├── public ├── favicon.ico ├── javascripts │ ├── .gitkeep │ └── application.js ├── stylesheets │ ├── .gitkeep │ └── general.css ├── images │ └── rails.png ├── robots.txt ├── 422.html ├── 404.html ├── 500.html └── index.html ├── app ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ └── movie.rb ├── helpers │ ├── application_helper.rb │ └── movies_helper.rb ├── assets │ ├── images │ │ └── rails.png │ ├── javascripts │ │ └── application.js │ └── stylesheets │ │ └── application.css ├── controllers │ ├── application_controller.rb │ └── movies_controller.rb └── views │ ├── movies │ ├── new.html.haml │ ├── same_director_listing.html.haml │ ├── edit.html.haml │ ├── show.html.haml │ └── index.html.haml │ └── layouts │ └── application.html.haml ├── lib └── assets │ └── .gitkeep ├── vendor ├── plugins │ └── .gitkeep └── assets │ └── stylesheets │ └── .gitkeep ├── .gitignore ├── autotest └── discover.rb ├── db ├── development.sqlite3 ├── seeds.rb └── migrate │ ├── 20111119180638_create_movies.rb │ └── 20120130161449_add_more_movies.rb ├── spec ├── .spec_helper.rb.swp ├── .movie_same_director_listing_spec.rb.swp ├── movie_same_director_listing_spec.rb └── spec_helper.rb ├── features ├── support │ ├── .paths.rb.swp │ ├── selectors.rb │ ├── paths.rb │ └── env.rb ├── step_definitions │ ├── .web_steps.rb.swp │ ├── .movie_steps.rb.swp │ ├── movie_steps.rb │ └── web_steps.rb ├── .search_for_movies_by_director.feature.swp ├── search_for_movies_by_director.feature ├── sort_movie_list.feature └── filter_movie_list.feature ├── config.ru ├── config ├── environment.rb ├── boot.rb ├── initializers │ ├── mime_types.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── session_store.rb │ ├── secret_token.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── database.yml ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── routes.rb └── application.rb ├── doc └── README_FOR_APP ├── Rakefile ├── script └── rails ├── Gemfile ├── Gemfile.lock └── README /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/javascripts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/javascripts/application.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | \#*\# 3 | *~ 4 | TAGS 5 | db/schema.rb 6 | log/ 7 | db/*.sqlite3 8 | -------------------------------------------------------------------------------- /autotest/discover.rb: -------------------------------------------------------------------------------- 1 | Autotest.add_discovery { "rails" } 2 | Autotest.add_discovery { "rspec2" } 3 | -------------------------------------------------------------------------------- /db/development.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/db/development.sqlite3 -------------------------------------------------------------------------------- /public/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/public/images/rails.png -------------------------------------------------------------------------------- /spec/.spec_helper.rb.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/spec/.spec_helper.rb.swp -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/app/assets/images/rails.png -------------------------------------------------------------------------------- /features/support/.paths.rb.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/features/support/.paths.rb.swp -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /app/models/movie.rb: -------------------------------------------------------------------------------- 1 | class Movie < ActiveRecord::Base 2 | def self.all_ratings 3 | %w(G PG PG-13 NC-17 R) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /features/step_definitions/.web_steps.rb.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/features/step_definitions/.web_steps.rb.swp -------------------------------------------------------------------------------- /features/step_definitions/.movie_steps.rb.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/features/step_definitions/.movie_steps.rb.swp -------------------------------------------------------------------------------- /spec/.movie_same_director_listing_spec.rb.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/spec/.movie_same_director_listing_spec.rb.swp -------------------------------------------------------------------------------- /app/helpers/movies_helper.rb: -------------------------------------------------------------------------------- 1 | module MoviesHelper 2 | # Checks if a number is odd: 3 | def oddness(count) 4 | count.odd? ? "odd" : "even" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /features/.search_for_movies_by_director.feature.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceshine/hw4_rottenpotatoes/master/features/.search_for_movies_by_director.feature.swp -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rottenpotatoes::Application 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Rottenpotatoes::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Rottenpotatoes::Application.load_tasks 8 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /app/views/movies/new.html.haml: -------------------------------------------------------------------------------- 1 | %h1 Create New Movie 2 | 3 | = form_tag movies_path do 4 | 5 | = label :movie, :title, 'Title' 6 | = text_field :movie, 'title' 7 | 8 | = label :movie, :rating, 'Rating' 9 | = select :movie, :rating, ['G','PG','PG-13','R','NC-17'] 10 | 11 | = label :movie, :release_date, 'Released On' 12 | = date_select :movie, :release_date 13 | 14 | = submit_tag 'Save Changes' 15 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html 3 | %head 4 | %title Rotten Potatoes! 5 | = stylesheet_link_tag 'application' 6 | = javascript_include_tag 'application' 7 | = csrf_meta_tags 8 | 9 | %body 10 | %h1.title Rotten Potatoes! 11 | #main 12 | - if flash[:notice] 13 | #notice.message= flash[:notice] 14 | - elsif flash[:warning] 15 | #warning.message= flash[:warning] 16 | 17 | = yield 18 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rottenpotatoes::Application.config.session_store :cookie_store, key: '_rottenpotatoes_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Rottenpotatoes::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /db/migrate/20111119180638_create_movies.rb: -------------------------------------------------------------------------------- 1 | class CreateMovies < ActiveRecord::Migration 2 | def up 3 | create_table :movies do |t| 4 | t.string :title 5 | t.string :rating 6 | t.text :description 7 | t.datetime :release_date 8 | # Add fields that let Rails automatically keep track 9 | # of when movies are added or modified: 10 | t.timestamps 11 | end 12 | end 13 | 14 | def down 15 | drop_table :movies 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/movies/same_director_listing.html.haml: -------------------------------------------------------------------------------- 1 | %h1 Movies 2 | 3 | %table#movies 4 | %thead 5 | %tr 6 | %th Title 7 | %th Rating 8 | %th Release Date 9 | %th Director 10 | %th More Info 11 | %tbody 12 | - @movies_same_director.each do |movie| 13 | %tr 14 | %td= movie.title 15 | %td= movie.rating 16 | %td= movie.director 17 | %td= movie.release_date 18 | %td= link_to "More about #{movie.title}", movie_path(movie) 19 | 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into including all the files listed below. 2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically 3 | // be included in the compiled file accessible from http://example.com/assets/application.js 4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 5 | // the compiled file. 6 | // 7 | //= require jquery 8 | //= require jquery_ujs 9 | //= require_tree . 10 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Rottenpotatoes::Application.config.secret_token = '683d4dea01b4bc5f21a276ea8cedf23a4f26d44d8e8680a2c16fb0c10ee60daae78896b37cce798dc793dc270bc7c1325ab83b175c6b35aea8e2cb2d19a25f8f' 8 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /app/views/movies/edit.html.haml: -------------------------------------------------------------------------------- 1 | -# edit.html.haml using partial 2 | 3 | %h1 Edit Existing Movie 4 | 5 | = form_tag movie_path(@movie), :method => :put do 6 | 7 | = label :movie, :title, 'Title' 8 | = text_field :movie, 'title' 9 | 10 | = label :movie, :director, 'Director' 11 | = text_field :movie, 'director' 12 | 13 | = label :movie, :rating, 'Rating' 14 | = select :movie, :rating, ['G','PG','PG-13','R','NC-17'] 15 | 16 | = label :movie, :release_date, 'Released On' 17 | = date_select :movie, :release_date 18 | 19 | = submit_tag 'Update Movie Info' 20 | -------------------------------------------------------------------------------- /app/views/movies/show.html.haml: -------------------------------------------------------------------------------- 1 | -# in app/views/movies/show.html.haml 2 | 3 | %h2 Details about #{@movie.title} 4 | 5 | %ul#details 6 | %li 7 | Director: 8 | = @movie.director 9 | %li 10 | Rating: 11 | = @movie.rating 12 | %li 13 | Released on: 14 | = @movie.release_date.strftime("%B %d, %Y") 15 | 16 | %h3 Description: 17 | 18 | %p#description= @movie.description 19 | 20 | = link_to 'Find Movies With Same Director', :controller => "movies", :action => "same_director_listing", :id => @movie.id 21 | = link_to 'Edit', edit_movie_path(@movie) 22 | = button_to 'Delete', movie_path(@movie), :method => :delete, :confirm => 'Are you sure?' 23 | = link_to 'Back to movie list', movies_path 24 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: &test 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | 27 | cucumber: 28 | <<: *test 29 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |

We've been notified about this issue and we'll take a look at it shortly.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/movie_same_director_listing_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe MoviesController, :type => :controller do 4 | 5 | before(:each) do 6 | @tmp = mock_model(Movie, :title => "Test Movie", :rating => "R", :director=>"T") 7 | @tmp_nd = mock_model(Movie, :title => "tt", :director => " ") 8 | Movie.stub!(:find).and_return(@tmp) 9 | Movie.stub!(:where).and_return([@tmp,]) 10 | end 11 | 12 | it "should respond properly to same_director_listing request" do 13 | Movie.should_receive(:find) 14 | Movie.should_receive(:where) 15 | 16 | get :same_director_listing, :id => @tmp.id 17 | response.should render_template("same_director_listing") 18 | end 19 | 20 | it "should redirect to homepage if director field is empty" do 21 | Movie.should_receive(:find) 22 | 23 | get :same_director_listing, :id => @tmp_nd.id 24 | response.should render_template("") 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'rails', '3.1.0' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | # for Heroku deployment - as described in Ap. A of ELLS book 9 | group :development, :test do 10 | gem 'sqlite3' 11 | gem 'ruby-debug19', :require => 'ruby-debug' 12 | gem 'cucumber-rails' 13 | gem 'cucumber-rails-training-wheels' 14 | gem 'database_cleaner' 15 | gem 'capybara' 16 | gem 'launchy' 17 | gem 'rspec-mocks' 18 | gem 'rspec-rails' 19 | gem 'simplecov' 20 | end 21 | group :production do 22 | gem 'pg' 23 | end 24 | 25 | # Gems used only for assets and not required 26 | # in production environments by default. 27 | group :assets do 28 | gem 'therubyracer' 29 | gem 'sass-rails', " ~> 3.1.0" 30 | gem 'coffee-rails', "~> 3.1.0" 31 | gem 'uglifier' 32 | end 33 | 34 | gem 'jquery-rails' 35 | 36 | # Use unicorn as the web server 37 | # gem 'unicorn' 38 | 39 | # Deploy with Capistrano 40 | # gem 'capistrano' 41 | 42 | # To use debugger 43 | gem 'haml' 44 | -------------------------------------------------------------------------------- /app/views/movies/index.html.haml: -------------------------------------------------------------------------------- 1 | -# This file is app/views/movies/index.html.haml 2 | %h1 All Movies 3 | 4 | = form_tag movies_path, :method => :get, :id => 'ratings_form' do 5 | = hidden_field_tag "title_sort", true if @title_header 6 | = hidden_field_tag ":release_date_sort", true if @date_header 7 | Include: 8 | - @all_ratings.each do |rating| 9 | = rating 10 | = check_box_tag "ratings[#{rating}]", 1, @selected_ratings.include?(rating) 11 | = submit_tag 'Refresh', :id => 'ratings_submit' 12 | 13 | %table#movies 14 | %thead 15 | %tr 16 | %th{:class => @title_header}= link_to 'Movie Title', movies_path(:sort => 'title', :ratings => @selected_ratings), :id => 'title_header' 17 | %th Rating 18 | %th{:class => @date_header}= link_to 'Release Date', movies_path(:sort => 'release_date', :ratings => @selected_ratings), :id => 'release_date_header' 19 | %th More Info 20 | %tbody 21 | - @movies.each do |movie| 22 | %tr 23 | %td= movie.title 24 | %td= movie.rating 25 | %td= movie.release_date 26 | %td= link_to "More about #{movie.title}", movie_path(movie) 27 | 28 | = link_to 'Add new movie', new_movie_path 29 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rottenpotatoes::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Do not compress assets 26 | config.assets.compress = false 27 | 28 | # Expands the lines which load the assets 29 | config.assets.debug = true 30 | end 31 | -------------------------------------------------------------------------------- /db/migrate/20120130161449_add_more_movies.rb: -------------------------------------------------------------------------------- 1 | class AddMoreMovies < ActiveRecord::Migration 2 | MORE_MOVIES = [ 3 | {:title => 'Aladdin', :rating => 'G', :release_date => '25-Nov-1992'}, 4 | {:title => 'The Terminator', :rating => 'R', :release_date => '26-Oct-1984'}, 5 | {:title => 'When Harry Met Sally', :rating => 'R', :release_date => '21-Jul-1989'}, 6 | {:title => 'The Help', :rating => 'PG-13', :release_date => '10-Aug-2011'}, 7 | {:title => 'Chocolat', :rating => 'PG-13', :release_date => '5-Jan-2001'}, 8 | {:title => 'Amelie', :rating => 'R', :release_date => '25-Apr-2001'}, 9 | {:title => '2001: A Space Odyssey', :rating => 'G', :release_date => '6-Apr-1968'}, 10 | {:title => 'The Incredibles', :rating => 'PG', :release_date => '5-Nov-2004'}, 11 | {:title => 'Raiders of the Lost Ark', :rating => 'PG', :release_date => '12-Jun-1981'}, 12 | {:title => 'Chicken Run', :rating => 'G', :release_date => '21-Jun-2000'}, 13 | ] 14 | def up 15 | MORE_MOVIES.each do |movie| 16 | Movie.create!(movie) 17 | end 18 | end 19 | 20 | def down 21 | MORE_MOVIES.each do |movie| 22 | Movie.find_by_title_and_rating(movie[:title], movie[:rating]).destroy 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /features/support/selectors.rb: -------------------------------------------------------------------------------- 1 | # TL;DR: YOU SHOULD DELETE THIS FILE 2 | # 3 | # This file is used by web_steps.rb, which you should also delete 4 | # 5 | # You have been warned 6 | module HtmlSelectorsHelpers 7 | # Maps a name to a selector. Used primarily by the 8 | # 9 | # When /^(.+) within (.+)$/ do |step, scope| 10 | # 11 | # step definitions in web_steps.rb 12 | # 13 | def selector_for(locator) 14 | case locator 15 | 16 | when "the page" 17 | "html > body" 18 | 19 | # Add more mappings here. 20 | # Here is an example that pulls values out of the Regexp: 21 | # 22 | # when /^the (notice|error|info) flash$/ 23 | # ".flash.#{$1}" 24 | 25 | # You can also return an array to use a different selector 26 | # type, like: 27 | # 28 | # when /the header/ 29 | # [:xpath, "//header"] 30 | 31 | # This allows you to provide a quoted selector as the scope 32 | # for "within" steps as was previously the default for the 33 | # web steps: 34 | when /^"(.+)"$/ 35 | $1 36 | 37 | else 38 | raise "Can't find mapping from \"#{locator}\" to a selector.\n" + 39 | "Now, go and add a mapping in #{__FILE__}" 40 | end 41 | end 42 | end 43 | 44 | World(HtmlSelectorsHelpers) 45 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] ||= 'test' 3 | require File.expand_path("../../config/environment", __FILE__) 4 | require 'rspec/rails' 5 | require 'rspec/autorun' 6 | require 'simplecov' 7 | SimpleCov.start 'rails' 8 | 9 | # Requires supporting ruby files with custom matchers and macros, etc, 10 | # in spec/support/ and its subdirectories. 11 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 12 | 13 | RSpec.configure do |config| 14 | # ## Mock Framework 15 | # 16 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 17 | # 18 | # config.mock_with :mocha 19 | # config.mock_with :flexmock 20 | # config.mock_with :rr 21 | 22 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 23 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 24 | 25 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 26 | # examples within a transaction, remove the following line or assign false 27 | # instead of true. 28 | config.use_transactional_fixtures = true 29 | 30 | # If true, the base class of anonymous controllers will be inferred 31 | # automatically. This will be the default behavior in future versions of 32 | # rspec-rails. 33 | config.infer_base_class_for_anonymous_controllers = false 34 | end 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | padding: 0; 4 | background: White; 5 | color: DarkSlateGrey; 6 | font-family: Tahoma, Verdana, sans-serif; 7 | font-size: 10pt; 8 | } 9 | div#main { 10 | margin: 0; 11 | padding: 0 20px 20px; 12 | } 13 | a { 14 | background: transparent; 15 | color: maroon; 16 | text-decoration: underline; 17 | font-weight: bold; 18 | } 19 | h1 { 20 | color: maroon; 21 | font-size: 150%; 22 | font-style: italic; 23 | display: block; 24 | width: 100%; 25 | border-bottom: 1px solid DarkSlateGrey; 26 | } 27 | h1.title { 28 | margin: 0 0 1em; 29 | padding: 10px; 30 | background-color: orange; 31 | color: white; 32 | border-bottom: 4px solid gold; 33 | font-size: 2em; 34 | font-style: normal; 35 | } 36 | table#movies { 37 | margin: 10px; 38 | border-collapse: collapse; 39 | width: 100%; 40 | border-bottom: 2px solid black; 41 | } 42 | table#movies th { 43 | border: 2px solid white; 44 | font-weight: bold; 45 | background-color: wheat; 46 | } 47 | table#movies th, table#movies td { 48 | padding: 4px; 49 | text-align: left; 50 | } 51 | table#movies th.hilite { 52 | background-color: yellow; 53 | } 54 | #notice #warning { 55 | background: rosybrown; 56 | margin: 1em 0; 57 | padding: 4px; 58 | } 59 | form label { 60 | display: block; 61 | line-height: 25px; 62 | font-weight: bold; 63 | color: maroon; 64 | } 65 | -------------------------------------------------------------------------------- /features/search_for_movies_by_director.feature: -------------------------------------------------------------------------------- 1 | Feature: search for movies by director 2 | 3 | As a movie buff 4 | So that I can find movies with my favorite director 5 | I want to include and serach on director information in movies I enter 6 | 7 | Background: movies in database 8 | 9 | Given the following movies exist: 10 | | title | rating | director | release_date | 11 | | Star Wars | PG | George Lucas | 1977-05-25 | 12 | | Blade Runner | PG | Ridley Scott | 1982-06-25 | 13 | | Alien | R | | 1979-05-25 | 14 | | THX-1138 | R | George Lucas | 1971-03-11 | 15 | 16 | Scenario: add director to existing movie 17 | When I go to the edit page for "Alien" 18 | And I fill in "Director" with "Ridley Scott" 19 | And I press "Update Movie Info" 20 | Then the director of "Alien" should be "Ridley Scott" 21 | 22 | Scenario: find movie with same director 23 | Given I am on the details page for "Star Wars" 24 | When I follow "Find Movies With Same Director" 25 | Then I should be on the Similar Movies page for "Star Wars" 26 | And I should see "THX-1138" 27 | But I should not see "Blade Runner" 28 | 29 | Scenario: can't find similar movies if we don't know director (sad path) 30 | Given I am on the details page for "Alien" 31 | Then I should not see "Ridley Scott" 32 | When I follow "Find Movies With Same Director" 33 | Then I should be on the home page 34 | And I should see "'Alien' has no director info" 35 | -------------------------------------------------------------------------------- /features/support/paths.rb: -------------------------------------------------------------------------------- 1 | # TL;DR: YOU SHOULD DELETE THIS FILE 2 | # 3 | # This file is used by web_steps.rb, which you should also delete 4 | # 5 | # You have been warned 6 | module NavigationHelpers 7 | # Maps a name to a path. Used by the 8 | # 9 | # When /^I go to (.+)$/ do |page_name| 10 | # 11 | # step definition in web_steps.rb 12 | # 13 | def path_to(page_name) 14 | case page_name 15 | 16 | when /^the (RottenPotatoes )?home\s?page$/ then '/movies' 17 | when /^the movies page$/ then '/movies' 18 | when /^the home\s?page$/ 19 | '/movies' 20 | 21 | when /^the edit page for \"(.*)\"$/ 22 | id = Movie.where("title = ?", $1).first.id 23 | "/movies/#{id}/edit" 24 | # Add more mappings here. 25 | # Here is an example that pulls values out of the Regexp: 26 | # 27 | # when /^(.*)'s profile page$/i 28 | # user_profile_path(User.find_by_login($1)) 29 | when /^the details page for \"(.*)\"$/ 30 | id = Movie.where("title = ?", $1).first.id 31 | "/movies/#{id}" 32 | 33 | when /^the Similar Movies page for \"(.*)\"$/ 34 | id = Movie.where("title = ?", $1).first.id 35 | "/movies/#{id}/same_director_listing" 36 | 37 | 38 | else 39 | begin 40 | page_name =~ /^the (.*) page$/ 41 | path_components = $1.split(/\s+/) 42 | self.send(path_components.push('path').join('_').to_sym) 43 | rescue NoMethodError, ArgumentError 44 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" + 45 | "Now, go and add a mapping in #{__FILE__}" 46 | end 47 | end 48 | end 49 | end 50 | 51 | World(NavigationHelpers) 52 | -------------------------------------------------------------------------------- /features/sort_movie_list.feature: -------------------------------------------------------------------------------- 1 | Feature: display list of movies sorted by different criteria 2 | 3 | As an avid moviegoer 4 | So that I can quickly browse movies based on my preferences 5 | I want to see movies sorted by title or release date 6 | 7 | Background: movies have been added to database 8 | 9 | Given the following movies exist: 10 | | title | rating | release_date | 11 | | Aladdin | G | 25-Nov-1992 | 12 | | The Terminator | R | 26-Oct-1984 | 13 | | When Harry Met Sally | R | 21-Jul-1989 | 14 | | The Help | PG-13 | 10-Aug-2011 | 15 | | Chocolat | PG-13 | 5-Jan-2001 | 16 | | Amelie | R | 25-Apr-2001 | 17 | | 2001: A Space Odyssey | G | 6-Apr-1968 | 18 | | The Incredibles | PG | 5-Nov-2004 | 19 | | Raiders of the Lost Ark | PG | 12-Jun-1981 | 20 | | Chicken Run | G | 21-Jun-2000 | 21 | 22 | And I am on the RottenPotatoes home page 23 | 24 | Scenario: sort movies alphabetically 25 | When I follow "Movie Title" 26 | When I check the following ratings: PG,G,PG-13,NC-17,R 27 | When I press "Refresh" 28 | Then I should see "2001" before " Aladdin" 29 | Then I should see "Aladdin" before "Amelie" 30 | Then I should see "Amelie" before "Chicken Run" 31 | Then I should see "Chicken Run" before "Chocolat" 32 | Then I should see "Chocolat" before "Raider" 33 | Then I should see "Raider" before "The Help" 34 | 35 | Scenario: sort movies in increasing order of release date 36 | When I follow "Release Date" 37 | When I check the following ratings: PG,G,PG-13,NC-17,R 38 | When I press "Refresh" 39 | Then I should see "When Harry" before "Chicken Run" 40 | 41 | -------------------------------------------------------------------------------- /features/step_definitions/movie_steps.rb: -------------------------------------------------------------------------------- 1 | # Add a declarative step here for populating the DB with movies. 2 | 3 | Given /the following movies exist/ do |movies_table| 4 | movies_table.hashes.each do |movie| 5 | Movie.create(movie) 6 | end 7 | end 8 | 9 | # Make sure that one string (regexp) occurs before or after another one 10 | # on the same page 11 | 12 | Then /I should see "(.*)" before "(.*)"/ do |e1, e2| 13 | # ensure that that e1 occurs before e2. 14 | r = page.body =~ (/#{Regexp.quote(e1)}.*#{Regexp.quote(e2)}/m) 15 | assert r 16 | end 17 | 18 | # Make it easier to express checking or unchecking several boxes at once 19 | # "When I uncheck the following ratings: PG, G, R" 20 | # "When I check the following ratings: G" 21 | 22 | When /I (un)?check the following ratings: (.*)/ do |uncheck, rating_list| 23 | ratings = rating_list.split(',') 24 | if uncheck then 25 | ratings.each{ |rating| 26 | uncheck("ratings_"+rating) 27 | } 28 | else 29 | ratings.each{ |rating| 30 | check("ratings_"+rating) 31 | } 32 | end 33 | end 34 | 35 | 36 | Then /I should see all of the movies/ do 37 | movies = Movie.all 38 | movies.each{ |movie| 39 | if page.respond_to? :should 40 | page.should have_content(movie.title) 41 | else 42 | assert page.has_content?(movie.title) 43 | end 44 | } 45 | end 46 | 47 | Then /I should see none of the movies/ do 48 | movies = Movie.all 49 | movies.each{ |movie| 50 | if page.respond_to? :should 51 | page.should have_no_content(movie.title) 52 | else 53 | assert page.has_no_content?(movie.title) 54 | end 55 | } 56 | end 57 | 58 | Then /the director of \"(.*)\" should be \"(.*)\"/ do |movie_name, director| 59 | movie = Movie.where('title = ?', movie_name).first 60 | r = page.body =~ (/
  • .*Director:\s*#{Regexp.quote(director)}.*
  • /m) 61 | assert r 62 | 63 | end 64 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rottenpotatoes::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Use SQL instead of Active Record's schema dumper when creating the test database. 33 | # This is necessary if your schema can't be completely dumped by the schema dumper, 34 | # like if you have constraints or database-specific column types 35 | # config.active_record.schema_format = :sql 36 | 37 | # Print deprecation notices to the stderr 38 | config.active_support.deprecation = :stderr 39 | 40 | # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets 41 | config.assets.allow_debugging = true 42 | end 43 | -------------------------------------------------------------------------------- /features/filter_movie_list.feature: -------------------------------------------------------------------------------- 1 | Feature: display list of movies filtered by MPAA rating 2 | 3 | As a concerned parent 4 | So that I can quickly browse movies appropriate for my family 5 | I want to see movies matching only certain MPAA ratings 6 | 7 | Background: movies have been added to database 8 | 9 | Given the following movies exist: 10 | | title | rating | release_date | 11 | | Aladdin | G | 25-Nov-1992 | 12 | | The Terminator | R | 26-Oct-1984 | 13 | | When Harry Met Sally | R | 21-Jul-1989 | 14 | | The Help | PG-13 | 10-Aug-2011 | 15 | | Chocolat | PG-13 | 5-Jan-2001 | 16 | | Amelie | R | 25-Apr-2001 | 17 | | 2001: A Space Odyssey | G | 6-Apr-1968 | 18 | | The Incredibles | PG | 5-Nov-2004 | 19 | | Raiders of the Lost Ark | PG | 12-Jun-1981 | 20 | | Chicken Run | G | 21-Jun-2000 | 21 | 22 | And I am on the RottenPotatoes home page 23 | 24 | Scenario: restrict to movies with 'PG' or 'R' ratings 25 | When I check "ratings_PG" 26 | When I check "ratings_R" 27 | When I uncheck "ratings_PG-13" 28 | When I uncheck "ratings_NC-17" 29 | When I uncheck "ratings_G" 30 | When I press "Refresh" 31 | Then I should not see "Aladdin" 32 | Then I should see "The Terminator" 33 | Then I should see "When Harry Met Sally" 34 | Then I should not see "The Help" 35 | Then I should not see "Chocolat" 36 | Then I should see "Amelie" 37 | Then I should not see "2011: A Space Odyssey" 38 | Then I should see "The Incredibles" 39 | Then I should see "Raiders of the Lost Ark" 40 | Then I should not see "Chicken Run" 41 | 42 | Scenario: no ratings selected 43 | When I uncheck the following ratings: PG,G,PG-13,NC-17,R 44 | When I press "Refresh" 45 | Then I should see none of the movies 46 | 47 | Scenario: all ratings selected 48 | # see assignment 49 | When I check the following ratings: PG,G,PG-13,NC-17,R 50 | When I press "Refresh" 51 | Then I should see all of the movies 52 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rottenpotatoes::Application.routes.draw do 2 | # The priority is based upon order of creation: 3 | # first created -> highest priority. 4 | 5 | # Sample of regular route: 6 | # match 'products/:id' => 'catalog#view' 7 | # Keep in mind you can assign values other than :controller and :action 8 | 9 | # Sample of named route: 10 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 11 | # This route can be invoked with purchase_url(:id => product.id) 12 | 13 | # Sample resource route (maps HTTP verbs to controller actions automatically): 14 | # resources :products 15 | 16 | resources :movies 17 | 18 | match '/movies/(:id)/same_director_listing', :to => 'movies#same_director_listing' 19 | 20 | # Sample resource route with options: 21 | # resources :products do 22 | # member do 23 | # get 'short' 24 | # post 'toggle' 25 | # end 26 | # 27 | # collection do 28 | # get 'sold' 29 | # end 30 | # end 31 | 32 | # Sample resource route with sub-resources: 33 | # resources :products do 34 | # resources :comments, :sales 35 | # resource :seller 36 | # end 37 | 38 | # Sample resource route with more complex sub-resources 39 | # resources :products do 40 | # resources :comments 41 | # resources :sales do 42 | # get 'recent', :on => :collection 43 | # end 44 | # end 45 | 46 | # Sample resource route within a namespace: 47 | # namespace :admin do 48 | # # Directs /admin/products/* to Admin::ProductsController 49 | # # (app/controllers/admin/products_controller.rb) 50 | # resources :products 51 | # end 52 | 53 | # You can have the root of your site routed with "root" 54 | # just remember to delete public/index.html. 55 | # root :to => 'welcome#index' 56 | 57 | # See how all your routes lay out with "rake routes" 58 | 59 | # This is a legacy wild controller route that's not recommended for RESTful applications. 60 | # Note: This route will make all actions in every controller accessible via GET requests. 61 | # match ':controller(/:action(/:id(.:format)))' 62 | end 63 | -------------------------------------------------------------------------------- /app/controllers/movies_controller.rb: -------------------------------------------------------------------------------- 1 | class MoviesController < ApplicationController 2 | 3 | def show 4 | id = params[:id] # retrieve movie ID from URI route 5 | @movie = Movie.find(id) # look up movie by unique ID 6 | # will render app/views/movies/show. by default 7 | end 8 | 9 | def index 10 | sort = params[:sort] || session[:sort] 11 | case sort 12 | when 'title' 13 | ordering,@title_header = {:order => :title}, 'hilite' 14 | when 'release_date' 15 | ordering,@date_header = {:order => :release_date}, 'hilite' 16 | end 17 | @all_ratings = Movie.all_ratings 18 | @selected_ratings = params[:ratings] || session[:ratings] || {} 19 | 20 | if params[:sort] != session[:sort] 21 | session[:sort] = sort 22 | redirect_to :sort => sort, :ratings => @selected_ratings and return 23 | end 24 | 25 | if params[:ratings] != session[:ratings] and @selected_ratings != {} 26 | session[:sort] = sort 27 | session[:ratings] = @selected_ratings 28 | redirect_to :sort => sort, :ratings => @selected_ratings and return 29 | end 30 | @movies = Movie.find_all_by_rating(@selected_ratings.keys, ordering) 31 | end 32 | 33 | def new 34 | # default: render 'new' template 35 | end 36 | 37 | def create 38 | @movie = Movie.create!(params[:movie]) 39 | flash[:notice] = "#{@movie.title} was successfully created." 40 | redirect_to movies_path 41 | end 42 | 43 | def edit 44 | @movie = Movie.find params[:id] 45 | end 46 | 47 | def update 48 | @movie = Movie.find params[:id] 49 | @movie.update_attributes!(params[:movie]) 50 | flash[:notice] = "#{@movie.title} was successfully updated." 51 | redirect_to movie_path(@movie) 52 | end 53 | 54 | def destroy 55 | @movie = Movie.find(params[:id]) 56 | @movie.destroy 57 | flash[:notice] = "Movie '#{@movie.title}' deleted." 58 | redirect_to movies_path 59 | end 60 | 61 | def same_director_listing 62 | @movie = Movie.find(params[:id]) 63 | director = @movie.director.strip 64 | if director.length > 0 65 | @movies_same_director = Movie.where(:director => @movie.director) 66 | else 67 | flash[:notice] = "'#{@movie.title}' has no director info" 68 | redirect_to movies_path 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rottenpotatoes::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # DO fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = true 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to Rails.root.join("public/assets") 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Use a different logger for distributed setups 37 | # config.logger = SyslogLogger.new 38 | 39 | # Use a different cache store in production 40 | # config.cache_store = :mem_cache_store 41 | 42 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 43 | # config.action_controller.asset_host = "http://assets.example.com" 44 | 45 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 46 | # config.assets.precompile += %w( search.js ) 47 | 48 | # Disable delivery errors, bad email addresses will be ignored 49 | # config.action_mailer.raise_delivery_errors = false 50 | 51 | # Enable threaded mode 52 | # config.threadsafe! 53 | 54 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 55 | # the I18n.default_locale when a translation can not be found) 56 | config.i18n.fallbacks = true 57 | 58 | # Send deprecation notices to registered listeners 59 | config.active_support.deprecation = :notify 60 | end 61 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "active_resource/railtie" 8 | require "sprockets/railtie" 9 | # require "rails/test_unit/railtie" 10 | 11 | if defined?(Bundler) 12 | # If you precompile assets before deploying to production, use this line 13 | Bundler.require *Rails.groups(:assets => %w(development test)) 14 | # If you want your assets lazily compiled in production, use this line 15 | # Bundler.require(:default, :assets, Rails.env) 16 | end 17 | 18 | module Rottenpotatoes 19 | class Application < Rails::Application 20 | # Settings in config/environments/* take precedence over those specified here. 21 | # Application configuration should go into files in config/initializers 22 | # -- all .rb files in that directory are automatically loaded. 23 | 24 | # Custom directories with classes and modules you want to be autoloadable. 25 | # config.autoload_paths += %W(#{config.root}/extras) 26 | 27 | # Only load the plugins named here, in the order given (default is alphabetical). 28 | # :all can be used as a placeholder for all plugins not explicitly named. 29 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 30 | 31 | # Activate observers that should always be running. 32 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 33 | 34 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 35 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 36 | # config.time_zone = 'Central Time (US & Canada)' 37 | 38 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 39 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 40 | # config.i18n.default_locale = :de 41 | 42 | # Configure the default encoding used in templates for Ruby 1.9. 43 | config.encoding = "utf-8" 44 | 45 | # Configure sensitive parameters which will be filtered from the log file. 46 | config.filter_parameters += [:password] 47 | 48 | # Enable the asset pipeline 49 | config.assets.enabled = true 50 | 51 | # Version of your assets, change this if you want to expire all your assets 52 | config.assets.version = '1.0' 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /public/stylesheets/general.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | padding: 0; 4 | background: White; 5 | color: DarkSlateGrey; 6 | font-family: Tahoma, Verdana, sans-serif; 7 | font-size: 10pt; 8 | } 9 | h2 { 10 | margin: 1em 0 .5em; 11 | padding: 0; 12 | background: transparent; 13 | color: maroon; 14 | font-size: 1.5em; 15 | } 16 | .odd { 17 | background: white; 18 | } 19 | .even { 20 | background: wheat; 21 | } 22 | a { 23 | background: transparent; 24 | color: maroon; 25 | text-decoration: underline; 26 | font-weight: bold; 27 | } 28 | h1 { 29 | margin: 0 0 1em; 30 | padding: 10px; 31 | background-color: orange; 32 | color: white; 33 | border-bottom: 4px solid gold; 34 | font-size: 2em; 35 | } 36 | h1 a { 37 | text-decoration: none; 38 | background: transparent; 39 | color: white; 40 | } 41 | table#movies { 42 | border-collapse: collapse; 43 | width: 100%; 44 | border-bottom: 2px solid black; 45 | } 46 | table#movies th { 47 | border: 2px solid black; 48 | font-weight: bold; 49 | } 50 | table#movies th, table#movies td { 51 | padding: 4px; 52 | text-align: left; 53 | } 54 | em { 55 | font-weight: bold; 56 | font-style: normal; 57 | } 58 | div#body { 59 | margin: 0; 60 | padding: 0 20px 20px; 61 | } 62 | .errorExplanation { 63 | padding: 0 10px; 64 | margin: 1em 2px; 65 | border: 2px solid red; 66 | background: #fcb; 67 | } 68 | .errorExplanation h2 { 69 | font-size: 1.1em; 70 | color: red; 71 | } 72 | .errorExplanation ul { 73 | list-style: disc inside; 74 | } 75 | div.fieldWithErrors { 76 | display: inline; 77 | } 78 | .fieldWithErrors input, .fieldWithErrors textarea, .fieldWithErrors select { 79 | background: #fcb; 80 | } 81 | #flash_notice { 82 | background: rosybrown; 83 | margin: 1em 0; 84 | padding: 4px; 85 | } 86 | #flash_error { 87 | background: pink; 88 | margin: 1em 0; 89 | padding: 4px; 90 | } 91 | ul#page_nav { 92 | margin: 2em 0 0; 93 | padding: 0; 94 | list-style: none; 95 | } 96 | ul#page_nav li { 97 | margin: 1em 0; 98 | padding: 0; 99 | } 100 | form ul { 101 | margin: 10px; 102 | padding: 0; 103 | list-style: none; 104 | } 105 | form li { 106 | margin: 1em 0; 107 | padding: 0; 108 | } 109 | form label { 110 | display: inline-block; 111 | width: 150px; 112 | vertical-align: top; 113 | line-height: 25px; 114 | } 115 | form #submit { 116 | margin-left: 150px; 117 | } 118 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'simplecov' 2 | SimpleCov.start 'rails' 3 | # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. 4 | # It is recommended to regenerate this file in the future when you upgrade to a 5 | # newer version of cucumber-rails. Consider adding your own code to a new file 6 | # instead of editing this one. Cucumber will automatically load all features/**/*.rb 7 | # files. 8 | 9 | require 'cucumber/rails' 10 | 11 | # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In 12 | # order to ease the transition to Capybara we set the default here. If you'd 13 | # prefer to use XPath just remove this line and adjust any selectors in your 14 | # steps to use the XPath syntax. 15 | Capybara.default_selector = :css 16 | 17 | # By default, any exception happening in your Rails application will bubble up 18 | # to Cucumber so that your scenario will fail. This is a different from how 19 | # your application behaves in the production environment, where an error page will 20 | # be rendered instead. 21 | # 22 | # Sometimes we want to override this default behaviour and allow Rails to rescue 23 | # exceptions and display an error page (just like when the app is running in production). 24 | # Typical scenarios where you want to do this is when you test your error pages. 25 | # There are two ways to allow Rails to rescue exceptions: 26 | # 27 | # 1) Tag your scenario (or feature) with @allow-rescue 28 | # 29 | # 2) Set the value below to true. Beware that doing this globally is not 30 | # recommended as it will mask a lot of errors for you! 31 | # 32 | ActionController::Base.allow_rescue = false 33 | 34 | # Remove/comment out the lines below if your app doesn't have a database. 35 | # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. 36 | begin 37 | DatabaseCleaner.strategy = :transaction 38 | rescue NameError 39 | raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." 40 | end 41 | 42 | # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. 43 | # See the DatabaseCleaner documentation for details. Example: 44 | # 45 | # Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do 46 | # # { :except => [:widgets] } may not do what you expect here 47 | # # as tCucumber::Rails::Database.javascript_strategy overrides 48 | # # this setting. 49 | # DatabaseCleaner.strategy = :truncation 50 | # end 51 | # 52 | # Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do 53 | # DatabaseCleaner.strategy = :transaction 54 | # end 55 | # 56 | 57 | # Possible values are :truncation and :transaction 58 | # The :transaction strategy is faster, but might give you threading problems. 59 | # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature 60 | Cucumber::Rails::Database.javascript_strategy = :truncation 61 | 62 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (3.1.0) 5 | actionpack (= 3.1.0) 6 | mail (~> 2.3.0) 7 | actionpack (3.1.0) 8 | activemodel (= 3.1.0) 9 | activesupport (= 3.1.0) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | i18n (~> 0.6) 13 | rack (~> 1.3.2) 14 | rack-cache (~> 1.0.3) 15 | rack-mount (~> 0.8.2) 16 | rack-test (~> 0.6.1) 17 | sprockets (~> 2.0.0) 18 | activemodel (3.1.0) 19 | activesupport (= 3.1.0) 20 | bcrypt-ruby (~> 3.0.0) 21 | builder (~> 3.0.0) 22 | i18n (~> 0.6) 23 | activerecord (3.1.0) 24 | activemodel (= 3.1.0) 25 | activesupport (= 3.1.0) 26 | arel (~> 2.2.1) 27 | tzinfo (~> 0.3.29) 28 | activeresource (3.1.0) 29 | activemodel (= 3.1.0) 30 | activesupport (= 3.1.0) 31 | activesupport (3.1.0) 32 | multi_json (~> 1.0) 33 | addressable (2.2.7) 34 | archive-tar-minitar (0.5.2) 35 | arel (2.2.1) 36 | bcrypt-ruby (3.0.1) 37 | builder (3.0.0) 38 | capybara (1.1.2) 39 | mime-types (>= 1.16) 40 | nokogiri (>= 1.3.3) 41 | rack (>= 1.0.0) 42 | rack-test (>= 0.5.4) 43 | selenium-webdriver (~> 2.0) 44 | xpath (~> 0.1.4) 45 | childprocess (0.3.1) 46 | ffi (~> 1.0.6) 47 | coffee-rails (3.1.1) 48 | coffee-script (>= 2.2.0) 49 | railties (~> 3.1.0) 50 | coffee-script (2.2.0) 51 | coffee-script-source 52 | execjs 53 | coffee-script-source (1.2.0) 54 | columnize (0.3.6) 55 | cucumber (1.1.8) 56 | builder (>= 2.1.2) 57 | diff-lcs (>= 1.1.2) 58 | gherkin (~> 2.8.0) 59 | json (>= 1.4.6) 60 | term-ansicolor (>= 1.0.6) 61 | cucumber-rails (1.3.0) 62 | capybara (>= 1.1.2) 63 | cucumber (>= 1.1.8) 64 | nokogiri (>= 1.5.0) 65 | cucumber-rails-training-wheels (1.0.0) 66 | cucumber-rails (>= 1.1.1) 67 | database_cleaner (0.7.1) 68 | diff-lcs (1.1.3) 69 | erubis (2.7.0) 70 | execjs (1.3.0) 71 | multi_json (~> 1.0) 72 | ffi (1.0.11) 73 | gherkin (2.8.0) 74 | json (>= 1.4.6) 75 | haml (3.1.4) 76 | hike (1.2.1) 77 | i18n (0.6.0) 78 | jquery-rails (1.0.19) 79 | railties (~> 3.0) 80 | thor (~> 0.14) 81 | json (1.6.5) 82 | json_pure (1.6.5) 83 | launchy (2.0.5) 84 | addressable (~> 2.2.6) 85 | libv8 (3.3.10.4) 86 | linecache19 (0.5.12) 87 | ruby_core_source (>= 0.1.4) 88 | mail (2.3.0) 89 | i18n (>= 0.4.0) 90 | mime-types (~> 1.16) 91 | treetop (~> 1.4.8) 92 | mime-types (1.17.2) 93 | multi_json (1.1.0) 94 | nokogiri (1.5.0) 95 | pg (0.13.1) 96 | polyglot (0.3.3) 97 | rack (1.3.6) 98 | rack-cache (1.0.3) 99 | rack (>= 0.4) 100 | rack-mount (0.8.3) 101 | rack (>= 1.0.0) 102 | rack-ssl (1.3.2) 103 | rack 104 | rack-test (0.6.1) 105 | rack (>= 1.0) 106 | rails (3.1.0) 107 | actionmailer (= 3.1.0) 108 | actionpack (= 3.1.0) 109 | activerecord (= 3.1.0) 110 | activeresource (= 3.1.0) 111 | activesupport (= 3.1.0) 112 | bundler (~> 1.0) 113 | railties (= 3.1.0) 114 | railties (3.1.0) 115 | actionpack (= 3.1.0) 116 | activesupport (= 3.1.0) 117 | rack-ssl (~> 1.3.2) 118 | rake (>= 0.8.7) 119 | rdoc (~> 3.4) 120 | thor (~> 0.14.6) 121 | rake (0.9.2.2) 122 | rdoc (3.12) 123 | json (~> 1.4) 124 | rspec (2.8.0) 125 | rspec-core (~> 2.8.0) 126 | rspec-expectations (~> 2.8.0) 127 | rspec-mocks (~> 2.8.0) 128 | rspec-core (2.8.0) 129 | rspec-expectations (2.8.0) 130 | diff-lcs (~> 1.1.2) 131 | rspec-mocks (2.8.0) 132 | rspec-rails (2.8.1) 133 | actionpack (>= 3.0) 134 | activesupport (>= 3.0) 135 | railties (>= 3.0) 136 | rspec (~> 2.8.0) 137 | ruby-debug-base19 (0.11.25) 138 | columnize (>= 0.3.1) 139 | linecache19 (>= 0.5.11) 140 | ruby_core_source (>= 0.1.4) 141 | ruby-debug19 (0.11.6) 142 | columnize (>= 0.3.1) 143 | linecache19 (>= 0.5.11) 144 | ruby-debug-base19 (>= 0.11.19) 145 | ruby_core_source (0.1.5) 146 | archive-tar-minitar (>= 0.5.2) 147 | rubyzip (0.9.6.1) 148 | sass (3.1.15) 149 | sass-rails (3.1.5) 150 | actionpack (~> 3.1.0) 151 | railties (~> 3.1.0) 152 | sass (~> 3.1.10) 153 | tilt (~> 1.3.2) 154 | selenium-webdriver (2.13.0) 155 | childprocess (>= 0.2.1) 156 | ffi (~> 1.0.9) 157 | json_pure 158 | rubyzip 159 | simplecov (0.4.2) 160 | simplecov-html (~> 0.4.4) 161 | simplecov-html (0.4.5) 162 | sprockets (2.0.3) 163 | hike (~> 1.2) 164 | rack (~> 1.0) 165 | tilt (~> 1.1, != 1.3.0) 166 | sqlite3 (1.3.5) 167 | term-ansicolor (1.0.7) 168 | therubyracer (0.9.10) 169 | libv8 (~> 3.3.10) 170 | thor (0.14.6) 171 | tilt (1.3.3) 172 | treetop (1.4.10) 173 | polyglot 174 | polyglot (>= 0.3.1) 175 | tzinfo (0.3.31) 176 | uglifier (1.2.3) 177 | execjs (>= 0.3.0) 178 | multi_json (>= 1.0.2) 179 | xpath (0.1.4) 180 | nokogiri (~> 1.3) 181 | 182 | PLATFORMS 183 | ruby 184 | 185 | DEPENDENCIES 186 | capybara 187 | coffee-rails (~> 3.1.0) 188 | cucumber-rails 189 | cucumber-rails-training-wheels 190 | database_cleaner 191 | haml 192 | jquery-rails 193 | launchy 194 | pg 195 | rails (= 3.1.0) 196 | rspec-mocks 197 | rspec-rails 198 | ruby-debug19 199 | sass-rails (~> 3.1.0) 200 | simplecov 201 | sqlite3 202 | therubyracer 203 | uglifier 204 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Ruby on Rails: Welcome aboard 5 | 174 | 187 | 188 | 189 |
    190 | 203 | 204 |
    205 | 209 | 210 | 214 | 215 |
    216 |

    Getting started

    217 |

    Here’s how to get rolling:

    218 | 219 |
      220 |
    1. 221 |

      Use rails generate to create your models and controllers

      222 |

      To see all available options, run it without parameters.

      223 |
    2. 224 | 225 |
    3. 226 |

      Set up a default route and remove public/index.html

      227 |

      Routes are set up in config/routes.rb.

      228 |
    4. 229 | 230 |
    5. 231 |

      Create your database

      232 |

      Run rake db:create to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

      233 |
    6. 234 |
    235 |
    236 |
    237 | 238 | 239 |
    240 | 241 | 242 | -------------------------------------------------------------------------------- /features/step_definitions/web_steps.rb: -------------------------------------------------------------------------------- 1 | # TL;DR: YOU SHOULD DELETE THIS FILE 2 | # 3 | # This file was generated by Cucumber-Rails and is only here to get you a head start 4 | # These step definitions are thin wrappers around the Capybara/Webrat API that lets you 5 | # visit pages, interact with widgets and make assertions about page content. 6 | # 7 | # If you use these step definitions as basis for your features you will quickly end up 8 | # with features that are: 9 | # 10 | # * Hard to maintain 11 | # * Verbose to read 12 | # 13 | # A much better approach is to write your own higher level step definitions, following 14 | # the advice in the following blog posts: 15 | # 16 | # * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html 17 | # * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/ 18 | # * http://elabs.se/blog/15-you-re-cuking-it-wrong 19 | # 20 | 21 | 22 | require 'uri' 23 | require 'cgi' 24 | require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) 25 | require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors")) 26 | 27 | module WithinHelpers 28 | def with_scope(locator) 29 | locator ? within(*selector_for(locator)) { yield } : yield 30 | end 31 | end 32 | World(WithinHelpers) 33 | 34 | # Single-line step scoper 35 | When /^(.*) within (.*[^:])$/ do |step, parent| 36 | with_scope(parent) { When step } 37 | end 38 | 39 | # Multi-line step scoper 40 | When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string| 41 | with_scope(parent) { When "#{step}:", table_or_string } 42 | end 43 | 44 | Given /^(?:|I )am on (.+)$/ do |page_name| 45 | visit path_to(page_name) 46 | end 47 | 48 | When /^(?:|I )go to (.+)$/ do |page_name| 49 | visit path_to(page_name) 50 | end 51 | 52 | When /^(?:|I )press "([^"]*)"$/ do |button| 53 | click_button(button) 54 | end 55 | 56 | When /^(?:|I )follow "([^"]*)"$/ do |link| 57 | click_link(link) 58 | end 59 | 60 | When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value| 61 | fill_in(field, :with => value) 62 | end 63 | 64 | When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field| 65 | fill_in(field, :with => value) 66 | end 67 | 68 | # Use this to fill in an entire form with data from a table. Example: 69 | # 70 | # When I fill in the following: 71 | # | Account Number | 5002 | 72 | # | Expiry date | 2009-11-01 | 73 | # | Note | Nice guy | 74 | # | Wants Email? | | 75 | # 76 | # TODO: Add support for checkbox, select or option 77 | # based on naming conventions. 78 | # 79 | When /^(?:|I )fill in the following:$/ do |fields| 80 | fields.rows_hash.each do |name, value| 81 | When %{I fill in "#{name}" with "#{value}"} 82 | end 83 | end 84 | 85 | When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field| 86 | select(value, :from => field) 87 | end 88 | 89 | When /^(?:|I )check "([^"]*)"$/ do |field| 90 | check(field) 91 | end 92 | 93 | When /^(?:|I )uncheck "([^"]*)"$/ do |field| 94 | uncheck(field) 95 | end 96 | 97 | When /^(?:|I )choose "([^"]*)"$/ do |field| 98 | choose(field) 99 | end 100 | 101 | When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field| 102 | attach_file(field, File.expand_path(path)) 103 | end 104 | 105 | Then /^(?:|I )should see "([^"]*)"$/ do |text| 106 | if page.respond_to? :should 107 | page.should have_content(text) 108 | else 109 | assert page.has_content?(text) 110 | end 111 | end 112 | 113 | Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp| 114 | regexp = Regexp.new(regexp) 115 | 116 | if page.respond_to? :should 117 | page.should have_xpath('//*', :text => regexp) 118 | else 119 | assert page.has_xpath?('//*', :text => regexp) 120 | end 121 | end 122 | 123 | Then /^(?:|I )should not see "([^"]*)"$/ do |text| 124 | if page.respond_to? :should 125 | page.should have_no_content(text) 126 | else 127 | assert page.has_no_content?(text) 128 | end 129 | end 130 | 131 | Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp| 132 | regexp = Regexp.new(regexp) 133 | 134 | if page.respond_to? :should 135 | page.should have_no_xpath('//*', :text => regexp) 136 | else 137 | assert page.has_no_xpath?('//*', :text => regexp) 138 | end 139 | end 140 | 141 | Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value| 142 | with_scope(parent) do 143 | field = find_field(field) 144 | field_value = (field.tag_name == 'textarea') ? field.text : field.value 145 | if field_value.respond_to? :should 146 | field_value.should =~ /#{value}/ 147 | else 148 | assert_match(/#{value}/, field_value) 149 | end 150 | end 151 | end 152 | 153 | Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value| 154 | with_scope(parent) do 155 | field = find_field(field) 156 | field_value = (field.tag_name == 'textarea') ? field.text : field.value 157 | if field_value.respond_to? :should_not 158 | field_value.should_not =~ /#{value}/ 159 | else 160 | assert_no_match(/#{value}/, field_value) 161 | end 162 | end 163 | end 164 | 165 | Then /^the "([^"]*)" field should have the error "([^"]*)"$/ do |field, error_message| 166 | element = find_field(field) 167 | classes = element.find(:xpath, '..')[:class].split(' ') 168 | 169 | form_for_input = element.find(:xpath, 'ancestor::form[1]') 170 | using_formtastic = form_for_input[:class].include?('formtastic') 171 | error_class = using_formtastic ? 'error' : 'field_with_errors' 172 | 173 | if classes.respond_to? :should 174 | classes.should include(error_class) 175 | else 176 | assert classes.include?(error_class) 177 | end 178 | 179 | if page.respond_to?(:should) 180 | if using_formtastic 181 | error_paragraph = element.find(:xpath, '../*[@class="inline-errors"][1]') 182 | error_paragraph.should have_content(error_message) 183 | else 184 | page.should have_content("#{field.titlecase} #{error_message}") 185 | end 186 | else 187 | if using_formtastic 188 | error_paragraph = element.find(:xpath, '../*[@class="inline-errors"][1]') 189 | assert error_paragraph.has_content?(error_message) 190 | else 191 | assert page.has_content?("#{field.titlecase} #{error_message}") 192 | end 193 | end 194 | end 195 | 196 | Then /^the "([^"]*)" field should have no error$/ do |field| 197 | element = find_field(field) 198 | classes = element.find(:xpath, '..')[:class].split(' ') 199 | if classes.respond_to? :should 200 | classes.should_not include('field_with_errors') 201 | classes.should_not include('error') 202 | else 203 | assert !classes.include?('field_with_errors') 204 | assert !classes.include?('error') 205 | end 206 | end 207 | 208 | Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent| 209 | with_scope(parent) do 210 | field_checked = find_field(label)['checked'] 211 | if field_checked.respond_to? :should 212 | field_checked.should be_true 213 | else 214 | assert field_checked 215 | end 216 | end 217 | end 218 | 219 | Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent| 220 | with_scope(parent) do 221 | field_checked = find_field(label)['checked'] 222 | if field_checked.respond_to? :should 223 | field_checked.should be_false 224 | else 225 | assert !field_checked 226 | end 227 | end 228 | end 229 | 230 | Then /^(?:|I )should be on (.+)$/ do |page_name| 231 | current_path = URI.parse(current_url).path 232 | if current_path.respond_to? :should 233 | current_path.should == path_to(page_name) 234 | else 235 | assert_equal path_to(page_name), current_path 236 | end 237 | end 238 | 239 | Then /^(?:|I )should have the following query string:$/ do |expected_pairs| 240 | query = URI.parse(current_url).query 241 | actual_params = query ? CGI.parse(query) : {} 242 | expected_params = {} 243 | expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} 244 | 245 | if actual_params.respond_to? :should 246 | actual_params.should == expected_params 247 | else 248 | assert_equal expected_params, actual_params 249 | end 250 | end 251 | 252 | Then /^show me the page$/ do 253 | save_and_open_page 254 | end 255 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == Welcome to Rails 2 | 3 | Rails is a web-application framework that includes everything needed to create 4 | database-backed web applications according to the Model-View-Control pattern. 5 | 6 | This pattern splits the view (also called the presentation) into "dumb" 7 | templates that are primarily responsible for inserting pre-built data in between 8 | HTML tags. The model contains the "smart" domain objects (such as Account, 9 | Product, Person, Post) that holds all the business logic and knows how to 10 | persist themselves to a database. The controller handles the incoming requests 11 | (such as Save New Account, Update Product, Show Post) by manipulating the model 12 | and directing data to the view. 13 | 14 | In Rails, the model is handled by what's called an object-relational mapping 15 | layer entitled Active Record. This layer allows you to present the data from 16 | database rows as objects and embellish these data objects with business logic 17 | methods. You can read more about Active Record in 18 | link:files/vendor/rails/activerecord/README.html. 19 | 20 | The controller and view are handled by the Action Pack, which handles both 21 | layers by its two parts: Action View and Action Controller. These two layers 22 | are bundled in a single package due to their heavy interdependence. This is 23 | unlike the relationship between the Active Record and Action Pack that is much 24 | more separate. Each of these packages can be used independently outside of 25 | Rails. You can read more about Action Pack in 26 | link:files/vendor/rails/actionpack/README.html. 27 | 28 | 29 | == Getting Started 30 | 31 | 1. At the command prompt, create a new Rails application: 32 | rails new myapp (where myapp is the application name) 33 | 34 | 2. Change directory to myapp and start the web server: 35 | cd myapp; rails server (run with --help for options) 36 | 37 | 3. Go to http://localhost:3000/ and you'll see: 38 | "Welcome aboard: You're riding Ruby on Rails!" 39 | 40 | 4. Follow the guidelines to start developing your application. You can find 41 | the following resources handy: 42 | 43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html 44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/ 45 | 46 | 47 | == Debugging Rails 48 | 49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that 50 | will help you debug it and get it back on the rails. 51 | 52 | First area to check is the application log files. Have "tail -f" commands 53 | running on the server.log and development.log. Rails will automatically display 54 | debugging and runtime information to these files. Debugging info will also be 55 | shown in the browser on requests from 127.0.0.1. 56 | 57 | You can also log your own messages directly into the log file from your code 58 | using the Ruby logger class from inside your controllers. Example: 59 | 60 | class WeblogController < ActionController::Base 61 | def destroy 62 | @weblog = Weblog.find(params[:id]) 63 | @weblog.destroy 64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") 65 | end 66 | end 67 | 68 | The result will be a message in your log file along the lines of: 69 | 70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! 71 | 72 | More information on how to use the logger is at http://www.ruby-doc.org/core/ 73 | 74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are 75 | several books available online as well: 76 | 77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) 78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) 79 | 80 | These two books will bring you up to speed on the Ruby language and also on 81 | programming in general. 82 | 83 | 84 | == Debugger 85 | 86 | Debugger support is available through the debugger command when you start your 87 | Mongrel or WEBrick server with --debugger. This means that you can break out of 88 | execution at any point in the code, investigate and change the model, and then, 89 | resume execution! You need to install ruby-debug to run the server in debugging 90 | mode. With gems, use sudo gem install ruby-debug. Example: 91 | 92 | class WeblogController < ActionController::Base 93 | def index 94 | @posts = Post.all 95 | debugger 96 | end 97 | end 98 | 99 | So the controller will accept the action, run the first line, then present you 100 | with a IRB prompt in the server window. Here you can do things like: 101 | 102 | >> @posts.inspect 103 | => "[#nil, "body"=>nil, "id"=>"1"}>, 105 | #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" 107 | >> @posts.first.title = "hello from a debugger" 108 | => "hello from a debugger" 109 | 110 | ...and even better, you can examine how your runtime objects actually work: 111 | 112 | >> f = @posts.first 113 | => #nil, "body"=>nil, "id"=>"1"}> 114 | >> f. 115 | Display all 152 possibilities? (y or n) 116 | 117 | Finally, when you're ready to resume execution, you can enter "cont". 118 | 119 | 120 | == Console 121 | 122 | The console is a Ruby shell, which allows you to interact with your 123 | application's domain model. Here you'll have all parts of the application 124 | configured, just like it is when the application is running. You can inspect 125 | domain models, change values, and save to the database. Starting the script 126 | without arguments will launch it in the development environment. 127 | 128 | To start the console, run rails console from the application 129 | directory. 130 | 131 | Options: 132 | 133 | * Passing the -s, --sandbox argument will rollback any modifications 134 | made to the database. 135 | * Passing an environment name as an argument will load the corresponding 136 | environment. Example: rails console production. 137 | 138 | To reload your controllers and models after launching the console run 139 | reload! 140 | 141 | More information about irb can be found at: 142 | link:http://www.rubycentral.org/pickaxe/irb.html 143 | 144 | 145 | == dbconsole 146 | 147 | You can go to the command line of your database directly through rails 148 | dbconsole. You would be connected to the database with the credentials 149 | defined in database.yml. Starting the script without arguments will connect you 150 | to the development database. Passing an argument will connect you to a different 151 | database, like rails dbconsole production. Currently works for MySQL, 152 | PostgreSQL and SQLite 3. 153 | 154 | == Description of Contents 155 | 156 | The default directory structure of a generated Ruby on Rails application: 157 | 158 | |-- app 159 | | |-- assets 160 | | |-- images 161 | | |-- javascripts 162 | | `-- stylesheets 163 | | |-- controllers 164 | | |-- helpers 165 | | |-- mailers 166 | | |-- models 167 | | `-- views 168 | | `-- layouts 169 | |-- config 170 | | |-- environments 171 | | |-- initializers 172 | | `-- locales 173 | |-- db 174 | |-- doc 175 | |-- lib 176 | | `-- tasks 177 | |-- log 178 | |-- public 179 | |-- script 180 | |-- test 181 | | |-- fixtures 182 | | |-- functional 183 | | |-- integration 184 | | |-- performance 185 | | `-- unit 186 | |-- tmp 187 | | |-- cache 188 | | |-- pids 189 | | |-- sessions 190 | | `-- sockets 191 | `-- vendor 192 | |-- assets 193 | `-- stylesheets 194 | `-- plugins 195 | 196 | app 197 | Holds all the code that's specific to this particular application. 198 | 199 | app/assets 200 | Contains subdirectories for images, stylesheets, and JavaScript files. 201 | 202 | app/controllers 203 | Holds controllers that should be named like weblogs_controller.rb for 204 | automated URL mapping. All controllers should descend from 205 | ApplicationController which itself descends from ActionController::Base. 206 | 207 | app/models 208 | Holds models that should be named like post.rb. Models descend from 209 | ActiveRecord::Base by default. 210 | 211 | app/views 212 | Holds the template files for the view that should be named like 213 | weblogs/index.html.erb for the WeblogsController#index action. All views use 214 | eRuby syntax by default. 215 | 216 | app/views/layouts 217 | Holds the template files for layouts to be used with views. This models the 218 | common header/footer method of wrapping views. In your views, define a layout 219 | using the layout :default and create a file named default.html.erb. 220 | Inside default.html.erb, call <% yield %> to render the view using this 221 | layout. 222 | 223 | app/helpers 224 | Holds view helpers that should be named like weblogs_helper.rb. These are 225 | generated for you automatically when using generators for controllers. 226 | Helpers can be used to wrap functionality for your views into methods. 227 | 228 | config 229 | Configuration files for the Rails environment, the routing map, the database, 230 | and other dependencies. 231 | 232 | db 233 | Contains the database schema in schema.rb. db/migrate contains all the 234 | sequence of Migrations for your schema. 235 | 236 | doc 237 | This directory is where your application documentation will be stored when 238 | generated using rake doc:app 239 | 240 | lib 241 | Application specific libraries. Basically, any kind of custom code that 242 | doesn't belong under controllers, models, or helpers. This directory is in 243 | the load path. 244 | 245 | public 246 | The directory available for the web server. Also contains the dispatchers and the 247 | default HTML files. This should be set as the DOCUMENT_ROOT of your web 248 | server. 249 | 250 | script 251 | Helper scripts for automation and generation. 252 | 253 | test 254 | Unit and functional tests along with fixtures. When using the rails generate 255 | command, template test files will be generated for you and placed in this 256 | directory. 257 | 258 | vendor 259 | External libraries that the application depends on. Also includes the plugins 260 | subdirectory. If the app has frozen rails, those gems also go here, under 261 | vendor/rails/. This directory is in the load path. 262 | --------------------------------------------------------------------------------