├── .autotest
├── .gitignore
├── .rspec
├── Gemfile
├── Gemfile.lock
├── README.markdown
├── Rakefile
├── app
├── controllers
│ ├── application_controller.rb
│ ├── microposts_controller.rb
│ ├── pages_controller.rb
│ ├── relationships_controller.rb
│ ├── sessions_controller.rb
│ └── users_controller.rb
├── helpers
│ ├── application_helper.rb
│ ├── microposts_helper.rb
│ ├── pages_helper.rb
│ ├── sessions_helper.rb
│ └── users_helper.rb
├── models
│ ├── micropost.rb
│ ├── relationship.rb
│ └── user.rb
└── views
│ ├── layouts
│ ├── _footer.html.erb
│ ├── _header.html.erb
│ ├── _stylesheets.html.erb
│ └── application.html.erb
│ ├── microposts
│ └── _micropost.html.erb
│ ├── pages
│ ├── about.html.erb
│ ├── contact.html.erb
│ ├── help.html.erb
│ └── home.html.erb
│ ├── relationships
│ ├── create.js.erb
│ └── destroy.js.erb
│ ├── sessions
│ └── new.html.erb
│ ├── shared
│ ├── _error_messages.html.erb
│ ├── _feed.html.erb
│ ├── _feed_item.html.erb
│ ├── _micropost_form.html.erb
│ ├── _stats.html.erb
│ └── _user_info.html.erb
│ └── users
│ ├── _fields.html.erb
│ ├── _follow.html.erb
│ ├── _follow_form.html.erb
│ ├── _unfollow.html.erb
│ ├── _user.html.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ ├── new.html.erb
│ ├── show.html.erb
│ └── show_follow.html.erb
├── autotest
└── discover.rb
├── bin
├── annotate
├── autospec
├── autotest
├── erubis
├── htmldiff
├── ldiff
├── multigem
├── multiruby
├── multiruby_setup
├── nokogiri
├── rackup
├── rails
├── rake
├── rake2thor
├── rdoc
├── ri
├── rspec
├── spork
├── thor
├── tt
├── unit_diff
└── zentest
├── bundler_stubs
├── annotate
├── autospec
├── erubis
├── htmldiff
├── ldiff
├── nokogiri
├── rackup
├── rails
├── rake
├── rake2thor
├── rdoc
├── ri
├── rspec
├── spork
├── thor
└── tt
├── config.ru
├── config
├── application.rb
├── boot.rb
├── database.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── backtrace_silencers.rb
│ ├── inflections.rb
│ ├── mime_types.rb
│ ├── secret_token.rb
│ └── session_store.rb
├── locales
│ └── en.yml
└── routes.rb
├── db
├── migrate
│ ├── 20100821203213_create_users.rb
│ ├── 20100822012431_add_email_uniqueness_index.rb
│ ├── 20100822204528_add_password_to_users.rb
│ ├── 20100822233125_add_salt_to_users.rb
│ ├── 20100829021049_add_admin_to_users.rb
│ ├── 20100829210229_create_microposts.rb
│ └── 20100831012055_create_relationships.rb
├── schema.rb
└── seeds.rb
├── doc
└── README_FOR_APP
├── lib
└── tasks
│ ├── .gitkeep
│ └── sample_data.rake
├── public
├── 404.html
├── 422.html
├── 500.html
├── favicon.ico
├── images
│ ├── logo.png
│ └── rails.png
├── javascripts
│ ├── application.js
│ ├── controls.js
│ ├── dragdrop.js
│ ├── effects.js
│ ├── prototype.js
│ └── rails.js
├── robots.txt
└── stylesheets
│ ├── .gitkeep
│ ├── blueprint
│ ├── ie.css
│ ├── plugins
│ │ ├── buttons
│ │ │ ├── icons
│ │ │ │ ├── cross.png
│ │ │ │ ├── key.png
│ │ │ │ └── tick.png
│ │ │ ├── readme.txt
│ │ │ └── screen.css
│ │ ├── fancy-type
│ │ │ ├── readme.txt
│ │ │ └── screen.css
│ │ ├── link-icons
│ │ │ ├── icons
│ │ │ │ ├── doc.png
│ │ │ │ ├── email.png
│ │ │ │ ├── external.png
│ │ │ │ ├── feed.png
│ │ │ │ ├── im.png
│ │ │ │ ├── pdf.png
│ │ │ │ ├── visited.png
│ │ │ │ └── xls.png
│ │ │ ├── readme.txt
│ │ │ └── screen.css
│ │ └── rtl
│ │ │ ├── readme.txt
│ │ │ └── screen.css
│ ├── print.css
│ ├── screen.css
│ └── src
│ │ ├── forms.css
│ │ ├── grid.css
│ │ ├── grid.png
│ │ ├── ie.css
│ │ ├── print.css
│ │ ├── reset.css
│ │ └── typography.css
│ └── custom.css
├── script
└── rails
├── spec
├── controllers
│ ├── microposts_controller_spec.rb
│ ├── pages_controller_spec.rb
│ ├── relationships_controller_spec.rb
│ ├── sessions_controller_spec.rb
│ └── users_controller_spec.rb
├── factories.rb
├── models
│ ├── micropost_spec.rb
│ ├── relationship_spec.rb
│ └── user_spec.rb
├── requests
│ ├── friendly_forwardings_spec.rb
│ ├── layout_links_spec.rb
│ ├── microposts_spec.rb
│ └── users_spec.rb
└── spec_helper.rb
└── vendor
└── plugins
└── .gitkeep
/.autotest:
--------------------------------------------------------------------------------
1 | require 'autotest/growl'
2 | require 'autotest/fsevent'
3 |
4 | Autotest.add_hook :initialize do |autotest|
5 | autotest.add_mapping(/^spec\/requests\/.*_spec\.rb$/) do
6 | autotest.files_matching(/^spec\/requests\/.*_spec\.rb$/)
7 | end
8 | end
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | db/*.sqlite3*
3 | log/*.log
4 | *.log
5 | /tmp/
6 | doc/
7 | *.swp
8 | *~
9 | .project
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --colour
2 | --drb
3 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | gem 'rails', '3.0.12'
4 | gem 'gravatar_image_tag', '1.0.0.pre2'
5 | gem 'will_paginate', '3.0.pre2'
6 | gem 'sqlite3', '1.3.4'
7 |
8 | group :development do
9 | gem 'rspec-rails', '2.6.1'
10 | gem 'annotate', '2.4.0'
11 | gem 'faker', '0.3.1'
12 | end
13 |
14 | group :test do
15 | gem 'rspec-rails', '2.6.1'
16 | gem 'webrat', '0.7.1'
17 | gem 'spork', '0.9.0.rc8'
18 | gem 'factory_girl_rails', '1.0'
19 | # gem 'autotest', '4.4.6'
20 | # gem 'autotest-rails-pure', '4.1.2'
21 | # gem 'autotest-fsevent', '0.2.4'
22 | # gem 'autotest-growl', '0.2.9'
23 | end
24 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | abstract (1.0.0)
5 | actionmailer (3.0.12)
6 | actionpack (= 3.0.12)
7 | mail (~> 2.2.19)
8 | actionpack (3.0.12)
9 | activemodel (= 3.0.12)
10 | activesupport (= 3.0.12)
11 | builder (~> 2.1.2)
12 | erubis (~> 2.6.6)
13 | i18n (~> 0.5.0)
14 | rack (~> 1.2.5)
15 | rack-mount (~> 0.6.14)
16 | rack-test (~> 0.5.7)
17 | tzinfo (~> 0.3.23)
18 | activemodel (3.0.12)
19 | activesupport (= 3.0.12)
20 | builder (~> 2.1.2)
21 | i18n (~> 0.5.0)
22 | activerecord (3.0.12)
23 | activemodel (= 3.0.12)
24 | activesupport (= 3.0.12)
25 | arel (~> 2.0.10)
26 | tzinfo (~> 0.3.23)
27 | activeresource (3.0.12)
28 | activemodel (= 3.0.12)
29 | activesupport (= 3.0.12)
30 | activesupport (3.0.12)
31 | annotate (2.4.0)
32 | arel (2.0.10)
33 | builder (2.1.2)
34 | diff-lcs (1.1.2)
35 | erubis (2.6.6)
36 | abstract (>= 1.0.0)
37 | factory_girl (1.3.3)
38 | factory_girl_rails (1.0)
39 | factory_girl (~> 1.3)
40 | rails (>= 3.0.0.beta4)
41 | faker (0.3.1)
42 | gravatar_image_tag (1.0.0.pre2)
43 | i18n (0.5.0)
44 | json (1.6.6)
45 | mail (2.2.19)
46 | activesupport (>= 2.3.6)
47 | i18n (>= 0.4.0)
48 | mime-types (~> 1.16)
49 | treetop (~> 1.4.8)
50 | mime-types (1.18)
51 | nokogiri (1.4.4)
52 | polyglot (0.3.3)
53 | rack (1.2.5)
54 | rack-mount (0.6.14)
55 | rack (>= 1.0.0)
56 | rack-test (0.5.7)
57 | rack (>= 1.0)
58 | rails (3.0.12)
59 | actionmailer (= 3.0.12)
60 | actionpack (= 3.0.12)
61 | activerecord (= 3.0.12)
62 | activeresource (= 3.0.12)
63 | activesupport (= 3.0.12)
64 | bundler (~> 1.0)
65 | railties (= 3.0.12)
66 | railties (3.0.12)
67 | actionpack (= 3.0.12)
68 | activesupport (= 3.0.12)
69 | rake (>= 0.8.7)
70 | rdoc (~> 3.4)
71 | thor (~> 0.14.4)
72 | rake (0.9.2.2)
73 | rdoc (3.12)
74 | json (~> 1.4)
75 | rspec (2.6.0)
76 | rspec-core (~> 2.6.0)
77 | rspec-expectations (~> 2.6.0)
78 | rspec-mocks (~> 2.6.0)
79 | rspec-core (2.6.4)
80 | rspec-expectations (2.6.0)
81 | diff-lcs (~> 1.1.2)
82 | rspec-mocks (2.6.0)
83 | rspec-rails (2.6.1)
84 | actionpack (~> 3.0)
85 | activesupport (~> 3.0)
86 | railties (~> 3.0)
87 | rspec (~> 2.6.0)
88 | spork (0.9.0.rc8)
89 | sqlite3 (1.3.4)
90 | thor (0.14.6)
91 | treetop (1.4.10)
92 | polyglot
93 | polyglot (>= 0.3.1)
94 | tzinfo (0.3.32)
95 | webrat (0.7.1)
96 | nokogiri (>= 1.2.0)
97 | rack (>= 1.0)
98 | rack-test (>= 0.5.3)
99 | will_paginate (3.0.pre2)
100 |
101 | PLATFORMS
102 | ruby
103 |
104 | DEPENDENCIES
105 | annotate (= 2.4.0)
106 | factory_girl_rails (= 1.0)
107 | faker (= 0.3.1)
108 | gravatar_image_tag (= 1.0.0.pre2)
109 | rails (= 3.0.12)
110 | rspec-rails (= 2.6.1)
111 | spork (= 0.9.0.rc8)
112 | sqlite3 (= 1.3.4)
113 | webrat (= 0.7.1)
114 | will_paginate (= 3.0.pre2)
115 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # Ruby on Rails Tutorial: sample application
2 |
3 | **NOTE: This repository is out of date.**
4 |
5 | Go to the [Rails Tutorial Help Page](https://www.railstutorial.org/help) to get a link to the latest version of the Rails Tutorial sample app.
6 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 | require 'rake'
6 |
7 | SampleApp::Application.load_tasks
8 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 | include SessionsHelper
4 | end
5 |
--------------------------------------------------------------------------------
/app/controllers/microposts_controller.rb:
--------------------------------------------------------------------------------
1 | class MicropostsController < ApplicationController
2 | before_filter :authenticate
3 | before_filter :authorized_user, :only => :destroy
4 |
5 | def create
6 | @micropost = current_user.microposts.build(params[:micropost])
7 | if @micropost.save
8 | redirect_to root_path, :flash => { :success => "Micropost created!" }
9 | else
10 | @feed_items = []
11 | render 'pages/home'
12 | end
13 | end
14 |
15 | def destroy
16 | @micropost.destroy
17 | redirect_to root_path, :flash => { :success => "Micropost deleted!" }
18 | end
19 |
20 | private
21 |
22 | def authorized_user
23 | @micropost = current_user.microposts.find_by_id(params[:id])
24 | redirect_to root_path if @micropost.nil?
25 | end
26 | end
--------------------------------------------------------------------------------
/app/controllers/pages_controller.rb:
--------------------------------------------------------------------------------
1 | class PagesController < ApplicationController
2 |
3 | def home
4 | @title = "Home"
5 | if signed_in?
6 | @micropost = Micropost.new
7 | @feed_items = current_user.feed.paginate(:page => params[:page])
8 | end
9 | end
10 |
11 | def contact
12 | @title = "Contact"
13 | end
14 |
15 | def about
16 | @title = "About"
17 | end
18 |
19 | def help
20 | @title = "Help"
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/app/controllers/relationships_controller.rb:
--------------------------------------------------------------------------------
1 | class RelationshipsController < ApplicationController
2 | before_filter :authenticate
3 |
4 | def create
5 | @user = User.find(params[:relationship][:followed_id])
6 | current_user.follow!(@user)
7 | respond_to do |format|
8 | format.html { redirect_to @user }
9 | format.js
10 | end
11 | end
12 |
13 | def destroy
14 | @user = Relationship.find(params[:id]).followed
15 | current_user.unfollow!(@user)
16 | respond_to do |format|
17 | format.html { redirect_to @user }
18 | format.js
19 | end
20 | end
21 | end
--------------------------------------------------------------------------------
/app/controllers/sessions_controller.rb:
--------------------------------------------------------------------------------
1 | class SessionsController < ApplicationController
2 |
3 | def new
4 | @title = "Sign in"
5 | end
6 |
7 | def create
8 | user = User.authenticate(params[:session][:email],
9 | params[:session][:password])
10 | if user.nil?
11 | flash.now[:error] = "Invalid email/password combination."
12 | @title = "Sign in"
13 | render 'new'
14 | else
15 | sign_in user
16 | redirect_back_or user
17 | end
18 | end
19 |
20 | def destroy
21 | sign_out
22 | redirect_to root_path
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/app/controllers/users_controller.rb:
--------------------------------------------------------------------------------
1 | class UsersController < ApplicationController
2 | before_filter :authenticate,
3 | :only => [:index, :edit, :update, :destroy,
4 | :followers, :following]
5 | before_filter :correct_user, :only => [:edit, :update]
6 | before_filter :admin_user, :only => :destroy
7 |
8 | def index
9 | @users = User.paginate(:page => params[:page])
10 | @title = "All users"
11 | end
12 |
13 | def show
14 | @user = User.find(params[:id])
15 | @microposts = @user.microposts.paginate(:page => params[:page])
16 | @title = @user.name
17 | end
18 |
19 | def following
20 | @title = "Following"
21 | @user = User.find(params[:id])
22 | @users = @user.following.paginate(:page => params[:page])
23 | render 'show_follow'
24 | end
25 |
26 | def followers
27 | @title = "Followers"
28 | @user = User.find(params[:id])
29 | @users = @user.followers.paginate(:page => params[:page])
30 | render 'show_follow'
31 | end
32 |
33 | def new
34 | @user = User.new
35 | @title = "Sign up"
36 | end
37 |
38 | def create
39 | @user = User.new(params[:user])
40 | if @user.save
41 | sign_in @user
42 | redirect_to @user, :flash => { :success => "Welcome to the Sample App!" }
43 | else
44 | @title = "Sign up"
45 | render 'new'
46 | end
47 | end
48 |
49 | def edit
50 | @title = "Edit user"
51 | end
52 |
53 | def update
54 | if @user.update_attributes(params[:user])
55 | redirect_to @user, :flash => { :success => "Profile updated." }
56 | else
57 | @title = "Edit user"
58 | render 'edit'
59 | end
60 | end
61 |
62 | def destroy
63 | @user.destroy
64 | redirect_to users_path, :flash => { :success => "User destroyed." }
65 | end
66 |
67 | private
68 |
69 | def correct_user
70 | @user = User.find(params[:id])
71 | redirect_to(root_path) unless current_user?(@user)
72 | end
73 |
74 | def admin_user
75 | @user = User.find(params[:id])
76 | redirect_to(root_path) if !current_user.admin? || current_user?(@user)
77 | end
78 | end
79 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 |
3 | # Return a title on a per-page basis.
4 | def title
5 | base_title = "Ruby on Rails Tutorial Sample App"
6 | if @title.nil?
7 | base_title
8 | else
9 | "#{base_title} | #{@title}"
10 | end
11 | end
12 |
13 | def logo
14 | image_tag("logo.png", :alt => "Sample App", :class => "round")
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/app/helpers/microposts_helper.rb:
--------------------------------------------------------------------------------
1 | module MicropostsHelper
2 |
3 | def wrap(content)
4 | sanitize(raw(content.split.map{ |s| wrap_long_string(s) }.join(' ')))
5 | end
6 |
7 | private
8 |
9 | def wrap_long_string(text, max_width = 30)
10 | zero_width_space = ""
11 | regex = /.{1,#{max_width}}/
12 | (text.length < max_width) ? text :
13 | text.scan(regex).join(zero_width_space)
14 | end
15 | end
--------------------------------------------------------------------------------
/app/helpers/pages_helper.rb:
--------------------------------------------------------------------------------
1 | module PagesHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/sessions_helper.rb:
--------------------------------------------------------------------------------
1 | module SessionsHelper
2 |
3 | def sign_in(user)
4 | cookies.permanent.signed[:remember_token] = [user.id, user.salt]
5 | self.current_user = user
6 | end
7 |
8 | def current_user=(user)
9 | @current_user = user
10 | end
11 |
12 | def current_user
13 | @current_user ||= user_from_remember_token
14 | end
15 |
16 | def signed_in?
17 | !current_user.nil?
18 | end
19 |
20 | def sign_out
21 | cookies.delete(:remember_token)
22 | self.current_user = nil
23 | end
24 |
25 | def current_user?(user)
26 | user == current_user
27 | end
28 |
29 | def authenticate
30 | deny_access unless signed_in?
31 | end
32 |
33 | def deny_access
34 | store_location
35 | redirect_to signin_path, :notice => "Please sign in to access this page."
36 | end
37 |
38 | def redirect_back_or(default)
39 | redirect_to(session[:return_to] || default)
40 | clear_return_to
41 | end
42 |
43 | private
44 |
45 | def user_from_remember_token
46 | User.authenticate_with_salt(*remember_token)
47 | end
48 |
49 | def remember_token
50 | cookies.signed[:remember_token] || [nil, nil]
51 | end
52 |
53 | def store_location
54 | session[:return_to] = request.fullpath
55 | end
56 |
57 | def clear_return_to
58 | session[:return_to] = nil
59 | end
60 | end
61 |
62 |
--------------------------------------------------------------------------------
/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | module UsersHelper
2 | def gravatar_for(user, options = { :size => 50 })
3 | gravatar_image_tag(user.email.downcase, :alt => h(user.name),
4 | :class => 'gravatar',
5 | :gravatar => options)
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/models/micropost.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | # Schema version: 20100829210229
3 | #
4 | # Table name: microposts
5 | #
6 | # id :integer not null, primary key
7 | # content :string(255)
8 | # user_id :integer
9 | # created_at :datetime
10 | # updated_at :datetime
11 | #
12 |
13 | class Micropost < ActiveRecord::Base
14 | attr_accessible :content
15 |
16 | belongs_to :user
17 |
18 | validates :content, :presence => true, :length => { :maximum => 140 }
19 | validates :user_id, :presence => true
20 |
21 | default_scope :order => 'microposts.created_at DESC'
22 |
23 | scope :from_users_followed_by, lambda { |user| followed_by(user) }
24 |
25 | private
26 |
27 | def self.followed_by(user)
28 | following_ids = %(SELECT followed_id FROM relationships
29 | WHERE follower_id = :user_id)
30 | where("user_id IN (#{following_ids}) OR user_id = :user_id",
31 | :user_id => user)
32 | end
33 | end
--------------------------------------------------------------------------------
/app/models/relationship.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | # Schema version: 20100831012055
3 | #
4 | # Table name: relationships
5 | #
6 | # id :integer not null, primary key
7 | # follower_id :integer
8 | # followed_id :integer
9 | # created_at :datetime
10 | # updated_at :datetime
11 | #
12 |
13 | class Relationship < ActiveRecord::Base
14 | attr_accessible :followed_id
15 |
16 | belongs_to :follower, :class_name => "User"
17 | belongs_to :followed, :class_name => "User"
18 |
19 | validates :follower_id, :presence => true
20 | validates :followed_id, :presence => true
21 | end
22 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | # == Schema Information
2 | # Schema version: 20100829021049
3 | #
4 | # Table name: users
5 | #
6 | # id :integer not null, primary key
7 | # name :string(255)
8 | # email :string(255)
9 | # created_at :datetime
10 | # updated_at :datetime
11 | # encrypted_password :string(255)
12 | # salt :string(255)
13 | # admin :boolean
14 | #
15 |
16 | class User < ActiveRecord::Base
17 | attr_accessor :password
18 | attr_accessible :name, :email, :password, :password_confirmation
19 |
20 | has_many :microposts, :dependent => :destroy
21 | has_many :relationships, :dependent => :destroy,
22 | :foreign_key => "follower_id"
23 | has_many :reverse_relationships, :dependent => :destroy,
24 | :foreign_key => "followed_id",
25 | :class_name => "Relationship"
26 | has_many :following, :through => :relationships, :source => :followed
27 | has_many :followers, :through => :reverse_relationships,
28 | :source => :follower
29 |
30 | email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
31 |
32 | validates :name, :presence => true,
33 | :length => { :maximum => 50 }
34 | validates :email, :presence => true,
35 | :format => { :with => email_regex },
36 | :uniqueness => { :case_sensitive => false }
37 | validates :password, :presence => true,
38 | :confirmation => true,
39 | :length => { :within => 6..40 }
40 |
41 | before_save :encrypt_password
42 |
43 | def has_password?(submitted_password)
44 | encrypted_password == encrypt(submitted_password)
45 | end
46 |
47 | def feed
48 | Micropost.from_users_followed_by(self)
49 | end
50 |
51 | def following?(followed)
52 | relationships.find_by_followed_id(followed)
53 | end
54 |
55 | def follow!(followed)
56 | relationships.create!(:followed_id => followed.id)
57 | end
58 |
59 | def unfollow!(followed)
60 | relationships.find_by_followed_id(followed).destroy
61 | end
62 |
63 | class << self
64 | def authenticate(email, submitted_password)
65 | user = find_by_email(email)
66 | (user && user.has_password?(submitted_password)) ? user : nil
67 | end
68 |
69 | def authenticate_with_salt(id, cookie_salt)
70 | user = find_by_id(id)
71 | (user && user.salt == cookie_salt) ? user : nil
72 | end
73 | end
74 |
75 | private
76 |
77 | def encrypt_password
78 | self.salt = make_salt unless has_password?(password)
79 | self.encrypted_password = encrypt(password)
80 | end
81 |
82 | def encrypt(string)
83 | secure_hash("#{salt}--#{string}")
84 | end
85 |
86 | def make_salt
87 | secure_hash("#{Time.now.utc}--#{password}")
88 | end
89 |
90 | def secure_hash(string)
91 | Digest::SHA2.hexdigest(string)
92 | end
93 | end
94 |
--------------------------------------------------------------------------------
/app/views/layouts/_footer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= link_to "About", about_path %>
5 | <%= link_to "Contact", contact_path %>
6 | <%= link_to "News", 'http://news.railstutorial.org/' %>
7 | <%= link_to "Rails Tutorial", 'http://railstutorial.org/' %>
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/views/layouts/_header.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= link_to logo, root_path %>
3 |
4 |
5 | <%= link_to "Home", root_path %>
6 | <% if signed_in? %>
7 | <%= link_to "Profile", current_user %>
8 | <%= link_to "Users", users_path %>
9 | <%= link_to "Settings", edit_user_path(current_user) %>
10 | <% end %>
11 | <%= link_to "Help", help_path %>
12 | <% if signed_in? %>
13 | <%= link_to "Sign out", signout_path %>
14 | <% else %>
15 | <%= link_to "Sign in", signin_path %>
16 | <% end %>
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/views/layouts/_stylesheets.html.erb:
--------------------------------------------------------------------------------
1 |
4 | <%= stylesheet_link_tag 'blueprint/screen', :media => 'screen' %>
5 | <%= stylesheet_link_tag 'blueprint/print', :media => 'print' %>
6 |
7 | <%= stylesheet_link_tag 'custom', :media => 'screen' %>
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= title %>
5 | <%= csrf_meta_tag %>
6 | <%= render 'layouts/stylesheets' %>
7 | <%= javascript_include_tag :defaults %>
8 |
9 |
10 |
11 | <%= render 'layouts/header' %>
12 |
13 | <% flash.each do |key, value| %>
14 | <%= value %>
15 | <% end %>
16 | <%= yield %>
17 |
18 | <%= render 'layouts/footer' %>
19 | <%= debug(params) if Rails.env.development? %>
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/views/microposts/_micropost.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= micropost.content %>
4 |
5 | Posted <%= time_ago_in_words(micropost.created_at) %> ago.
6 |
7 |
8 | <% user = micropost.user rescue User.find(micropost.user_id) %>
9 | <% if current_user?(user) %>
10 |
11 | <%= link_to "delete", micropost, :method => :delete,
12 | :confirm => "You sure?",
13 | :title => micropost.content %>
14 |
15 | <% end %>
16 |
--------------------------------------------------------------------------------
/app/views/pages/about.html.erb:
--------------------------------------------------------------------------------
1 | About Us
2 |
3 | Ruby on Rails Tutorial
4 | is a project to make a book and screencasts to teach web development
5 | with Ruby on Rails . This
6 | is the sample application for the tutorial.
7 |
8 |
--------------------------------------------------------------------------------
/app/views/pages/contact.html.erb:
--------------------------------------------------------------------------------
1 | Contact
2 |
3 | Contact Ruby on Rails Tutorial about the sample app at the
4 | feedback page .
5 |
6 |
--------------------------------------------------------------------------------
/app/views/pages/help.html.erb:
--------------------------------------------------------------------------------
1 | Help
2 |
3 | Get help on Ruby on Rails Tutorial at the
4 | Rails Tutorial help page .
5 | To get help on this sample app, see the
6 | Rails Tutorial book .
7 |
8 |
--------------------------------------------------------------------------------
/app/views/pages/home.html.erb:
--------------------------------------------------------------------------------
1 | <% if signed_in? %>
2 |
3 |
4 |
5 |
6 | What's up?
7 | <%= render 'shared/micropost_form' %>
8 | <%= render 'shared/feed' %>
9 |
10 |
14 |
15 |
16 |
17 | <% else %>
18 |
19 | Sample App
20 |
21 | This is the home page for the Ruby on Rails Tutorial sample application.
22 |
23 |
24 | <%= link_to "Sign up now!", signup_path, :class => "signup_button round" %>
25 |
26 | <% end %>
--------------------------------------------------------------------------------
/app/views/relationships/create.js.erb:
--------------------------------------------------------------------------------
1 | $("follow_form").update("<%= escape_javascript(render('users/unfollow')) %>")
2 | $("followers").update('<%= "#{@user.followers.count} followers" %>')
--------------------------------------------------------------------------------
/app/views/relationships/destroy.js.erb:
--------------------------------------------------------------------------------
1 | $("follow_form").update("<%= escape_javascript(render('users/follow')) %>")
2 | $("followers").update('<%= "#{@user.followers.count} followers" %>')
--------------------------------------------------------------------------------
/app/views/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 | Sign in
2 |
3 | <%= form_for(:session, :url => sessions_path) do |f| %>
4 |
5 | <%= f.label :email %>
6 | <%= f.text_field :email %>
7 |
8 |
9 | <%= f.label :password %>
10 | <%= f.password_field :password %>
11 |
12 |
13 | <%= f.submit "Sign in" %>
14 |
15 | <% end %>
16 |
17 | New user? <%= link_to "Sign up now!", signup_path %>
--------------------------------------------------------------------------------
/app/views/shared/_error_messages.html.erb:
--------------------------------------------------------------------------------
1 | <% if object.errors.any? %>
2 |
3 |
4 | <%= pluralize(object.errors.count, "error") %>
5 | prohibited this <%= object.class.to_s.underscore.humanize.downcase %>
6 | from being saved:
7 |
8 |
There were problems with the following fields:
9 |
10 | <% object.errors.full_messages.each do |message| %>
11 | <%= message %>
12 | <% end %>
13 |
14 |
15 |
16 | <% end %>
--------------------------------------------------------------------------------
/app/views/shared/_feed.html.erb:
--------------------------------------------------------------------------------
1 | <% if @feed_items.any? %>
2 |
3 | <%= render :partial => 'shared/feed_item', :collection => @feed_items %>
4 |
5 | <%= will_paginate @feed_items %>
6 | <% end %>
--------------------------------------------------------------------------------
/app/views/shared/_feed_item.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= link_to gravatar_for(feed_item.user), feed_item.user %>
4 |
5 |
6 |
7 | <%= link_to feed_item.user.name, feed_item.user %>
8 |
9 | <%= wrap(feed_item.content) %>
10 |
11 | Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
12 |
13 |
14 | <% if current_user?(feed_item.user) %>
15 |
16 | <%= link_to "delete", feed_item, :method => :delete,
17 | :confirm => "You sure?",
18 | :title => feed_item.content %>
19 |
20 | <% end %>
21 |
--------------------------------------------------------------------------------
/app/views/shared/_micropost_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(@micropost) do |f| %>
2 | <%= render 'shared/error_messages', :object => f.object %>
3 |
4 | <%= f.text_area :content %>
5 |
6 |
7 | <%= f.submit "Submit" %>
8 |
9 | <% end %>
--------------------------------------------------------------------------------
/app/views/shared/_stats.html.erb:
--------------------------------------------------------------------------------
1 | <% @user ||= current_user %>
2 |
--------------------------------------------------------------------------------
/app/views/shared/_user_info.html.erb:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/users/_fields.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.label :name %>
3 | <%= f.text_field :name %>
4 |
5 |
6 | <%= f.label :email %>
7 | <%= f.text_field :email %>
8 |
9 |
10 | <%= f.label :password %>
11 | <%= f.password_field :password %>
12 |
13 |
14 | <%= f.label :password_confirmation, "Confirmation" %>
15 | <%= f.password_field :password_confirmation %>
16 |
--------------------------------------------------------------------------------
/app/views/users/_follow.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(current_user.relationships.
2 | build(:followed_id => @user.id),
3 | :remote => true) do |f| %>
4 | <%= f.hidden_field :followed_id %>
5 | <%= f.submit "Follow" %>
6 | <% end %>
--------------------------------------------------------------------------------
/app/views/users/_follow_form.html.erb:
--------------------------------------------------------------------------------
1 | <% unless current_user?(@user) %>
2 |
3 | <% if current_user.following?(@user) %>
4 | <%= render 'unfollow' %>
5 | <% else %>
6 | <%= render 'follow' %>
7 | <% end %>
8 |
9 | <% end %>
--------------------------------------------------------------------------------
/app/views/users/_unfollow.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(current_user.relationships.find_by_followed_id(@user),
2 | :html => { :method => :delete },
3 | :remote => true) do |f| %>
4 | <%= f.submit "Unfollow" %>
5 | <% end %>
--------------------------------------------------------------------------------
/app/views/users/_user.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= gravatar_for user, :size => 30 %>
3 | <%= link_to user.name, user %>
4 | <% if current_user.admin? %>
5 | |
6 | <%= link_to "delete", user, :method => :delete, :confirm => "You sure?",
7 | :title => "Delete #{user.name}" %>
8 | <% end %>
9 |
--------------------------------------------------------------------------------
/app/views/users/edit.html.erb:
--------------------------------------------------------------------------------
1 | Edit user
2 |
3 | <%= form_for(@user) do |f| %>
4 | <%= render 'shared/error_messages', :object => f.object %>
5 | <%= render 'fields', :f => f %>
6 |
7 | <%= f.submit "Update" %>
8 |
9 | <% end %>
10 |
11 |
12 | <%= gravatar_for @user %>
13 |
change
14 |
15 |
--------------------------------------------------------------------------------
/app/views/users/index.html.erb:
--------------------------------------------------------------------------------
1 | All users
2 |
3 | <%= will_paginate %>
4 |
5 |
6 | <%= render @users %>
7 |
8 |
9 | <%= will_paginate %>
10 |
--------------------------------------------------------------------------------
/app/views/users/new.html.erb:
--------------------------------------------------------------------------------
1 | Sign up
2 |
3 | <%= form_for(@user) do |f| %>
4 | <%= render 'shared/error_messages', :object => f.object %>
5 | <%= render 'fields', :f => f %>
6 |
7 | <%= f.submit "Sign up" %>
8 |
9 | <% end %>
10 |
--------------------------------------------------------------------------------
/app/views/users/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= gravatar_for @user %>
6 | <%= @user.name %>
7 |
8 | <%= render 'follow_form' if signed_in? %>
9 | <% if @user.microposts.any? %>
10 |
11 | <%= render @microposts %>
12 |
13 | <%= will_paginate @microposts %>
14 | <% end %>
15 |
16 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/views/users/show_follow.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= @title %>
5 |
6 | <% if @users.any? %>
7 |
8 | <%= render @users %>
9 |
10 | <%= will_paginate @users %>
11 | <% end %>
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/autotest/discover.rb:
--------------------------------------------------------------------------------
1 | Autotest.add_discovery { "rails" }
2 | Autotest.add_discovery { "rspec2" }
3 |
--------------------------------------------------------------------------------
/bin/annotate:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'annotate' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('annotate', 'annotate')
17 |
--------------------------------------------------------------------------------
/bin/autospec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'autospec' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rspec-core', 'autospec')
17 |
--------------------------------------------------------------------------------
/bin/autotest:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'autotest' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'autotest')
17 |
--------------------------------------------------------------------------------
/bin/erubis:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'erubis' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('erubis', 'erubis')
17 |
--------------------------------------------------------------------------------
/bin/htmldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'htmldiff' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('diff-lcs', 'htmldiff')
17 |
--------------------------------------------------------------------------------
/bin/ldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'ldiff' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('diff-lcs', 'ldiff')
17 |
--------------------------------------------------------------------------------
/bin/multigem:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'multigem' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'multigem')
17 |
--------------------------------------------------------------------------------
/bin/multiruby:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'multiruby' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'multiruby')
17 |
--------------------------------------------------------------------------------
/bin/multiruby_setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'multiruby_setup' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'multiruby_setup')
17 |
--------------------------------------------------------------------------------
/bin/nokogiri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'nokogiri' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('nokogiri', 'nokogiri')
17 |
--------------------------------------------------------------------------------
/bin/rackup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rackup' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rack', 'rackup')
17 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rails' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rails', 'rails')
17 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rake' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rake', 'rake')
17 |
--------------------------------------------------------------------------------
/bin/rake2thor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rake2thor' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('thor', 'rake2thor')
17 |
--------------------------------------------------------------------------------
/bin/rdoc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rdoc' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rdoc', 'rdoc')
17 |
--------------------------------------------------------------------------------
/bin/ri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'ri' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rdoc', 'ri')
17 |
--------------------------------------------------------------------------------
/bin/rspec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rspec' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rspec-core', 'rspec')
17 |
--------------------------------------------------------------------------------
/bin/spork:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'spork' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('spork', 'spork')
17 |
--------------------------------------------------------------------------------
/bin/thor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'thor' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('thor', 'thor')
17 |
--------------------------------------------------------------------------------
/bin/tt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'tt' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('treetop', 'tt')
17 |
--------------------------------------------------------------------------------
/bin/unit_diff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'unit_diff' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'unit_diff')
17 |
--------------------------------------------------------------------------------
/bin/zentest:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'zentest' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('ZenTest', 'zentest')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/annotate:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'annotate' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('annotate', 'annotate')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/autospec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'autospec' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rspec-core', 'autospec')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/erubis:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'erubis' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('erubis', 'erubis')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/htmldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'htmldiff' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('diff-lcs', 'htmldiff')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/ldiff:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'ldiff' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('diff-lcs', 'ldiff')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/nokogiri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'nokogiri' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('nokogiri', 'nokogiri')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rackup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rackup' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rack', 'rackup')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rails' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rails', 'rails')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rake' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rake', 'rake')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rake2thor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rake2thor' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('thor', 'rake2thor')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rdoc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rdoc' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rdoc', 'rdoc')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/ri:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'ri' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rdoc', 'ri')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/rspec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'rspec' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('rspec-core', 'rspec')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/spork:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'spork' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('spork', 'spork')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/thor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'thor' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('thor', 'thor')
17 |
--------------------------------------------------------------------------------
/bundler_stubs/tt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This file was generated by Bundler.
4 | #
5 | # The application 'tt' is installed as part of a gem, and
6 | # this file is here to facilitate running it.
7 | #
8 |
9 | require 'pathname'
10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11 | Pathname.new(__FILE__).realpath)
12 |
13 | require 'rubygems'
14 | require 'bundler/setup'
15 |
16 | load Gem.bin_path('treetop', 'tt')
17 |
--------------------------------------------------------------------------------
/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 SampleApp::Application
5 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # If you have a Gemfile, require the gems listed there, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(:default, Rails.env) if defined?(Bundler)
8 |
9 | module SampleApp
10 | class Application < Rails::Application
11 | # Settings in config/environments/* take precedence over those specified here.
12 | # Application configuration should go into files in config/initializers
13 | # -- all .rb files in that directory are automatically loaded.
14 |
15 | # Custom directories with classes and modules you want to be autoloadable.
16 | # config.autoload_paths += %W(#{config.root}/extras)
17 |
18 | # Only load the plugins named here, in the order given (default is alphabetical).
19 | # :all can be used as a placeholder for all plugins not explicitly named.
20 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
21 |
22 | # Activate observers that should always be running.
23 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
24 |
25 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
26 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
27 | # config.time_zone = 'Central Time (US & Canada)'
28 |
29 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
30 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
31 | # config.i18n.default_locale = :de
32 |
33 | # JavaScript files you want as :defaults (application.js is always included).
34 | # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
35 |
36 | # Configure the default encoding used in templates for Ruby 1.9.
37 | config.encoding = "utf-8"
38 |
39 | # Configure sensitive parameters which will be filtered from the log file.
40 | config.filter_parameters += [:password]
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | # Set up gems listed in the Gemfile.
4 | gemfile = File.expand_path('../../Gemfile', __FILE__)
5 | begin
6 | ENV['BUNDLE_GEMFILE'] = gemfile
7 | require 'bundler'
8 | Bundler.setup
9 | rescue Bundler::GemNotFound => e
10 | STDERR.puts e.message
11 | STDERR.puts "Try running `bundle install`."
12 | exit!
13 | end if File.exist?(gemfile)
14 |
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3-ruby (not necessary on OS X Leopard)
3 | development:
4 | adapter: sqlite3
5 | database: db/development.sqlite3
6 | pool: 5
7 | timeout: 5000
8 |
9 | # Warning: The database defined as "test" will be erased and
10 | # re-generated from your development database when you run "rake".
11 | # Do not set this db to the same as development or production.
12 | test:
13 | adapter: sqlite3
14 | database: db/test.sqlite3
15 | pool: 5
16 | timeout: 5000
17 |
18 | production:
19 | adapter: sqlite3
20 | database: db/production.sqlite3
21 | pool: 5
22 | timeout: 5000
23 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | SampleApp::Application.initialize!
6 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | SampleApp::Application.configure do
2 | # Settings specified here will take precedence over those in config/environment.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 webserver 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_view.debug_rjs = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Don't care if the mailer can't send
18 | config.action_mailer.raise_delivery_errors = false
19 |
20 | # Print deprecation notices to the Rails logger
21 | config.active_support.deprecation = :log
22 | end
23 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | SampleApp::Application.configure do
2 | # Settings specified here will take precedence over those in config/environment.rb
3 |
4 | # The production environment is meant for finished, "live" apps.
5 | # Code is not reloaded between requests
6 | config.cache_classes = true
7 |
8 | # Full error reports are disabled and caching is turned on
9 | config.consider_all_requests_local = false
10 | config.action_controller.perform_caching = true
11 |
12 | # Specifies the header that your server uses for sending files
13 | config.action_dispatch.x_sendfile_header = "X-Sendfile"
14 |
15 | # For nginx:
16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
17 |
18 | # If you have no front-end server that supports something like X-Sendfile,
19 | # just comment this out and Rails will serve the files
20 |
21 | # See everything in the log (default is :info)
22 | # config.log_level = :debug
23 |
24 | # Use a different logger for distributed setups
25 | # config.logger = SyslogLogger.new
26 |
27 | # Use a different cache store in production
28 | # config.cache_store = :mem_cache_store
29 |
30 | # Disable Rails's static asset server
31 | # In production, Apache or nginx will already do this
32 | config.serve_static_assets = false
33 |
34 | # Enable serving of images, stylesheets, and javascripts from an asset server
35 | # config.action_controller.asset_host = "http://assets.example.com"
36 |
37 | # Disable delivery errors, bad email addresses will be ignored
38 | # config.action_mailer.raise_delivery_errors = false
39 |
40 | # Enable threaded mode
41 | # config.threadsafe!
42 |
43 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44 | # the I18n.default_locale when a translation can not be found)
45 | config.i18n.fallbacks = true
46 |
47 | # Send deprecation notices to registered listeners
48 | config.active_support.deprecation = :notify
49 | end
50 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | SampleApp::Application.configure do
2 | # Settings specified here will take precedence over those in config/environment.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 | # Log error messages when you accidentally call methods on nil.
11 | config.whiny_nils = true
12 |
13 | # Show full error reports and disable caching
14 | config.consider_all_requests_local = true
15 | config.action_controller.perform_caching = false
16 |
17 | # Raise exceptions instead of rendering exception templates
18 | config.action_dispatch.show_exceptions = false
19 |
20 | # Disable request forgery protection in test environment
21 | config.action_controller.allow_forgery_protection = false
22 |
23 | # Tell Action Mailer not to deliver emails to the real world.
24 | # The :test delivery method accumulates sent emails in the
25 | # ActionMailer::Base.deliveries array.
26 | config.action_mailer.delivery_method = :test
27 |
28 | # Use SQL instead of Active Record's schema dumper when creating the test database.
29 | # This is necessary if your schema can't be completely dumped by the schema dumper,
30 | # like if you have constraints or database-specific column types
31 | # config.active_record.schema_format = :sql
32 |
33 | # Print deprecation notices to the stderr
34 | config.active_support.deprecation = :stderr
35 | end
36 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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 | SampleApp::Application.config.secret_token = '30df044d52659429e4a8b0b0620397c49ff7acc241b9c8fc24aaad9f0292a3db3cd0ba77084213e74286ea4b9c5df3992cf16532c3e454a152e08889a8eb3d2e'
8 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | SampleApp::Application.config.session_store :cookie_store, :key => '_sample_app_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 "rake db:sessions:create")
8 | # SampleApp::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Sample localization file for English. Add more files in this directory for other locales.
2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 |
4 | en:
5 | hello: "Hello world"
6 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | SampleApp::Application.routes.draw do
2 |
3 | resources :users do
4 | member do
5 | get :following, :followers
6 | end
7 | end
8 |
9 | resources :sessions, :only => [:new, :create, :destroy]
10 | resources :microposts, :only => [:create, :destroy]
11 | resources :relationships, :only => [:create, :destroy]
12 |
13 | root :to => "pages#home"
14 |
15 | match '/contact', :to => 'pages#contact'
16 | match '/about', :to => 'pages#about'
17 | match '/help', :to => 'pages#help'
18 | match '/signup', :to => 'users#new'
19 | match '/signin', :to => 'sessions#new'
20 | match '/signout', :to => 'sessions#destroy'
21 |
22 | # The priority is based upon order of creation:
23 | # first created -> highest priority.
24 |
25 | # Sample of regular route:
26 | # match 'products/:id' => 'catalog#view'
27 | # Keep in mind you can assign values other than :controller and :action
28 |
29 | # Sample of named route:
30 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
31 | # This route can be invoked with purchase_url(:id => product.id)
32 |
33 | # Sample resource route (maps HTTP verbs to controller actions automatically):
34 | # resources :products
35 |
36 | # Sample resource route with options:
37 | # resources :products do
38 | # member do
39 | # get :short
40 | # post :toggle
41 | # end
42 | #
43 | # collection do
44 | # get :sold
45 | # end
46 | # end
47 |
48 | # Sample resource route with sub-resources:
49 | # resources :products do
50 | # resources :comments, :sales
51 | # resource :seller
52 | # end
53 |
54 | # Sample resource route with more complex sub-resources
55 | # resources :products do
56 | # resources :comments
57 | # resources :sales do
58 | # get :recent, :on => :collection
59 | # end
60 | # end
61 |
62 | # Sample resource route within a namespace:
63 | # namespace :admin do
64 | # # Directs /admin/products/* to Admin::ProductsController
65 | # # (app/controllers/admin/products_controller.rb)
66 | # resources :products
67 | # end
68 |
69 | # You can have the root of your site routed with "root"
70 | # just remember to delete public/index.html.
71 | # root :to => "welcome#index"
72 |
73 | # See how all your routes lay out with "rake routes"
74 |
75 | # This is a legacy wild controller route that's not recommended for RESTful applications.
76 | # Note: This route will make all actions in every controller accessible via GET requests.
77 | # match ':controller(/:action(/:id(.:format)))'
78 | end
79 |
--------------------------------------------------------------------------------
/db/migrate/20100821203213_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration
2 | def self.up
3 | create_table :users do |t|
4 | t.string :name
5 | t.string :email
6 |
7 | t.timestamps
8 | end
9 | end
10 |
11 | def self.down
12 | drop_table :users
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20100822012431_add_email_uniqueness_index.rb:
--------------------------------------------------------------------------------
1 | class AddEmailUniquenessIndex < ActiveRecord::Migration
2 | def self.up
3 | add_index :users, :email, :unique => true
4 | end
5 |
6 | def self.down
7 | remove_index :users, :email
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20100822204528_add_password_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddPasswordToUsers < ActiveRecord::Migration
2 | def self.up
3 | add_column :users, :encrypted_password, :string
4 | end
5 |
6 | def self.down
7 | remove_column :users, :encrypted_password
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20100822233125_add_salt_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddSaltToUsers < ActiveRecord::Migration
2 | def self.up
3 | add_column :users, :salt, :string
4 | end
5 |
6 | def self.down
7 | remove_column :users, :salt
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20100829021049_add_admin_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddAdminToUsers < ActiveRecord::Migration
2 | def self.up
3 | add_column :users, :admin, :boolean, :default => false
4 | end
5 |
6 | def self.down
7 | remove_column :users, :admin
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20100829210229_create_microposts.rb:
--------------------------------------------------------------------------------
1 | class CreateMicroposts < ActiveRecord::Migration
2 | def self.up
3 | create_table :microposts do |t|
4 | t.string :content
5 | t.integer :user_id
6 |
7 | t.timestamps
8 | end
9 | add_index :microposts, [:user_id, :created_at]
10 | end
11 |
12 | def self.down
13 | drop_table :microposts
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/db/migrate/20100831012055_create_relationships.rb:
--------------------------------------------------------------------------------
1 | class CreateRelationships < ActiveRecord::Migration
2 | def self.up
3 | create_table :relationships do |t|
4 | t.integer :follower_id
5 | t.integer :followed_id
6 |
7 | t.timestamps
8 | end
9 | add_index :relationships, :follower_id
10 | add_index :relationships, :followed_id
11 | add_index :relationships, [:follower_id, :followed_id], :unique => true
12 | end
13 |
14 | def self.down
15 | drop_table :relationships
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended to check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(:version => 20100831012055) do
15 |
16 | create_table "microposts", :force => true do |t|
17 | t.string "content"
18 | t.integer "user_id"
19 | t.datetime "created_at"
20 | t.datetime "updated_at"
21 | end
22 |
23 | add_index "microposts", ["user_id", "created_at"], :name => "index_microposts_on_user_id_and_created_at"
24 |
25 | create_table "relationships", :force => true do |t|
26 | t.integer "follower_id"
27 | t.integer "followed_id"
28 | t.datetime "created_at"
29 | t.datetime "updated_at"
30 | end
31 |
32 | add_index "relationships", ["followed_id"], :name => "index_relationships_on_followed_id"
33 | add_index "relationships", ["follower_id", "followed_id"], :name => "index_relationships_on_follower_id_and_followed_id", :unique => true
34 | add_index "relationships", ["follower_id"], :name => "index_relationships_on_follower_id"
35 |
36 | create_table "users", :force => true do |t|
37 | t.string "name"
38 | t.string "email"
39 | t.datetime "created_at"
40 | t.datetime "updated_at"
41 | t.string "encrypted_password"
42 | t.string "salt"
43 | t.boolean "admin", :default => false
44 | end
45 |
46 | add_index "users", ["email"], :name => "index_users_on_email", :unique => true
47 |
48 | end
49 |
--------------------------------------------------------------------------------
/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 => 'Daley', :city => cities.first)
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/tasks/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/lib/tasks/.gitkeep
--------------------------------------------------------------------------------
/lib/tasks/sample_data.rake:
--------------------------------------------------------------------------------
1 | namespace :db do
2 | desc "Fill database with sample data"
3 | task :populate => :environment do
4 | Rake::Task['db:reset'].invoke
5 | make_users
6 | make_microposts
7 | make_relationships
8 | end
9 | end
10 |
11 | def make_users
12 | admin = User.create!(:name => "Example User",
13 | :email => "example@railstutorial.org",
14 | :password => "foobar",
15 | :password_confirmation => "foobar")
16 | admin.toggle!(:admin)
17 | 99.times do |n|
18 | name = Faker::Name.name
19 | email = "example-#{n+1}@railstutorial.org"
20 | password = "password"
21 | User.create!(:name => name,
22 | :email => email,
23 | :password => password,
24 | :password_confirmation => password)
25 | end
26 | end
27 |
28 | def make_microposts
29 | 50.times do
30 | User.all(:limit => 6).each do |user|
31 | user.microposts.create!(:content => Faker::Lorem.sentence(5))
32 | end
33 | end
34 | end
35 |
36 | def make_relationships
37 | users = User.all
38 | user = users.first
39 | following = users[1..50]
40 | followers = users[3..40]
41 | following.each { |followed| user.follow!(followed) }
42 | followers.each { |follower| follower.follow!(user) }
43 | end
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/images/logo.png
--------------------------------------------------------------------------------
/public/images/rails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/images/rails.png
--------------------------------------------------------------------------------
/public/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // Place your application-specific JavaScript functions and classes here
2 | // This file is automatically included by javascript_include_tag :defaults
3 |
--------------------------------------------------------------------------------
/public/javascripts/rails.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | // Technique from Juriy Zaytsev
3 | // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4 | function isEventSupported(eventName) {
5 | var el = document.createElement('div');
6 | eventName = 'on' + eventName;
7 | var isSupported = (eventName in el);
8 | if (!isSupported) {
9 | el.setAttribute(eventName, 'return;');
10 | isSupported = typeof el[eventName] == 'function';
11 | }
12 | el = null;
13 | return isSupported;
14 | }
15 |
16 | function isForm(element) {
17 | return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18 | }
19 |
20 | function isInput(element) {
21 | if (Object.isElement(element)) {
22 | var name = element.nodeName.toUpperCase()
23 | return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24 | }
25 | else return false
26 | }
27 |
28 | var submitBubbles = isEventSupported('submit'),
29 | changeBubbles = isEventSupported('change')
30 |
31 | if (!submitBubbles || !changeBubbles) {
32 | // augment the Event.Handler class to observe custom events when needed
33 | Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34 | function(init, element, eventName, selector, callback) {
35 | init(element, eventName, selector, callback)
36 | // is the handler being attached to an element that doesn't support this event?
37 | if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38 | (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39 | // "submit" => "emulated:submit"
40 | this.eventName = 'emulated:' + this.eventName
41 | }
42 | }
43 | )
44 | }
45 |
46 | if (!submitBubbles) {
47 | // discover forms on the page by observing focus events which always bubble
48 | document.on('focusin', 'form', function(focusEvent, form) {
49 | // special handler for the real "submit" event (one-time operation)
50 | if (!form.retrieve('emulated:submit')) {
51 | form.on('submit', function(submitEvent) {
52 | var emulated = form.fire('emulated:submit', submitEvent, true)
53 | // if custom event received preventDefault, cancel the real one too
54 | if (emulated.returnValue === false) submitEvent.preventDefault()
55 | })
56 | form.store('emulated:submit', true)
57 | }
58 | })
59 | }
60 |
61 | if (!changeBubbles) {
62 | // discover form inputs on the page
63 | document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64 | // special handler for real "change" events
65 | if (!input.retrieve('emulated:change')) {
66 | input.on('change', function(changeEvent) {
67 | input.fire('emulated:change', changeEvent, true)
68 | })
69 | input.store('emulated:change', true)
70 | }
71 | })
72 | }
73 |
74 | function handleRemote(element) {
75 | var method, url, params;
76 |
77 | var event = element.fire("ajax:before");
78 | if (event.stopped) return false;
79 |
80 | if (element.tagName.toLowerCase() === 'form') {
81 | method = element.readAttribute('method') || 'post';
82 | url = element.readAttribute('action');
83 | params = element.serialize();
84 | } else {
85 | method = element.readAttribute('data-method') || 'get';
86 | url = element.readAttribute('href');
87 | params = {};
88 | }
89 |
90 | new Ajax.Request(url, {
91 | method: method,
92 | parameters: params,
93 | evalScripts: true,
94 |
95 | onComplete: function(request) { element.fire("ajax:complete", request); },
96 | onSuccess: function(request) { element.fire("ajax:success", request); },
97 | onFailure: function(request) { element.fire("ajax:failure", request); }
98 | });
99 |
100 | element.fire("ajax:after");
101 | }
102 |
103 | function handleMethod(element) {
104 | var method = element.readAttribute('data-method'),
105 | url = element.readAttribute('href'),
106 | csrf_param = $$('meta[name=csrf-param]')[0],
107 | csrf_token = $$('meta[name=csrf-token]')[0];
108 |
109 | var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110 | element.parentNode.insert(form);
111 |
112 | if (method !== 'post') {
113 | var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114 | form.insert(field);
115 | }
116 |
117 | if (csrf_param) {
118 | var param = csrf_param.readAttribute('content'),
119 | token = csrf_token.readAttribute('content'),
120 | field = new Element('input', { type: 'hidden', name: param, value: token });
121 | form.insert(field);
122 | }
123 |
124 | form.submit();
125 | }
126 |
127 |
128 | document.on("click", "*[data-confirm]", function(event, element) {
129 | var message = element.readAttribute('data-confirm');
130 | if (!confirm(message)) event.stop();
131 | });
132 |
133 | document.on("click", "a[data-remote]", function(event, element) {
134 | if (event.stopped) return;
135 | handleRemote(element);
136 | event.stop();
137 | });
138 |
139 | document.on("click", "a[data-method]", function(event, element) {
140 | if (event.stopped) return;
141 | handleMethod(element);
142 | event.stop();
143 | });
144 |
145 | document.on("submit", function(event) {
146 | var element = event.findElement(),
147 | message = element.readAttribute('data-confirm');
148 | if (message && !confirm(message)) {
149 | event.stop();
150 | return false;
151 | }
152 |
153 | var inputs = element.select("input[type=submit][data-disable-with]");
154 | inputs.each(function(input) {
155 | input.disabled = true;
156 | input.writeAttribute('data-original-value', input.value);
157 | input.value = input.readAttribute('data-disable-with');
158 | });
159 |
160 | var element = event.findElement("form[data-remote]");
161 | if (element) {
162 | handleRemote(element);
163 | event.stop();
164 | }
165 | });
166 |
167 | document.on("ajax:after", "form", function(event, element) {
168 | var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169 | inputs.each(function(input) {
170 | input.value = input.readAttribute('data-original-value');
171 | input.removeAttribute('data-original-value');
172 | input.disabled = false;
173 | });
174 | });
175 | })();
176 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/public/stylesheets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/.gitkeep
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/ie.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 |
3 |
4 | Blueprint CSS Framework 0.9
5 | http://blueprintcss.org
6 |
7 | * Copyright (c) 2007-Present. See LICENSE for more info.
8 | * See README for instructions on how to use Blueprint.
9 | * For credits and origins, see AUTHORS.
10 | * This is a compressed file. See the sources in the 'src' directory.
11 |
12 | ----------------------------------------------------------------------- */
13 |
14 | /* ie.css */
15 | body {text-align:center;}
16 | .container {text-align:left;}
17 | * html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
18 | * html legend {margin:0px -8px 16px 0;padding:0;}
19 | sup {vertical-align:text-top;}
20 | sub {vertical-align:text-bottom;}
21 | html>body p code {*white-space:normal;}
22 | hr {margin:-8px auto 11px;}
23 | img {-ms-interpolation-mode:bicubic;}
24 | .clearfix, .container {display:inline-block;}
25 | * html .clearfix, * html .container {height:1%;}
26 | fieldset {padding-top:0;}
27 | textarea {overflow:auto;}
28 | input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
29 | input.text:focus, input.title:focus {border-color:#666;}
30 | input.text, input.title, textarea, select {margin:0.5em 0;}
31 | input.checkbox, input.radio {position:relative;top:.25em;}
32 | form.inline div, form.inline p {vertical-align:middle;}
33 | form.inline label {position:relative;top:-0.25em;}
34 | form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
35 | button, input.button {position:relative;top:0.25em;}
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/buttons/icons/cross.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/buttons/icons/cross.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/buttons/icons/key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/buttons/icons/key.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/buttons/icons/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/buttons/icons/tick.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/buttons/readme.txt:
--------------------------------------------------------------------------------
1 | Buttons
2 |
3 | * Gives you great looking CSS buttons, for both and .
4 | * Demo: particletree.com/features/rediscovering-the-button-element
5 |
6 |
7 | Credits
8 | ----------------------------------------------------------------
9 |
10 | * Created by Kevin Hale [particletree.com]
11 | * Adapted for Blueprint by Olav Bjorkoy [bjorkoy.com]
12 |
13 |
14 | Usage
15 | ----------------------------------------------------------------
16 |
17 | 1) Add this plugin to lib/settings.yml.
18 | See compress.rb for instructions.
19 |
20 | 2) Use the following HTML code to place the buttons on your site:
21 |
22 |
23 | Save
24 |
25 |
26 |
27 | Change Password
28 |
29 |
30 |
31 | Cancel
32 |
33 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/buttons/screen.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | buttons.css
4 | * Gives you some great CSS-only buttons.
5 |
6 | Created by Kevin Hale [particletree.com]
7 | * particletree.com/features/rediscovering-the-button-element
8 |
9 | See Readme.txt in this folder for instructions.
10 |
11 | -------------------------------------------------------------- */
12 |
13 | a.button, button {
14 | display:block;
15 | float:left;
16 | margin: 0.7em 0.5em 0.7em 0;
17 | padding:5px 10px 5px 7px; /* Links */
18 |
19 | border:1px solid #dedede;
20 | border-top:1px solid #eee;
21 | border-left:1px solid #eee;
22 |
23 | background-color:#f5f5f5;
24 | font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
25 | font-size:100%;
26 | line-height:130%;
27 | text-decoration:none;
28 | font-weight:bold;
29 | color:#565656;
30 | cursor:pointer;
31 | }
32 | button {
33 | width:auto;
34 | overflow:visible;
35 | padding:4px 10px 3px 7px; /* IE6 */
36 | }
37 | button[type] {
38 | padding:4px 10px 4px 7px; /* Firefox */
39 | line-height:17px; /* Safari */
40 | }
41 | *:first-child+html button[type] {
42 | padding:4px 10px 3px 7px; /* IE7 */
43 | }
44 | button img, a.button img{
45 | margin:0 3px -3px 0 !important;
46 | padding:0;
47 | border:none;
48 | width:16px;
49 | height:16px;
50 | float:none;
51 | }
52 |
53 |
54 | /* Button colors
55 | -------------------------------------------------------------- */
56 |
57 | /* Standard */
58 | button:hover, a.button:hover{
59 | background-color:#dff4ff;
60 | border:1px solid #c2e1ef;
61 | color:#336699;
62 | }
63 | a.button:active{
64 | background-color:#6299c5;
65 | border:1px solid #6299c5;
66 | color:#fff;
67 | }
68 |
69 | /* Positive */
70 | body .positive {
71 | color:#529214;
72 | }
73 | a.positive:hover, button.positive:hover {
74 | background-color:#E6EFC2;
75 | border:1px solid #C6D880;
76 | color:#529214;
77 | }
78 | a.positive:active {
79 | background-color:#529214;
80 | border:1px solid #529214;
81 | color:#fff;
82 | }
83 |
84 | /* Negative */
85 | body .negative {
86 | color:#d12f19;
87 | }
88 | a.negative:hover, button.negative:hover {
89 | background-color:#fbe3e4;
90 | border:1px solid #fbc2c4;
91 | color:#d12f19;
92 | }
93 | a.negative:active {
94 | background-color:#d12f19;
95 | border:1px solid #d12f19;
96 | color:#fff;
97 | }
98 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/fancy-type/readme.txt:
--------------------------------------------------------------------------------
1 | Fancy Type
2 |
3 | * Gives you classes to use if you'd like some
4 | extra fancy typography.
5 |
6 | Credits and instructions are specified above each class
7 | in the fancy-type.css file in this directory.
8 |
9 |
10 | Usage
11 | ----------------------------------------------------------------
12 |
13 | 1) Add this plugin to lib/settings.yml.
14 | See compress.rb for instructions.
15 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/fancy-type/screen.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | fancy-type.css
4 | * Lots of pretty advanced classes for manipulating text.
5 |
6 | See the Readme file in this folder for additional instructions.
7 |
8 | -------------------------------------------------------------- */
9 |
10 | /* Indentation instead of line shifts for sibling paragraphs. */
11 | p + p { text-indent:2em; margin-top:-1.5em; }
12 | form p + p { text-indent: 0; } /* Don't want this in forms. */
13 |
14 |
15 | /* For great looking type, use this code instead of asdf:
16 | asdf
17 | Best used on prepositions and ampersands. */
18 |
19 | .alt {
20 | color: #666;
21 | font-family: "Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif;
22 | font-style: italic;
23 | font-weight: normal;
24 | }
25 |
26 |
27 | /* For great looking quote marks in titles, replace "asdf" with:
28 | “ asdf”
29 | (That is, when the title starts with a quote mark).
30 | (You may have to change this value depending on your font size). */
31 |
32 | .dquo { margin-left: -.5em; }
33 |
34 |
35 | /* Reduced size type with incremental leading
36 | (http://www.markboulton.co.uk/journal/comments/incremental_leading/)
37 |
38 | This could be used for side notes. For smaller type, you don't necessarily want to
39 | follow the 1.5x vertical rhythm -- the line-height is too much.
40 |
41 | Using this class, it reduces your font size and line-height so that for
42 | every four lines of normal sized type, there is five lines of the sidenote. eg:
43 |
44 | New type size in em's:
45 | 10px (wanted side note size) / 12px (existing base size) = 0.8333 (new type size in ems)
46 |
47 | New line-height value:
48 | 12px x 1.5 = 18px (old line-height)
49 | 18px x 4 = 72px
50 | 72px / 5 = 14.4px (new line height)
51 | 14.4px / 10px = 1.44 (new line height in em's) */
52 |
53 | p.incr, .incr p {
54 | font-size: 10px;
55 | line-height: 1.44em;
56 | margin-bottom: 1.5em;
57 | }
58 |
59 |
60 | /* Surround uppercase words and abbreviations with this class.
61 | Based on work by Jørgen Arnor Gårdsø Lom [http://twistedintellect.com/] */
62 |
63 | .caps {
64 | font-variant: small-caps;
65 | letter-spacing: 1px;
66 | text-transform: lowercase;
67 | font-size:1.2em;
68 | line-height:1%;
69 | font-weight:bold;
70 | padding:0 2px;
71 | }
72 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/doc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/doc.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/email.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/email.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/external.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/external.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/feed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/feed.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/im.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/im.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/pdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/pdf.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/visited.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/visited.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/icons/xls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/plugins/link-icons/icons/xls.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/readme.txt:
--------------------------------------------------------------------------------
1 | Link Icons
2 | * Icons for links based on protocol or file type.
3 |
4 | This is not supported in IE versions < 7.
5 |
6 |
7 | Credits
8 | ----------------------------------------------------------------
9 |
10 | * Marc Morgan
11 | * Olav Bjorkoy [bjorkoy.com]
12 |
13 |
14 | Usage
15 | ----------------------------------------------------------------
16 |
17 | 1) Add this line to your HTML:
18 |
19 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/link-icons/screen.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | link-icons.css
4 | * Icons for links based on protocol or file type.
5 |
6 | See the Readme file in this folder for additional instructions.
7 |
8 | -------------------------------------------------------------- */
9 |
10 | /* Use this class if a link gets an icon when it shouldn't. */
11 | body a.noicon {
12 | background:transparent none !important;
13 | padding:0 !important;
14 | margin:0 !important;
15 | }
16 |
17 | /* Make sure the icons are not cut */
18 | a[href^="http:"], a[href^="mailto:"], a[href^="http:"]:visited,
19 | a[href$=".pdf"], a[href$=".doc"], a[href$=".xls"], a[href$=".rss"],
20 | a[href$=".rdf"], a[href^="aim:"] {
21 | padding:2px 22px 2px 0;
22 | margin:-2px 0;
23 | background-repeat: no-repeat;
24 | background-position: right center;
25 | }
26 |
27 | /* External links */
28 | a[href^="http:"] { background-image: url(icons/external.png); }
29 | a[href^="mailto:"] { background-image: url(icons/email.png); }
30 | a[href^="http:"]:visited { background-image: url(icons/visited.png); }
31 |
32 | /* Files */
33 | a[href$=".pdf"] { background-image: url(icons/pdf.png); }
34 | a[href$=".doc"] { background-image: url(icons/doc.png); }
35 | a[href$=".xls"] { background-image: url(icons/xls.png); }
36 |
37 | /* Misc */
38 | a[href$=".rss"],
39 | a[href$=".rdf"] { background-image: url(icons/feed.png); }
40 | a[href^="aim:"] { background-image: url(icons/im.png); }
41 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/rtl/readme.txt:
--------------------------------------------------------------------------------
1 | RTL
2 | * Mirrors Blueprint, so it can be used with Right-to-Left languages.
3 |
4 | By Ran Yaniv Hartstein, ranh.co.il
5 |
6 | Usage
7 | ----------------------------------------------------------------
8 |
9 | 1) Add this line to your HTML:
10 |
11 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/plugins/rtl/screen.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | rtl.css
4 | * Mirrors Blueprint for left-to-right languages
5 |
6 | By Ran Yaniv Hartstein [ranh.co.il]
7 |
8 | -------------------------------------------------------------- */
9 |
10 | body .container { direction: rtl; }
11 | body .column, body .span-1, body .span-2, body .span-3, body .span-4, body .span-5, body .span-6, body .span-7, body .span-8, body .span-9, body .span-10, body .span-11, body .span-12, body .span-13, body .span-14, body .span-15, body .span-16, body .span-17, body .span-18, body .span-19, body .span-20, body .span-21, body .span-22, body .span-23, body .span-24 {
12 | float: right;
13 | margin-right: 0;
14 | margin-left: 10px;
15 | text-align:right;
16 | }
17 |
18 | body div.last { margin-left: 0; }
19 | body table .last { padding-left: 0; }
20 |
21 | body .append-1 { padding-right: 0; padding-left: 40px; }
22 | body .append-2 { padding-right: 0; padding-left: 80px; }
23 | body .append-3 { padding-right: 0; padding-left: 120px; }
24 | body .append-4 { padding-right: 0; padding-left: 160px; }
25 | body .append-5 { padding-right: 0; padding-left: 200px; }
26 | body .append-6 { padding-right: 0; padding-left: 240px; }
27 | body .append-7 { padding-right: 0; padding-left: 280px; }
28 | body .append-8 { padding-right: 0; padding-left: 320px; }
29 | body .append-9 { padding-right: 0; padding-left: 360px; }
30 | body .append-10 { padding-right: 0; padding-left: 400px; }
31 | body .append-11 { padding-right: 0; padding-left: 440px; }
32 | body .append-12 { padding-right: 0; padding-left: 480px; }
33 | body .append-13 { padding-right: 0; padding-left: 520px; }
34 | body .append-14 { padding-right: 0; padding-left: 560px; }
35 | body .append-15 { padding-right: 0; padding-left: 600px; }
36 | body .append-16 { padding-right: 0; padding-left: 640px; }
37 | body .append-17 { padding-right: 0; padding-left: 680px; }
38 | body .append-18 { padding-right: 0; padding-left: 720px; }
39 | body .append-19 { padding-right: 0; padding-left: 760px; }
40 | body .append-20 { padding-right: 0; padding-left: 800px; }
41 | body .append-21 { padding-right: 0; padding-left: 840px; }
42 | body .append-22 { padding-right: 0; padding-left: 880px; }
43 | body .append-23 { padding-right: 0; padding-left: 920px; }
44 |
45 | body .prepend-1 { padding-left: 0; padding-right: 40px; }
46 | body .prepend-2 { padding-left: 0; padding-right: 80px; }
47 | body .prepend-3 { padding-left: 0; padding-right: 120px; }
48 | body .prepend-4 { padding-left: 0; padding-right: 160px; }
49 | body .prepend-5 { padding-left: 0; padding-right: 200px; }
50 | body .prepend-6 { padding-left: 0; padding-right: 240px; }
51 | body .prepend-7 { padding-left: 0; padding-right: 280px; }
52 | body .prepend-8 { padding-left: 0; padding-right: 320px; }
53 | body .prepend-9 { padding-left: 0; padding-right: 360px; }
54 | body .prepend-10 { padding-left: 0; padding-right: 400px; }
55 | body .prepend-11 { padding-left: 0; padding-right: 440px; }
56 | body .prepend-12 { padding-left: 0; padding-right: 480px; }
57 | body .prepend-13 { padding-left: 0; padding-right: 520px; }
58 | body .prepend-14 { padding-left: 0; padding-right: 560px; }
59 | body .prepend-15 { padding-left: 0; padding-right: 600px; }
60 | body .prepend-16 { padding-left: 0; padding-right: 640px; }
61 | body .prepend-17 { padding-left: 0; padding-right: 680px; }
62 | body .prepend-18 { padding-left: 0; padding-right: 720px; }
63 | body .prepend-19 { padding-left: 0; padding-right: 760px; }
64 | body .prepend-20 { padding-left: 0; padding-right: 800px; }
65 | body .prepend-21 { padding-left: 0; padding-right: 840px; }
66 | body .prepend-22 { padding-left: 0; padding-right: 880px; }
67 | body .prepend-23 { padding-left: 0; padding-right: 920px; }
68 |
69 | body .border {
70 | padding-right: 0;
71 | padding-left: 4px;
72 | margin-right: 0;
73 | margin-left: 5px;
74 | border-right: none;
75 | border-left: 1px solid #eee;
76 | }
77 |
78 | body .colborder {
79 | padding-right: 0;
80 | padding-left: 24px;
81 | margin-right: 0;
82 | margin-left: 25px;
83 | border-right: none;
84 | border-left: 1px solid #eee;
85 | }
86 |
87 | body .pull-1 { margin-left: 0; margin-right: -40px; }
88 | body .pull-2 { margin-left: 0; margin-right: -80px; }
89 | body .pull-3 { margin-left: 0; margin-right: -120px; }
90 | body .pull-4 { margin-left: 0; margin-right: -160px; }
91 |
92 | body .push-0 { margin: 0 18px 0 0; }
93 | body .push-1 { margin: 0 18px 0 -40px; }
94 | body .push-2 { margin: 0 18px 0 -80px; }
95 | body .push-3 { margin: 0 18px 0 -120px; }
96 | body .push-4 { margin: 0 18px 0 -160px; }
97 | body .push-0, body .push-1, body .push-2,
98 | body .push-3, body .push-4 { float: left; }
99 |
100 |
101 | /* Typography with RTL support */
102 | body h1,body h2,body h3,
103 | body h4,body h5,body h6 { font-family: Arial, sans-serif; }
104 | html body { font-family: Arial, sans-serif; }
105 | body pre,body code,body tt { font-family: monospace; }
106 |
107 | /* Mirror floats and margins on typographic elements */
108 | body p img { float: right; margin: 1.5em 0 1.5em 1.5em; }
109 | body dd, body ul, body ol { margin-left: 0; margin-right: 1.5em;}
110 | body td, body th { text-align:right; }
111 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/print.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 |
3 |
4 | Blueprint CSS Framework 0.9
5 | http://blueprintcss.org
6 |
7 | * Copyright (c) 2007-Present. See LICENSE for more info.
8 | * See README for instructions on how to use Blueprint.
9 | * For credits and origins, see AUTHORS.
10 | * This is a compressed file. See the sources in the 'src' directory.
11 |
12 | ----------------------------------------------------------------------- */
13 |
14 | /* print.css */
15 | body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
16 | .container {background:none;}
17 | hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
18 | hr.space {background:#fff;color:#fff;visibility:hidden;}
19 | h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
20 | code {font:.9em "Courier New", Monaco, Courier, monospace;}
21 | a img {border:none;}
22 | p img.top {margin-top:0;}
23 | blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
24 | .small {font-size:.9em;}
25 | .large {font-size:1.1em;}
26 | .quiet {color:#999;}
27 | .hide {display:none;}
28 | a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
29 | a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;}
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/screen.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 |
3 |
4 | Blueprint CSS Framework 0.9
5 | http://blueprintcss.org
6 |
7 | * Copyright (c) 2007-Present. See LICENSE for more info.
8 | * See README for instructions on how to use Blueprint.
9 | * For credits and origins, see AUTHORS.
10 | * This is a compressed file. See the sources in the 'src' directory.
11 |
12 | ----------------------------------------------------------------------- */
13 |
14 | /* reset.css */
15 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, nav, section {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
16 | article, aside, dialog, figure, footer, header, hgroup, nav, section {display:block;}
17 | body {line-height:1.5;}
18 | table {border-collapse:separate;border-spacing:0;}
19 | caption, th, td {text-align:left;font-weight:normal;}
20 | table, td, th {vertical-align:middle;}
21 | blockquote:before, blockquote:after, q:before, q:after {content:"";}
22 | blockquote, q {quotes:"" "";}
23 | a img {border:none;}
24 |
25 | /* typography.css */
26 | html {font-size:100.01%;}
27 | body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
28 | h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
29 | h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
30 | h2 {font-size:2em;margin-bottom:0.75em;}
31 | h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
32 | h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
33 | h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
34 | h6 {font-size:1em;font-weight:bold;}
35 | h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
36 | p {margin:0 0 1.5em;}
37 | p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
38 | p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
39 | a:focus, a:hover {color:#000;}
40 | a {color:#009;text-decoration:underline;}
41 | blockquote {margin:1.5em;color:#666;font-style:italic;}
42 | strong {font-weight:bold;}
43 | em, dfn {font-style:italic;}
44 | dfn {font-weight:bold;}
45 | sup, sub {line-height:0;}
46 | abbr, acronym {border-bottom:1px dotted #666;}
47 | address {margin:0 0 1.5em;font-style:italic;}
48 | del {color:#666;}
49 | pre {margin:1.5em 0;white-space:pre;}
50 | pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
51 | li ul, li ol {margin:0;}
52 | ul, ol {margin:0 1.5em 1.5em 0;padding-left:3.333em;}
53 | ul {list-style-type:disc;}
54 | ol {list-style-type:decimal;}
55 | dl {margin:0 0 1.5em 0;}
56 | dl dt {font-weight:bold;}
57 | dd {margin-left:1.5em;}
58 | table {margin-bottom:1.4em;width:100%;}
59 | th {font-weight:bold;}
60 | thead th {background:#c3d9ff;}
61 | th, td, caption {padding:4px 10px 4px 5px;}
62 | tr.even td {background:#e5ecf9;}
63 | tfoot {font-style:italic;}
64 | caption {background:#eee;}
65 | .small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
66 | .large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
67 | .hide {display:none;}
68 | .quiet {color:#666;}
69 | .loud {color:#000;}
70 | .highlight {background:#ff0;}
71 | .added {background:#060;color:#fff;}
72 | .removed {background:#900;color:#fff;}
73 | .first {margin-left:0;padding-left:0;}
74 | .last {margin-right:0;padding-right:0;}
75 | .top {margin-top:0;padding-top:0;}
76 | .bottom {margin-bottom:0;padding-bottom:0;}
77 |
78 | /* forms.css */
79 | label {font-weight:bold;}
80 | fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
81 | legend {font-weight:bold;font-size:1.2em;}
82 | input[type=text], input[type=password], input.text, input.title, textarea, select {background-color:#fff;border:1px solid #bbb;}
83 | input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus, select:focus {border-color:#666;}
84 | input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;}
85 | input.text, input.title {width:300px;padding:5px;}
86 | input.title {font-size:1.5em;}
87 | textarea {width:390px;height:250px;padding:5px;}
88 | input[type=checkbox], input[type=radio], input.checkbox, input.radio {position:relative;top:.25em;}
89 | form.inline {line-height:3;}
90 | form.inline p {margin-bottom:0;}
91 | .error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;}
92 | .error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;}
93 | .notice {background:#FFF6BF;color:#514721;border-color:#FFD324;}
94 | .success {background:#E6EFC2;color:#264409;border-color:#C6D880;}
95 | .error a {color:#8a1f11;}
96 | .notice a {color:#514721;}
97 | .success a {color:#264409;}
98 |
99 | /* grid.css */
100 | .container {width:950px;margin:0 auto;}
101 | .showgrid {background:url(src/grid.png);}
102 | .column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {float:left;margin-right:10px;}
103 | .last {margin-right:0;}
104 | .span-1 {width:30px;}
105 | .span-2 {width:70px;}
106 | .span-3 {width:110px;}
107 | .span-4 {width:150px;}
108 | .span-5 {width:190px;}
109 | .span-6 {width:230px;}
110 | .span-7 {width:270px;}
111 | .span-8 {width:310px;}
112 | .span-9 {width:350px;}
113 | .span-10 {width:390px;}
114 | .span-11 {width:430px;}
115 | .span-12 {width:470px;}
116 | .span-13 {width:510px;}
117 | .span-14 {width:550px;}
118 | .span-15 {width:590px;}
119 | .span-16 {width:630px;}
120 | .span-17 {width:670px;}
121 | .span-18 {width:710px;}
122 | .span-19 {width:750px;}
123 | .span-20 {width:790px;}
124 | .span-21 {width:830px;}
125 | .span-22 {width:870px;}
126 | .span-23 {width:910px;}
127 | .span-24 {width:950px;margin-right:0;}
128 | input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {border-left-width:1px;border-right-width:1px;padding-left:5px;padding-right:5px;}
129 | input.span-1, textarea.span-1 {width:18px;}
130 | input.span-2, textarea.span-2 {width:58px;}
131 | input.span-3, textarea.span-3 {width:98px;}
132 | input.span-4, textarea.span-4 {width:138px;}
133 | input.span-5, textarea.span-5 {width:178px;}
134 | input.span-6, textarea.span-6 {width:218px;}
135 | input.span-7, textarea.span-7 {width:258px;}
136 | input.span-8, textarea.span-8 {width:298px;}
137 | input.span-9, textarea.span-9 {width:338px;}
138 | input.span-10, textarea.span-10 {width:378px;}
139 | input.span-11, textarea.span-11 {width:418px;}
140 | input.span-12, textarea.span-12 {width:458px;}
141 | input.span-13, textarea.span-13 {width:498px;}
142 | input.span-14, textarea.span-14 {width:538px;}
143 | input.span-15, textarea.span-15 {width:578px;}
144 | input.span-16, textarea.span-16 {width:618px;}
145 | input.span-17, textarea.span-17 {width:658px;}
146 | input.span-18, textarea.span-18 {width:698px;}
147 | input.span-19, textarea.span-19 {width:738px;}
148 | input.span-20, textarea.span-20 {width:778px;}
149 | input.span-21, textarea.span-21 {width:818px;}
150 | input.span-22, textarea.span-22 {width:858px;}
151 | input.span-23, textarea.span-23 {width:898px;}
152 | input.span-24, textarea.span-24 {width:938px;}
153 | .append-1 {padding-right:40px;}
154 | .append-2 {padding-right:80px;}
155 | .append-3 {padding-right:120px;}
156 | .append-4 {padding-right:160px;}
157 | .append-5 {padding-right:200px;}
158 | .append-6 {padding-right:240px;}
159 | .append-7 {padding-right:280px;}
160 | .append-8 {padding-right:320px;}
161 | .append-9 {padding-right:360px;}
162 | .append-10 {padding-right:400px;}
163 | .append-11 {padding-right:440px;}
164 | .append-12 {padding-right:480px;}
165 | .append-13 {padding-right:520px;}
166 | .append-14 {padding-right:560px;}
167 | .append-15 {padding-right:600px;}
168 | .append-16 {padding-right:640px;}
169 | .append-17 {padding-right:680px;}
170 | .append-18 {padding-right:720px;}
171 | .append-19 {padding-right:760px;}
172 | .append-20 {padding-right:800px;}
173 | .append-21 {padding-right:840px;}
174 | .append-22 {padding-right:880px;}
175 | .append-23 {padding-right:920px;}
176 | .prepend-1 {padding-left:40px;}
177 | .prepend-2 {padding-left:80px;}
178 | .prepend-3 {padding-left:120px;}
179 | .prepend-4 {padding-left:160px;}
180 | .prepend-5 {padding-left:200px;}
181 | .prepend-6 {padding-left:240px;}
182 | .prepend-7 {padding-left:280px;}
183 | .prepend-8 {padding-left:320px;}
184 | .prepend-9 {padding-left:360px;}
185 | .prepend-10 {padding-left:400px;}
186 | .prepend-11 {padding-left:440px;}
187 | .prepend-12 {padding-left:480px;}
188 | .prepend-13 {padding-left:520px;}
189 | .prepend-14 {padding-left:560px;}
190 | .prepend-15 {padding-left:600px;}
191 | .prepend-16 {padding-left:640px;}
192 | .prepend-17 {padding-left:680px;}
193 | .prepend-18 {padding-left:720px;}
194 | .prepend-19 {padding-left:760px;}
195 | .prepend-20 {padding-left:800px;}
196 | .prepend-21 {padding-left:840px;}
197 | .prepend-22 {padding-left:880px;}
198 | .prepend-23 {padding-left:920px;}
199 | .border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;}
200 | .colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;}
201 | .pull-1 {margin-left:-40px;}
202 | .pull-2 {margin-left:-80px;}
203 | .pull-3 {margin-left:-120px;}
204 | .pull-4 {margin-left:-160px;}
205 | .pull-5 {margin-left:-200px;}
206 | .pull-6 {margin-left:-240px;}
207 | .pull-7 {margin-left:-280px;}
208 | .pull-8 {margin-left:-320px;}
209 | .pull-9 {margin-left:-360px;}
210 | .pull-10 {margin-left:-400px;}
211 | .pull-11 {margin-left:-440px;}
212 | .pull-12 {margin-left:-480px;}
213 | .pull-13 {margin-left:-520px;}
214 | .pull-14 {margin-left:-560px;}
215 | .pull-15 {margin-left:-600px;}
216 | .pull-16 {margin-left:-640px;}
217 | .pull-17 {margin-left:-680px;}
218 | .pull-18 {margin-left:-720px;}
219 | .pull-19 {margin-left:-760px;}
220 | .pull-20 {margin-left:-800px;}
221 | .pull-21 {margin-left:-840px;}
222 | .pull-22 {margin-left:-880px;}
223 | .pull-23 {margin-left:-920px;}
224 | .pull-24 {margin-left:-960px;}
225 | .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
226 | .push-1 {margin:0 -40px 1.5em 40px;}
227 | .push-2 {margin:0 -80px 1.5em 80px;}
228 | .push-3 {margin:0 -120px 1.5em 120px;}
229 | .push-4 {margin:0 -160px 1.5em 160px;}
230 | .push-5 {margin:0 -200px 1.5em 200px;}
231 | .push-6 {margin:0 -240px 1.5em 240px;}
232 | .push-7 {margin:0 -280px 1.5em 280px;}
233 | .push-8 {margin:0 -320px 1.5em 320px;}
234 | .push-9 {margin:0 -360px 1.5em 360px;}
235 | .push-10 {margin:0 -400px 1.5em 400px;}
236 | .push-11 {margin:0 -440px 1.5em 440px;}
237 | .push-12 {margin:0 -480px 1.5em 480px;}
238 | .push-13 {margin:0 -520px 1.5em 520px;}
239 | .push-14 {margin:0 -560px 1.5em 560px;}
240 | .push-15 {margin:0 -600px 1.5em 600px;}
241 | .push-16 {margin:0 -640px 1.5em 640px;}
242 | .push-17 {margin:0 -680px 1.5em 680px;}
243 | .push-18 {margin:0 -720px 1.5em 720px;}
244 | .push-19 {margin:0 -760px 1.5em 760px;}
245 | .push-20 {margin:0 -800px 1.5em 800px;}
246 | .push-21 {margin:0 -840px 1.5em 840px;}
247 | .push-22 {margin:0 -880px 1.5em 880px;}
248 | .push-23 {margin:0 -920px 1.5em 920px;}
249 | .push-24 {margin:0 -960px 1.5em 960px;}
250 | .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;}
251 | .prepend-top {margin-top:1.5em;}
252 | .append-bottom {margin-bottom:1.5em;}
253 | .box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
254 | hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
255 | hr.space {background:#fff;color:#fff;visibility:hidden;}
256 | .clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
257 | .clearfix, .container {display:block;}
258 | .clear {clear:both;}
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/forms.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | forms.css
4 | * Sets up some default styling for forms
5 | * Gives you classes to enhance your forms
6 |
7 | Usage:
8 | * For text fields, use class .title or .text
9 | * For inline forms, use .inline (even when using columns)
10 |
11 | -------------------------------------------------------------- */
12 |
13 | label { font-weight: bold; }
14 | fieldset { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; }
15 | legend { font-weight: bold; font-size:1.2em; }
16 |
17 |
18 | /* Form fields
19 | -------------------------------------------------------------- */
20 |
21 | input[type=text], input[type=password],
22 | input.text, input.title,
23 | textarea, select {
24 | background-color:#fff;
25 | border:1px solid #bbb;
26 | }
27 | input[type=text]:focus, input[type=password]:focus,
28 | input.text:focus, input.title:focus,
29 | textarea:focus, select:focus {
30 | border-color:#666;
31 | }
32 |
33 | input[type=text], input[type=password],
34 | input.text, input.title,
35 | textarea, select {
36 | margin:0.5em 0;
37 | }
38 |
39 | input.text,
40 | input.title { width: 300px; padding:5px; }
41 | input.title { font-size:1.5em; }
42 | textarea { width: 390px; height: 250px; padding:5px; }
43 |
44 | input[type=checkbox], input[type=radio],
45 | input.checkbox, input.radio {
46 | position:relative; top:.25em;
47 | }
48 |
49 | form.inline { line-height:3; }
50 | form.inline p { margin-bottom:0; }
51 |
52 |
53 | /* Success, notice and error boxes
54 | -------------------------------------------------------------- */
55 |
56 | .error,
57 | .notice,
58 | .success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
59 |
60 | .error { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
61 | .notice { background: #FFF6BF; color: #514721; border-color: #FFD324; }
62 | .success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
63 | .error a { color: #8a1f11; }
64 | .notice a { color: #514721; }
65 | .success a { color: #264409; }
66 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/grid.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | grid.css
4 | * Sets up an easy-to-use grid of 24 columns.
5 |
6 | By default, the grid is 950px wide, with 24 columns
7 | spanning 30px, and a 10px margin between columns.
8 |
9 | If you need fewer or more columns, namespaces or semantic
10 | element names, use the compressor script (lib/compress.rb)
11 |
12 | -------------------------------------------------------------- */
13 |
14 | /* A container should group all your columns. */
15 | .container {
16 | width: 950px;
17 | margin: 0 auto;
18 | }
19 |
20 | /* Use this class on any .span / container to see the grid. */
21 | .showgrid {
22 | background: url(src/grid.png);
23 | }
24 |
25 |
26 | /* Columns
27 | -------------------------------------------------------------- */
28 |
29 | /* Sets up basic grid floating and margin. */
30 | .column, .span-1, .span-2, .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9, .span-10, .span-11, .span-12, .span-13, .span-14, .span-15, .span-16, .span-17, .span-18, .span-19, .span-20, .span-21, .span-22, .span-23, .span-24 {
31 | float: left;
32 | margin-right: 10px;
33 | }
34 |
35 | /* The last column in a row needs this class. */
36 | .last { margin-right: 0; }
37 |
38 | /* Use these classes to set the width of a column. */
39 | .span-1 {width: 30px;}
40 |
41 | .span-2 {width: 70px;}
42 | .span-3 {width: 110px;}
43 | .span-4 {width: 150px;}
44 | .span-5 {width: 190px;}
45 | .span-6 {width: 230px;}
46 | .span-7 {width: 270px;}
47 | .span-8 {width: 310px;}
48 | .span-9 {width: 350px;}
49 | .span-10 {width: 390px;}
50 | .span-11 {width: 430px;}
51 | .span-12 {width: 470px;}
52 | .span-13 {width: 510px;}
53 | .span-14 {width: 550px;}
54 | .span-15 {width: 590px;}
55 | .span-16 {width: 630px;}
56 | .span-17 {width: 670px;}
57 | .span-18 {width: 710px;}
58 | .span-19 {width: 750px;}
59 | .span-20 {width: 790px;}
60 | .span-21 {width: 830px;}
61 | .span-22 {width: 870px;}
62 | .span-23 {width: 910px;}
63 | .span-24 {width:950px; margin-right:0;}
64 |
65 | /* Use these classes to set the width of an input. */
66 | input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {
67 | border-left-width: 1px;
68 | border-right-width: 1px;
69 | padding-left: 5px;
70 | padding-right: 5px;
71 | }
72 |
73 | input.span-1, textarea.span-1 { width: 18px; }
74 | input.span-2, textarea.span-2 { width: 58px; }
75 | input.span-3, textarea.span-3 { width: 98px; }
76 | input.span-4, textarea.span-4 { width: 138px; }
77 | input.span-5, textarea.span-5 { width: 178px; }
78 | input.span-6, textarea.span-6 { width: 218px; }
79 | input.span-7, textarea.span-7 { width: 258px; }
80 | input.span-8, textarea.span-8 { width: 298px; }
81 | input.span-9, textarea.span-9 { width: 338px; }
82 | input.span-10, textarea.span-10 { width: 378px; }
83 | input.span-11, textarea.span-11 { width: 418px; }
84 | input.span-12, textarea.span-12 { width: 458px; }
85 | input.span-13, textarea.span-13 { width: 498px; }
86 | input.span-14, textarea.span-14 { width: 538px; }
87 | input.span-15, textarea.span-15 { width: 578px; }
88 | input.span-16, textarea.span-16 { width: 618px; }
89 | input.span-17, textarea.span-17 { width: 658px; }
90 | input.span-18, textarea.span-18 { width: 698px; }
91 | input.span-19, textarea.span-19 { width: 738px; }
92 | input.span-20, textarea.span-20 { width: 778px; }
93 | input.span-21, textarea.span-21 { width: 818px; }
94 | input.span-22, textarea.span-22 { width: 858px; }
95 | input.span-23, textarea.span-23 { width: 898px; }
96 | input.span-24, textarea.span-24 { width: 938px; }
97 |
98 | /* Add these to a column to append empty cols. */
99 |
100 | .append-1 { padding-right: 40px;}
101 | .append-2 { padding-right: 80px;}
102 | .append-3 { padding-right: 120px;}
103 | .append-4 { padding-right: 160px;}
104 | .append-5 { padding-right: 200px;}
105 | .append-6 { padding-right: 240px;}
106 | .append-7 { padding-right: 280px;}
107 | .append-8 { padding-right: 320px;}
108 | .append-9 { padding-right: 360px;}
109 | .append-10 { padding-right: 400px;}
110 | .append-11 { padding-right: 440px;}
111 | .append-12 { padding-right: 480px;}
112 | .append-13 { padding-right: 520px;}
113 | .append-14 { padding-right: 560px;}
114 | .append-15 { padding-right: 600px;}
115 | .append-16 { padding-right: 640px;}
116 | .append-17 { padding-right: 680px;}
117 | .append-18 { padding-right: 720px;}
118 | .append-19 { padding-right: 760px;}
119 | .append-20 { padding-right: 800px;}
120 | .append-21 { padding-right: 840px;}
121 | .append-22 { padding-right: 880px;}
122 | .append-23 { padding-right: 920px;}
123 |
124 | /* Add these to a column to prepend empty cols. */
125 |
126 | .prepend-1 { padding-left: 40px;}
127 | .prepend-2 { padding-left: 80px;}
128 | .prepend-3 { padding-left: 120px;}
129 | .prepend-4 { padding-left: 160px;}
130 | .prepend-5 { padding-left: 200px;}
131 | .prepend-6 { padding-left: 240px;}
132 | .prepend-7 { padding-left: 280px;}
133 | .prepend-8 { padding-left: 320px;}
134 | .prepend-9 { padding-left: 360px;}
135 | .prepend-10 { padding-left: 400px;}
136 | .prepend-11 { padding-left: 440px;}
137 | .prepend-12 { padding-left: 480px;}
138 | .prepend-13 { padding-left: 520px;}
139 | .prepend-14 { padding-left: 560px;}
140 | .prepend-15 { padding-left: 600px;}
141 | .prepend-16 { padding-left: 640px;}
142 | .prepend-17 { padding-left: 680px;}
143 | .prepend-18 { padding-left: 720px;}
144 | .prepend-19 { padding-left: 760px;}
145 | .prepend-20 { padding-left: 800px;}
146 | .prepend-21 { padding-left: 840px;}
147 | .prepend-22 { padding-left: 880px;}
148 | .prepend-23 { padding-left: 920px;}
149 |
150 |
151 | /* Border on right hand side of a column. */
152 | .border {
153 | padding-right: 4px;
154 | margin-right: 5px;
155 | border-right: 1px solid #eee;
156 | }
157 |
158 | /* Border with more whitespace, spans one column. */
159 | .colborder {
160 | padding-right: 24px;
161 | margin-right: 25px;
162 | border-right: 1px solid #eee;
163 | }
164 |
165 |
166 | /* Use these classes on an element to push it into the
167 | next column, or to pull it into the previous column. */
168 |
169 |
170 | .pull-1 { margin-left: -40px; }
171 | .pull-2 { margin-left: -80px; }
172 | .pull-3 { margin-left: -120px; }
173 | .pull-4 { margin-left: -160px; }
174 | .pull-5 { margin-left: -200px; }
175 | .pull-6 { margin-left: -240px; }
176 | .pull-7 { margin-left: -280px; }
177 | .pull-8 { margin-left: -320px; }
178 | .pull-9 { margin-left: -360px; }
179 | .pull-10 { margin-left: -400px; }
180 | .pull-11 { margin-left: -440px; }
181 | .pull-12 { margin-left: -480px; }
182 | .pull-13 { margin-left: -520px; }
183 | .pull-14 { margin-left: -560px; }
184 | .pull-15 { margin-left: -600px; }
185 | .pull-16 { margin-left: -640px; }
186 | .pull-17 { margin-left: -680px; }
187 | .pull-18 { margin-left: -720px; }
188 | .pull-19 { margin-left: -760px; }
189 | .pull-20 { margin-left: -800px; }
190 | .pull-21 { margin-left: -840px; }
191 | .pull-22 { margin-left: -880px; }
192 | .pull-23 { margin-left: -920px; }
193 | .pull-24 { margin-left: -960px; }
194 |
195 | .pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float: left; position:relative;}
196 |
197 |
198 | .push-1 { margin: 0 -40px 1.5em 40px; }
199 | .push-2 { margin: 0 -80px 1.5em 80px; }
200 | .push-3 { margin: 0 -120px 1.5em 120px; }
201 | .push-4 { margin: 0 -160px 1.5em 160px; }
202 | .push-5 { margin: 0 -200px 1.5em 200px; }
203 | .push-6 { margin: 0 -240px 1.5em 240px; }
204 | .push-7 { margin: 0 -280px 1.5em 280px; }
205 | .push-8 { margin: 0 -320px 1.5em 320px; }
206 | .push-9 { margin: 0 -360px 1.5em 360px; }
207 | .push-10 { margin: 0 -400px 1.5em 400px; }
208 | .push-11 { margin: 0 -440px 1.5em 440px; }
209 | .push-12 { margin: 0 -480px 1.5em 480px; }
210 | .push-13 { margin: 0 -520px 1.5em 520px; }
211 | .push-14 { margin: 0 -560px 1.5em 560px; }
212 | .push-15 { margin: 0 -600px 1.5em 600px; }
213 | .push-16 { margin: 0 -640px 1.5em 640px; }
214 | .push-17 { margin: 0 -680px 1.5em 680px; }
215 | .push-18 { margin: 0 -720px 1.5em 720px; }
216 | .push-19 { margin: 0 -760px 1.5em 760px; }
217 | .push-20 { margin: 0 -800px 1.5em 800px; }
218 | .push-21 { margin: 0 -840px 1.5em 840px; }
219 | .push-22 { margin: 0 -880px 1.5em 880px; }
220 | .push-23 { margin: 0 -920px 1.5em 920px; }
221 | .push-24 { margin: 0 -960px 1.5em 960px; }
222 |
223 | .push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float: right; position:relative;}
224 |
225 |
226 | /* Misc classes and elements
227 | -------------------------------------------------------------- */
228 |
229 | /* In case you need to add a gutter above/below an element */
230 | .prepend-top {
231 | margin-top:1.5em;
232 | }
233 | .append-bottom {
234 | margin-bottom:1.5em;
235 | }
236 |
237 | /* Use a .box to create a padded box inside a column. */
238 | .box {
239 | padding: 1.5em;
240 | margin-bottom: 1.5em;
241 | background: #E5ECF9;
242 | }
243 |
244 | /* Use this to create a horizontal ruler across a column. */
245 | hr {
246 | background: #ddd;
247 | color: #ddd;
248 | clear: both;
249 | float: none;
250 | width: 100%;
251 | height: .1em;
252 | margin: 0 0 1.45em;
253 | border: none;
254 | }
255 |
256 | hr.space {
257 | background: #fff;
258 | color: #fff;
259 | visibility: hidden;
260 | }
261 |
262 |
263 | /* Clearing floats without extra markup
264 | Based on How To Clear Floats Without Structural Markup by PiE
265 | [http://www.positioniseverything.net/easyclearing.html] */
266 |
267 | .clearfix:after, .container:after {
268 | content: "\0020";
269 | display: block;
270 | height: 0;
271 | clear: both;
272 | visibility: hidden;
273 | overflow:hidden;
274 | }
275 | .clearfix, .container {display: block;}
276 |
277 | /* Regular clearing
278 | apply to column that should drop below previous ones. */
279 |
280 | .clear { clear:both; }
281 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/public/stylesheets/blueprint/src/grid.png
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/ie.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | ie.css
4 |
5 | Contains every hack for Internet Explorer,
6 | so that our core files stay sweet and nimble.
7 |
8 | -------------------------------------------------------------- */
9 |
10 | /* Make sure the layout is centered in IE5 */
11 | body { text-align: center; }
12 | .container { text-align: left; }
13 |
14 | /* Fixes IE margin bugs */
15 | * html .column, * html .span-1, * html .span-2,
16 | * html .span-3, * html .span-4, * html .span-5,
17 | * html .span-6, * html .span-7, * html .span-8,
18 | * html .span-9, * html .span-10, * html .span-11,
19 | * html .span-12, * html .span-13, * html .span-14,
20 | * html .span-15, * html .span-16, * html .span-17,
21 | * html .span-18, * html .span-19, * html .span-20,
22 | * html .span-21, * html .span-22, * html .span-23,
23 | * html .span-24 { display:inline; overflow-x: hidden; }
24 |
25 |
26 | /* Elements
27 | -------------------------------------------------------------- */
28 |
29 | /* Fixes incorrect styling of legend in IE6. */
30 | * html legend { margin:0px -8px 16px 0; padding:0; }
31 |
32 | /* Fixes wrong line-height on sup/sub in IE. */
33 | sup { vertical-align:text-top; }
34 | sub { vertical-align:text-bottom; }
35 |
36 | /* Fixes IE7 missing wrapping of code elements. */
37 | html>body p code { *white-space: normal; }
38 |
39 | /* IE 6&7 has problems with setting proper margins. */
40 | hr { margin:-8px auto 11px; }
41 |
42 | /* Explicitly set interpolation, allowing dynamically resized images to not look horrible */
43 | img { -ms-interpolation-mode:bicubic; }
44 |
45 | /* Clearing
46 | -------------------------------------------------------------- */
47 |
48 | /* Makes clearfix actually work in IE */
49 | .clearfix, .container { display:inline-block; }
50 | * html .clearfix,
51 | * html .container { height:1%; }
52 |
53 |
54 | /* Forms
55 | -------------------------------------------------------------- */
56 |
57 | /* Fixes padding on fieldset */
58 | fieldset { padding-top:0; }
59 |
60 | /* Makes classic textareas in IE 6 resemble other browsers */
61 | textarea { overflow:auto; }
62 |
63 | /* Fixes rule that IE 6 ignores */
64 | input.text, input.title, textarea { background-color:#fff; border:1px solid #bbb; }
65 | input.text:focus, input.title:focus { border-color:#666; }
66 | input.text, input.title, textarea, select { margin:0.5em 0; }
67 | input.checkbox, input.radio { position:relative; top:.25em; }
68 |
69 | /* Fixes alignment of inline form elements */
70 | form.inline div, form.inline p { vertical-align:middle; }
71 | form.inline label { position:relative;top:-0.25em; }
72 | form.inline input.checkbox, form.inline input.radio,
73 | form.inline input.button, form.inline button {
74 | margin:0.5em 0;
75 | }
76 | button, input.button { position:relative;top:0.25em; }
77 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/print.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | print.css
4 | * Gives you some sensible styles for printing pages.
5 | * See Readme file in this directory for further instructions.
6 |
7 | Some additions you'll want to make, customized to your markup:
8 | #header, #footer, #navigation { display:none; }
9 |
10 | -------------------------------------------------------------- */
11 |
12 | body {
13 | line-height: 1.5;
14 | font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
15 | color:#000;
16 | background: none;
17 | font-size: 10pt;
18 | }
19 |
20 |
21 | /* Layout
22 | -------------------------------------------------------------- */
23 |
24 | .container {
25 | background: none;
26 | }
27 |
28 | hr {
29 | background:#ccc;
30 | color:#ccc;
31 | width:100%;
32 | height:2px;
33 | margin:2em 0;
34 | padding:0;
35 | border:none;
36 | }
37 | hr.space {
38 | background: #fff;
39 | color: #fff;
40 | visibility: hidden;
41 | }
42 |
43 |
44 | /* Text
45 | -------------------------------------------------------------- */
46 |
47 | h1,h2,h3,h4,h5,h6 { font-family: "Helvetica Neue", Arial, "Lucida Grande", sans-serif; }
48 | code { font:.9em "Courier New", Monaco, Courier, monospace; }
49 |
50 | a img { border:none; }
51 | p img.top { margin-top: 0; }
52 |
53 | blockquote {
54 | margin:1.5em;
55 | padding:1em;
56 | font-style:italic;
57 | font-size:.9em;
58 | }
59 |
60 | .small { font-size: .9em; }
61 | .large { font-size: 1.1em; }
62 | .quiet { color: #999; }
63 | .hide { display:none; }
64 |
65 |
66 | /* Links
67 | -------------------------------------------------------------- */
68 |
69 | a:link, a:visited {
70 | background: transparent;
71 | font-weight:700;
72 | text-decoration: underline;
73 | }
74 |
75 | a:link:after, a:visited:after {
76 | content: " (" attr(href) ")";
77 | font-size: 90%;
78 | }
79 |
80 | /* If you're having trouble printing relative links, uncomment and customize this:
81 | (note: This is valid CSS3, but it still won't go through the W3C CSS Validator) */
82 |
83 | /* a[href^="/"]:after {
84 | content: " (http://www.yourdomain.com" attr(href) ") ";
85 | } */
86 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/reset.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | reset.css
4 | * Resets default browser CSS.
5 |
6 | -------------------------------------------------------------- */
7 |
8 | html, body, div, span, object, iframe,
9 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
10 | a, abbr, acronym, address, code,
11 | del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
12 | fieldset, form, label, legend,
13 | table, caption, tbody, tfoot, thead, tr, th, td,
14 | article, aside, dialog, figure, footer, header,
15 | hgroup, nav, section {
16 | margin: 0;
17 | padding: 0;
18 | border: 0;
19 | font-weight: inherit;
20 | font-style: inherit;
21 | font-size: 100%;
22 | font-family: inherit;
23 | vertical-align: baseline;
24 | }
25 |
26 | article, aside, dialog, figure, footer, header,
27 | hgroup, nav, section {
28 | display:block;
29 | }
30 |
31 | body {
32 | line-height: 1.5;
33 | }
34 |
35 | /* Tables still need 'cellspacing="0"' in the markup. */
36 | table { border-collapse: separate; border-spacing: 0; }
37 | caption, th, td { text-align: left; font-weight: normal; }
38 | table, td, th { vertical-align: middle; }
39 |
40 | /* Remove possible quote marks (") from , . */
41 | blockquote:before, blockquote:after, q:before, q:after { content: ""; }
42 | blockquote, q { quotes: "" ""; }
43 |
44 | /* Remove annoying border on linked images. */
45 | a img { border: none; }
46 |
--------------------------------------------------------------------------------
/public/stylesheets/blueprint/src/typography.css:
--------------------------------------------------------------------------------
1 | /* --------------------------------------------------------------
2 |
3 | typography.css
4 | * Sets up some sensible default typography.
5 |
6 | -------------------------------------------------------------- */
7 |
8 | /* Default font settings.
9 | The font-size percentage is of 16px. (0.75 * 16px = 12px) */
10 | html { font-size:100.01%; }
11 | body {
12 | font-size: 75%;
13 | color: #222;
14 | background: #fff;
15 | font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
16 | }
17 |
18 |
19 | /* Headings
20 | -------------------------------------------------------------- */
21 |
22 | h1,h2,h3,h4,h5,h6 { font-weight: normal; color: #111; }
23 |
24 | h1 { font-size: 3em; line-height: 1; margin-bottom: 0.5em; }
25 | h2 { font-size: 2em; margin-bottom: 0.75em; }
26 | h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; }
27 | h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1.25em; }
28 | h5 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; }
29 | h6 { font-size: 1em; font-weight: bold; }
30 |
31 | h1 img, h2 img, h3 img,
32 | h4 img, h5 img, h6 img {
33 | margin: 0;
34 | }
35 |
36 |
37 | /* Text elements
38 | -------------------------------------------------------------- */
39 |
40 | p { margin: 0 0 1.5em; }
41 | p img.left { float: left; margin: 1.5em 1.5em 1.5em 0; padding: 0; }
42 | p img.right { float: right; margin: 1.5em 0 1.5em 1.5em; }
43 |
44 | a:focus,
45 | a:hover { color: #000; }
46 | a { color: #009; text-decoration: underline; }
47 |
48 | blockquote { margin: 1.5em; color: #666; font-style: italic; }
49 | strong { font-weight: bold; }
50 | em,dfn { font-style: italic; }
51 | dfn { font-weight: bold; }
52 | sup, sub { line-height: 0; }
53 |
54 | abbr,
55 | acronym { border-bottom: 1px dotted #666; }
56 | address { margin: 0 0 1.5em; font-style: italic; }
57 | del { color:#666; }
58 |
59 | pre { margin: 1.5em 0; white-space: pre; }
60 | pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; }
61 |
62 |
63 | /* Lists
64 | -------------------------------------------------------------- */
65 |
66 | li ul,
67 | li ol { margin: 0; }
68 | ul, ol { margin: 0 1.5em 1.5em 0; padding-left: 3.333em; }
69 |
70 | ul { list-style-type: disc; }
71 | ol { list-style-type: decimal; }
72 |
73 | dl { margin: 0 0 1.5em 0; }
74 | dl dt { font-weight: bold; }
75 | dd { margin-left: 1.5em;}
76 |
77 |
78 | /* Tables
79 | -------------------------------------------------------------- */
80 |
81 | table { margin-bottom: 1.4em; width:100%; }
82 | th { font-weight: bold; }
83 | thead th { background: #c3d9ff; }
84 | th,td,caption { padding: 4px 10px 4px 5px; }
85 | tr.even td { background: #e5ecf9; }
86 | tfoot { font-style: italic; }
87 | caption { background: #eee; }
88 |
89 |
90 | /* Misc classes
91 | -------------------------------------------------------------- */
92 |
93 | .small { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; }
94 | .large { font-size: 1.2em; line-height: 2.5em; margin-bottom: 1.25em; }
95 | .hide { display: none; }
96 |
97 | .quiet { color: #666; }
98 | .loud { color: #000; }
99 | .highlight { background:#ff0; }
100 | .added { background:#060; color: #fff; }
101 | .removed { background:#900; color: #fff; }
102 |
103 | .first { margin-left:0; padding-left:0; }
104 | .last { margin-right:0; padding-right:0; }
105 | .top { margin-top:0; padding-top:0; }
106 | .bottom { margin-bottom:0; padding-bottom:0; }
107 |
--------------------------------------------------------------------------------
/public/stylesheets/custom.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 710px;
3 | }
4 |
5 | body {
6 | background: #cff;
7 | }
8 |
9 | header {
10 | padding-top: 20px;
11 | }
12 |
13 | header img {
14 | padding: 1em;
15 | background: #fff;
16 | }
17 |
18 | section {
19 | margin-top: 1em;
20 | font-size: 120%;
21 | padding: 20px;
22 | background: #fff;
23 | }
24 |
25 | section h1 {
26 | font-size: 200%;
27 | }
28 |
29 | /* Links */
30 |
31 | a {
32 | color: #09c;
33 | text-decoration: none;
34 | }
35 |
36 | a:hover {
37 | color: #069;
38 | text-decoration: underline;
39 | }
40 |
41 | a:visited {
42 | color: #069;
43 | }
44 |
45 | /* Navigation */
46 |
47 | nav {
48 | float: right;
49 | background: white;
50 | padding: 0 0.7em;
51 | white-space: nowrap;
52 | }
53 |
54 | nav ul {
55 | margin: 0;
56 | padding: 0;
57 | }
58 |
59 | nav ul li {
60 | list-style-type: none;
61 | display: inline-block;
62 | padding: 0.2em 0;
63 | }
64 |
65 | nav ul li a {
66 | padding: 0 5px;
67 | font-weight: bold;
68 | }
69 |
70 | nav ul li a:visited {
71 | color: #09c;
72 | }
73 |
74 | nav ul li a:hover {
75 | text-decoration: underline;
76 | }
77 |
78 | /* Sign up button */
79 |
80 | a.signup_button {
81 | margin-left: auto;
82 | margin-right: auto;
83 | display: block;
84 | text-align: center;
85 | width: 190px;
86 | color: #fff;
87 | background: #006400;
88 | font-size: 150%;
89 | font-weight: bold;
90 | padding: 20px;
91 | }
92 |
93 | /* Round corners */
94 |
95 | .round {
96 | -moz-border-radius: 10px;
97 | -webkit-border-radius: 10px;
98 | border-radius: 10px;
99 | }
100 |
101 | /* Footer */
102 |
103 | footer {
104 | text-align: center;
105 | margin-top: 10px;
106 | width: 710px;
107 | margin-left: auto;
108 | margin-right: auto;
109 | }
110 |
111 | footer nav {
112 | float: none;
113 | }
114 |
115 | /* User show page */
116 |
117 | table.profile {
118 | width: 100%;
119 | margin-bottom: 0;
120 | }
121 |
122 | td.main {
123 | width: 70%;
124 | padding: 1em;
125 | }
126 |
127 | td.sidebar {
128 | width: 30%;
129 | padding: 1em;
130 | vertical-align: top;
131 | background: #ffc;
132 | }
133 |
134 | .profile img.gravatar {
135 | border: 1px solid #999;
136 | margin-bottom: -15px;
137 | }
138 |
139 | div.field, div.actions {
140 | margin-bottom: 10px;
141 | }
142 |
143 | /* Error messages */
144 |
145 | .field_with_errors {
146 | margin-top: 10px;
147 | padding: 2px;
148 | background-color: red;
149 | display: table;
150 | }
151 |
152 | .field_with_errors label {
153 | color: #fff;
154 | }
155 |
156 | #error_explanation {
157 | width: 400px;
158 | border: 2px solid red;
159 | padding: 7px;
160 | padding-bottom: 12px;
161 | margin-bottom: 20px;
162 | background-color: #f0f0f0;
163 | }
164 |
165 | #error_explanation h2 {
166 | text-align: left;
167 | font-weight: bold;
168 | padding: 5px 5px 5px 15px;
169 | font-size: 12px;
170 | margin: -7px;
171 | background-color: #c00;
172 | color: #fff;
173 | }
174 |
175 | #error_explanation p {
176 | color: #333;
177 | margin-bottom: 0;
178 | padding: 5px;
179 | }
180 |
181 | #error_explanation ul li {
182 | font-size: 12px;
183 | list-style: square;
184 | }
185 |
186 | ul.users {
187 | margin-top: 1em;
188 | }
189 |
190 | ul.users li {
191 | list-style: none;
192 | }
193 |
194 | /* Micropost styling */
195 |
196 | h1.micropost {
197 | margin-bottom: 0.3em;
198 | }
199 |
200 | table.microposts {
201 | margin-top: 1em;
202 | }
203 |
204 | table.microposts tr {
205 | height: 70px;
206 | }
207 |
208 | table.microposts tr td.gravatar {
209 | border-top: 1px solid #ccc;
210 | vertical-align: top;
211 | width: 50px;
212 | }
213 |
214 | table.microposts tr td.micropost {
215 | border-top: 1px solid #ccc;
216 | vertical-align: top;
217 | padding-top: 10px;
218 | }
219 |
220 | table.microposts tr td.micropost span.timestamp {
221 | display: block;
222 | font-size: 85%;
223 | color: #666;
224 | }
225 |
226 | div.user_info img {
227 | padding-right: 0.1em;
228 | }
229 |
230 | div.user_info a {
231 | text-decoration: none;
232 | }
233 |
234 | div.user_info span.user_name {
235 | position: absolute;
236 | }
237 |
238 | div.user_info span.microposts {
239 | font-size: 80%;
240 | }
241 |
242 | form.new_micropost {
243 | margin-bottom: 2em;
244 | }
245 |
246 | form.new_micropost textarea {
247 | height: 4em;
248 | margin-bottom: 0;
249 | }
250 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/spec/controllers/microposts_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe MicropostsController do
4 | render_views
5 |
6 | describe "access control" do
7 | it "should deny access to 'create'" do
8 | post :create
9 | response.should redirect_to(signin_path)
10 | end
11 |
12 | it "should deny access to 'destroy'" do
13 | delete :destroy, :id => 1
14 | response.should redirect_to(signin_path)
15 | end
16 | end
17 |
18 | describe "POST 'create'" do
19 |
20 | before(:each) do
21 | @user = test_sign_in(Factory(:user))
22 | end
23 |
24 | describe "failure" do
25 |
26 | before(:each) do
27 | @attr = { :content => "" }
28 | end
29 |
30 | it "should not create a micropost" do
31 | lambda do
32 | post :create, :micropost => @attr
33 | end.should_not change(Micropost, :count)
34 | end
35 |
36 | it "should re-render the home page" do
37 | post :create, :micropost => @attr
38 | response.should render_template('pages/home')
39 | end
40 | end
41 |
42 | describe "success" do
43 |
44 | before(:each) do
45 | @attr = { :content => "Lorem ipsum dolor sit amet" }
46 | end
47 |
48 | it "should create a micropost" do
49 | lambda do
50 | post :create, :micropost => @attr
51 | end.should change(Micropost, :count).by(1)
52 | end
53 |
54 | it "should redirect to the root path" do
55 | post :create, :micropost => @attr
56 | response.should redirect_to(root_path)
57 | end
58 |
59 | it "should have a flash success message" do
60 | post :create, :micropost => @attr
61 | flash[:success].should =~ /micropost created/i
62 | end
63 | end
64 | end
65 |
66 | describe "DELETE 'destroy'" do
67 |
68 | describe "for an unauthorized user" do
69 |
70 | before(:each) do
71 | @user = Factory(:user)
72 | wrong_user = Factory(:user, :email => Factory.next(:email))
73 | @micropost = Factory(:micropost, :user => @user)
74 | test_sign_in(wrong_user)
75 | end
76 |
77 | it "should deny access" do
78 | delete :destroy, :id => @micropost
79 | response.should redirect_to(root_path)
80 | end
81 | end
82 |
83 | describe "for an authorized user" do
84 |
85 | before(:each) do
86 | @user = test_sign_in(Factory(:user))
87 | @micropost = Factory(:micropost, :user => @user)
88 | end
89 |
90 | it "should destroy the micropost" do
91 | lambda do
92 | delete :destroy, :id => @micropost
93 | flash[:success].should =~ /deleted/i
94 | response.should redirect_to(root_path)
95 | end.should change(Micropost, :count).by(-1)
96 | end
97 | end
98 | end
99 | end
--------------------------------------------------------------------------------
/spec/controllers/pages_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe PagesController do
4 | render_views
5 |
6 | before(:each) do
7 | @base_title = "Ruby on Rails Tutorial Sample App"
8 | end
9 |
10 | describe "GET 'home'" do
11 |
12 | describe "when not signed in" do
13 | it "should be successful" do
14 | get 'home'
15 | response.should be_success
16 | end
17 |
18 | it "should have the right title" do
19 | get 'home'
20 | response.should have_selector("title",
21 | :content => "#{@base_title} | Home")
22 | end
23 |
24 | it "should have a non-blank body" do
25 | get 'home'
26 | response.body.should_not =~ /\s*<\/body>/
27 | end
28 | end
29 |
30 | describe "when signed in" do
31 | before(:each) do
32 | @user = test_sign_in(Factory(:user))
33 | other_user = Factory(:user, :email => Factory.next(:email))
34 | other_user.follow!(@user)
35 | end
36 |
37 | it "should have the right follower/following counts" do
38 | get :home
39 | response.should have_selector('a', :href => following_user_path(@user),
40 | :content => "0 following")
41 | response.should have_selector('a', :href => followers_user_path(@user),
42 | :content => "1 follower")
43 | end
44 | end
45 |
46 | end
47 |
48 | describe "GET 'contact'" do
49 | it "should be successful" do
50 | get 'contact'
51 | response.should be_success
52 | end
53 |
54 | it "should have the right title" do
55 | get 'contact'
56 | response.should have_selector("title",
57 | :content => "#{@base_title} | Contact")
58 | end
59 | end
60 |
61 | describe "GET 'about'" do
62 | it "should be successful" do
63 | get 'about'
64 | response.should be_success
65 | end
66 |
67 | it "should have the right title" do
68 | get 'about'
69 | response.should have_selector("title",
70 | :content => "#{@base_title} | About")
71 | end
72 | end
73 |
74 | describe "GET 'help'" do
75 | it "should be successful" do
76 | get 'help'
77 | response.should be_success
78 | end
79 |
80 | it "should have the right title" do
81 | get 'help'
82 | response.should have_selector("title",
83 | :content => "#{@base_title} | Help")
84 | end
85 | end
86 | end
87 |
--------------------------------------------------------------------------------
/spec/controllers/relationships_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe RelationshipsController do
4 |
5 | describe "access control" do
6 | it "should require signin for create" do
7 | post :create
8 | response.should redirect_to(signin_path)
9 | end
10 |
11 | it "should require signin for destroy" do
12 | delete :destroy, :id => 1
13 | response.should redirect_to(signin_path)
14 | end
15 | end
16 |
17 | describe "POST 'create'" do
18 |
19 | before(:each) do
20 | @user = test_sign_in(Factory(:user))
21 | @followed = Factory(:user, :email => Factory.next(:email))
22 | end
23 |
24 | it "should create a relationship" do
25 | lambda do
26 | post :create, :relationship => { :followed_id => @followed }
27 | response.should redirect_to(user_path(@followed))
28 | end.should change(Relationship, :count).by(1)
29 | end
30 |
31 | it "should create a relationship with Ajax" do
32 | lambda do
33 | xhr :post, :create, :relationship => { :followed_id => @followed }
34 | response.should be_success
35 | end.should change(Relationship, :count).by(1)
36 | end
37 | end
38 |
39 | describe "DELETE 'destroy'" do
40 |
41 | before(:each) do
42 | @user = test_sign_in(Factory(:user))
43 | @followed = Factory(:user, :email => Factory.next(:email))
44 | @user.follow!(@followed)
45 | @relationship = @user.relationships.find_by_followed_id(@followed)
46 | end
47 |
48 | it "should destroy a relationship" do
49 | lambda do
50 | delete :destroy, :id => @relationship
51 | response.should redirect_to(user_path(@followed))
52 | end.should change(Relationship, :count).by(-1)
53 | end
54 |
55 | it "should destroy a relationship with Ajax" do
56 | lambda do
57 | xhr :delete, :destroy, :id => @relationship
58 | response.should be_success
59 | end.should change(Relationship, :count).by(-1)
60 | end
61 | end
62 | end
--------------------------------------------------------------------------------
/spec/controllers/sessions_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SessionsController do
4 | render_views
5 |
6 | describe "GET 'new'" do
7 | it "should be successful" do
8 | get :new
9 | response.should be_success
10 | end
11 |
12 | it "should have the right title" do
13 | get :new
14 | response.should have_selector('title', :content => "Sign in")
15 | end
16 | end
17 |
18 | describe "POST 'create'" do
19 |
20 | describe "failure" do
21 |
22 | before(:each) do
23 | @attr = { :email => "", :password => "" }
24 | end
25 |
26 | it "should re-render the new page" do
27 | post :create, :session => @attr
28 | response.should render_template('new')
29 | end
30 |
31 | it "should have the right title" do
32 | post :create, :session => @attr
33 | response.should have_selector('title', :content => "Sign in")
34 | end
35 |
36 | it "should have an error message" do
37 | post :create, :session => @attr
38 | flash.now[:error].should =~ /invalid/i
39 | end
40 | end
41 |
42 | describe "success" do
43 |
44 | before(:each) do
45 | @user = Factory(:user)
46 | @attr = { :email => @user.email, :password => @user.password }
47 | end
48 |
49 | it "should sign the user in" do
50 | post :create, :session => @attr
51 | controller.current_user.should == @user
52 | controller.should be_signed_in
53 | end
54 |
55 | it "should redirect to the user show page" do
56 | post :create, :session => @attr
57 | response.should redirect_to(user_path(@user))
58 | end
59 | end
60 | end
61 |
62 | describe "DELETE 'destroy'" do
63 | it "should sign a user out" do
64 | test_sign_in(Factory(:user))
65 | delete :destroy
66 | controller.should_not be_signed_in
67 | response.should redirect_to(root_path)
68 | end
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/spec/controllers/users_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe UsersController do
4 | render_views
5 |
6 | describe "GET 'index'" do
7 |
8 | describe "for non-signed-in users" do
9 | it "should deny access" do
10 | get :index
11 | response.should redirect_to(signin_path)
12 | end
13 | end
14 |
15 | describe "for signed-in-users" do
16 |
17 | before(:each) do
18 | @user = test_sign_in(Factory(:user))
19 | second = Factory(:user, :name => "Bob", :email => "another@example.com")
20 | third = Factory(:user, :name => "Ben", :email => "another@example.net")
21 |
22 | 30.times do
23 | Factory(:user, :name => Factory.next(:name),
24 | :email => Factory.next(:email))
25 | end
26 | end
27 |
28 | it "should be successful" do
29 | get :index
30 | response.should be_success
31 | end
32 |
33 | it "should have the right title" do
34 | get :index
35 | response.should have_selector('title', :content => "All users")
36 | end
37 |
38 | it "should have an element for each user" do
39 | get :index
40 | User.paginate(:page => 1).each do |user|
41 | response.should have_selector('li', :content => user.name)
42 | end
43 | end
44 |
45 | it "should paginate users" do
46 | get :index
47 | response.should have_selector('div.pagination')
48 | response.should have_selector('span.disabled', :content => "Previous")
49 | response.should have_selector('a', :href => "/users?page=2",
50 | :content => "2")
51 | response.should have_selector('a', :href => "/users?page=2",
52 | :content => "Next")
53 | end
54 |
55 | it "should have delete links for admins" do
56 | @user.toggle!(:admin)
57 | other_user = User.all.second
58 | get :index
59 | response.should have_selector('a', :href => user_path(other_user),
60 | :content => "delete")
61 | end
62 |
63 | it "should not have delete links for non-admins" do
64 | other_user = User.all.second
65 | get :index
66 | response.should_not have_selector('a', :href => user_path(other_user),
67 | :content => "delete")
68 | end
69 | end
70 | end
71 |
72 | describe "GET 'show'" do
73 |
74 | before(:each) do
75 | @user = Factory(:user)
76 | end
77 |
78 | it "should be successful" do
79 | get :show, :id => @user
80 | response.should be_success
81 | end
82 |
83 | it "should find the right user" do
84 | get :show, :id => @user
85 | assigns(:user).should == @user
86 | end
87 |
88 | it "should have the right title" do
89 | get :show, :id => @user
90 | response.should have_selector('title', :content => @user.name)
91 | end
92 |
93 | it "should have the user's name" do
94 | get :show, :id => @user
95 | response.should have_selector('h1', :content => @user.name)
96 | end
97 |
98 | it "should have a profile image" do
99 | get :show, :id => @user
100 | response.should have_selector('h1>img', :class => "gravatar")
101 | end
102 |
103 | it "should have the right URL" do
104 | get :show, :id => @user
105 | response.should have_selector('td>a', :content => user_path(@user),
106 | :href => user_path(@user))
107 | end
108 |
109 | it "should show the user's microposts" do
110 | mp1 = Factory(:micropost, :user => @user, :content => "Foo bar")
111 | mp2 = Factory(:micropost, :user => @user, :content => "Baz quux")
112 | get :show, :id => @user
113 | response.should have_selector('span.content', :content => mp1.content)
114 | response.should have_selector('span.content', :content => mp2.content)
115 | end
116 |
117 | it "should paginate microposts" do
118 | 35.times { Factory(:micropost, :user => @user, :content => "foo") }
119 | get :show, :id => @user
120 | response.should have_selector('div.pagination')
121 | end
122 |
123 | it "should display the micropost count" do
124 | 10.times { Factory(:micropost, :user => @user, :content => "foo") }
125 | get :show, :id => @user
126 | response.should have_selector('td.sidebar',
127 | :content => @user.microposts.count.to_s)
128 | end
129 |
130 | describe "when signed in as another user" do
131 | it "should be successful" do
132 | test_sign_in(Factory(:user, :email => Factory.next(:email)))
133 | get :show, :id => @user
134 | response.should be_success
135 | end
136 | end
137 | end
138 |
139 | describe "GET 'new'" do
140 |
141 | it "should be successful" do
142 | get :new
143 | response.should be_success
144 | end
145 |
146 | it "should have the right title" do
147 | get :new
148 | response.should have_selector('title', :content => "Sign up")
149 | end
150 | end
151 |
152 | describe "POST 'create'" do
153 |
154 | describe "failure" do
155 |
156 | before(:each) do
157 | @attr = { :name => "", :email => "", :password => "",
158 | :password_confirmation => "" }
159 | end
160 |
161 | it "should have the right title" do
162 | post :create, :user => @attr
163 | response.should have_selector('title', :content => "Sign up")
164 | end
165 |
166 | it "should render the 'new' page" do
167 | post :create, :user => @attr
168 | response.should render_template('new')
169 | end
170 |
171 | it "should not create a user" do
172 | lambda do
173 | post :create, :user => @attr
174 | end.should_not change(User, :count)
175 | end
176 | end
177 |
178 | describe "success" do
179 |
180 | before(:each) do
181 | @attr = { :name => "New User", :email => "user@example.com",
182 | :password => "foobar", :password_confirmation => "foobar" }
183 | end
184 |
185 | it "should create a user" do
186 | lambda do
187 | post :create, :user => @attr
188 | end.should change(User, :count).by(1)
189 | end
190 |
191 | it "should redirect to the user show page" do
192 | post :create, :user => @attr
193 | response.should redirect_to(user_path(assigns(:user)))
194 | end
195 |
196 | it "should have a welcome message" do
197 | post :create, :user => @attr
198 | flash[:success].should =~ /welcome to the sample app/i
199 | end
200 |
201 | it "should sign the user in" do
202 | post :create, :user => @attr
203 | controller.should be_signed_in
204 | end
205 | end
206 | end
207 |
208 | describe "GET 'edit'" do
209 |
210 | before(:each) do
211 | @user = Factory(:user)
212 | test_sign_in(@user)
213 | end
214 |
215 | it "should be successful" do
216 | get :edit, :id => @user
217 | response.should be_success
218 | end
219 |
220 | it "should have the right title" do
221 | get :edit, :id => @user
222 | response.should have_selector('title', :content => "Edit user")
223 | end
224 |
225 | it "should have a link to change the Gravatar" do
226 | get :edit, :id => @user
227 | response.should have_selector('a', :href => 'http://gravatar.com/emails',
228 | :content => "change")
229 | end
230 | end
231 |
232 | describe "PUT 'update'" do
233 |
234 | before(:each) do
235 | @user = Factory(:user)
236 | test_sign_in(@user)
237 | end
238 |
239 | describe "failure" do
240 |
241 | before(:each) do
242 | @attr = { :name => "", :email => "", :password => "",
243 | :password_confirmation => "" }
244 | end
245 |
246 | it "should render the 'edit' page" do
247 | put :update, :id => @user, :user => @attr
248 | response.should render_template('edit')
249 | end
250 |
251 | it "should have the right title" do
252 | put :update, :id => @user, :user => @attr
253 | response.should have_selector('title', :content => "Edit user")
254 | end
255 | end
256 |
257 | describe "success" do
258 |
259 | before(:each) do
260 | @attr = { :name => "New Name", :email => "user@example.org",
261 | :password => "barbaz", :password_confirmation => "barbaz" }
262 | end
263 |
264 | it "should change the user's attributes" do
265 | put :update, :id => @user, :user => @attr
266 | @user.reload
267 | @user.name.should == @attr[:name]
268 | @user.email.should == @attr[:email]
269 | @user.encrypted_password.should == assigns(:user).encrypted_password
270 | end
271 |
272 | it "should have a flash message" do
273 | put :update, :id => @user, :user => @attr
274 | flash[:success].should =~ /updated/
275 | end
276 | end
277 | end
278 |
279 | describe "authentication of edit/update actions" do
280 |
281 | before(:each) do
282 | @user = Factory(:user)
283 | end
284 |
285 | describe "for non-signed-in users" do
286 |
287 | it "should deny access to 'edit'" do
288 | get :edit, :id => @user
289 | response.should redirect_to(signin_path)
290 | flash[:notice].should =~ /sign in/i
291 | end
292 |
293 | it "should deny access to 'update'" do
294 | put :update, :id => @user, :user => {}
295 | response.should redirect_to(signin_path)
296 | end
297 | end
298 |
299 | describe "for signed-in users" do
300 |
301 | before(:each) do
302 | wrong_user = Factory(:user, :email => "user@example.net")
303 | test_sign_in(wrong_user)
304 | end
305 |
306 | it "should require matching users for 'edit'" do
307 | get :edit, :id => @user
308 | response.should redirect_to(root_path)
309 | end
310 |
311 | it "should require matching users for 'update'" do
312 | put :update, :id => @user, :user => {}
313 | response.should redirect_to(root_path)
314 | end
315 | end
316 | end
317 |
318 | describe "DELETE 'destroy'" do
319 |
320 | before(:each) do
321 | @user = Factory(:user)
322 | end
323 |
324 | describe "as a non-signed-in user" do
325 | it "should deny access" do
326 | delete :destroy, :id => @user
327 | response.should redirect_to(signin_path)
328 | end
329 | end
330 |
331 | describe "as non-admin user" do
332 | it "should protect the action" do
333 | test_sign_in(@user)
334 | delete :destroy, :id => @user
335 | response.should redirect_to(root_path)
336 | end
337 | end
338 |
339 | describe "as an admin user" do
340 |
341 | before(:each) do
342 | @admin = Factory(:user, :email => "admin@example.com", :admin => true)
343 | test_sign_in(@admin)
344 | end
345 |
346 | it "should destroy the user" do
347 | lambda do
348 | delete :destroy, :id => @user
349 | end.should change(User, :count).by(-1)
350 | end
351 |
352 | it "should redirect to the users page" do
353 | delete :destroy, :id => @user
354 | flash[:success].should =~ /destroyed/i
355 | response.should redirect_to(users_path)
356 | end
357 |
358 | it "should not be able to destroy itself" do
359 | lambda do
360 | delete :destroy, :id => @admin
361 | end.should_not change(User, :count)
362 | end
363 | end
364 | end
365 |
366 | describe "follow pages" do
367 |
368 | describe "when not signed in" do
369 |
370 | it "should protect 'following'" do
371 | get :following, :id => 1
372 | response.should redirect_to(signin_path)
373 | end
374 |
375 | it "should protect 'followers'" do
376 | get :followers, :id => 1
377 | response.should redirect_to(signin_path)
378 | end
379 | end
380 |
381 | describe "when signed in" do
382 |
383 | before(:each) do
384 | @user = test_sign_in(Factory(:user))
385 | @other_user = Factory(:user, :email => Factory.next(:email))
386 | @user.follow!(@other_user)
387 | end
388 |
389 | it "should show user following" do
390 | get :following, :id => @user
391 | response.should have_selector('a', :href => user_path(@other_user),
392 | :content => @other_user.name)
393 | end
394 |
395 | it "should show user followers" do
396 | get :followers, :id => @other_user
397 | response.should have_selector('a', :href => user_path(@user),
398 | :content => @user.name)
399 | end
400 | end
401 | end
402 | end
403 |
--------------------------------------------------------------------------------
/spec/factories.rb:
--------------------------------------------------------------------------------
1 | Factory.define :user do |user|
2 | user.name "Michael Hartl"
3 | user.email "mhartl@example.com"
4 | user.password "foobar"
5 | user.password_confirmation "foobar"
6 | end
7 |
8 | Factory.sequence :email do |n|
9 | "person-#{n}@example.com"
10 | end
11 |
12 | Factory.sequence :name do |n|
13 | "Person #{n}"
14 | end
15 |
16 | Factory.define :micropost do |micropost|
17 | micropost.content "Foo bar"
18 | micropost.association :user
19 | end
--------------------------------------------------------------------------------
/spec/models/micropost_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Micropost do
4 |
5 | before(:each) do
6 | @user = Factory(:user)
7 | @attr = { :content => "lorem ipsum" }
8 | end
9 |
10 | it "should create a new instance with valid attributes" do
11 | @user.microposts.create!(@attr)
12 | end
13 |
14 | describe "user associations" do
15 |
16 | before(:each) do
17 | @micropost = @user.microposts.create(@attr)
18 | end
19 |
20 | it "should have a user attribute" do
21 | @micropost.should respond_to(:user)
22 | end
23 |
24 | it "should have the right associated user" do
25 | @micropost.user_id.should == @user.id
26 | @micropost.user.should == @user
27 | end
28 | end
29 |
30 | describe "validations" do
31 |
32 | it "should have a user id" do
33 | Micropost.new(@attr).should_not be_valid
34 | end
35 |
36 | it "should require nonblank content" do
37 | @user.microposts.build(:content => " ").should_not be_valid
38 | end
39 |
40 | it "should reject long content" do
41 | @user.microposts.build(:content => "a" * 141).should_not be_valid
42 | end
43 | end
44 |
45 | describe "from_users_followed_by" do
46 |
47 | before(:each) do
48 | @other_user = Factory(:user, :email => Factory.next(:email))
49 | @third_user = Factory(:user, :email => Factory.next(:email))
50 |
51 | @user_post = @user.microposts.create!(:content => "foo")
52 | @other_post = @other_user.microposts.create!(:content => "bar")
53 | @third_post = @third_user.microposts.create!(:content => "baz")
54 |
55 | @user.follow!(@other_user)
56 | end
57 |
58 | it "should have a from_users_followed_by method" do
59 | Micropost.should respond_to(:from_users_followed_by)
60 | end
61 |
62 | it "should include the followed user's microposts" do
63 | Micropost.from_users_followed_by(@user).should include(@other_post)
64 | end
65 |
66 | it "should include the user's own microposts" do
67 | Micropost.from_users_followed_by(@user).should include(@user_post)
68 | end
69 |
70 | it "should not include an unfollowed user's microposts" do
71 | Micropost.from_users_followed_by(@user).should_not include(@third_post)
72 | end
73 | end
74 | end
75 |
--------------------------------------------------------------------------------
/spec/models/relationship_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Relationship do
4 |
5 | before(:each) do
6 | @follower = Factory(:user)
7 | @followed = Factory(:user, :email => Factory.next(:email))
8 |
9 | @attr = { :followed_id => @followed.id }
10 | end
11 |
12 | it "should create a new instance with valid attributes" do
13 | @follower.relationships.create!(@attr)
14 | end
15 |
16 | describe "follow methods" do
17 |
18 | before(:each) do
19 | @relationship = @follower.relationships.create!(@attr)
20 | end
21 |
22 | it "should have a follower attribute" do
23 | @relationship.should respond_to(:follower)
24 | end
25 |
26 | it "should have the right follower" do
27 | @relationship.follower.should == @follower
28 | end
29 |
30 | it "should have a followed attribute" do
31 | @relationship.should respond_to(:followed)
32 | end
33 |
34 | it "should have the right followed user" do
35 | @relationship.followed.should == @followed
36 | end
37 | end
38 |
39 | describe "validations" do
40 |
41 | it "should require a follower id" do
42 | Relationship.new(@attr).should_not be_valid
43 | end
44 |
45 | it "should require a followed id" do
46 | @follower.relationships.build.should_not be_valid
47 | end
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe User do
4 |
5 | before(:each) do
6 | @attr = {
7 | :name => "Example User",
8 | :email => "user@example.com",
9 | :password => "foobar",
10 | :password_confirmation => "foobar"
11 | }
12 | end
13 |
14 | it "should create a new instance given a valid attribute" do
15 | User.create!(@attr)
16 | end
17 |
18 | it "should require a name" do
19 | no_name_user = User.new(@attr.merge(:name => ""))
20 | no_name_user.should_not be_valid
21 | end
22 |
23 | it "should require an email address" do
24 | no_email_user = User.new(@attr.merge(:email => ""))
25 | no_email_user.should_not be_valid
26 | end
27 |
28 | it "should reject names that are too long" do
29 | long_name = "a" * 51
30 | long_name_user = User.new(@attr.merge(:name => long_name))
31 | long_name_user.should_not be_valid
32 | end
33 |
34 | it "should accept valid email addresses" do
35 | addresses = %w[user@foo.com THE_USER@foo.bar.org first.last@foo.jp]
36 | addresses.each do |address|
37 | valid_email_user = User.new(@attr.merge(:email => address))
38 | valid_email_user.should be_valid
39 | end
40 | end
41 |
42 | it "should reject invalid email addresses" do
43 | addresses = %w[user@foo,com user_at_foo.org example.user@foo.]
44 | addresses.each do |address|
45 | invalid_email_user = User.new(@attr.merge(:email => address))
46 | invalid_email_user.should_not be_valid
47 | end
48 | end
49 |
50 | it "should reject duplicate email addresses" do
51 | User.create!(@attr)
52 | user_with_duplicate_email = User.new(@attr)
53 | user_with_duplicate_email.should_not be_valid
54 | end
55 |
56 | it "should reject email addresses identical up to case" do
57 | upcased_email = @attr[:email].upcase
58 | User.create!(@attr.merge(:email => upcased_email))
59 | user_with_duplicate_email = User.new(@attr)
60 | user_with_duplicate_email.should_not be_valid
61 | end
62 |
63 | describe "passwords" do
64 |
65 | before(:each) do
66 | @user = User.new(@attr)
67 | end
68 |
69 | it "should have a password attribute" do
70 | @user.should respond_to(:password)
71 | end
72 |
73 | it "should have a password confirmation attribute" do
74 | @user.should respond_to(:password_confirmation)
75 | end
76 | end
77 |
78 | describe "password validations" do
79 |
80 | it "should require a password" do
81 | User.new(@attr.merge(:password => "", :password_confirmation => "")).
82 | should_not be_valid
83 | end
84 |
85 | it "should require a matching password confirmation" do
86 | User.new(@attr.merge(:password_confirmation => "invalid")).
87 | should_not be_valid
88 | end
89 |
90 | it "should reject short passwords" do
91 | short = "a" * 5
92 | hash = @attr.merge(:password => short, :password_confirmation => short)
93 | User.new(hash).should_not be_valid
94 | end
95 |
96 | it "should reject long passwords" do
97 | long = "a" * 41
98 | hash = @attr.merge(:password => long, :password_confirmation => long)
99 | User.new(hash).should_not be_valid
100 | end
101 | end
102 |
103 | describe "password encryption" do
104 |
105 | before(:each) do
106 | @user = User.create!(@attr)
107 | end
108 |
109 | it "should have an encrypted password attribute" do
110 | @user.should respond_to(:encrypted_password)
111 | end
112 |
113 | it "should set the encrypted password attribute" do
114 | @user.encrypted_password.should_not be_blank
115 | end
116 |
117 | it "should have a salt" do
118 | @user.should respond_to(:salt)
119 | end
120 |
121 | describe "has_password? method" do
122 |
123 | it "should exist" do
124 | @user.should respond_to(:has_password?)
125 | end
126 |
127 | it "should return true if the passwords match" do
128 | @user.has_password?(@attr[:password]).should be_true
129 | end
130 |
131 | it "should return false if the passwords don't match" do
132 | @user.has_password?("invalid").should be_false
133 | end
134 | end
135 |
136 | describe "authenticate method" do
137 |
138 | it "should exist" do
139 | User.should respond_to(:authenticate)
140 | end
141 |
142 | it "should return nil on email/password mismatch" do
143 | User.authenticate(@attr[:email], "wrongpass").should be_nil
144 | end
145 |
146 | it "should return nil for an email address with no user" do
147 | User.authenticate("bar@foo.com", @attr[:password]).should be_nil
148 | end
149 |
150 | it "should return the user on email/password match" do
151 | User.authenticate(@attr[:email], @attr[:password]).should == @user
152 | end
153 | end
154 | end
155 |
156 | describe "admin attribute" do
157 |
158 | before(:each) do
159 | @user = User.create!(@attr)
160 | end
161 |
162 | it "should respond to admin" do
163 | @user.should respond_to(:admin)
164 | end
165 |
166 | it "should not be an admin by default" do
167 | @user.should_not be_admin
168 | end
169 |
170 | it "should be convertible to an admin" do
171 | @user.toggle!(:admin)
172 | @user.should be_admin
173 | end
174 | end
175 |
176 | describe "micropost associations" do
177 |
178 | before(:each) do
179 | @user = User.create(@attr)
180 | @mp1 = Factory(:micropost, :user => @user, :created_at => 1.day.ago)
181 | @mp2 = Factory(:micropost, :user => @user, :created_at => 1.hour.ago)
182 | end
183 |
184 | it "should have a microposts attribute" do
185 | @user.should respond_to(:microposts)
186 | end
187 |
188 | it "should have the right microposts in the right order" do
189 | @user.microposts.should == [@mp2, @mp1]
190 | end
191 |
192 | it "should destroy associated microposts" do
193 | @user.destroy
194 | [@mp1, @mp2].each do |micropost|
195 | lambda do
196 | Micropost.find(micropost)
197 | end.should raise_error(ActiveRecord::RecordNotFound)
198 | end
199 | end
200 |
201 | describe "status feed" do
202 | it "should have a feed" do
203 | @user.should respond_to(:feed)
204 | end
205 |
206 | it "should include the user's microposts" do
207 | @user.feed.should include(@mp1)
208 | @user.feed.should include(@mp2)
209 | end
210 |
211 | it "should not include a different user's microposts" do
212 | mp3 = Factory(:micropost,
213 | :user => Factory(:user, :email => Factory.next(:email)))
214 | @user.feed.should_not include(mp3)
215 | end
216 |
217 | it "should include the microposts of followed users" do
218 | followed = Factory(:user, :email => Factory.next(:email))
219 | mp3 = Factory(:micropost, :user => followed)
220 | @user.follow!(followed)
221 | @user.feed.should include(mp3)
222 | end
223 | end
224 | end
225 |
226 | describe "relationships" do
227 |
228 | before(:each) do
229 | @user = User.create!(@attr)
230 | @followed = Factory(:user)
231 | end
232 |
233 | it "should have a relationships method" do
234 | @user.should respond_to(:relationships)
235 | end
236 |
237 | it "should have a following method" do
238 | @user.should respond_to(:following)
239 | end
240 |
241 | it "should follow another user" do
242 | @user.follow!(@followed)
243 | @user.should be_following(@followed)
244 | end
245 |
246 | it "should include the followed user in the following array" do
247 | @user.follow!(@followed)
248 | @user.following.should include(@followed)
249 | end
250 |
251 | it "should have an unfollow! method" do
252 | @user.should respond_to(:unfollow!)
253 | end
254 |
255 | it "should unfollow a user" do
256 | @user.follow!(@followed)
257 | @user.unfollow!(@followed)
258 | @user.should_not be_following(@followed)
259 | end
260 |
261 | it "should have a reverse_relationships method" do
262 | @user.should respond_to(:reverse_relationships)
263 | end
264 |
265 | it "should have a followers method" do
266 | @user.should respond_to(:followers)
267 | end
268 |
269 | it "should include the follower in the followers array" do
270 | @user.follow!(@followed)
271 | @followed.followers.should include(@user)
272 | end
273 | end
274 | end
275 |
--------------------------------------------------------------------------------
/spec/requests/friendly_forwardings_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe "FriendlyForwardings" do
4 |
5 | it "should forward to the requested page after signin" do
6 | user = Factory(:user)
7 | visit edit_user_path(user)
8 | fill_in :email, :with => user.email
9 | fill_in :password, :with => user.password
10 | click_button
11 | response.should render_template('users/edit')
12 | visit signout_path
13 | visit signin_path
14 | fill_in :email, :with => user.email
15 | fill_in :password, :with => user.password
16 | click_button
17 | response.should render_template('users/show')
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/requests/layout_links_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe "LayoutLinks" do
4 |
5 | it "should have a Home page at '/'" do
6 | get '/'
7 | response.should have_selector('title', :content => "Home")
8 | end
9 |
10 | it "should have a Contact page at '/contact'" do
11 | get '/contact'
12 | response.should have_selector('title', :content => "Contact")
13 | end
14 |
15 | it "should have an About page at '/about'" do
16 | get '/about'
17 | response.should have_selector('title', :content => "About")
18 | end
19 |
20 | it "should have a Help page at '/help'" do
21 | get '/help'
22 | response.should have_selector('title', :content => "Help")
23 | end
24 |
25 | it "should have a signup page at '/signup'" do
26 | get '/signup'
27 | response.should have_selector('title', :content => "Sign up")
28 | end
29 |
30 | it "should have a signin page at '/signin'" do
31 | get '/signin'
32 | response.should have_selector('title', :content => "Sign in")
33 | end
34 |
35 | it "should have the right links on the layout" do
36 | visit root_path
37 | response.should have_selector('title', :content => "Home")
38 | click_link "About"
39 | response.should have_selector('title', :content => "About")
40 | click_link "Contact"
41 | response.should have_selector('title', :content => "Contact")
42 | click_link "Home"
43 | response.should have_selector('title', :content => "Home")
44 | click_link "Sign up now!"
45 | response.should have_selector('title', :content => "Sign up")
46 | response.should have_selector('a[href="/"]>img')
47 | end
48 |
49 | describe "when not signed in" do
50 | it "should have a signin link" do
51 | visit root_path
52 | response.should have_selector("a", :href => signin_path,
53 | :content => "Sign in")
54 | end
55 | end
56 |
57 | describe "when signed in" do
58 |
59 | before(:each) do
60 | @user = Factory(:user)
61 | visit signin_path
62 | fill_in :email, :with => @user.email
63 | fill_in :password, :with => @user.password
64 | click_button
65 | end
66 |
67 | it "should have a signout link" do
68 | visit root_path
69 | response.should have_selector("a", :href => signout_path,
70 | :content => "Sign out")
71 | end
72 |
73 | it "should have a profile link" do
74 | visit root_path
75 | response.should have_selector("a", :href => user_path(@user),
76 | :content => "Profile")
77 | end
78 |
79 | it "should have a settings link" do
80 | visit root_path
81 | response.should have_selector("a", :href => edit_user_path(@user),
82 | :content => "Settings")
83 | end
84 |
85 | it "should have a users link" do
86 | visit root_path
87 | response.should have_selector("a", :href => users_path,
88 | :content => "Users")
89 | end
90 | end
91 | end
92 |
--------------------------------------------------------------------------------
/spec/requests/microposts_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe "Microposts" do
4 |
5 | before(:each) do
6 | user = Factory(:user)
7 | visit signin_path
8 | fill_in :email, :with => user.email
9 | fill_in :password, :with => user.password
10 | click_button
11 | end
12 |
13 | describe "creation" do
14 |
15 | describe "failure" do
16 | it "should not make a new micropost" do
17 | lambda do
18 | visit root_path
19 | fill_in :micropost_content, :with => ""
20 | click_button
21 | response.should render_template('pages/home')
22 | response.should have_selector('div#error_explanation')
23 | end.should_not change(Micropost, :count)
24 | end
25 | end
26 |
27 | describe "success" do
28 | it "should make a new micropost" do
29 | content = "Lorem ipsum dolor sit amet"
30 | lambda do
31 | visit root_path
32 | fill_in :micropost_content, :with => content
33 | click_button
34 | response.should have_selector('span.content', :content => content)
35 | end.should change(Micropost, :count).by(1)
36 | end
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/spec/requests/users_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe "Users" do
4 |
5 | describe "signup" do
6 |
7 | describe "failure" do
8 | it "should not make a new user" do
9 | lambda do
10 | visit signup_path
11 | fill_in "Name", :with => ""
12 | fill_in "Email", :with => ""
13 | fill_in "Password", :with => ""
14 | fill_in "Confirmation", :with => ""
15 | click_button
16 | response.should render_template('users/new')
17 | response.should have_selector('div#error_explanation')
18 | end.should_not change(User, :count)
19 | end
20 | end
21 |
22 | describe "success" do
23 | it "should make a new user" do
24 | lambda do
25 | visit signup_path
26 | fill_in "Name", :with => "Example User"
27 | fill_in "Email", :with => "user@example.com"
28 | fill_in "Password", :with => "foobar"
29 | fill_in "Confirmation", :with => "foobar"
30 | click_button
31 | response.should have_selector('div.flash.success',
32 | :content => "Welcome")
33 | response.should render_template('users/show')
34 | end.should change(User, :count).by(1)
35 | end
36 | end
37 | end
38 |
39 | describe "signin" do
40 |
41 | describe "failure" do
42 | it "should not sign a user in" do
43 | visit signin_path
44 | fill_in "Email", :with => ""
45 | fill_in "Password", :with => ""
46 | click_button
47 | response.should have_selector('div.flash.error',
48 | :content => "Invalid")
49 | response.should render_template('sessions/new')
50 | end
51 | end
52 |
53 | describe "success" do
54 | it "should sign a user in and out" do
55 | user = Factory(:user)
56 | visit signin_path
57 | fill_in "Email", :with => user.email
58 | fill_in "Password", :with => user.password
59 | click_button
60 | controller.should be_signed_in
61 | click_link "Sign out"
62 | controller.should_not be_signed_in
63 | end
64 | end
65 | end
66 | end
67 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'spork'
2 |
3 | Spork.prefork do
4 | # Loading more in this block will cause your tests to run faster. However,
5 | # if you change any configuration or code from libraries loaded here, you'll
6 | # need to restart spork for it take effect.
7 | ENV["RAILS_ENV"] ||= 'test'
8 | require File.expand_path("../../config/environment", __FILE__)
9 | require 'rspec/rails'
10 |
11 | # Requires supporting files with custom matchers and macros, etc,
12 | # in ./support/ and its subdirectories.
13 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
14 |
15 | RSpec.configure do |config|
16 | # == Mock Framework
17 | #
18 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
19 | #
20 | # config.mock_with :mocha
21 | # config.mock_with :flexmock
22 | # config.mock_with :rr
23 | config.mock_with :rspec
24 |
25 | config.fixture_path = "#{::Rails.root}/spec/fixtures"
26 |
27 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
28 | # examples within a transaction, comment the following line or assign false
29 | # instead of true.
30 | config.use_transactional_fixtures = true
31 |
32 | def test_sign_in(user)
33 | controller.sign_in(user)
34 | end
35 | end
36 | end
37 |
38 | Spork.each_run do
39 | end
40 |
--------------------------------------------------------------------------------
/vendor/plugins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railstutorial/sample_app/fe776b59458d3306cdeaabf49f8232971acc7e1b/vendor/plugins/.gitkeep
--------------------------------------------------------------------------------