├── 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 | -
221 |
Use rails generate to create your models and controllers
222 | To see all available options, run it without parameters.
223 |
224 |
225 | -
226 |
Set up a default route and remove public/index.html
227 | Routes are set up in config/routes.rb.
228 |
229 |
230 | -
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 |
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 |
--------------------------------------------------------------------------------