Merge branch 'master' of github.com:lifo/docrails

Conflicts:
	actionpack/lib/action_dispatch/routing/redirection.rb
This commit is contained in:
Vijay Dev 2012-11-17 01:50:49 +05:30
commit 7b70eeed43
61 changed files with 959 additions and 957 deletions

View File

@ -70,7 +70,7 @@ module ActionMailer
# The block syntax is also useful in providing information specific to a part:
#
# mail(to: user.email) do |format|
# format.text(:content_transfer_encoding => "base64")
# format.text(content_transfer_encoding: "base64")
# format.html
# end
#
@ -129,12 +129,12 @@ module ActionMailer
# It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt>
# option as a configuration option in <tt>config/application.rb</tt>:
#
# config.action_mailer.default_url_options = { :host => "example.com" }
# config.action_mailer.default_url_options = { host: "example.com" }
#
# When you decide to set a default <tt>:host</tt> for your mailers, then you need to make sure to use the
# <tt>:only_path => false</tt> option when using <tt>url_for</tt>. Since the <tt>url_for</tt> view helper
# <tt>only_path: false</tt> option when using <tt>url_for</tt>. Since the <tt>url_for</tt> view helper
# will generate relative URLs by default when a <tt>:host</tt> option isn't explicitly provided, passing
# <tt>:only_path => false</tt> will ensure that absolute URLs are generated.
# <tt>only_path: false</tt> will ensure that absolute URLs are generated.
#
# = Sending mail
#
@ -246,10 +246,10 @@ module ActionMailer
# You can pass in any header value that a <tt>Mail::Message</tt> accepts. Out of the box,
# <tt>ActionMailer::Base</tt> sets the following:
#
# * <tt>:mime_version => "1.0"</tt>
# * <tt>:charset => "UTF-8",</tt>
# * <tt>:content_type => "text/plain",</tt>
# * <tt>:parts_order => [ "text/plain", "text/enriched", "text/html" ]</tt>
# * <tt>mime_version: "1.0"</tt>
# * <tt>charset: "UTF-8",</tt>
# * <tt>content_type: "text/plain",</tt>
# * <tt>parts_order: [ "text/plain", "text/enriched", "text/html" ]</tt>
#
# <tt>parts_order</tt> and <tt>charset</tt> are not actually valid <tt>Mail::Message</tt> header fields,
# but Action Mailer translates them appropriately and sets the correct values.
@ -665,7 +665,7 @@ module ActionMailer
#
# The block syntax also allows you to customize the part headers if desired:
#
# mail(:to => 'mikel@test.lindsaar.net') do |format|
# mail(to: 'mikel@test.lindsaar.net') do |format|
# format.text(content_transfer_encoding: "base64")
# format.html
# end

View File

@ -170,7 +170,7 @@ module AbstractController
# <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
#
# class WeblogController < ActionController::Base
# layout "weblog_standard", :except => :rss
# layout "weblog_standard", except: :rss
#
# # ...
#
@ -180,7 +180,7 @@ module AbstractController
# be rendered directly, without wrapping a layout around the rendered view.
#
# Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
# #<tt>:except => [ :rss, :text_only ]</tt> is valid, as is <tt>:except => :rss</tt>.
# #<tt>except: [ :rss, :text_only ]</tt> is valid, as is <tt>except: :rss</tt>.
#
# == Using a different layout in the action render call
#
@ -192,7 +192,7 @@ module AbstractController
# layout "weblog_standard"
#
# def help
# render :action => "help", :layout => "help"
# render action: "help", layout: "help"
# end
# end
#

View File

@ -299,7 +299,7 @@ module ActionDispatch
# and +:action+ to the controller's action. A pattern can also map
# wildcard segments (globs) to params:
#
# match 'songs/*category/:title' => 'songs#show'
# match 'songs/*category/:title', to: 'songs#show'
#
# # 'songs/rock/classic/stairway-to-heaven' sets
# # params[:category] = 'rock/classic'
@ -315,10 +315,14 @@ module ActionDispatch
# A pattern can also point to a +Rack+ endpoint i.e. anything that
# responds to +call+:
#
# match 'photos/:id' => lambda {|hash| [200, {}, "Coming soon"] }
# match 'photos/:id' => PhotoRackApp
# match 'photos/:id', to: lambda {|hash| [200, {}, "Coming soon"] }
# match 'photos/:id', to: PhotoRackApp
# # Yes, controller actions are just rack endpoints
# match 'photos/:id' => PhotosController.action(:show)
# match 'photos/:id', to: PhotosController.action(:show)
#
# Because request various HTTP verbs with a single action has security
# implications, is recommendable use HttpHelpers[rdoc-ref:HttpHelpers]
# instead +match+
#
# === Options
#
@ -336,7 +340,7 @@ module ActionDispatch
# [:module]
# The namespace for :controller.
#
# match 'path' => 'c#a', module: 'sekret', controller: 'posts'
# match 'path', to: 'c#a', module: 'sekret', controller: 'posts'
# #=> Sekret::PostsController
#
# See <tt>Scoping#namespace</tt> for its scope equivalent.
@ -347,8 +351,9 @@ module ActionDispatch
# [:via]
# Allowed HTTP verb(s) for route.
#
# match 'path' => 'c#a', via: :get
# match 'path' => 'c#a', via: [:get, :post]
# match 'path', to: 'c#a', via: :get
# match 'path', to: 'c#a', via: [:get, :post]
# match 'path', to: 'c#a', via: :all
#
# [:to]
# Points to a +Rack+ endpoint. Can be an object that responds to
@ -364,14 +369,14 @@ module ActionDispatch
# <tt>resource(s)</tt> block. For example:
#
# resource :bar do
# match 'foo' => 'c#a', on: :member, via: [:get, :post]
# match 'foo', to: 'c#a', on: :member, via: [:get, :post]
# end
#
# Is equivalent to:
#
# resource :bar do
# member do
# match 'foo' => 'c#a', via: [:get, :post]
# match 'foo', to: 'c#a', via: [:get, :post]
# end
# end
#
@ -384,7 +389,7 @@ module ActionDispatch
# class Blacklist
# def matches?(request) request.remote_ip == '1.2.3.4' end
# end
# match 'path' => 'c#a', constraints: Blacklist.new
# match 'path', to: 'c#a', constraints: Blacklist.new
#
# See <tt>Scoping#constraints</tt> for more examples with its scope
# equivalent.
@ -393,7 +398,7 @@ module ActionDispatch
# Sets defaults for parameters
#
# # Sets params[:format] to 'jpg' by default
# match 'path' => 'c#a', defaults: { format: 'jpg' }
# match 'path', to: 'c#a', defaults: { format: 'jpg' }
#
# See <tt>Scoping#defaults</tt> for its scope equivalent.
#
@ -402,7 +407,7 @@ module ActionDispatch
# false, the pattern matches any request prefixed with the given path.
#
# # Matches any request starting with 'path'
# match 'path' => 'c#a', anchor: false
# match 'path', to: 'c#a', anchor: false
#
# [:format]
# Allows you to specify the default value for optional +format+
@ -499,7 +504,7 @@ module ActionDispatch
module HttpHelpers
# Define a route that only recognizes HTTP GET.
# For supported arguments, see <tt>Base#match</tt>.
# For supported arguments, see match[rdoc-ref:Base#match]
#
# get 'bacon', to: 'food#bacon'
def get(*args, &block)
@ -507,7 +512,7 @@ module ActionDispatch
end
# Define a route that only recognizes HTTP POST.
# For supported arguments, see <tt>Base#match</tt>.
# For supported arguments, see match[rdoc-ref:Base#match]
#
# post 'bacon', to: 'food#bacon'
def post(*args, &block)
@ -515,7 +520,7 @@ module ActionDispatch
end
# Define a route that only recognizes HTTP PATCH.
# For supported arguments, see <tt>Base#match</tt>.
# For supported arguments, see match[rdoc-ref:Base#match]
#
# patch 'bacon', to: 'food#bacon'
def patch(*args, &block)
@ -523,7 +528,7 @@ module ActionDispatch
end
# Define a route that only recognizes HTTP PUT.
# For supported arguments, see <tt>Base#match</tt>.
# For supported arguments, see match[rdoc-ref:Base#match]
#
# put 'bacon', to: 'food#bacon'
def put(*args, &block)
@ -531,7 +536,7 @@ module ActionDispatch
end
# Define a route that only recognizes HTTP DELETE.
# For supported arguments, see <tt>Base#match</tt>.
# For supported arguments, see match[rdoc-ref:Base#match]
#
# delete 'broccoli', to: 'food#broccoli'
def delete(*args, &block)

View File

@ -13,6 +13,10 @@ module ActiveModel
# you wish to turn off validations, pass <tt>validations: false</tt> as an
# argument. You can add more validations by hand if need be.
#
# If you don't need the confirmation validation, just don't set any
# value to the password_confirmation attribute and the the validation
# will not be triggered.
#
# You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use #has_secure_password:
#
# gem 'bcrypt-ruby', '~> 3.0.0'

View File

@ -16,8 +16,8 @@ module ActiveRecord
# the database).
#
# class Customer < ActiveRecord::Base
# composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
# composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ]
# composed_of :balance, class_name: "Money", mapping: %w(balance amount)
# composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
# end
#
# The customer class now has the following methods to manipulate the value objects:
@ -138,15 +138,15 @@ module ActiveRecord
#
# class NetworkResource < ActiveRecord::Base
# composed_of :cidr,
# :class_name => 'NetAddr::CIDR',
# :mapping => [ %w(network_address network), %w(cidr_range bits) ],
# :allow_nil => true,
# :constructor => Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
# :converter => Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
# class_name: 'NetAddr::CIDR',
# mapping: [ %w(network_address network), %w(cidr_range bits) ],
# allow_nil: true,
# constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
# converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
# end
#
# # This calls the :constructor
# network_resource = NetworkResource.new(:network_address => '192.168.0.1', :cidr_range => 24)
# network_resource = NetworkResource.new(network_address: '192.168.0.1', cidr_range: 24)
#
# # These assignments will both use the :converter
# network_resource.cidr = [ '192.168.2.1', 8 ]
@ -165,7 +165,7 @@ module ActiveRecord
# by specifying an instance of the value object in the conditions hash. The following example
# finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
#
# Customer.where(:balance => Money.new(20, "USD")).all
# Customer.where(balance: Money.new(20, "USD")).all
#
module ClassMethods
# Adds reader and writer methods for manipulating a value object:
@ -197,17 +197,17 @@ module ActiveRecord
# can return nil to skip the assignment.
#
# Option examples:
# composed_of :temperature, :mapping => %w(reading celsius)
# composed_of :balance, :class_name => "Money", :mapping => %w(balance amount),
# :converter => Proc.new { |balance| balance.to_money }
# composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ]
# composed_of :temperature, mapping: %w(reading celsius)
# composed_of :balance, class_name: "Money", mapping: %w(balance amount),
# converter: Proc.new { |balance| balance.to_money }
# composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
# composed_of :gps_location
# composed_of :gps_location, :allow_nil => true
# composed_of :gps_location, allow_nil: true
# composed_of :ip_address,
# :class_name => 'IPAddr',
# :mapping => %w(ip to_i),
# :constructor => Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
# :converter => Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
# class_name: 'IPAddr',
# mapping: %w(ip to_i),
# constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
# converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
#
def composed_of(part_id, options = {})
options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)

View File

@ -308,11 +308,11 @@ module ActiveRecord
# end
# class Programmer < ActiveRecord::Base
# has_many :assignments
# has_many :projects, :through => :assignments
# has_many :projects, through: :assignments
# end
# class Project < ActiveRecord::Base
# has_many :assignments
# has_many :programmers, :through => :assignments
# has_many :programmers, through: :assignments
# end
#
# For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
@ -429,7 +429,7 @@ module ActiveRecord
# object from an association collection.
#
# class Project
# has_and_belongs_to_many :developers, :after_add => :evaluate_velocity
# has_and_belongs_to_many :developers, after_add: :evaluate_velocity
#
# def evaluate_velocity(developer)
# ...
@ -440,7 +440,7 @@ module ActiveRecord
#
# class Project
# has_and_belongs_to_many :developers,
# :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
# after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
# end
#
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
@ -510,7 +510,7 @@ module ActiveRecord
#
# class Author < ActiveRecord::Base
# has_many :authorships
# has_many :books, :through => :authorships
# has_many :books, through: :authorships
# end
#
# class Authorship < ActiveRecord::Base
@ -526,7 +526,7 @@ module ActiveRecord
#
# class Firm < ActiveRecord::Base
# has_many :clients
# has_many :invoices, :through => :clients
# has_many :invoices, through: :clients
# end
#
# class Client < ActiveRecord::Base
@ -546,7 +546,7 @@ module ActiveRecord
#
# class Group < ActiveRecord::Base
# has_many :users
# has_many :avatars, :through => :users
# has_many :avatars, through: :users
# end
#
# class User < ActiveRecord::Base
@ -574,7 +574,7 @@ module ActiveRecord
# works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association):
#
# @post = Post.first
# @tag = @post.tags.build :name => "ruby"
# @tag = @post.tags.build name: "ruby"
# @tag.save
#
# The last line ought to save the through record (a <tt>Taggable</tt>). This will only work if the
@ -582,7 +582,7 @@ module ActiveRecord
#
# class Taggable < ActiveRecord::Base
# belongs_to :post
# belongs_to :tag, :inverse_of => :taggings
# belongs_to :tag, inverse_of: :taggings
# end
#
# == Nested Associations
@ -592,8 +592,8 @@ module ActiveRecord
#
# class Author < ActiveRecord::Base
# has_many :posts
# has_many :comments, :through => :posts
# has_many :commenters, :through => :comments
# has_many :comments, through: :posts
# has_many :commenters, through: :comments
# end
#
# class Post < ActiveRecord::Base
@ -611,12 +611,12 @@ module ActiveRecord
#
# class Author < ActiveRecord::Base
# has_many :posts
# has_many :commenters, :through => :posts
# has_many :commenters, through: :posts
# end
#
# class Post < ActiveRecord::Base
# has_many :comments
# has_many :commenters, :through => :comments
# has_many :commenters, through: :comments
# end
#
# class Comment < ActiveRecord::Base
@ -635,11 +635,11 @@ module ActiveRecord
# must adhere to.
#
# class Asset < ActiveRecord::Base
# belongs_to :attachable, :polymorphic => true
# belongs_to :attachable, polymorphic: true
# end
#
# class Post < ActiveRecord::Base
# has_many :assets, :as => :attachable # The :as option specifies the polymorphic interface to use.
# has_many :assets, as: :attachable # The :as option specifies the polymorphic interface to use.
# end
#
# @asset.attachable = @post
@ -656,7 +656,7 @@ module ActiveRecord
# column in the posts table.
#
# class Asset < ActiveRecord::Base
# belongs_to :attachable, :polymorphic => true
# belongs_to :attachable, polymorphic: true
#
# def attachable_type=(sType)
# super(sType.to_s.classify.constantize.base_class.to_s)
@ -664,8 +664,8 @@ module ActiveRecord
# end
#
# class Post < ActiveRecord::Base
# # because we store "Post" in attachable_type now :dependent => :destroy will work
# has_many :assets, :as => :attachable, :dependent => :destroy
# # because we store "Post" in attachable_type now dependent: :destroy will work
# has_many :assets, as: :attachable, dependent: :destroy
# end
#
# class GuestPost < Post
@ -727,7 +727,7 @@ module ActiveRecord
#
# To include a deep hierarchy of associations, use a hash:
#
# Post.includes(:author, {:comments => {:author => :gravatar}}).each do |post|
# Post.includes(:author, {comments: {author: :gravatar}}).each do |post|
#
# That'll grab not only all the comments but all their authors and gravatar pictures.
# You can mix and match symbols, arrays and hashes in any combination to describe the
@ -752,13 +752,13 @@ module ActiveRecord
# In the above example posts with no approved comments are not returned at all, because
# the conditions apply to the SQL statement as a whole and not just to the association.
# You must disambiguate column references for this fallback to happen, for example
# <tt>:order => "author.name DESC"</tt> will work but <tt>:order => "name DESC"</tt> will not.
# <tt>order: "author.name DESC"</tt> will work but <tt>order: "name DESC"</tt> will not.
#
# If you do want eager load only some members of an association it is usually more natural
# to include an association which has conditions defined on it:
#
# class Post < ActiveRecord::Base
# has_many :approved_comments, -> { where approved: true }, :class_name => 'Comment'
# has_many :approved_comments, -> { where approved: true }, class_name: 'Comment'
# end
#
# Post.includes(:approved_comments)
@ -770,7 +770,7 @@ module ActiveRecord
# returning all the associated objects:
#
# class Picture < ActiveRecord::Base
# has_many :most_recent_comments, -> { order('id DESC').limit(10) }, :class_name => 'Comment'
# has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment'
# end
#
# Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
@ -778,7 +778,7 @@ module ActiveRecord
# Eager loading is supported with polymorphic associations.
#
# class Address < ActiveRecord::Base
# belongs_to :addressable, :polymorphic => true
# belongs_to :addressable, polymorphic: true
# end
#
# A call that tries to eager load the addressable model
@ -812,10 +812,10 @@ module ActiveRecord
#
# TreeMixin.joins(:children)
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# TreeMixin.joins(:children => :parent)
# TreeMixin.joins(children: :parent)
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# INNER JOIN parents_mixins ...
# TreeMixin.joins(:children => {:parent => :children})
# TreeMixin.joins(children: {parent: :children})
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# INNER JOIN parents_mixins ...
# INNER JOIN mixins childrens_mixins_2
@ -824,10 +824,10 @@ module ActiveRecord
#
# Post.joins(:categories)
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# Post.joins(:categories => :posts)
# Post.joins(categories: :posts)
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
# Post.joins(:categories => {:posts => :categories})
# Post.joins(categories: {posts: :categories})
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
@ -871,7 +871,7 @@ module ActiveRecord
#
# module Billing
# class Account < ActiveRecord::Base
# belongs_to :firm, :class_name => "MyApplication::Business::Firm"
# belongs_to :firm, class_name: "MyApplication::Business::Firm"
# end
# end
# end
@ -913,16 +913,16 @@ module ActiveRecord
# example, if we changed our model definitions to:
#
# class Dungeon < ActiveRecord::Base
# has_many :traps, :inverse_of => :dungeon
# has_one :evil_wizard, :inverse_of => :dungeon
# has_many :traps, inverse_of: :dungeon
# has_one :evil_wizard, inverse_of: :dungeon
# end
#
# class Trap < ActiveRecord::Base
# belongs_to :dungeon, :inverse_of => :traps
# belongs_to :dungeon, inverse_of: :traps
# end
#
# class EvilWizard < ActiveRecord::Base
# belongs_to :dungeon, :inverse_of => :evil_wizard
# belongs_to :dungeon, inverse_of: :evil_wizard
# end
#
# Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
@ -945,7 +945,7 @@ module ActiveRecord
# For example:
#
# class Author
# has_many :posts, :dependent => :destroy
# has_many :posts, dependent: :destroy
# end
# Author.find(1).destroy # => Will destroy all of the author's posts, too
#
@ -1029,12 +1029,12 @@ module ActiveRecord
# parent object.
# [collection.delete(object, ...)]
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
# Objects will be in addition destroyed if they're associated with <tt>:dependent => :destroy</tt>,
# and deleted if they're associated with <tt>:dependent => :delete_all</tt>.
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
# and deleted if they're associated with <tt>dependent: :delete_all</tt>.
#
# If the <tt>:through</tt> option is used, then the join records are deleted (rather than
# nullified) by default, but you can specify <tt>:dependent => :destroy</tt> or
# <tt>:dependent => :nullify</tt> to override this.
# nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
# <tt>dependent: :nullify</tt> to override this.
# [collection.destroy(object, ...)]
# Removes one or more objects from the collection by running <tt>destroy</tt> on
# each record, regardless of any dependent option, ensuring callbacks are run.
@ -1052,8 +1052,8 @@ module ActiveRecord
# method loads the models and calls <tt>collection=</tt>. See above.
# [collection.clear]
# Removes every object from the collection. This destroys the associated objects if they
# are associated with <tt>:dependent => :destroy</tt>, deletes them directly from the
# database if <tt>:dependent => :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
# are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
# database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
# If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
# Join models are directly deleted.
# [collection.empty?]
@ -1081,7 +1081,7 @@ module ActiveRecord
# === Example
#
# Example: A Firm class declares <tt>has_many :clients</tt>, which will add:
# * <tt>Firm#clients</tt> (similar to <tt>Clients.all :conditions => ["firm_id = ?", id]</tt>)
# * <tt>Firm#clients</tt> (similar to <tt>Clients.all conditions: ["firm_id = ?", id]</tt>)
# * <tt>Firm#clients<<</tt>
# * <tt>Firm#clients.delete</tt>
# * <tt>Firm#clients.destroy</tt>
@ -1091,8 +1091,8 @@ module ActiveRecord
# * <tt>Firm#clients.clear</tt>
# * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>)
# * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
# * <tt>Firm#clients.find</tt> (similar to <tt>Client.find(id, :conditions => "firm_id = #{id}")</tt>)
# * <tt>Firm#clients.exists?(:name => 'ACME')</tt> (similar to <tt>Client.exists?(:name => 'ACME', :firm_id => firm.id)</tt>)
# * <tt>Firm#clients.find</tt> (similar to <tt>Client.find(id, conditions: "firm_id = #{id}")</tt>)
# * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
# * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
# * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
# The declaration can also include an options hash to specialize the behavior of the association.
@ -1149,7 +1149,7 @@ module ActiveRecord
# [:source]
# Specifies the source association name used by <tt>has_many :through</tt> queries.
# Only use it if the name cannot be inferred from the association.
# <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either <tt>:subscribers</tt> or
# <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
# [:source_type]
# Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
@ -1213,7 +1213,7 @@ module ActiveRecord
# === Example
#
# An Account class declares <tt>has_one :beneficiary</tt>, which will add:
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.first(:conditions => "account_id = #{id}")</tt>)
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.first(conditions: "account_id = #{id}")</tt>)
# * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
# * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
# * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
@ -1253,7 +1253,7 @@ module ActiveRecord
# [:source]
# Specifies the source association name used by <tt>has_one :through</tt> queries.
# Only use it if the name cannot be inferred from the association.
# <tt>has_one :favorite, :through => :favorites</tt> will look for a
# <tt>has_one :favorite, through: :favorites</tt> will look for a
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
# [:source_type]
# Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
@ -1273,11 +1273,11 @@ module ActiveRecord
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
#
# Option examples:
# has_one :credit_card, :dependent => :destroy # destroys the associated credit card
# has_one :credit_card, :dependent => :nullify # updates the associated records foreign
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
# has_one :credit_card, dependent: :nullify # updates the associated records foreign
# # key value to NULL rather than destroying it
# has_one :last_comment, -> { order 'posted_on' }, :class_name => "Comment"
# has_one :project_manager, -> { where role: 'project_manager' }, :class_name => "Person"
# has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
# has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
# has_one :attachment, as: :attachable
# has_one :boss, readonly: :true
# has_one :club, through: :membership
@ -1332,12 +1332,12 @@ module ActiveRecord
# Specify the foreign key used for the association. By default this is guessed to be the name
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
# <tt>belongs_to :favorite_person, :class_name => "Person"</tt> will use a foreign key
# <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
# of "favorite_person_id".
# [:foreign_type]
# Specify the column used to store the associated object's type, if this is a polymorphic
# association. By default this is guessed to be the name of the association with a "_type"
# suffix. So a class that defines a <tt>belongs_to :taggable, :polymorphic => true</tt>
# suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
# association will use "taggable_type" as the default <tt>:foreign_type</tt>.
# [:primary_key]
# Specify the method that returns the primary key of associated object used for the association.
@ -1357,7 +1357,7 @@ module ActiveRecord
# <tt>#{table_name}_count</tt> is created on the associate class (such that Post.comments_count will
# return the count cached, see note below). You can also specify a custom counter
# cache column by providing a column name instead of a +true+/+false+ value to this
# option (e.g., <tt>:counter_cache => :my_custom_counter</tt>.)
# option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
# Note: Specifying a counter cache will add it to that model's list of readonly attributes
# using +attr_readonly+.
# [:polymorphic]
@ -1415,7 +1415,7 @@ module ActiveRecord
#
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
# def change
# create_table :developers_projects, :id => false do |t|
# create_table :developers_projects, id: false do |t|
# t.integer :developer_id
# t.integer :project_id
# end

View File

@ -16,7 +16,7 @@ module ActiveRecord
# Note that it also means that associations marked for destruction won't
# be destroyed directly. They will however still be marked for destruction.
#
# Note that <tt>:autosave => false</tt> is not same as not declaring <tt>:autosave</tt>.
# Note that <tt>autosave: false</tt> is not same as not declaring <tt>:autosave</tt>.
# When the <tt>:autosave</tt> option is not present new associations are saved.
#
# == Validation
@ -37,7 +37,7 @@ module ActiveRecord
# === One-to-one Example
#
# class Post
# has_one :author, :autosave => true
# has_one :author, autosave: true
# end
#
# Saving changes to the parent and its associated model can now be performed
@ -81,27 +81,27 @@ module ActiveRecord
# has_many :comments # :autosave option is not declared
# end
#
# post = Post.new(:title => 'ruby rocks')
# post.comments.build(:body => 'hello world')
# post = Post.new(title: 'ruby rocks')
# post.comments.build(body: 'hello world')
# post.save # => saves both post and comment
#
# post = Post.create(:title => 'ruby rocks')
# post.comments.build(:body => 'hello world')
# post = Post.create(title: 'ruby rocks')
# post.comments.build(body: 'hello world')
# post.save # => saves both post and comment
#
# post = Post.create(:title => 'ruby rocks')
# post.comments.create(:body => 'hello world')
# post = Post.create(title: 'ruby rocks')
# post.comments.create(body: 'hello world')
# post.save # => saves both post and comment
#
# When <tt>:autosave</tt> is true all children are saved, no matter whether they
# are new records or not:
#
# class Post
# has_many :comments, :autosave => true
# has_many :comments, autosave: true
# end
#
# post = Post.create(:title => 'ruby rocks')
# post.comments.create(:body => 'hello world')
# post = Post.create(title: 'ruby rocks')
# post.comments.create(body: 'hello world')
# post.comments[0].body = 'hi everyone'
# post.save # => saves both post and comment, with 'hi everyone' as body
#

View File

@ -35,7 +35,7 @@ module ActiveRecord #:nodoc:
# method is especially useful when you're receiving the data from somewhere else, like an
# HTTP request. It works like this:
#
# user = User.new(:name => "David", :occupation => "Code Artist")
# user = User.new(name: "David", occupation: "Code Artist")
# user.name # => "David"
#
# You can also use block initialization:
@ -68,7 +68,7 @@ module ActiveRecord #:nodoc:
# end
#
# def self.authenticate_safely_simply(user_name, password)
# where(:user_name => user_name, :password => password).first
# where(user_name: user_name, password: password).first
# end
# end
#
@ -86,27 +86,27 @@ module ActiveRecord #:nodoc:
#
# Company.where(
# "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
# { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
# { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
# ).first
#
# Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
# operator. For instance:
#
# Student.where(:first_name => "Harvey", :status => 1)
# Student.where(first_name: "Harvey", status: 1)
# Student.where(params[:student])
#
# A range may be used in the hash to use the SQL BETWEEN operator:
#
# Student.where(:grade => 9..12)
# Student.where(grade: 9..12)
#
# An array may be used in the hash to use the SQL IN operator:
#
# Student.where(:grade => [9,11,12])
# Student.where(grade: [9,11,12])
#
# When joining tables, nested hashes or keys written in the form 'table_name.column_name'
# can be used to qualify the table name of a particular condition. For instance:
#
# Student.joins(:schools).where(:schools => { :category => 'public' })
# Student.joins(:schools).where(schools: { category: 'public' })
# Student.joins(:schools).where('schools.category' => 'public' )
#
# == Overwriting default accessors
@ -140,10 +140,10 @@ module ActiveRecord #:nodoc:
# For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
# to determine whether the user has a name:
#
# user = User.new(:name => "David")
# user = User.new(name: "David")
# user.name? # => true
#
# anonymous = User.new(:name => "")
# anonymous = User.new(name: "")
# anonymous.name? # => false
#
# == Accessing attributes before they have been typecasted
@ -164,8 +164,8 @@ module ActiveRecord #:nodoc:
# to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt> and thus produces finders
# like <tt>Person.find_by_user_name</tt>, <tt>Person.find_all_by_last_name</tt>, and
# <tt>Payment.find_by_transaction_id</tt>. Instead of writing
# <tt>Person.where(:user_name => user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
# And instead of writing <tt>Person.where(:last_name => last_name).all</tt>, you just do
# <tt>Person.where(user_name: user_name).first</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
# And instead of writing <tt>Person.where(last_name: last_name).all</tt>, you just do
# <tt>Person.find_all_by_last_name(last_name)</tt>.
#
# It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
@ -174,7 +174,7 @@ module ActiveRecord #:nodoc:
#
# It's also possible to use multiple attributes in the same find by separating them with "_and_".
#
# Person.where(:user_name => user_name, :password => password).first
# Person.where(user_name: user_name, password: password).first
# Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
#
# It's even possible to call these dynamic finder methods on relations and named scopes.
@ -188,13 +188,13 @@ module ActiveRecord #:nodoc:
# unless they are given in a block.
#
# # No 'Summer' tag exists
# Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")
# Tag.find_or_create_by_name("Summer") # equal to Tag.create(name: "Summer")
#
# # Now the 'Summer' tag does exist
# Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
#
# # Now 'Bob' exist and is an 'admin'
# User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
# User.find_or_create_by_name('Bob', age: 40) { |u| u.admin = true }
#
# Adding an exclamation point (!) on to the end of <tt>find_or_create_by_</tt> will
# raise an <tt>ActiveRecord::RecordInvalid</tt> error if the new record is invalid.
@ -209,7 +209,7 @@ module ActiveRecord #:nodoc:
# To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of
# a list of parameters.
#
# Tag.find_or_create_by_name(:name => "rails", :creator => current_user)
# Tag.find_or_create_by_name(name: "rails", creator: current_user)
#
# That will either find an existing tag named "rails", or create a new one while setting the
# user that created it.
@ -231,7 +231,7 @@ module ActiveRecord #:nodoc:
# serialize :preferences
# end
#
# user = User.create(:preferences => { "background" => "black", "display" => large })
# user = User.create(preferences: { "background" => "black", "display" => large })
# User.find(user.id).preferences # => { "background" => "black", "display" => large }
#
# You can also specify a class option as the second parameter that'll raise an exception
@ -241,7 +241,7 @@ module ActiveRecord #:nodoc:
# serialize :preferences, Hash
# end
#
# user = User.create(:preferences => %w( one two three ))
# user = User.create(preferences: %w( one two three ))
# User.find(user.id).preferences # raises SerializationTypeMismatch
#
# When you specify a class option, the default value for that attribute will be a new
@ -266,9 +266,9 @@ module ActiveRecord #:nodoc:
# class Client < Company; end
# class PriorityClient < Client; end
#
# When you do <tt>Firm.create(:name => "37signals")</tt>, this record will be saved in
# When you do <tt>Firm.create(name: "37signals")</tt>, this record will be saved in
# the companies table with type = "Firm". You can then fetch this row again using
# <tt>Company.where(:name => '37signals').first</tt> and it will return a Firm object.
# <tt>Company.where(name: '37signals').first</tt> and it will return a Firm object.
#
# If you don't have a type column defined in your table, single-table inheritance won't
# be triggered. In that case, it'll work just like normal subclasses with no special magic

View File

@ -35,7 +35,7 @@ module ActiveRecord
# class CreditCard < ActiveRecord::Base
# # Strip everything but digits, so the user can specify "555 234 34" or
# # "5552-3434" and both will mean "55523434"
# before_validation(:on => :create) do
# before_validation(on: :create) do
# self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
# end
# end

View File

@ -5,18 +5,18 @@ module ActiveRecord
# example for regular databases (MySQL, Postgresql, etc):
#
# ActiveRecord::Base.establish_connection(
# :adapter => "mysql",
# :host => "localhost",
# :username => "myuser",
# :password => "mypass",
# :database => "somedatabase"
# adapter: "mysql",
# host: "localhost",
# username: "myuser",
# password: "mypass",
# database: "somedatabase"
# )
#
# Example for SQLite database:
#
# ActiveRecord::Base.establish_connection(
# :adapter => "sqlite",
# :database => "path/to/dbfile"
# adapter: "sqlite",
# database: "path/to/dbfile"
# )
#
# Also accepts keys as strings (for parsing from YAML for example):
@ -64,7 +64,7 @@ module ActiveRecord
# Returns the configuration of the associated connection as a hash:
#
# ActiveRecord::Base.connection_config
# # => {:pool=>5, :timeout=>5000, :database=>"db/development.sqlite3", :adapter=>"sqlite3"}
# # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}
#
# Please use only for reading.
def connection_config

View File

@ -154,7 +154,7 @@ module ActiveRecord
#
# ==== Example:
# # Instantiates a single new object
# User.new(:first_name => 'Jamie')
# User.new(first_name: 'Jamie')
def initialize(attributes = nil)
defaults = self.class.column_defaults.dup
defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? }

View File

@ -56,7 +56,7 @@ module ActiveRecord
#
# # For the Post with id of 5, decrement the comment_count by 1, and
# # increment the action_count by 1
# Post.update_counters 5, :comment_count => -1, :action_count => 1
# Post.update_counters 5, comment_count: -1, action_count: 1
# # Executes the following SQL:
# # UPDATE posts
# # SET comment_count = COALESCE(comment_count, 0) - 1,
@ -64,7 +64,7 @@ module ActiveRecord
# # WHERE id = 5
#
# # For the Posts with id of 10 and 15, increment the comment_count by 1
# Post.update_counters [10, 15], :comment_count => 1
# Post.update_counters [10, 15], comment_count: 1
# # Executes the following SQL:
# # UPDATE posts
# # SET comment_count = COALESCE(comment_count, 0) + 1

View File

@ -22,7 +22,7 @@ module ActiveRecord
# end
#
# # Comments are not patches, this assignment raises AssociationTypeMismatch.
# @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
# @ticket.patches << Comment.new(content: "Please attach tests to your patch.")
class AssociationTypeMismatch < ActiveRecordError
end

View File

@ -250,7 +250,7 @@ module ActiveRecord
#
# ### in fruit.rb
#
# belongs_to :eater, :polymorphic => true
# belongs_to :eater, polymorphic: true
#
# ### in fruits.yml
#
@ -730,7 +730,7 @@ module ActiveRecord
#
# Examples:
#
# set_fixture_class :some_fixture => SomeModel,
# set_fixture_class some_fixture: SomeModel,
# 'namespaced/fixture' => Another::Model
#
# The keys must be the fixture names, that coincide with the short paths to the fixture files.

View File

@ -3,12 +3,12 @@ module ActiveRecord
# Locking::Pessimistic provides support for row-level locking using
# SELECT ... FOR UPDATE and other lock types.
#
# Pass <tt>:lock => true</tt> to <tt>ActiveRecord::Base.find</tt> to obtain an exclusive
# Pass <tt>lock: true</tt> to <tt>ActiveRecord::Base.find</tt> to obtain an exclusive
# lock on the selected rows:
# # select * from accounts where id=1 for update
# Account.find(1, :lock => true)
# Account.find(1, lock: true)
#
# Pass <tt>:lock => 'some locking clause'</tt> to give a database-specific locking clause
# Pass <tt>lock: 'some locking clause'</tt> to give a database-specific locking clause
# of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'. Example:
#
# Account.transaction do

View File

@ -285,7 +285,7 @@ module ActiveRecord
#
# JobLevel.reset_column_information
# %w{assistant executive manager director}.each do |type|
# JobLevel.create(:name => type)
# JobLevel.create(name: type)
# end
# end
#

View File

@ -50,14 +50,14 @@ module ActiveRecord
# Enabling nested attributes on a one-to-one association allows you to
# create the member and avatar in one go:
#
# params = { :member => { :name => 'Jack', :avatar_attributes => { :icon => 'smiling' } } }
# params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } }
# member = Member.create(params[:member])
# member.avatar.id # => 2
# member.avatar.icon # => 'smiling'
#
# It also allows you to update the avatar through the member:
#
# params = { :member => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }
# params = { member: { avatar_attributes: { id: '2', icon: 'sad' } } }
# member.update_attributes params[:member]
# member.avatar.icon # => 'sad'
#
@ -68,13 +68,13 @@ module ActiveRecord
#
# class Member < ActiveRecord::Base
# has_one :avatar
# accepts_nested_attributes_for :avatar, :allow_destroy => true
# accepts_nested_attributes_for :avatar, allow_destroy: true
# end
#
# Now, when you add the <tt>_destroy</tt> key to the attributes hash, with a
# value that evaluates to +true+, you will destroy the associated model:
#
# member.avatar_attributes = { :id => '2', :_destroy => '1' }
# member.avatar_attributes = { id: '2', _destroy: '1' }
# member.avatar.marked_for_destruction? # => true
# member.save
# member.reload.avatar # => nil
@ -97,11 +97,11 @@ module ActiveRecord
# be instantiated, unless the hash also contains a <tt>_destroy</tt> key
# that evaluates to +true+.
#
# params = { :member => {
# :name => 'joe', :posts_attributes => [
# { :title => 'Kari, the awesome Ruby documentation browser!' },
# { :title => 'The egalitarian assumption of the modern citizen' },
# { :title => '', :_destroy => '1' } # this will be ignored
# params = { member: {
# name: 'joe', posts_attributes: [
# { title: 'Kari, the awesome Ruby documentation browser!' },
# { title: 'The egalitarian assumption of the modern citizen' },
# { title: '', _destroy: '1' } # this will be ignored
# ]
# }}
#
@ -116,14 +116,14 @@ module ActiveRecord
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, :reject_if => proc { |attributes| attributes['title'].blank? }
# accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? }
# end
#
# params = { :member => {
# :name => 'joe', :posts_attributes => [
# { :title => 'Kari, the awesome Ruby documentation browser!' },
# { :title => 'The egalitarian assumption of the modern citizen' },
# { :title => '' } # this will be ignored because of the :reject_if proc
# params = { member: {
# name: 'joe', posts_attributes: [
# { title: 'Kari, the awesome Ruby documentation browser!' },
# { title: 'The egalitarian assumption of the modern citizen' },
# { title: '' } # this will be ignored because of the :reject_if proc
# ]
# }}
#
@ -136,12 +136,12 @@ module ActiveRecord
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, :reject_if => :new_record?
# accepts_nested_attributes_for :posts, reject_if: :new_record?
# end
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, :reject_if => :reject_posts
# accepts_nested_attributes_for :posts, reject_if: :reject_posts
#
# def reject_posts(attributed)
# attributed['title'].blank?
@ -152,10 +152,10 @@ module ActiveRecord
# associated record, the matching record will be modified:
#
# member.attributes = {
# :name => 'Joe',
# :posts_attributes => [
# { :id => 1, :title => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
# { :id => 2, :title => '[UPDATED] other post' }
# name: 'Joe',
# posts_attributes: [
# { id: 1, title: '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
# { id: 2, title: '[UPDATED] other post' }
# ]
# }
#
@ -170,11 +170,11 @@ module ActiveRecord
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, :allow_destroy => true
# accepts_nested_attributes_for :posts, allow_destroy: true
# end
#
# params = { :member => {
# :posts_attributes => [{ :id => '2', :_destroy => '1' }]
# params = { member: {
# posts_attributes: [{ id: '2', _destroy: '1' }]
# }}
#
# member.attributes = params[:member]
@ -197,12 +197,12 @@ module ActiveRecord
# <tt>inverse_of</tt> as this example illustrates:
#
# class Member < ActiveRecord::Base
# has_many :posts, :inverse_of => :member
# has_many :posts, inverse_of: :member
# accepts_nested_attributes_for :posts
# end
#
# class Post < ActiveRecord::Base
# belongs_to :member, :inverse_of => :posts
# belongs_to :member, inverse_of: :posts
# validates_presence_of :member
# end
module ClassMethods
@ -248,11 +248,11 @@ module ActiveRecord
#
# Examples:
# # creates avatar_attributes=
# accepts_nested_attributes_for :avatar, :reject_if => proc { |attributes| attributes['name'].blank? }
# accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
# # creates avatar_attributes=
# accepts_nested_attributes_for :avatar, :reject_if => :all_blank
# accepts_nested_attributes_for :avatar, reject_if: :all_blank
# # creates avatar_attributes= and posts_attributes=
# accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true
# accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
def accepts_nested_attributes_for(*attr_names)
options = { :allow_destroy => false, :update_only => false }
options.update(attr_names.extract_options!)
@ -348,9 +348,9 @@ module ActiveRecord
# For example:
#
# assign_nested_attributes_for_collection_association(:people, {
# '1' => { :id => '1', :name => 'Peter' },
# '2' => { :name => 'John' },
# '3' => { :id => '2', :_destroy => true }
# '1' => { id: '1', name: 'Peter' },
# '2' => { name: 'John' },
# '3' => { id: '2', _destroy: true }
# })
#
# Will update the name of the Person with ID 1, build a new associated
@ -360,9 +360,9 @@ module ActiveRecord
# Also accepts an Array of attribute hashes:
#
# assign_nested_attributes_for_collection_association(:people, [
# { :id => '1', :name => 'Peter' },
# { :name => 'John' },
# { :id => '2', :_destroy => true }
# { id: '1', name: 'Peter' },
# { name: 'John' },
# { id: '2', _destroy: true }
# ])
def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
options = self.nested_attributes_options[association_name]

View File

@ -486,7 +486,7 @@ module ActiveRecord
# Returns a hash of where conditions
#
# Users.where(name: 'Oscar').where_values_hash
# # => {:name=>"oscar"}
# # => {name: "oscar"}
def where_values_hash
equalities = with_default_scope.where_values.grep(Arel::Nodes::Equality).find_all { |node|
node.left.relation.name == table_name

View File

@ -145,7 +145,7 @@ module ActiveRecord
# # SELECT DISTINCT role FROM people
# # => ['admin', 'member', 'guest']
#
# Person.where(:age => 21).limit(5).pluck(:id)
# Person.where(age: 21).limit(5).pluck(:id)
# # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
# # => [2, 3]
#

View File

@ -76,7 +76,7 @@ module ActiveRecord
#
# Person.first # returns the first object fetched by SELECT * FROM people
# Person.where(["user_name = ?", user_name]).first
# Person.where(["user_name = :u", { :u => user_name }]).first
# Person.where(["user_name = :u", { u: user_name }]).first
# Person.order("created_on DESC").offset(5).first
# Person.first(3) # returns the first three objects fetched by SELECT * FROM people LIMIT 3
def first(limit = nil)

View File

@ -36,10 +36,10 @@ module ActiveRecord
queries = []
# Find the foreign key when using queries such as:
# Post.where(:author => author)
# Post.where(author: author)
#
# For polymorphic relationships, find the foreign key and type:
# PriceEstimate.where(:estimate_of => treasure)
# PriceEstimate.where(estimate_of: treasure)
if klass && value.class < Base && reflection = klass.reflect_on_association(column.to_sym)
if reflection.polymorphic?
queries << build(table[reflection.foreign_type], value.class.base_class)

View File

@ -355,17 +355,17 @@ module ActiveRecord
# author = Author.find(1)
#
# # The following queries will be equivalent:
# Post.where(:author => author)
# Post.where(:author_id => author)
# Post.where(author: author)
# Post.where(author_id: author)
#
# This also works with polymorphic belongs_to relationships:
#
# treasure = Treasure.create(:name => 'gold coins')
# treasure.price_estimates << PriceEstimate.create(:price => 125)
# treasure = Treasure.create(name: 'gold coins')
# treasure.price_estimates << PriceEstimate.create(price: 125)
#
# # The following queries will be equivalent:
# PriceEstimate.where(:estimate_of => treasure)
# PriceEstimate.where(:estimate_of_type => 'Treasure', :estimate_of_id => treasure)
# PriceEstimate.where(estimate_of: treasure)
# PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)
#
# === Joins
#
@ -377,7 +377,7 @@ module ActiveRecord
# For hash conditions, you can either use the table name in the key, or use a sub-hash.
#
# User.joins(:posts).where({ "posts.published" => true })
# User.joins(:posts).where({ :posts => { :published => true } })
# User.joins(:posts).where({ posts: { published: true } })
#
# === empty condition
#
@ -476,13 +476,13 @@ module ActiveRecord
#
# For example:
#
# @posts = current_user.visible_posts.where(:name => params[:name])
# @posts = current_user.visible_posts.where(name: params[:name])
# # => the visible_posts method is expected to return a chainable Relation
#
# def visible_posts
# case role
# when 'Country Manager'
# Post.where(:country => country)
# Post.where(country: country)
# when 'Reviewer'
# Post.published
# when 'Bad User'

View File

@ -15,11 +15,11 @@ module ActiveRecord
#
# ==== Examples
#
# Post.where(:published => true).joins(:comments).merge( Comment.where(:spam => false) )
# Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
# # Performs a single join query with both where conditions.
#
# recent_posts = Post.order('created_at DESC').first(5)
# Post.where(:published => true).merge(recent_posts)
# Post.where(published: true).merge(recent_posts)
# # Returns the intersection of all published posts with the 5 most recently created posts.
# # (This is just an example. You'd probably want to do this with a single query!)
#

View File

@ -17,7 +17,7 @@ module ActiveRecord
# Accepts an array, hash, or string of SQL conditions and sanitizes
# them into a valid SQL fragment for a WHERE clause.
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
# { name: "foo'bar", group_id: 4 } returns "name='foo''bar' and group_id='4'"
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
def sanitize_sql_for_conditions(condition, table_name = self.table_name)
return nil if condition.blank?
@ -32,7 +32,7 @@ module ActiveRecord
# Accepts an array, hash, or string of SQL conditions and sanitizes
# them into a valid SQL fragment for a SET clause.
# { :name => nil, :group_id => 4 } returns "name = NULL , group_id='4'"
# { name: nil, group_id: 4 } returns "name = NULL , group_id='4'"
def sanitize_sql_for_assignment(assignments)
case assignments
when Array; sanitize_sql_array(assignments)
@ -46,12 +46,12 @@ module ActiveRecord
# aggregate attribute values.
# Given:
# class Person < ActiveRecord::Base
# composed_of :address, :class_name => "Address",
# :mapping => [%w(address_street street), %w(address_city city)]
# composed_of :address, class_name: "Address",
# mapping: [%w(address_street street), %w(address_city city)]
# end
# Then:
# { :address => Address.new("813 abc st.", "chicago") }
# # => { :address_street => "813 abc st.", :address_city => "chicago" }
# { address: Address.new("813 abc st.", "chicago") }
# # => { address_street: "813 abc st.", address_city: "chicago" }
def expand_hash_conditions_for_aggregates(attrs)
expanded_attrs = {}
attrs.each do |attr, value|
@ -72,18 +72,18 @@ module ActiveRecord
end
# Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.
# { :name => "foo'bar", :group_id => 4 }
# { name: "foo'bar", group_id: 4 }
# # => "name='foo''bar' and group_id= 4"
# { :status => nil, :group_id => [1,2,3] }
# { status: nil, group_id: [1,2,3] }
# # => "status IS NULL and group_id IN (1,2,3)"
# { :age => 13..18 }
# { age: 13..18 }
# # => "age BETWEEN 13 AND 18"
# { 'other_records.id' => 7 }
# # => "`other_records`.`id` = 7"
# { :other_records => { :id => 7 } }
# { other_records: { id: 7 } }
# # => "`other_records`.`id` = 7"
# And for value objects on a composed_of relationship:
# { :address => Address.new("123 abc st.", "chicago") }
# { address: Address.new("123 abc st.", "chicago") }
# # => "address_street='123 abc st.' and address_city='chicago'"
def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name)
attrs = expand_hash_conditions_for_aggregates(attrs)
@ -96,7 +96,7 @@ module ActiveRecord
alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
# Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
# { :status => nil, :group_id => 1 }
# { status: nil, group_id: 1 }
# # => "status = NULL , group_id = 1"
def sanitize_sql_hash_for_assignment(attrs)
attrs.map do |attr, value|

View File

@ -36,7 +36,7 @@ module ActiveRecord #:nodoc:
#
# For instance:
#
# topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])
# topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ])
#
# <topic>
# <title>The First Topic</title>
@ -50,7 +50,7 @@ module ActiveRecord #:nodoc:
#
# To include first level associations use <tt>:include</tt>:
#
# firm.to_xml :include => [ :account, :clients ]
# firm.to_xml include: [ :account, :clients ]
#
# <?xml version="1.0" encoding="UTF-8"?>
# <firm>
@ -81,7 +81,7 @@ module ActiveRecord #:nodoc:
# associated with models.
#
# proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
# firm.to_xml :procs => [ proc ]
# firm.to_xml procs: [ proc ]
#
# <firm>
# # ... normal attributes as shown above ...
@ -90,7 +90,7 @@ module ActiveRecord #:nodoc:
#
# To include deeper levels of associations pass a hash like this:
#
# firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
# firm.to_xml include: {account: {}, clients: {include: :address}}
# <?xml version="1.0" encoding="UTF-8"?>
# <firm>
# <id type="integer">1</id>
@ -120,7 +120,7 @@ module ActiveRecord #:nodoc:
#
# To include any methods on the model being called use <tt>:methods</tt>:
#
# firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
# firm.to_xml methods: [ :calculated_earnings, :real_earnings ]
#
# <firm>
# # ... normal attributes as shown above ...
@ -132,7 +132,7 @@ module ActiveRecord #:nodoc:
# modified version of the options hash that was given to +to_xml+:
#
# proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
# firm.to_xml :procs => [ proc ]
# firm.to_xml procs: [ proc ]
#
# <firm>
# # ... normal attributes as shown above ...
@ -164,7 +164,7 @@ module ActiveRecord #:nodoc:
# def to_xml(options = {})
# require 'builder'
# options[:indent] ||= 2
# xml = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
# xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent])
# xml.instruct! unless options[:skip_instruct]
# xml.level_one do
# xml.tag!(:second_level, 'content')

View File

@ -108,10 +108,10 @@ module ActiveRecord
#
# # Suppose that we have a Number model with a unique column called 'i'.
# Number.transaction do
# Number.create(:i => 0)
# Number.create(i: 0)
# begin
# # This will raise a unique constraint error...
# Number.create(:i => 0)
# Number.create(i: 0)
# rescue ActiveRecord::StatementInvalid
# # ...which we ignore.
# end
@ -119,7 +119,7 @@ module ActiveRecord
# # On PostgreSQL, the transaction is now unusable. The following
# # statement will cause a PostgreSQL error, even though the unique
# # constraint is no longer violated:
# Number.create(:i => 1)
# Number.create(i: 1)
# # => "PGError: ERROR: current transaction is aborted, commands
# # ignored until end of transaction block"
# end
@ -134,9 +134,9 @@ module ActiveRecord
# transaction. For example, the following behavior may be surprising:
#
# User.transaction do
# User.create(:username => 'Kotori')
# User.create(username: 'Kotori')
# User.transaction do
# User.create(:username => 'Nemu')
# User.create(username: 'Nemu')
# raise ActiveRecord::Rollback
# end
# end
@ -147,14 +147,14 @@ module ActiveRecord
# real transaction is committed.
#
# In order to get a ROLLBACK for the nested transaction you may ask for a real
# sub-transaction by passing <tt>:requires_new => true</tt>. If anything goes wrong,
# sub-transaction by passing <tt>requires_new: true</tt>. If anything goes wrong,
# the database rolls back to the beginning of the sub-transaction without rolling
# back the parent transaction. If we add it to the previous example:
#
# User.transaction do
# User.create(:username => 'Kotori')
# User.transaction(:requires_new => true) do
# User.create(:username => 'Nemu')
# User.create(username: 'Kotori')
# User.transaction(requires_new: true) do
# User.create(username: 'Nemu')
# raise ActiveRecord::Rollback
# end
# end
@ -194,7 +194,7 @@ module ActiveRecord
# automatically released. The following example demonstrates the problem:
#
# Model.connection.transaction do # BEGIN
# Model.connection.transaction(:requires_new => true) do # CREATE SAVEPOINT active_record_1
# Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
# Model.connection.create_table(...) # active_record_1 now automatically released
# end # RELEASE savepoint active_record_1
# # ^^^^ BOOM! database error!
@ -213,13 +213,13 @@ module ActiveRecord
# You can specify that the callback should only be fired by a certain action with
# the +:on+ option:
#
# after_commit :do_foo, :on => :create
# after_commit :do_bar, :on => :update
# after_commit :do_baz, :on => :destroy
# after_commit :do_foo, on: :create
# after_commit :do_bar, on: :update
# after_commit :do_baz, on: :destroy
#
# Also, to have the callback fired on create and update, but not on destroy:
#
# after_commit :do_zoo, :if => :persisted?
# after_commit :do_zoo, if: :persisted?
#
# Note that transactional fixtures do not play well with this feature. Please
# use the +test_after_commit+ gem to have these hooks fired in tests.

View File

@ -4,7 +4,9 @@ module ActiveSupport
# module M
# def self.included(base)
# base.extend ClassMethods
# scope :disabled, -> { where(disabled: true) }
# base.class_eval do
# scope :disabled, -> { where(disabled: true) }
# end
# end
#
# module ClassMethods
@ -77,10 +79,8 @@ module ActiveSupport
# module Foo
# extend ActiveSupport::Concern
# included do
# class_eval do
# def self.method_injected_by_foo
# ...
# end
# def self.method_injected_by_foo
# ...
# end
# end
# end

View File

@ -84,15 +84,15 @@ module ActiveSupport
# resulting in the following output within the logs including a hash with the payload:
#
# notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
# :controller=>"Devise::SessionsController",
# :action=>"new",
# :params=>{"action"=>"new", "controller"=>"devise/sessions"},
# :format=>:html,
# :method=>"GET",
# :path=>"/login/sign_in",
# :status=>200,
# :view_runtime=>279.3080806732178,
# :db_runtime=>40.053
# controller: "Devise::SessionsController",
# action: "new",
# params: {"action"=>"new", "controller"=>"devise/sessions"},
# format: :html,
# method: "GET",
# path: "/login/sign_in",
# status: 200,
# view_runtime: 279.3080806732178,
# db_runtime: 40.053
# }
#
# You can also subscribe to all events whose name matches a certain regexp:

View File

@ -81,7 +81,7 @@ class ClientsController < ActionController::Base
else
# This line overrides the default rendering behavior, which
# would have been to render the "create" view.
render action: "new"
render "new"
end
end
end
@ -179,9 +179,9 @@ Your application has a session for each user in which you can store small amount
All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure).
For most stores this ID is used to look up the session data on the server, e.g. in a database table. There is one exception, and that is the default and recommended session store - the CookieStore - which stores all session data in the cookie itself (the ID is still available to you if you need it). This has the advantage of being very lightweight and it requires zero setup in a new application in order to use the session. The cookie data is cryptographically signed to make it tamper-proof, but it is not encrypted, so anyone with access to it can read its contents but not edit it (Rails will not accept it if it has been edited).
For most stores, this ID is used to look up the session data on the server, e.g. in a database table. There is one exception, and that is the default and recommended session store - the CookieStore - which stores all session data in the cookie itself (the ID is still available to you if you need it). This has the advantage of being very lightweight and it requires zero setup in a new application in order to use the session. The cookie data is cryptographically signed to make it tamper-proof, but it is not encrypted, so anyone with access to it can read its contents but not edit it (Rails will not accept it if it has been edited).
The CookieStore can store around 4kB of data -- much less than the others -- but this is usually enough. Storing large amounts of data in the session is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error.
The CookieStore can store around 4kB of data — much less than the others — but this is usually enough. Storing large amounts of data in the session is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error.
If your user sessions don't store critical data or don't need to be around for long periods (for instance if you just use the flash for messaging), you can consider using ActionDispatch::Session::CacheStore. This will store sessions using the cache implementation you have configured for your application. The advantage of this is that you can use your existing cache infrastructure for storing sessions without requiring any additional setup or administration. The downside, of course, is that the sessions will be ephemeral and could disappear at any time.
@ -371,13 +371,13 @@ end
Cookies
-------
Your application can store small amounts of data on the client -- called cookies -- that will be persisted across requests and even sessions. Rails provides easy access to cookies via the `cookies` method, which -- much like the `session` -- works like a hash:
Your application can store small amounts of data on the client — called cookies — that will be persisted across requests and even sessions. Rails provides easy access to cookies via the `cookies` method, which — much like the `session` works like a hash:
```ruby
class CommentsController < ApplicationController
def new
# Auto-fill the commenter's name if it has been stored in a cookie
@comment = Comment.new(name: cookies[:commenter_name])
@comment = Comment.new(author: cookies[:commenter_name])
end
def create
@ -386,7 +386,7 @@ class CommentsController < ApplicationController
flash[:notice] = "Thanks for your comment!"
if params[:remember_name]
# Remember the commenter's name.
cookies[:commenter_name] = @comment.name
cookies[:commenter_name] = @comment.author
else
# Delete cookie for the commenter's name cookie, if any.
cookies.delete(:commenter_name)
@ -404,7 +404,7 @@ Note that while for session values you set the key to `nil`, to delete a cookie
Rendering xml and json data
---------------------------
ActionController makes it extremely easy to render `xml` or `json` data. If you generate a controller using scaffold then your controller would look something like this.
ActionController makes it extremely easy to render `xml` or `json` data. If you generate a controller using scaffolding then it would look something like this:
```ruby
class UsersController < ApplicationController
@ -428,7 +428,7 @@ Filters are methods that are run before, after or "around" a controller action.
Filters are inherited, so if you set a filter on `ApplicationController`, it will be run on every controller in your application.
Before filters may halt the request cycle. A common before filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:
"Before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:
```ruby
class ApplicationController < ActionController::Base
@ -454,7 +454,7 @@ class ApplicationController < ActionController::Base
end
```
The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a before filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter they are also cancelled.
The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a "before" filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.
In this example the filter is added to `ApplicationController` and thus all controllers in the application inherit it. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn't be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with `skip_before_filter`:
@ -468,11 +468,11 @@ Now, the `LoginsController`'s `new` and `create` actions will work as before wit
### After Filters and Around Filters
In addition to before filters, you can also run filters after an action has been executed, or both before and after.
In addition to "before" filters, you can also run filters after an action has been executed, or both before and after.
After filters are similar to before filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, after filters cannot stop the action from running.
"After" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running.
Around filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
"Around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:
@ -494,7 +494,7 @@ class ChangesController < ActionController::Base
end
```
Note that an around filter also wraps rendering. In particular, if in the example above, the view itself reads from the database (e.g. via a scope), it will do so within the transaction and thus present the data to preview.
Note that an "around" filter also wraps rendering. In particular, if in the example above, the view itself reads from the database (e.g. via a scope), it will do so within the transaction and thus present the data to preview.
You can choose not to yield and build the response yourself, in which case the action will not be run.
@ -616,6 +616,8 @@ If you want to set custom headers for a response then `response.headers` is the
response.headers["Content-Type"] = "application/pdf"
```
Note: in the above case it would make more sense to use the `content_type` setter directly.
HTTP Authentications
--------------------
@ -711,7 +713,7 @@ This will read and stream the file 4kB at the time, avoiding loading the entire
If `:type` is not specified, it will be guessed from the file extension specified in `:filename`. If the content type is not registered for the extension, `application/octet-stream` will be used.
WARNING: Be careful when using data coming from the client (params, cookies, etc.) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to see.
WARNING: Be careful when using data coming from the client (params, cookies, etc.) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to.
TIP: It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack.
@ -824,7 +826,7 @@ NOTE: Certain exceptions are only rescuable from the `ApplicationController` cla
Force HTTPS protocol
--------------------
Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. Since Rails 3.1 you can now use `force_ssl` method in your controller to enforce that:
Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. Since Rails 3.1 you can now use the `force_ssl` method in your controller to enforce that:
```ruby
class DinnerController
@ -832,7 +834,7 @@ class DinnerController
end
```
Just like the filter, you could also passing `:only` and `:except` to enforce the secure connection only to specific actions.
Just like the filter, you could also passing `:only` and `:except` to enforce the secure connection only to specific actions:
```ruby
class DinnerController
@ -842,4 +844,4 @@ class DinnerController
end
```
Please note that if you found yourself adding `force_ssl` to many controllers, you may found yourself wanting to force the whole application to use HTTPS instead. In that case, you can set the `config.force_ssl` in your environment file.
Please note that if you find yourself adding `force_ssl` to many controllers, you may want to force the whole application to use HTTPS instead. In that case, you can set the `config.force_ssl` in your environment file.

View File

@ -293,7 +293,7 @@ class UserMailer < ActionMailer::Base
end
```
In this case it will look for templates at `app/views/notifications` with name `another`.
In this case it will look for templates at `app/views/notifications` with name `another`. You can also specify an array of paths for `template_path`, and they will be searched in order.
If you want more flexibility you can also pass a block and render specific templates or even render inline or text without using a template file:

View File

@ -3,11 +3,11 @@ Action View Overview
In this guide you will learn:
* What Action View is, and how to use it with Rails
* How to use Action View outside of Rails
* What Action View is and how to use it with Rails
* How best to use templates, partials, and layouts
* What helpers are provided by Action View, and how to make your own
* What helpers are provided by Action View and how to make your own
* How to use localized views
* How to use Action View outside of Rails
--------------------------------------------------------------------------------
@ -18,7 +18,7 @@ Action View and Action Controller are the two major components of Action Pack. I
Action View templates are written using embedded Ruby in tags mingled with HTML. To avoid cluttering the templates with boilerplate code, a number of helper classes provide common behavior for forms, dates, and strings. It's also easy to add new helpers to your application as it evolves.
NOTE. Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
NOTE: Some features of Action View are tied to Active Record, but that doesn't mean Action View depends on Active Record. Action View is an independent package that can be used with any sort of Ruby libraries.
Using Action View with Rails
----------------------------
@ -44,82 +44,14 @@ $ rails generate scaffold post
There is a naming convention for views in Rails. Typically, the views share their name with the associated controller action, as you can see above.
For example, the index controller action of the `posts_controller.rb` will use the `index.html.erb` view file in the `app/views/posts` directory.
The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference. Later on this guide you can find a more detailed documentation of each one of this three components.
The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference. Later on this guide you can find a more detailed documentation of each one of these three components.
Using Action View outside of Rails
----------------------------------
Action View works well with Action Record, but it can also be used with other Ruby tools. We can demonstrate this by creating a small [Rack](http://rack.rubyforge.org/) application that includes Action View functionality. This may be useful, for example, if you'd like access to Action View's helpers in a Rack application.
Let's start by ensuring that you have the Action Pack and Rack gems installed:
```bash
$ gem install actionpack
$ gem install rack
```
Now we'll create a simple "Hello World" application that uses the `titleize` method provided by Active Support.
**hello_world.rb:**
```ruby
require 'active_support/core_ext/string/inflections'
require 'rack'
def hello_world(env)
[200, {"Content-Type" => "text/html"}, "hello world".titleize]
end
Rack::Handler::Mongrel.run method(:hello_world), :Port => 4567
```
We can see this all come together by starting up the application and then visiting `http://localhost:4567/`
```bash
$ ruby hello_world.rb
```
TODO needs a screenshot? I have one - not sure where to put it.
Notice how 'hello world' has been converted into 'Hello World' by the `titleize` helper method.
Action View can also be used with [Sinatra](http://www.sinatrarb.com/) in the same way.
Let's start by ensuring that you have the Action Pack and Sinatra gems installed:
```bash
$ gem install actionpack
$ gem install sinatra
```
Now we'll create the same "Hello World" application in Sinatra.
**hello_world.rb:**
```ruby
require 'action_view'
require 'sinatra'
get '/' do
erb 'hello world'.titleize
end
```
Then, we can run the application:
```bash
$ ruby hello_world.rb
```
Once the application is running, you can see Sinatra and Action View working together by visiting `http://localhost:4567/`
TODO needs a screenshot? I have one - not sure where to put it.
Templates, Partials and Layouts
-------------------------------
As mentioned before, the final HTML output is a composition of three Rails elements: `Templates`, `Partials` and `Layouts`.
Find below a brief overview of each one of them.
Below is a brief overview of each one of them.
### Templates
@ -129,18 +61,18 @@ Rails supports multiple template systems and uses a file extension to distinguis
#### ERB
Within an ERB template Ruby code can be included using both `<% %>` and `<%= %>` tags. The `<% %>` are used to execute Ruby code that does not return anything, such as conditions, loops or blocks, and the `<%= %>` tags are used when you want output.
Within an ERB template, Ruby code can be included using both `<% %>` and `<%= %>` tags. The `<% %>` tags are used to execute Ruby code that does not return anything, such as conditions, loops or blocks, and the `<%= %>` tags are used when you want output.
Consider the following loop for names:
```html+erb
<b>Names of all the people</b>
<h1>Names of all the people</h1>
<% @people.each do |person| %>
Name: <%= person.name %><br/>
<% end %>
```
The loop is setup in regular embedding tags `<% %>` and the name is written using the output embedding tag `<%= %>`. Note that this is not just a usage suggestion, for Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
The loop is set up in regular embedding tags (`<% %>`) and the name is written using the output embedding tags (`<%= %>`). Note that this is not just a usage suggestion, for regular output functions like `print` or `puts` won't work with ERB templates. So this would be wrong:
```html+erb
<%# WRONG %>
@ -158,11 +90,11 @@ Here are some basic examples:
```ruby
xml.em("emphasized")
xml.em { xml.b("emph & bold") }
xml.a("A Link", "href"=>"http://rubyonrails.org")
xml.target("name"=>"compile", "option"=>"fast")
xml.a("A Link", "href" => "http://rubyonrails.org")
xml.target("name" => "compile", "option" => "fast")
```
will produce
which would produce:
```html
<em>emphasized</em>
@ -189,7 +121,7 @@ would produce something like:
</div>
```
A full-length RSS example actually used on Basecamp:
Below is a full-length RSS example actually used on Basecamp:
```ruby
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
@ -220,7 +152,7 @@ By default, Rails will compile each template to a method in order to render it.
### Partials
Partial templates usually just called "partials" are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
Partial templates usually just called "partials" are another device for breaking the rendering process into more manageable chunks. With partials, you can extract pieces of code from your templates to separate files and also reuse them throughout your templates.
#### Naming Partials
@ -230,7 +162,7 @@ To render a partial as part of a view, you use the `render` method within the vi
<%= render "menu" %>
```
This will render a file named `_menu.html.erb` at that point within the view is being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore. This holds true even when you're pulling in a partial from another folder:
This will render a file named `_menu.html.erb` at that point within the view that is being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore. This holds true even when you're pulling in a partial from another folder:
```erb
<%= render "shared/menu" %>
@ -249,7 +181,7 @@ One way to use partials is to treat them as the equivalent of subroutines: as a
<p>Here are a few of our fine products:</p>
<% @products.each do |product| %>
<%= render :partial => "product", :locals => { :product => product } %>
<%= render partial: "product", locals: {product: product} %>
<% end %>
<%= render "shared/footer" %>
@ -257,76 +189,89 @@ One way to use partials is to treat them as the equivalent of subroutines: as a
Here, the `_ad_banner.html.erb` and `_footer.html.erb` partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
#### The :as and :object options
#### The `as` and `object` options
By default `ActionView::Partials::PartialRenderer` has its object in a local variable with the same name as the template. So, given
By default `ActionView::Partials::PartialRenderer` has its object in a local variable with the same name as the template. So, given:
```erb
<%= render :partial => "product" %>
<%= render partial: "product" %>
```
within product we'll get `@product` in the local variable `product`, as if we had written:
```erb
<%= render :partial => "product", :locals => { :product => @product } %>
<%= render partial: "product", locals: {product: @product} %>
```
With the `:as` option we can specify a different name for said local variable. For example, if we wanted it to be `item` instead of product+ we'd do:
With the `as` option we can specify a different name for the local variable. For example, if we wanted it to be `item` instead of `product` we would do:
```erb
<%= render :partial => "product", :as => 'item' %>
<%= render partial: "product", as: "item" %>
```
The `:object` option can be used to directly specify which object is rendered into the partial; useful when the template's object is elsewhere, in a different ivar or in a local variable for instance.
The `object` option can be used to directly specify which object is rendered into the partial; useful when the template's object is elsewhere (eg. in a different instance variable or in a local variable).
For example, instead of:
```erb
<%= render :partial => "product", :locals => { :product => @item } %>
<%= render partial: "product", locals: {product: @item} %>
```
you'd do:
we would do:
```erb
<%= render :partial => "product", :object => @item %>
<%= render partial: "product", object: @item %>
```
The `:object` and `:as` options can be used together.
The `object` and `as` options can also be used together:
```erb
<%= render partial: "product", object: @item, as: "item" %>
```
#### Rendering Collections
The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within.
So the three-lined example for rendering all the products can be rewritten with a single line:
It is very common that a template needs to iterate over a collection and render a sub-template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial for each one of the elements in the array.
So this example for rendering all the products:
```erb
<%= render :partial => "product", :collection => @products %>
<% @products.each do |product| %>
<%= render partial: "product", locals: { product: product } %>
<% end %>
```
When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is `_product` , and within the `_product` partial, you can refer to `product` to get the instance that is being rendered.
can be rewritten in a single line:
You can use a shorthand syntax for rendering collections. Assuming @products is a collection of `Product` instances, you can simply write the following to produce the same result:
```erb
<%= render partial: "product", collection: @products %>
```
When a partial is called like this (eg. with a collection), the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is `_product`, and within it you can refer to `product` to get the instance that is being rendered.
You can use a shorthand syntax for rendering collections. Assuming `@products` is a collection of `Product` instances, you can simply write the following to produce the same result:
```erb
<%= render @products %>
```
Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection.
Rails determines the name of the partial to use by looking at the model name in the collection, `Product` in this case. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection.
#### Spacer Templates
You can also specify a second partial to be rendered between instances of the main partial by using the `:spacer_template` option:
```erb
<%= render @products, :spacer_template => "product_ruler" %>
<%= render @products, spacer_template: "product_ruler" %>
```
Rails will render the `_product_ruler` partial (with no data passed in to it) between each pair of `_product` partials.
Rails will render the `_product_ruler` partial (with no data passed to it) between each pair of `_product` partials.
### Layouts
TODO...
Using Templates, Partials and Layouts in "The Rails Way"
Using Templates, Partials and Layouts "The Rails Way"
--------------------------------------------------------
TODO...
@ -336,21 +281,21 @@ Partial Layouts
Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally for the entire action, but they work in a similar fashion.
Let's say we're displaying a post on a page where it should be wrapped in a `div` for display purposes. First, we'll create a new `Post`:
Let's say we're displaying a post on a page, that should be wrapped in a `div` for display purposes. First, we'll create a new `Post`:
```ruby
Post.create(:body => 'Partial Layouts are cool!')
Post.create(body: 'Partial Layouts are cool!')
```
In the `show` template, we'll render the `post` partial wrapped in the `box` layout:
In the `show` template, we'll render the `_post` partial wrapped in the `box` layout:
**posts/show.html.erb**
```erb
<%= render :partial => 'post', :layout => 'box', :locals => {:post => @post} %>
<%= render partial: 'post', layout: 'box', locals: {post: @post} %>
```
The `box` layout simply wraps the `post` partial in a `div`:
The `box` layout simply wraps the `_post` partial in a `div`:
**posts/_box.html.erb**
@ -360,7 +305,7 @@ The `box` layout simply wraps the `post` partial in a `div`:
</div>
```
The `post` partial wraps the post's `body` in a `div` with the `id` of the post using the `div_for` helper:
The `_post` partial wraps the post's `body` in a `div` with the `id` of the post using the `div_for` helper:
**posts/_post.html.erb**
@ -370,7 +315,7 @@ The `post` partial wraps the post's `body` in a `div` with the `id` of the post
<% end %>
```
This example would output the following:
this would output the following:
```html
<div class='box'>
@ -382,84 +327,31 @@ This example would output the following:
Note that the partial layout has access to the local `post` variable that was passed into the `render` call. However, unlike application-wide layouts, partial layouts still have the underscore prefix.
You can also render a block of code within a partial layout instead of calling `yield`. For example, if we didn't have the `post` partial, we could do this instead:
You can also render a block of code within a partial layout instead of calling `yield`. For example, if we didn't have the `_post` partial, we could do this instead:
**posts/show.html.erb**
```html+erb
<% render(:layout => 'box', :locals => {:post => @post}) do %>
<% render(layout: 'box', locals: {post: @post}) do %>
<%= div_for(post) do %>
<p><%= post.body %></p>
<% end %>
<% end %>
```
If we're using the same `box` partial from above, his would produce the same output as the previous example.
Supposing we use the same `_box` partial from above, this would produce the same output as the previous example.
View Paths
----------
TODO...
Overview of all the helpers provided by Action View
---------------------------------------------------
Overview of helpers provided by Action View
-------------------------------------------
The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the API Documentation, which covers all of the helpers in more detail, but this should serve as a good starting point.
WIP: Not all the helpers are listed here. For a full list see the [API documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html)
### ActiveRecordHelper
The Active Record Helper makes it easier to create forms for records kept in instance variables. You may also want to review the [Rails Form helpers guide](form_helpers.html).
#### error_message_on
Returns a string containing the error message attached to the method on the object if one exists.
```ruby
error_message_on "post", "title"
```
#### error_messages_for
Returns a string with a DIV containing all of the error messages for the objects located as instance variables by the names given.
```ruby
error_messages_for "post"
```
#### form
Returns a form with inputs for all attributes of the specified Active Record object. For example, let's say we have a `@post` with attributes named `title` of type `String` and `body` of type `Text`. Calling `form` would produce a form to creating a new post with inputs for those attributes.
```ruby
form("post")
```
```html
<form action='/posts/create' method='post'>
<p>
<label for="post_title">Title</label><br />
<input id="post_title" name="post[title]" type="text" value="Hello World" />
</p>
<p>
<label for="post_body">Body</label><br />
<textarea id="post_body" name="post[body]"></textarea>
</p>
<input name="commit" type="submit" value="Create" />
</form>
```
Typically, `form_for` is used instead of `form` because it doesn't automatically include all of the model's attributes.
#### input
Returns a default input tag for the type of object returned by the method.
For example, if `@post` has an attribute `title` mapped to a `String` column that holds "Hello World":
```ruby
input("post", "title") # =>
<input id="post_title" name="post[title]" type="text" value="Hello World" />
```
The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the [API Documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html), which covers all of the helpers in more detail, but this should serve as a good starting point.
### RecordTagHelper
@ -488,7 +380,7 @@ This will generate this HTML output:
You can also supply HTML attributes as an additional option hash. For example:
```html+erb
<%= content_tag_for(:tr, @post, :class => "frontpage") do %>
<%= content_tag_for(:tr, @post, class: "frontpage") do %>
<td><%= @post.title %></td>
<% end %>
```
@ -525,7 +417,7 @@ Will generate this HTML output:
This is actually a convenient method which calls `content_tag_for` internally with `:div` as the tag name. You can pass either an Active Record object or a collection of objects. For example:
```html+erb
<%= div_for(@post, :class => "frontpage") do %>
<%= div_for(@post, class: "frontpage") do %>
<td><%= @post.title %></td>
<% end %>
```
@ -554,7 +446,7 @@ image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png
Register one or more JavaScript files to be included when symbol is passed to javascript_include_tag. This method is typically intended to be called from plugin initialization to register JavaScript files that the plugin installed in `vendor/assets/javascripts`.
```ruby
ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]
ActionView::Helpers::AssetTagHelper.register_javascript_expansion monkey: ["head", "body", "tail"]
javascript_include_tag :monkey # =>
<script src="/assets/head.js"></script>
@ -567,7 +459,7 @@ javascript_include_tag :monkey # =>
Register one or more stylesheet files to be included when symbol is passed to `stylesheet_link_tag`. This method is typically intended to be called from plugin initialization to register stylesheet files that the plugin installed in `vendor/assets/stylesheets`.
```ruby
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion monkey: ["head", "body", "tail"]
stylesheet_link_tag :monkey # =>
<link href="/assets/head.css" media="screen" rel="stylesheet" />
@ -580,7 +472,7 @@ stylesheet_link_tag :monkey # =>
Returns a link tag that browsers and news readers can use to auto-detect an RSS or Atom feed.
```ruby
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "RSS Feed"}) # =>
auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "RSS Feed"}) # =>
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed" />
```
@ -637,7 +529,7 @@ javascript_include_tag :all
You can also cache multiple JavaScript files into one file, which requires less HTTP connections to download and can better be compressed by gzip (leading to faster transfers). Caching will only happen if `ActionController::Base.perform_caching` is set to true (which is the case by default for the Rails production environment, but not for the development environment).
```ruby
javascript_include_tag :all, :cache => true # =>
javascript_include_tag :all, cache: true # =>
<script src="/javascripts/all.js"></script>
```
@ -674,7 +566,7 @@ stylesheet_link_tag :all
You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be compressed by gzip (leading to faster transfers). Caching will only happen if ActionController::Base.perform_caching is set to true (which is the case by default for the Rails production environment, but not for the development environment).
```ruby
stylesheet_link_tag :all, :cache => true
stylesheet_link_tag :all, cache: true
# => <link href="/assets/all.css" media="screen" rel="stylesheet" />
```
@ -729,7 +621,7 @@ atom_feed do |feed|
@posts.each do |post|
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
entry.content(post.body, type: 'html')
entry.author do |author|
author.name(post.author_name)
@ -844,7 +736,7 @@ Reports the approximate distance in time between two Time or Date objects or int
```ruby
distance_of_time_in_words(Time.now, Time.now + 15.seconds) # => less than a minute
distance_of_time_in_words(Time.now, Time.now + 15.seconds, :include_seconds => true) # => less than 20 seconds
distance_of_time_in_words(Time.now, Time.now + 15.seconds, include_seconds: true) # => less than 20 seconds
```
#### select_date
@ -937,7 +829,7 @@ Returns a select tag with options for each of the five years on each side of the
select_year(Date.today)
# Generates a select field from 1900 to 2009 that defaults to the current year
select_year(Date.today, :start_year => 1900, :end_year => 2009)
select_year(Date.today, start_year: 1900, end_year: 2009)
```
#### time_ago_in_words
@ -945,7 +837,7 @@ select_year(Date.today, :start_year => 1900, :end_year => 2009)
Like `distance_of_time_in_words`, but where `to_time` is fixed to `Time.now`.
```ruby
time_ago_in_words(3.minutes.from_now) # => 3 minutes
time_ago_in_words(3.minutes.from_now) # => 3 minutes
```
#### time_select
@ -987,7 +879,7 @@ The core method of this helper, form_for, gives you the ability to create a form
```html+erb
# Note: a @person variable will have been created in the controller (e.g. @person = Person.new)
<%= form_for @person, :url => { :action => "create" } do |f| %>
<%= form_for @person, url: {action: "create"} do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= submit_tag 'Create' %>
@ -997,7 +889,7 @@ The core method of this helper, form_for, gives you the ability to create a form
The HTML generated for this would be:
```html
<form action="/persons/create" method="post">
<form action="/people/create" method="post">
<input id="person_first_name" name="person[first_name]" type="text" />
<input id="person_last_name" name="person[last_name]" type="text" />
<input name="commit" type="submit" value="Create" />
@ -1007,7 +899,7 @@ The HTML generated for this would be:
The params object created when this form is submitted would look like:
```ruby
{"action"=>"create", "controller"=>"persons", "person"=>{"first_name"=>"William", "last_name"=>"Smith"}}
{"action" => "create", "controller" => "people", "person" => {"first_name" => "William", "last_name" => "Smith"}}
```
The params hash has a nested person value, which can therefore be accessed with params[:person] in the controller.
@ -1028,7 +920,7 @@ check_box("post", "validated")
Creates a scope around a specific model object like form_for, but doesn't create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form:
```html+erb
<%= form_for @person, :url => { :action => "update" } do |person_form| %>
<%= form_for @person, url: {action: "update"} do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
@ -1104,7 +996,7 @@ radio_button("post", "category", "java")
Returns a textarea opening and closing tag set tailored for accessing a specified attribute.
```ruby
text_area(:comment, :text, :size => "20x30")
text_area(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
# #{@comment.text}
# </textarea>
@ -1145,7 +1037,7 @@ end
Sample usage (selecting the associated Author for an instance of Post, `@post`):
```ruby
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true})
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {prompt: true})
```
If `@post.author_id` is 1, this would return:
@ -1317,7 +1209,7 @@ Create a select tag and a series of contained option tags for the provided objec
Example:
```ruby
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true })
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: true})
```
If `@post.person_id` is 1, this would become:
@ -1374,7 +1266,7 @@ Creates a file upload field.
Prior to Rails 3.1, if you are using file uploads, then you will need to set the multipart option for the form tag. Rails 3.1+ does this automatically.
```html+erb
<%= form_tag { :action => "post" }, { :multipart => true } do %>
<%= form_tag {action: "post"}, {multipart: true} do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag %>
<% end %>
@ -1604,3 +1496,72 @@ end
Then you could create special views like `app/views/posts/show.expert.html.erb` that would only be displayed to expert users.
You can read more about the Rails Internationalization (I18n) API [here](i18n.html).
Using Action View outside of Rails
----------------------------------
Action View is a Rails component, but it can also be used without Rails. We can demonstrate this by creating a small [Rack](http://rack.rubyforge.org/) application that includes Action View functionality. This may be useful, for example, if you'd like access to Action View's helpers in a Rack application.
Let's start by ensuring that you have the Action Pack and Rack gems installed:
```bash
$ gem install actionpack
$ gem install rack
```
Now we'll create a simple "Hello World" application that uses the `titleize` method provided by Active Support.
**hello_world.rb:**
```ruby
require 'active_support/core_ext/string/inflections'
require 'rack'
def hello_world(env)
[200, {"Content-Type" => "text/html"}, "hello world".titleize]
end
Rack::Handler::Mongrel.run method(:hello_world), Port: 4567
```
We can see this all come together by starting up the application and then visiting `http://localhost:4567/`
```bash
$ ruby hello_world.rb
```
TODO needs a screenshot? I have one - not sure where to put it.
Notice how 'hello world' has been converted into 'Hello World' by the `titleize` helper method.
Action View can also be used with [Sinatra](http://www.sinatrarb.com/) in the same way.
Let's start by ensuring that you have the Action Pack and Sinatra gems installed:
```bash
$ gem install actionpack
$ gem install sinatra
```
Now we'll create the same "Hello World" application in Sinatra.
**hello_world.rb:**
```ruby
require 'action_view'
require 'sinatra'
get '/' do
erb 'hello world'.titleize
end
```
Then, we can run the application:
```bash
$ ruby hello_world.rb
```
Once the application is running, you can see Sinatra and Action View working together by visiting `http://localhost:4567/`
TODO needs a screenshot? I have one - not sure where to put it.

View File

@ -188,13 +188,13 @@ class Person
attr_accessor :name, :email, :token
validates :name, :presence => true
validates_format_of :email, :with => /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
validates! :token, :presence => true
validates :name, presence: true
validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
validates! :token, presence: true
end
person = Person.new(:token => "2b1f325")
person = Person.new(token: "2b1f325")
person.valid? #=> false
person.name = 'vishnu'
person.email = 'me'

View File

@ -119,7 +119,7 @@ If you do so, you will have to define manually the class name that is hosting th
```ruby
class FunnyJoke < ActiveSupport::TestCase
set_fixture_class :funny_jokes => 'Joke'
set_fixture_class funny_jokes: 'Joke'
fixtures :funny_jokes
...
end
@ -145,7 +145,7 @@ Active Record objects can be created from a hash, a block or have their attribut
For example, given a model `User` with attributes of `name` and `occupation`, the `create` method call will create and save a new record into the database:
```ruby
user = User.create(:name => "David", :occupation => "Code Artist")
user = User.create(name: "David", occupation: "Code Artist")
```
Using the `new` method, an object can be created without being saved:
@ -188,7 +188,7 @@ Active Record provides a rich API for accessing data within a database. Below ar
```ruby
# find all users named David who are Code Artists and sort by created_at in reverse chronological order
users = User.where(:name => 'David', :occupation => 'Code Artist').order('created_at DESC')
users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')
```
You can learn more about querying an Active Record model in the [Active Record Query Interface](active_record_querying.html) guide.

View File

@ -35,7 +35,7 @@ end
```ruby
class Order < ActiveRecord::Base
belongs_to :client, :counter_cache => true
belongs_to :client, counter_cache: true
end
```
@ -356,7 +356,7 @@ Two additional options, `:batch_size` and `:start`, are available as well.
The `:batch_size` option allows you to specify the number of records to be retrieved in each batch, before being passed individually to the block. For example, to retrieve records in batches of 5000:
```ruby
User.find_each(:batch_size => 5000) do |user|
User.find_each(batch_size: 5000) do |user|
NewsLetter.weekly_deliver(user)
end
```
@ -368,7 +368,7 @@ By default, records are fetched in ascending order of the primary key, which mus
For example, to send newsletters only to users with the primary key starting from 2000, and to retrieve them in batches of 5000:
```ruby
User.find_each(:start => 2000, :batch_size => 5000) do |user|
User.find_each(start: 2000, batch_size: 5000) do |user|
NewsLetter.weekly_deliver(user)
end
```
@ -381,7 +381,7 @@ The `find_in_batches` method is similar to `find_each`, since both retrieve batc
```ruby
# Give add_invoices an array of 1000 invoices at a time
Invoice.find_in_batches(:include => :invoice_lines) do |invoices|
Invoice.find_in_batches(include: :invoice_lines) do |invoices|
export.add_invoices(invoices)
end
```
@ -443,7 +443,7 @@ Similar to the `(?)` replacement style of params, you can also specify keys/valu
```ruby
Client.where("created_at >= :start_date AND created_at <= :end_date",
{:start_date => params[:start_date], :end_date => params[:end_date]})
{start_date: params[:start_date], end_date: params[:end_date]})
```
This makes for clearer readability if you have a large number of variable conditions.
@ -457,7 +457,7 @@ NOTE: Only equality, range and subset checking are possible with Hash conditions
#### Equality Conditions
```ruby
Client.where(:locked => true)
Client.where(locked: true)
```
The field name can also be a string:
@ -469,16 +469,16 @@ Client.where('locked' => true)
In the case of a belongs_to relationship, an association key can be used to specify the model if an ActiveRecord object is used as the value. This method works with polymorphic relationships as well.
```ruby
Post.where(:author => author)
Author.joins(:posts).where(:posts => {:author => author})
Post.where(author: author)
Author.joins(:posts).where(posts: {author: author})
```
NOTE: The values cannot be symbols. For example, you cannot do `Client.where(:status => :active)`.
NOTE: The values cannot be symbols. For example, you cannot do `Client.where(status: :active)`.
#### Range Conditions
```ruby
Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)
Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
```
This will find all clients created yesterday by using a `BETWEEN` SQL statement:
@ -494,7 +494,7 @@ This demonstrates a shorter syntax for the examples in [Array Conditions](#array
If you want to find records using the `IN` expression you can pass an array to the conditions hash:
```ruby
Client.where(:orders_count => [1,3,5])
Client.where(orders_count: [1,3,5])
```
This code will generate SQL like this:
@ -698,7 +698,7 @@ The `reorder` method overrides the default scope order. For example:
class Post < ActiveRecord::Base
..
..
has_many :comments, :order => 'posted_at DESC'
has_many :comments, order: 'posted_at DESC'
end
Post.find(10).comments.reorder('name')
@ -755,12 +755,12 @@ Post.none # returns an empty Relation and fires no queries.
```ruby
# The visible_posts method below is expected to return a Relation.
@posts = current_user.visible_posts.where(:name => params[:name])
@posts = current_user.visible_posts.where(name: params[:name])
def visible_posts
case role
when 'Country Manager'
Post.where(:country => country)
Post.where(country: country)
when 'Reviewer'
Post.published
when 'Bad User'
@ -954,7 +954,7 @@ Or, in English: "return all posts that have a category and at least one comment"
#### Joining Nested Associations (Single Level)
```ruby
Post.joins(:comments => :guest)
Post.joins(comments: :guest)
```
This produces:
@ -970,7 +970,7 @@ Or, in English: "return all posts that have a comment made by a guest."
#### Joining Nested Associations (Multiple Level)
```ruby
Category.joins(:posts => [{:comments => :guest}, :tags])
Category.joins(posts: [{comments: :guest}, :tags])
```
This produces:
@ -996,7 +996,7 @@ An alternative and cleaner syntax is to nest the hash conditions:
```ruby
time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Client.joins(:orders).where(:orders => {:created_at => time_range})
Client.joins(:orders).where(orders: {created_at: time_range})
```
This will find all clients who have orders that were created yesterday, again using a `BETWEEN` SQL expression.
@ -1057,7 +1057,7 @@ This loads all the posts and the associated category and comments for each post.
#### Nested Associations Hash
```ruby
Category.includes(:posts => [{:comments => :guest}, :tags]).find(1)
Category.includes(posts: [{comments: :guest}, :tags]).find(1)
```
This will find the category with id 1 and eager load all of the associated posts, the associated posts' tags and comments, and every comment's guest association.
@ -1109,7 +1109,7 @@ Scopes are also chainable within scopes:
```ruby
class Post < ActiveRecord::Base
scope :published, -> { where(:published => true) }
scope :published, -> { where(published: true) }
scope :published_and_commented, -> { published.where("comments_count > 0") }
end
```
@ -1278,7 +1278,7 @@ second time we run this code, the block will be ignored.
You can also use `find_or_create_by!` to raise an exception if the new record is invalid. Validations are not covered on this guide, but let's assume for a moment that you temporarily add
```ruby
validates :orders_count, :presence => true
validates :orders_count, presence: true
```
to your `Client` model. If you try to create a new `Client` without passing an `orders_count`, the record will be invalid and an exception will be raised:
@ -1346,7 +1346,7 @@ Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
`pluck` can be used to query a single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type.
```ruby
Client.where(:active => true).pluck(:id)
Client.where(active: true).pluck(:id)
# SELECT id FROM clients WHERE active = 1
# => [1, 2, 3]
@ -1364,6 +1364,8 @@ Client.pluck(:id, :name)
```ruby
Client.select(:id).map { |c| c.id }
# or
Client.select(:id).map(&:id)
# or
Client.select(:id).map { |c| [c.id, c.name] }
```
@ -1413,7 +1415,7 @@ Client.exists?([1,2,3])
It's even possible to use `exists?` without any arguments on a model or a relation.
```ruby
Client.where(:first_name => 'Ryan').exists?
Client.where(first_name: 'Ryan').exists?
```
The above returns `true` if there is at least one client with the `first_name` 'Ryan' and `false` otherwise.
@ -1436,8 +1438,8 @@ Post.recent.any?
Post.recent.many?
# via a relation
Post.where(:published => true).any?
Post.where(:published => true).many?
Post.where(published: true).any?
Post.where(published: true).many?
# via an association
Post.first.categories.any?
@ -1459,14 +1461,14 @@ Client.count
Or on a relation:
```ruby
Client.where(:first_name => 'Ryan').count
Client.where(first_name: 'Ryan').count
# SELECT count(*) AS count_all FROM clients WHERE (first_name = 'Ryan')
```
You can also use various finder methods on a relation for performing complex calculations:
```ruby
Client.includes("orders").where(:first_name => 'Ryan', :orders => {:status => 'received'}).count
Client.includes("orders").where(first_name: 'Ryan', orders: {status: 'received'}).count
```
Which will execute:
@ -1531,7 +1533,7 @@ Running EXPLAIN
You can run EXPLAIN on the queries triggered by relations. For example,
```ruby
User.where(:id => 1).joins(:posts).explain
User.where(id: 1).joins(:posts).explain
```
may yield
@ -1570,7 +1572,7 @@ may need the results of previous ones. Because of that, `explain` actually
executes the query, and then asks for the query plans. For example,
```ruby
User.where(:id => 1).includes(:posts).explain
User.where(id: 1).includes(:posts).explain
```
yields

View File

@ -14,7 +14,7 @@ How to Load Core Extensions
### Stand-Alone Active Support
In order to have a near zero default footprint, Active Support does not load anything by default. It is broken in small pieces so that you may load just what you need, and also has some convenience entry points to load related extensions in one shot, even everything.
In order to have a near-zero default footprint, Active Support does not load anything by default. It is broken in small pieces so that you can load just what you need, and also has some convenience entry points to load related extensions in one shot, even everything.
Thus, after a simple require like:
@ -85,11 +85,11 @@ The following values are considered to be blank in a Rails application:
* empty arrays and hashes, and
* any other object that responds to `empty?` and it is empty.
* any other object that responds to `empty?` and is empty.
INFO: The predicate for strings uses the Unicode-aware character class `[:space:]`, so for example U+2029 (paragraph separator) is considered to be whitespace.
WARNING: Note that numbers are not mentioned, in particular 0 and 0.0 are **not** blank.
WARNING: Note that numbers are not mentioned. In particular, 0 and 0.0 are **not** blank.
For example, this method from `ActionDispatch::Session::AbstractStore` uses `blank?` for checking whether a session key is present:
@ -147,19 +147,21 @@ Some numbers which are not singletons are not duplicable either:
Active Support provides `duplicable?` to programmatically query an object about this property:
```ruby
"foo".duplicable? # => true
"".duplicable? # => true
0.0.duplicable? # => false
false.duplicable? # => false
```
By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, and class and module objects.
By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and module objects.
WARNING. Any class can disallow duplication removing `dup` and `clone` or raising exceptions from them, only `rescue` can tell whether a given arbitrary object is duplicable. `duplicable?` depends on the hard-coded list above, but it is much faster than `rescue`. Use it only if you know the hard-coded list is enough in your use case.
WARNING: Any class can disallow duplication by removing `dup` and `clone` or raising exceptions from them. Thus only `rescue` can tell whether a given arbitrary object is duplicable. `duplicable?` depends on the hard-coded list above, but it is much faster than `rescue`. Use it only if you know the hard-coded list is enough in your use case.
NOTE: Defined in `active_support/core_ext/object/duplicable.rb`.
### `deep_dup`
The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, ruby does not `dup` them. If you have an array with a string, for example, it will look like this:
The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
```ruby
array = ['string']
@ -167,18 +169,18 @@ duplicate = array.dup
duplicate.push 'another-string'
# object was duplicated, so element was added only to duplicate
# the object was duplicated, so the element was added only to the duplicate
array #=> ['string']
duplicate #=> ['string', 'another-string']
duplicate.first.gsub!('string', 'foo')
# first element was not duplicated, it will be changed for both arrays
# first element was not duplicated, it will be changed in both arrays
array #=> ['foo']
duplicate #=> ['foo', 'another-string']
```
As you can see, after duplicating `Array` instance, we got another object, therefore we can modify it and the original object will stay unchanged. This is not true for array's elements, however. Since `dup` does not make deep copy, the string inside array is still the same object.
As you can see, after duplicating the `Array` instance, we got another object, therefore we can modify it and the original object will stay unchanged. This is not true for array's elements, however. Since `dup` does not make deep copy, the string inside the array is still the same object.
If you need a deep copy of an object, you should use `deep_dup`. Here is an example:
@ -192,12 +194,12 @@ array #=> ['string']
duplicate #=> ['foo']
```
If object is not duplicable, `deep_dup` will just return this object:
If the object is not duplicable, `deep_dup` will just return it:
```ruby
number = 1
dup = number.deep_dup
number.object_id == dup.object_id # => true
duplicate = number.deep_dup
number.object_id == duplicate.object_id # => true
```
NOTE: Defined in `active_support/core_ext/object/deep_dup.rb`.
@ -1913,8 +1915,8 @@ Produce a string representation of a number as a telephone number:
Produce a string representation of a number as currency:
```ruby
1234567890.50.to_s(:currency) # => $1,234,567,890.50
1234567890.506.to_s(:currency) # => $1,234,567,890.51
1234567890.50.to_s(:currency) # => $1,234,567,890.50
1234567890.506.to_s(:currency) # => $1,234,567,890.51
1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
```
@ -1934,8 +1936,8 @@ Produce a string representation of a number as a percentage:
Produce a string representation of a number in delimited form:
```ruby
12345678.to_s(:delimited) # => 12,345,678
12345678.05.to_s(:delimited) # => 12,345,678.05
12345678.to_s(:delimited) # => 12,345,678
12345678.05.to_s(:delimited) # => 12,345,678.05
12345678.to_s(:delimited, delimiter: ".") # => 12.345.678
12345678.to_s(:delimited, delimiter: ",") # => 12,345,678
12345678.05.to_s(:delimited, separator: " ") # => 12,345,678 05
@ -1944,7 +1946,7 @@ Produce a string representation of a number in delimited form:
Produce a string representation of a number rounded to a precision:
```ruby
111.2345.to_s(:rounded) # => 111.235
111.2345.to_s(:rounded) # => 111.235
111.2345.to_s(:rounded, precision: 2) # => 111.23
13.to_s(:rounded, precision: 5) # => 13.00000
389.32314.to_s(:rounded, precision: 0) # => 389

View File

@ -20,7 +20,8 @@ Write in present tense: "Returns a hash that...", rather than "Returned a hash t
Start comments in upper case. Follow regular punctuation rules:
```ruby
# Declares an attribute reader backed by an internally-named instance variable.
# Declares an attribute reader backed by an internally-named
# instance variable.
def attr_internal_reader(*attrs)
...
end
@ -51,8 +52,8 @@ Use two spaces to indent chunks of code--that is, for markup purposes, two space
Short docs do not need an explicit "Examples" label to introduce snippets; they just follow paragraphs:
```ruby
# Converts a collection of elements into a formatted string by calling
# `to_s` on all elements and joining them.
# Converts a collection of elements into a formatted string by
# calling +to_s+ on all elements and joining them.
#
# Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
```
@ -142,14 +143,16 @@ WARNING: Using a pair of `+...+` for fixed-width font only works with **words**;
When "true" and "false" are English words rather than Ruby keywords use a regular font:
```ruby
# Runs all the validations within the specified context. Returns true if no errors are found,
# false otherwise.
# Runs all the validations within the specified context.
# Returns true if no errors are found, false otherwise.
#
# If the argument is false (default is +nil+), the context is set to <tt>:create</tt> if
# <tt>new_record?</tt> is true, and to <tt>:update</tt> if it is not.
# If the argument is false (default is +nil+), the context is
# set to <tt>:create</tt> if <tt>new_record?</tt> is true,
# and to <tt>:update</tt> if it is not.
#
# Validations with no <tt>:on</tt> option will run no matter the context. Validations with
# some <tt>:on</tt> option will only run in the specified context.
# Validations with no <tt>:on</tt> option will run no
# matter the context. Validations with # some <tt>:on</tt>
# option will only run in the specified context.
def valid?(context = nil)
...
end
@ -161,7 +164,7 @@ Description Lists
In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols):
```ruby
# * <tt>:allow_nil</tt> - Skip validation if attribute is `nil`.
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
```
The description starts in upper case and ends with a full stop—it's standard English.

View File

@ -214,7 +214,7 @@ The asset pipeline automatically evaluates ERB. This means that if you add an `e
This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as `app/assets/images/image.png`, which would be referenced here. If this image is already available in `public/assets` as a fingerprinted file, then that path is referenced.
If you want to use a [data URI](http://en.wikipedia.org/wiki/Data_URI_scheme) -- a method of embedding the image data directly into the CSS file -- you can use the `asset_data_uri` helper.
If you want to use a [data URI](http://en.wikipedia.org/wiki/Data_URI_scheme) — a method of embedding the image data directly into the CSS file — you can use the `asset_data_uri` helper.
```css
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
@ -256,7 +256,7 @@ $('#logo').attr src: "<%= asset_path('logo.png') %>"
### Manifest Files and Directives
Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if `Rails.application.config.assets.compress` is true). By serving one file rather than many, the load time of pages can be greatly reduced because the browser makes fewer requests.
Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if `Rails.application.config.assets.compress` is true). By serving one file rather than many, the load time of pages can be greatly reduced because the browser makes fewer requests.
For example, a new Rails application includes a default `app/assets/javascripts/application.js` file which contains the following lines:
@ -309,7 +309,7 @@ The file extensions used on an asset determine what preprocessing is applied. Wh
When these files are requested, they are processed by the processors provided by the `coffee-script` and `sass` gems and then sent back to the browser as JavaScript and CSS respectively.
Additional layers of preprocessing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called `app/assets/stylesheets/projects.css.scss.erb` is first processed as ERB, then SCSS, and finally served as CSS. The same applies to a JavaScript file -- `app/assets/javascripts/projects.js.coffee.erb` is processed as ERB, then CoffeeScript, and served as JavaScript.
Additional layers of preprocessing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called `app/assets/stylesheets/projects.css.scss.erb` is first processed as ERB, then SCSS, and finally served as CSS. The same applies to a JavaScript file `app/assets/javascripts/projects.js.coffee.erb` is processed as ERB, then CoffeeScript, and served as JavaScript.
Keep in mind that the order of these preprocessors is important. For example, if you called your JavaScript file `app/assets/javascripts/projects.js.erb.coffee` then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore you would run into problems.
@ -350,7 +350,7 @@ When debug mode is off, Sprockets concatenates and runs the necessary preprocess
<script src="/assets/application.js"></script>
```
Assets are compiled and cached on the first request after the server is started. Sprockets sets a `must-revalidate` Cache-Control HTTP header to reduce request overhead on subsequent requests -- on these the browser gets a 304 (Not Modified) response.
Assets are compiled and cached on the first request after the server is started. Sprockets sets a `must-revalidate` Cache-Control HTTP header to reduce request overhead on subsequent requests on these the browser gets a 304 (Not Modified) response.
If any of the files in the manifest have changed between requests, the server responds with a new compiled file.
@ -575,6 +575,18 @@ group :production do
end
```
### CDNs
If your assets are being served by a CDN, ensure they don't stick around in
your cache forever. This can cause problems. If you use
`config.action_controller.perform_caching = true`, Rack::Cache will use
`Rails.cache` to store assets. This can cause your cache to fill up quickly.
Every cache is different, so evaluate how your CDN handles caching and make
sure that it plays nicely with the pipeline. You may find quirks related to
your specific set up, you may not. The defaults nginx uses, for example,
should give you no problems when used as an HTTP cache.
Customizing the Pipeline
------------------------

View File

@ -25,25 +25,24 @@ end
Now, suppose we wanted to add a new order for an existing customer. We'd need to do something like this:
```ruby
@order = Order.create(:order_date => Time.now,
:customer_id => @customer.id)
@order = Order.create(order_date: Time.now, customer_id: @customer.id)
```
Or consider deleting a customer, and ensuring that all of its orders get deleted as well:
```ruby
@orders = Order.where(:customer_id => @customer.id)
@orders = Order.where(customer_id: @customer.id)
@orders.each do |order|
order.destroy
end
@customer.destroy
```
With Active Record associations, we can streamline these -- and other -- operations by declaratively telling Rails that there is a connection between the two models. Here's the revised code for setting up customers and orders:
With Active Record associations, we can streamline these — and other — operations by declaratively telling Rails that there is a connection between the two models. Here's the revised code for setting up customers and orders:
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :dependent => :destroy
has_many :orders, dependent: :destroy
end
class Order < ActiveRecord::Base
@ -54,10 +53,10 @@ end
With this change, creating a new order for a particular customer is easier:
```ruby
@order = @customer.orders.create(:order_date => Time.now)
@order = @customer.orders.create(order_date: Time.now)
```
Deleting a customer and all of its orders is _much_ easier:
Deleting a customer and all of its orders is *much* easier:
```ruby
@customer.destroy
@ -126,7 +125,7 @@ A `has_many :through` association is often used to set up a many-to-many connect
```ruby
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
@ -136,7 +135,7 @@ end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
has_many :physicians, through: :appointments
end
```
@ -157,7 +156,7 @@ The `has_many :through` association is also useful for setting up "shortcuts" th
```ruby
class Document < ActiveRecord::Base
has_many :sections
has_many :paragraphs, :through => :sections
has_many :paragraphs, through: :sections
end
class Section < ActiveRecord::Base
@ -170,7 +169,7 @@ class Paragraph < ActiveRecord::Base
end
```
With `:through => :sections` specified, Rails will now understand:
With `through: :sections` specified, Rails will now understand:
```ruby
@document.paragraphs
@ -183,7 +182,7 @@ A `has_one :through` association sets up a one-to-one connection with another mo
```ruby
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, :through => :account
has_one :account_history, through: :account
end
class Account < ActiveRecord::Base
@ -270,7 +269,7 @@ The second way to declare a many-to-many relationship is to use `has_many :throu
```ruby
class Assembly < ActiveRecord::Base
has_many :manifests
has_many :parts, :through => :manifests
has_many :parts, through: :manifests
end
class Manifest < ActiveRecord::Base
@ -280,7 +279,7 @@ end
class Part < ActiveRecord::Base
has_many :manifests
has_many :assemblies, :through => :manifests
has_many :assemblies, through: :manifests
end
```
@ -294,15 +293,15 @@ A slightly more advanced twist on associations is the _polymorphic association_.
```ruby
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
belongs_to :imageable, polymorphic: true
end
class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
has_many :pictures, as: :imageable
end
```
@ -332,7 +331,7 @@ class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.string :name
t.references :imageable, :polymorphic => true
t.references :imageable, polymorphic: true
t.timestamps
end
end
@ -347,9 +346,10 @@ In designing a data model, you will sometimes find a model that should have a re
```ruby
class Employee < ActiveRecord::Base
has_many :subordinates, :class_name => "Employee",
:foreign_key => "manager_id"
belongs_to :manager, :class_name => "Employee"
has_many :subordinates, class_name: "Employee",
foreign_key: "manager_id"
belongs_to :manager, class_name: "Employee"
end
```
@ -442,7 +442,7 @@ These need to be backed up by a migration to create the `assemblies_parts` table
```ruby
class CreateAssemblyPartJoinTable < ActiveRecord::Migration
def change
create_table :assemblies_parts, :id => false do |t|
create_table :assemblies_parts, id: false do |t|
t.integer :assembly_id
t.integer :part_id
end
@ -450,7 +450,7 @@ class CreateAssemblyPartJoinTable < ActiveRecord::Migration
end
```
We pass `:id => false` to `create_table` because that table does not represent a model. That's required for the association to work properly. If you observe any strange behavior in a `has_and_belongs_to_many` association like mangled models IDs, or exceptions about conflicting IDs chances are you forgot that bit.
We pass `id: false` to `create_table` because that table does not represent a model. That's required for the association to work properly. If you observe any strange behavior in a `has_and_belongs_to_many` association like mangled models IDs, or exceptions about conflicting IDs chances are you forgot that bit.
### Controlling Association Scope
@ -495,14 +495,14 @@ module MyApplication
module Business
class Supplier < ActiveRecord::Base
has_one :account,
:class_name => "MyApplication::Billing::Account"
class_name: "MyApplication::Billing::Account"
end
end
module Billing
class Account < ActiveRecord::Base
belongs_to :supplier,
:class_name => "MyApplication::Business::Supplier"
class_name: "MyApplication::Business::Supplier"
end
end
end
@ -536,11 +536,11 @@ This happens because c and o.customer are two different in-memory representation
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :inverse_of => :customer
has_many :orders, inverse_of: :customer
end
class Order < ActiveRecord::Base
belongs_to :customer, :inverse_of => :orders
belongs_to :customer, inverse_of: :orders
end
```
@ -621,8 +621,8 @@ The `association=` method assigns an associated object to this object. Behind th
The `build_association` method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object's foreign key will be set, but the associated object will _not_ yet be saved.
```ruby
@customer = @order.build_customer(:customer_number => 123,
:customer_name => "John Doe")
@customer = @order.build_customer(customer_number: 123,
customer_name: "John Doe")
```
##### `create_association(attributes = {})`
@ -630,8 +630,8 @@ The `build_association` method returns a new object of the associated type. This
The `create_association` method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through this object's foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
```ruby
@customer = @order.create_customer(:customer_number => 123,
:customer_name => "John Doe")
@customer = @order.create_customer(customer_number: 123,
customer_name: "John Doe")
```
@ -641,8 +641,8 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :dependent => :destroy,
:counter_cache => true
belongs_to :customer, dependent: :destroy,
counter_cache: true
end
```
@ -668,7 +668,7 @@ If the name of the other model cannot be derived from the association name, you
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron"
belongs_to :customer, class_name: "Patron"
end
```
@ -689,7 +689,7 @@ With these declarations, asking for the value of `@customer.orders.size` require
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :counter_cache => true
belongs_to :customer, counter_cache: true
end
class Customer < ActiveRecord::Base
has_many :orders
@ -702,7 +702,7 @@ Although the `:counter_cache` option is specified on the model that includes the
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :counter_cache => :count_of_orders
belongs_to :customer, counter_cache: :count_of_orders
end
class Customer < ActiveRecord::Base
has_many :orders
@ -723,8 +723,8 @@ By convention, Rails assumes that the column used to hold the foreign key on thi
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron",
:foreign_key => "patron_id"
belongs_to :customer, class_name: "Patron",
foreign_key: "patron_id"
end
```
@ -736,11 +736,11 @@ The `:inverse_of` option specifies the name of the `has_many` or `has_one` assoc
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :inverse_of => :customer
has_many :orders, inverse_of: :customer
end
class Order < ActiveRecord::Base
belongs_to :customer, :inverse_of => :orders
belongs_to :customer, inverse_of: :orders
end
```
@ -754,7 +754,7 @@ If you set the `:touch` option to `:true`, then the `updated_at` or `updated_on`
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :touch => true
belongs_to :customer, touch: true
end
class Customer < ActiveRecord::Base
@ -766,7 +766,7 @@ In this case, saving or destroying an order will update the timestamp on the ass
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, :touch => :orders_updated_at
belongs_to :customer, touch: :orders_updated_at
end
```
@ -780,8 +780,8 @@ There may be times when you wish to customize the query used by `belongs_to`. Su
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, -> { where :active => true },
:dependent => :destroy
belongs_to :customer, -> { where active: true },
dependent: :destroy
end
```
@ -798,7 +798,7 @@ The `where` method lets you specify the conditions that the associated object mu
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, -> { where :active => true }
belongs_to :customer, -> { where active: true }
end
```
@ -919,7 +919,7 @@ The `association=` method assigns an associated object to this object. Behind th
The `build_association` method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through its foreign key will be set, but the associated object will _not_ yet be saved.
```ruby
@account = @supplier.build_account(:terms => "Net 30")
@account = @supplier.build_account(terms: "Net 30")
```
##### `create_association(attributes = {})`
@ -927,7 +927,7 @@ The `build_association` method returns a new object of the associated type. This
The `create_association` method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
```ruby
@account = @supplier.create_account(:terms => "Net 30")
@account = @supplier.create_account(terms: "Net 30")
```
#### Options for `has_one`
@ -936,7 +936,7 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Supplier < ActiveRecord::Base
has_one :account, :class_name => "Billing", :dependent => :nullify
has_one :account, class_name: "Billing", dependent: :nullify
end
```
@ -968,7 +968,7 @@ If the name of the other model cannot be derived from the association name, you
```ruby
class Supplier < ActiveRecord::Base
has_one :account, :class_name => "Billing"
has_one :account, class_name: "Billing"
end
```
@ -988,7 +988,7 @@ By convention, Rails assumes that the column used to hold the foreign key on the
```ruby
class Supplier < ActiveRecord::Base
has_one :account, :foreign_key => "supp_id"
has_one :account, foreign_key: "supp_id"
end
```
@ -1000,11 +1000,11 @@ The `:inverse_of` option specifies the name of the `belongs_to` association that
```ruby
class Supplier < ActiveRecord::Base
has_one :account, :inverse_of => :supplier
has_one :account, inverse_of: :supplier
end
class Account < ActiveRecord::Base
belongs_to :supplier, :inverse_of => :account
belongs_to :supplier, inverse_of: :account
end
```
@ -1034,7 +1034,7 @@ There may be times when you wish to customize the query used by `has_one`. Such
```ruby
class Supplier < ActiveRecord::Base
has_one :account, -> { where :active => true }
has_one :account, -> { where active: true }
end
```
@ -1195,7 +1195,7 @@ The `collection.delete` method removes one or more objects from the collection b
@customer.orders.delete(@order1)
```
WARNING: Additionally, objects will be destroyed if they're associated with `:dependent => :destroy`, and deleted if they're associated with `:dependent => :delete_all`.
WARNING: Additionally, objects will be destroyed if they're associated with `dependent: :destroy`, and deleted if they're associated with `dependent: :delete_all`.
##### `collection.destroy(object, ...)`
@ -1225,7 +1225,7 @@ The `collection_singular_ids=` method makes the collection contain only the obje
##### `collection.clear`
The `collection.clear` method removes every object from the collection. This destroys the associated objects if they are associated with `:dependent => :destroy`, deletes them directly from the database if `:dependent => :delete_all`, and otherwise sets their foreign keys to `NULL`.
The `collection.clear` method removes every object from the collection. This destroys the associated objects if they are associated with `dependent: :destroy`, deletes them directly from the database if `dependent: :delete_all`, and otherwise sets their foreign keys to `NULL`.
##### `collection.empty?`
@ -1258,7 +1258,7 @@ The `collection.find` method finds objects within the collection. It uses the sa
The `collection.where` method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
```ruby
@open_orders = @customer.orders.where(:open => true) # No query yet
@open_orders = @customer.orders.where(open: true) # No query yet
@open_order = @open_orders.first # Now the database will be queried
```
@ -1271,8 +1271,8 @@ The `collection.exists?` method checks whether an object meeting the supplied co
The `collection.build` method returns one or more new objects of the associated type. These objects will be instantiated from the passed attributes, and the link through their foreign key will be created, but the associated objects will _not_ yet be saved.
```ruby
@order = @customer.orders.build(:order_date => Time.now,
:order_number => "A12345")
@order = @customer.orders.build(order_date: Time.now,
order_number: "A12345")
```
##### `collection.create(attributes = {})`
@ -1280,8 +1280,8 @@ The `collection.build` method returns one or more new objects of the associated
The `collection.create` method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
```ruby
@order = @customer.orders.create(:order_date => Time.now,
:order_number => "A12345")
@order = @customer.orders.create(order_date: Time.now,
order_number: "A12345")
```
#### Options for `has_many`
@ -1290,7 +1290,7 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :dependent => :delete_all, :validate => :false
has_many :orders, dependent: :delete_all, validate: :false
end
```
@ -1322,7 +1322,7 @@ If the name of the other model cannot be derived from the association name, you
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :class_name => "Transaction"
has_many :orders, class_name: "Transaction"
end
```
@ -1344,7 +1344,7 @@ By convention, Rails assumes that the column used to hold the foreign key on the
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :foreign_key => "cust_id"
has_many :orders, foreign_key: "cust_id"
end
```
@ -1356,11 +1356,11 @@ The `:inverse_of` option specifies the name of the `belongs_to` association that
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :inverse_of => :customer
has_many :orders, inverse_of: :customer
end
class Order < ActiveRecord::Base
belongs_to :customer, :inverse_of => :orders
belongs_to :customer, inverse_of: :orders
end
```
@ -1390,7 +1390,7 @@ There may be times when you wish to customize the query used by `has_many`. Such
```ruby
class Customer < ActiveRecord::Base
has_many :orders, -> { where :processed => true }
has_many :orders, -> { where processed: true }
end
```
@ -1414,7 +1414,7 @@ The `where` method lets you specify the conditions that the associated object mu
```ruby
class Customer < ActiveRecord::Base
has_many :confirmed_orders, -> { where "confirmed = 1" },
:class_name => "Order"
class_name: "Order"
end
```
@ -1422,8 +1422,8 @@ You can also set conditions via a hash:
```ruby
class Customer < ActiveRecord::Base
has_many :confirmed_orders, -> { where :confirmed => true },
:class_name => "Order"
has_many :confirmed_orders, -> { where confirmed: true },
class_name: "Order"
end
```
@ -1440,7 +1440,7 @@ The `group` method supplies an attribute name to group the result set by, using
```ruby
class Customer < ActiveRecord::Base
has_many :line_items, -> { group 'orders.id' },
:through => :orders
through: :orders
end
```
@ -1488,7 +1488,7 @@ The `limit` method lets you restrict the total number of objects that will be fe
class Customer < ActiveRecord::Base
has_many :recent_orders,
-> { order('order_date desc').limit(100) },
:class_name => "Order",
class_name: "Order",
end
```
@ -1523,11 +1523,11 @@ Use the `uniq` method to keep the collection free of duplicates. This is mostly
```ruby
class Person < ActiveRecord::Base
has_many :readings
has_many :posts, :through => :readings
has_many :posts, through: :readings
end
person = Person.create(:name => 'john')
post = Post.create(:name => 'a1')
person = Person.create(name: 'John')
post = Post.create(name: 'a1')
person.posts << post
person.posts << post
person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5, name: "a1">]
@ -1541,11 +1541,11 @@ Now let's set `uniq`:
```ruby
class Person
has_many :readings
has_many :posts, -> { uniq }, :through => :readings
has_many :posts, -> { uniq }, through: :readings
end
person = Person.create(:name => 'honda')
post = Post.create(:name => 'a1')
person = Person.create(name: 'Honda')
post = Post.create(name: 'a1')
person.posts << post
person.posts << post
person.posts.inspect # => [#<Post id: 7, name: "a1">]
@ -1722,8 +1722,7 @@ The `collection.exists?` method checks whether an object meeting the supplied co
The `collection.build` method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through the join table will be created, but the associated object will _not_ yet be saved.
```ruby
@assembly = @part.assemblies.build(
{:assembly_name => "Transmission housing"})
@assembly = @part.assemblies.build({assembly_name: "Transmission housing"})
```
##### `collection.create(attributes = {})`
@ -1731,8 +1730,7 @@ The `collection.build` method returns a new object of the associated type. This
The `collection.create` method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through the join table will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
```ruby
@assembly = @part.assemblies.create(
{:assembly_name => "Transmission housing"})
@assembly = @part.assemblies.create({assembly_name: "Transmission housing"})
```
#### Options for `has_and_belongs_to_many`
@ -1741,8 +1739,8 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Parts < ActiveRecord::Base
has_and_belongs_to_many :assemblies, :uniq => true,
:read_only => true
has_and_belongs_to_many :assemblies, uniq: true,
read_only: true
end
```
@ -1763,9 +1761,10 @@ TIP: The `:foreign_key` and `:association_foreign_key` options are useful when s
```ruby
class User < ActiveRecord::Base
has_and_belongs_to_many :friends, :class_name => "User",
:foreign_key => "this_user_id",
:association_foreign_key => "other_user_id"
has_and_belongs_to_many :friends,
class_name: "User",
foreign_key: "this_user_id",
association_foreign_key: "other_user_id"
end
```
@ -1779,7 +1778,7 @@ If the name of the other model cannot be derived from the association name, you
```ruby
class Parts < ActiveRecord::Base
has_and_belongs_to_many :assemblies, :class_name => "Gadget"
has_and_belongs_to_many :assemblies, class_name: "Gadget"
end
```
@ -1789,9 +1788,10 @@ By convention, Rails assumes that the column in the join table used to hold the
```ruby
class User < ActiveRecord::Base
has_and_belongs_to_many :friends, :class_name => "User",
:foreign_key => "this_user_id",
:association_foreign_key => "other_user_id"
has_and_belongs_to_many :friends,
class_name: "User",
foreign_key: "this_user_id",
association_foreign_key: "other_user_id"
end
```
@ -1809,7 +1809,7 @@ There may be times when you wish to customize the query used by `has_and_belongs
```ruby
class Parts < ActiveRecord::Base
has_and_belongs_to_many :assemblies, -> { where :active => true }
has_and_belongs_to_many :assemblies, -> { where active: true }
end
```
@ -1842,7 +1842,7 @@ You can also set conditions via a hash:
```ruby
class Parts < ActiveRecord::Base
has_and_belongs_to_many :assemblies,
-> { where :factory => 'Seattle' }
-> { where factory: 'Seattle' }
end
```
@ -1929,7 +1929,7 @@ You define association callbacks by adding options to the association declaratio
```ruby
class Customer < ActiveRecord::Base
has_many :orders, :before_add => :check_credit_limit
has_many :orders, before_add: :check_credit_limit
def check_credit_limit(order)
...
@ -1944,7 +1944,7 @@ You can stack callbacks on a single event by passing them as an array:
```ruby
class Customer < ActiveRecord::Base
has_many :orders,
:before_add => [:check_credit_limit, :calculate_shipping_charges]
before_add: [:check_credit_limit, :calculate_shipping_charges]
def check_credit_limit(order)
...

View File

@ -5,10 +5,10 @@ This guide will teach you what you need to know about avoiding that expensive ro
After reading this guide, you should be able to use and configure:
* Page, action, and fragment caching.
* Sweepers.
* Alternative cache stores.
* Conditional GET support.
* Page, action, and fragment caching
* Sweepers
* Alternative cache stores
* Conditional GET support
--------------------------------------------------------------------------------
@ -61,7 +61,7 @@ class ProductsController < ActionController
end
def create
expire_page :action => :index
expire_page action: :index
end
end
@ -82,13 +82,13 @@ location / {
You can disable gzipping by setting `:gzip` option to false (for example, if action returns image):
```ruby
caches_page :image, :gzip => false
caches_page :image, gzip: false
```
Or, you can set custom gzip compression level (level names are taken from `Zlib` constants):
```ruby
caches_page :image, :gzip => :best_speed
caches_page :image, gzip: :best_speed
```
NOTE: Page caching ignores all parameters. For example `/products?page=1` will be written out to the filesystem as `products.html` with no reference to the `page` parameter. Thus, if someone requests `/products?page=2` later, they will get the cached first page. A workaround for this limitation is to include the parameters in the page's path, e.g. `/products/page/1`.
@ -114,13 +114,13 @@ class ProductsController < ActionController
end
def create
expire_action :action => :index
expire_action action: :index
end
end
```
You can also use `:if` (or `:unless`) to pass a Proc that specifies when the action should be cached. Also, you can use `:layout => false` to cache without layout so that dynamic information in the layout such as logged in user info or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2.
You can also use `:if` (or `:unless`) to pass a Proc that specifies when the action should be cached. Also, you can use `layout: false` to cache without layout so that dynamic information in the layout such as logged in user info or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2.
You can modify the default action cache path by passing a `:cache_path` option. This will be passed directly to `ActionCachePath.path_for`. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance.
@ -152,14 +152,14 @@ As an example, if you wanted to show all the orders placed on your website in re
The cache block in our example will bind to the action that called it and is written out to the same place as the Action Cache, which means that if you want to cache multiple fragments per action, you should provide an `action_suffix` to the cache call:
```html+erb
<% cache(:action => 'recent', :action_suffix => 'all_products') do %>
<% cache(action: 'recent', action_suffix: 'all_products') do %>
All available products:
```
and you can expire it using the `expire_fragment` method, like so:
```ruby
expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products')
expire_fragment(controller: 'products', action: 'recent', action_suffix: 'all_products')
```
If you don't want the cache block to bind to the action that called it, you can also use globally keyed fragments by calling the `cache` method with a key:
@ -206,7 +206,7 @@ class ProductSweeper < ActionController::Caching::Sweeper
private
def expire_cache_for(product)
# Expire the index page now that we added a new product
expire_page(:controller => 'products', :action => 'index')
expire_page(controller: 'products', action: 'index')
# Expire a fragment
expire_fragment('all_available_products')
@ -217,7 +217,7 @@ end
You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add an expire method which specifies the page we want to expire:
```ruby
expire_action(:controller => 'products', :action => 'edit', :id => product.id)
expire_action(controller: 'products', action: 'edit', id: product.id)
```
Then we add it to our controller to tell it to call the sweeper when certain actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:
@ -265,7 +265,7 @@ class ProductSweeper < ActionController::Caching::Sweeper
observe Product
def after_create(product)
expire_action(:controller => '/products', :action => 'index')
expire_action(controller: '/products', action: 'index')
end
end
```
@ -340,13 +340,11 @@ There are some common options used by all cache implementations. These can be pa
This cache store keeps entries in memory in the same Ruby process. The cache store has a bounded size specified by the `:size` options to the initializer (default is 32Mb). When the cache exceeds the allotted size, a cleanup will occur and the least recently used entries will be removed.
```ruby
config.cache_store = :memory_store, { :size => 64.megabytes }
config.cache_store = :memory_store, { size: 64.megabytes }
```
If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then your Rails server process instances won't be able to share cache data with each other. This cache store is not appropriate for large application deployments, but can work well for small, low traffic sites with only a couple of server processes or for development and test environments.
This is the default cache store implementation.
### ActiveSupport::Cache::FileStore
This cache store uses the file system to store entries. The path to the directory where the store files will be stored must be specified when initializing the cache.
@ -359,6 +357,8 @@ With this cache store, multiple server processes on the same host can share a ca
Note that the cache will grow until the disk is full unless you periodically clear out old entries.
This is the default cache store implementation.
### ActiveSupport::Cache::MemCacheStore
This cache store uses Danga's `memcached` server to provide a centralized cache for your application. Rails uses the bundled `dalli` gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
@ -394,8 +394,8 @@ In addition to the standard `:expires_in` option, the `write` method on this cac
These options are passed to the `write` method as Hash options using either camelCase or underscore notation, as in the following examples:
```ruby
Rails.cache.write('key', 'value', :time_to_idle => 60.seconds, :timeToLive => 600.seconds)
caches_action :index, :expires_in => 60.seconds, :unless_exist => true
Rails.cache.write('key', 'value', time_to_idle: 60.seconds, timeToLive: 600.seconds)
caches_action :index, expires_in: 60.seconds, unless_exist: true
```
For more information about Ehcache, see [http://ehcache.org/](http://ehcache.org/) .
@ -427,7 +427,7 @@ You can use Hashes and Arrays of values as cache keys.
```ruby
# This is a legal cache key
Rails.cache.read(:site => "mysite", :owners => [owner_1, owner_2])
Rails.cache.read(site: "mysite", owners: [owner_1, owner_2])
```
The keys you use on `Rails.cache` will not be the same as those actually used with the storage engine. They may be modified with a namespace or altered to fit technology backend constraints. This means, for instance, that you can't save values with `Rails.cache` and then try to pull them out with the `memcache-client` gem. However, you also don't need to worry about exceeding the memcached size limit or violating syntax rules.
@ -449,7 +449,7 @@ class ProductsController < ApplicationController
# If the request is stale according to the given timestamp and etag value
# (i.e. it needs to be processed again) then execute this block
if stale?(:last_modified => @product.updated_at.utc, :etag => @product.cache_key)
if stale?(last_modified: @product.updated_at.utc, etag: @product.cache_key)
respond_to do |wants|
# ... normal response processing
end
@ -484,7 +484,7 @@ class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
fresh_when :last_modified => @product.published_at.utc, :etag => @product
fresh_when last_modified: @product.published_at.utc, etag: @product
end
end
```

View File

@ -486,7 +486,7 @@ Custom rake tasks have a `.rake` extension and are placed in `Rails.root/lib/tas
```ruby
desc "I am short, but comprehensive description for my cool task"
task :task_name => [:prerequisite_task, :another_task_we_depend_on] do
task task_name: [:prerequisite_task, :another_task_we_depend_on] do
# All your magic here
# Any valid Ruby code is allowed
end

View File

@ -101,7 +101,7 @@ These configuration methods are to be called on a `Rails::Railtie` object, such
* `config.log_level` defines the verbosity of the Rails logger. This option defaults to `:debug` for all modes except production, where it defaults to `:info`.
* `config.log_tags` accepts a list of methods that respond to `request` object. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications.
* `config.log_tags` accepts a list of methods that respond to `request` object. This makes it easy to tag log lines with debug information like subdomain and request id both very helpful in debugging multi-user production applications.
* `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::BufferedLogger`, with auto flushing off in production mode.
@ -648,7 +648,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `initialize_cache` If `Rails.cache` isn't set yet, initializes the cache by referencing the value in `config.cache_store` and stores the outcome as `Rails.cache`. If this object responds to the `middleware` method, its middleware is inserted before `Rack::Runtime` in the middleware stack.
* `set_clear_dependencies_hook` Provides a hook for `active_record.set_dispatch_hooks` to use, which will run before this initializer. This initializer -- which runs only if `cache_classes` is set to `false` -- uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
* `set_clear_dependencies_hook` Provides a hook for `active_record.set_dispatch_hooks` to use, which will run before this initializer. This initializer — which runs only if `cache_classes` is set to `false` uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
* `initialize_dependency_mechanism` If `config.cache_classes` is true, configures `ActiveSupport::Dependencies.mechanism` to `require` dependencies rather than `load` them.
@ -659,7 +659,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `active_support.initialize_whiny_nils` Requires `active_support/whiny_nil` if `config.whiny_nils` is true. This file will output errors such as:
```
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Called id for nil, which would mistakenly be 4 if you really wanted the id of nil, use object_id
```
And:
@ -684,9 +684,9 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `action_view.set_configs` Sets up Action View by using the settings in `config.action_view` by `send`'ing the method names as setters to `ActionView::Base` and passing the values through.
* `action_controller.logger` Sets `ActionController::Base.logger` -- if it's not already set -- to `Rails.logger`.
* `action_controller.logger` Sets `ActionController::Base.logger` — if it's not already set — to `Rails.logger`.
* `action_controller.initialize_framework_caches` Sets `ActionController::Base.cache_store` -- if it's not already set -- to `Rails.cache`.
* `action_controller.initialize_framework_caches` Sets `ActionController::Base.cache_store` — if it's not already set — to `Rails.cache`.
* `action_controller.set_configs` Sets up Action Controller by using the settings in `config.action_controller` by `send`'ing the method names as setters to `ActionController::Base` and passing the values through.
@ -694,7 +694,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `active_record.initialize_timezone` Sets `ActiveRecord::Base.time_zone_aware_attributes` to true, as well as setting `ActiveRecord::Base.default_timezone` to UTC. When attributes are read from the database, they will be converted into the time zone specified by `Time.zone`.
* `active_record.logger` Sets `ActiveRecord::Base.logger` -- if it's not already set -- to `Rails.logger`.
* `active_record.logger` Sets `ActiveRecord::Base.logger` — if it's not already set — to `Rails.logger`.
* `active_record.set_configs` Sets up Active Record by using the settings in `config.active_record` by `send`'ing the method names as setters to `ActiveRecord::Base` and passing the values through.
@ -704,7 +704,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `active_record.set_dispatch_hooks` Resets all reloadable connections to the database if `config.cache_classes` is set to `false`.
* `action_mailer.logger` Sets `ActionMailer::Base.logger` -- if it's not already set -- to `Rails.logger`.
* `action_mailer.logger` Sets `ActionMailer::Base.logger` — if it's not already set — to `Rails.logger`.
* `action_mailer.set_configs` Sets up Action Mailer by using the settings in `config.action_mailer` by `send`'ing the method names as setters to `ActionMailer::Base` and passing the values through.

View File

@ -9,7 +9,7 @@ This guide covers ways in which _you_ can become a part of the ongoing developme
* Contributing to the Ruby on Rails documentation
* Contributing to the Ruby on Rails code
Ruby on Rails is not "someone else's framework." Over the years, hundreds of people have contributed to Ruby on Rails ranging from a single character to massive architectural changes or significant documentation -- all with the goal of making Ruby on Rails better for everyone. Even if you don't feel up to writing code or documentation yet, there are a variety of other ways that you can contribute, from reporting issues to testing patches.
Ruby on Rails is not "someone else's framework." Over the years, hundreds of people have contributed to Ruby on Rails ranging from a single character to massive architectural changes or significant documentation all with the goal of making Ruby on Rails better for everyone. Even if you don't feel up to writing code or documentation yet, there are a variety of other ways that you can contribute, from reporting issues to testing patches.
--------------------------------------------------------------------------------
@ -24,7 +24,7 @@ NOTE: Bugs in the most recent released version of Ruby on Rails are likely to ge
If you've found a problem in Ruby on Rails which is not a security risk, do a search in GitHub under [Issues](https://github.com/rails/rails/issues) in case it was already reported. If you find no issue addressing it you can [add a new one](https://github.com/rails/rails/issues/new). (See the next section for reporting security issues).
At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need at least to post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself -- and others -- to replicate the bug and figure out a fix.
At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need at least to post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself — and others — to replicate the bug and figure out a fix.
Then, don't get your hopes up! Unless you have a "Code Red, Mission Critical, the World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with an "I'm having this problem too" comment.
@ -146,7 +146,7 @@ After applying their branch, test it out! Here are some things to think about:
Once you're happy that the pull request contains a good change, comment on the GitHub issue indicating your approval. Your comment should indicate that you like the change and what you like about it. Something like:
<blockquote>
I like the way you've restructured that code in generate_finder_sql -- much nicer. The tests look good too.
I like the way you've restructured that code in generate_finder_sql much nicer. The tests look good too.
</blockquote>
If your comment simply says "+1", then odds are that other reviewers aren't going to take it too seriously. Show that you took the time to review the pull request.
@ -215,7 +215,7 @@ Rails follows a simple set of coding style conventions.
* Use a = b and not a=b.
* Follow the conventions in the source you see used already.
The above are guidelines -- please use your best judgment in using them.
The above are guidelines please use your best judgment in using them.
### Updating the CHANGELOG

View File

@ -164,7 +164,7 @@ class PostsController < ApplicationController
logger.debug "The post was saved and now the user is going to be redirected..."
redirect_to(@post)
else
render :action => "new"
render action: "new"
end
end

View File

@ -19,6 +19,8 @@ In case you can't use the Rails development box, see section above, these are th
Ruby on Rails uses Git for source code control. The [Git homepage](http://git-scm.com/) has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
* [Try Git course](http://try.github.com/) is an interactive course that will teach you the basics.
* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git
* [Everyday Git](http://schacon.github.com/git/everyday.html) will teach you just enough about Git to get by.
* The [PeepCode screencast](https://peepcode.com/products/git) on Git ($9) is easier to follow.
* [GitHub](http://help.github.com) offers links to a variety of Git resources.
@ -51,7 +53,7 @@ $ sudo yum install libxml2 libxml2-devel libxslt libxslt-devel
If you have any problems with these libraries, you should install them manually compiling the source code. Just follow the instructions at the [Red Hat/CentOS section of the Nokogiri tutorials](http://nokogiri.org/tutorials/installing_nokogiri.html#red_hat__centos) .
Also, SQLite3 and its development files for the `sqlite3-ruby` gem -- in Ubuntu you're done with just
Also, SQLite3 and its development files for the `sqlite3-ruby` gem in Ubuntu you're done with just
```bash
$ sudo apt-get install sqlite3 libsqlite3-dev

View File

@ -89,7 +89,7 @@ The `--mountable` option tells the generator that you want to create a "mountabl
Additionally, the `--mountable` option tells the generator to mount the engine inside the dummy testing application located at `test/dummy` by adding the following to the dummy application's routes file at `test/dummy/config/routes.rb`:
```ruby
mount Blorgh::Engine, :at => "blorgh"
mount Blorgh::Engine, at: "blorgh"
```
### Inside an engine
@ -99,7 +99,7 @@ mount Blorgh::Engine, :at => "blorgh"
At the root of this brand new engine's directory lives a `blorgh.gemspec` file. When you include the engine into an application later on, you will do so with this line in the Rails application's `Gemfile`:
```ruby
gem 'blorgh', :path => "vendor/engines/blorgh"
gem 'blorgh', path: "vendor/engines/blorgh"
```
By specifying it as a gem within the `Gemfile`, Bundler will load it as such, parsing this `blorgh.gemspec` file and requiring a file within the `lib` directory called `lib/blorgh.rb`. This file requires the `blorgh/engine.rb` file (located at `lib/blorgh/engine.rb`) and defines a base module called `Blorgh`.
@ -278,7 +278,7 @@ If you'd rather play around in the console, `rails console` will also work just
One final thing is that the `posts` resource for this engine should be the root of the engine. Whenever someone goes to the root path where the engine is mounted, they should be shown a list of posts. This can be made to happen if this line is inserted into the `config/routes.rb` file inside the engine:
```ruby
root :to => "posts#index"
root to: "posts#index"
```
Now people will only need to go to the root of the engine to see all the posts, rather than visiting `/posts`. This means that instead of `http://localhost:3000/blorgh/posts`, you only need to go to `http://localhost:3000/blorgh` now.
@ -438,7 +438,7 @@ gem 'devise'
However, because you are developing the `blorgh` engine on your local machine, you will need to specify the `:path` option in your `Gemfile`:
```ruby
gem 'blorgh', :path => "/path/to/blorgh"
gem 'blorgh', path: "/path/to/blorgh"
```
As described earlier, by placing the gem in the `Gemfile` it will be loaded when Rails is loaded, as it will first require `lib/blorgh.rb` in the engine and then `lib/blorgh/engine.rb`, which is the file that defines the major pieces of functionality for the engine.
@ -446,7 +446,7 @@ As described earlier, by placing the gem in the `Gemfile` it will be loaded when
To make the engine's functionality accessible from within an application, it needs to be mounted in that application's `config/routes.rb` file:
```ruby
mount Blorgh::Engine, :at => "/blog"
mount Blorgh::Engine, at: "/blog"
```
This line will mount the engine at `/blog` in the application. Making it accessible at `http://localhost:3000/blog` when the application runs with `rails server`.
@ -523,7 +523,7 @@ To do all this, you'll need to add the `attr_accessor` for `author_name`, the as
```ruby
attr_accessor :author_name
belongs_to :author, :class_name => "User"
belongs_to :author, class_name: "User"
before_save :set_author
@ -563,7 +563,7 @@ Run this migration using this command:
$ rake db:migrate
```
Now with all the pieces in place, an action will take place that will associate an author -- represented by a record in the `users` table -- with a post, represented by the `blorgh_posts` table from the engine.
Now with all the pieces in place, an action will take place that will associate an author — represented by a record in the `users` table — with a post, represented by the `blorgh_posts` table from the engine.
Finally, the author's name should be displayed on the post's page. Add this code above the "Title" output inside `app/views/blorgh/posts/show.html.erb`:
@ -622,7 +622,7 @@ This method works like its brothers `attr_accessor` and `cattr_accessor`, but pr
The next step is switching the `Blorgh::Post` model over to this new setting. For the `belongs_to` association inside this model (`app/models/blorgh/post.rb`), it will now become this:
```ruby
belongs_to :author, :class_name => Blorgh.user_class
belongs_to :author, class_name: Blorgh.user_class
```
The `set_author` method also located in this class should also use this class:
@ -665,7 +665,7 @@ There are now no strict dependencies on what the class is, only what the API for
Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines!
If you wish to use an initializer -- code that should run before the engine is loaded -- the place for it is the `config/initializers` folder. This directory's functionality is explained in the [Initializers section](http://guides.rubyonrails.org/configuring.html#initializers) of the Configuring guide, and works precisely the same way as the `config/initializers` directory inside an application. Same goes for if you want to use a standard initializer.
If you wish to use an initializer — code that should run before the engine is loaded — the place for it is the `config/initializers` folder. This directory's functionality is explained in the [Initializers section](http://guides.rubyonrails.org/configuring.html#initializers) of the Configuring guide, and works precisely the same way as the `config/initializers` directory inside an application. Same goes for if you want to use a standard initializer.
For locales, simply place the locale files in the `config/locales` directory, just like you would in an application.
@ -678,7 +678,7 @@ The `test` directory should be treated like a typical Rails testing environment,
### Functional tests
A matter worth taking into consideration when writing functional tests is that the tests are going to be running on an application -- the `test/dummy` application -- rather than your engine. This is due to the setup of the testing environment; an engine needs an application as a host for testing its main functionality, especially controllers. This means that if you were to make a typical `GET` to a controller in a controller's functional test like this:
A matter worth taking into consideration when writing functional tests is that the tests are going to be running on an application — the `test/dummy` application — rather than your engine. This is due to the setup of the testing environment; an engine needs an application as a host for testing its main functionality, especially controllers. This means that if you were to make a typical `GET` to a controller in a controller's functional test like this:
```ruby
get :index
@ -687,7 +687,7 @@ get :index
It may not function correctly. This is because the application doesn't know how to route these requests to the engine unless you explicitly tell it **how**. To do this, you must pass the `:use_route` option (as a parameter) on these requests also:
```ruby
get :index, :use_route => :blorgh
get :index, use_route: :blorgh
```
This tells the application that you still want to perform a `GET` request to the `index` action of this controller, just that you want to use the engine's route to get there, rather than the application.
@ -791,7 +791,7 @@ module Blorgh::Concerns::Models::Post
# executed in the module's context (blorgh/concerns/models/post).
included do
attr_accessor :author_name
belongs_to :author, :class_name => "User"
belongs_to :author, class_name: "User"
before_save :set_author

View File

@ -57,7 +57,7 @@ One of the most basic forms you see on the web is a search form. This form conta
To create this form you will use `form_tag`, `label_tag`, `text_field_tag`, and `submit_tag`, respectively. Like this:
```erb
<%= form_tag("/search", :method => "get") do %>
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
@ -87,14 +87,14 @@ The `form_tag` helper accepts 2 arguments: the path for the action and an option
As with the `link_to` helper, the path argument doesn't have to be a string; it can be a hash of URL parameters recognizable by Rails' routing mechanism, which will turn the hash into a valid URL. However, since both arguments to `form_tag` are hashes, you can easily run into a problem if you would like to specify both. For instance, let's say you write this:
```ruby
form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form")
form_tag(controller: "people", action: "search", method: "get", class: "nifty_form")
# => '<form accept-charset="UTF-8" action="/people/search?method=get&class=nifty_form" method="post">'
```
Here, `method` and `class` are appended to the query string of the generated URL because even though you mean to write two hashes, you really only specified one. So you need to tell Ruby which is which by delimiting the first hash (or both) with curly brackets. This will generate the HTML you expect:
```ruby
form_tag({:controller => "people", :action => "search"}, :method => "get", :class => "nifty_form")
form_tag({controller: "people", action: "search"}, method: "get", class: "nifty_form")
# => '<form accept-charset="UTF-8" action="/people/search" method="get" class="nifty_form">'
```
@ -155,7 +155,7 @@ NOTE: Always use labels for checkbox and radio buttons. They associate text with
Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, time fields, color fields, datetime fields, datetime-local fields, month fields, week fields, URL fields and email fields:
```erb
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
@ -236,9 +236,9 @@ end
The corresponding view `app/views/articles/new.html.erb` using `form_for` looks like this:
```erb
<%= form_for @article, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |f| %>
<%= form_for @article, url: {action: "create"}, html => {class: "nifty_form"} do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body, :size => "60x12" %>
<%= f.text_area :body, size: "60x12" %>
<%= f.submit "Create" %>
<% end %>
```
@ -267,7 +267,7 @@ The helper methods called on the form builder are identical to the model object
You can create a similar binding without actually creating `<form>` tags with the `fields_for` helper. This is useful for editing additional model objects with the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for creating both like so:
```erb
<%= form_for @person, :url => { :action => "create" } do |person_form| %>
<%= form_for @person, url: {action: "create"} do |person_form| %>
<%= person_form.text_field :name %>
<%= fields_for @person.contact_detail do |contact_details_form| %>
<%= contact_details_form.text_field :phone_number %>
@ -288,7 +288,7 @@ The object yielded by `fields_for` is a form builder like the one yielded by `fo
### Relying on Record Identification
The Article model is directly available to users of the application, so -- following the best practices for developing with Rails -- you should declare it **a resource**:
The Article model is directly available to users of the application, so — following the best practices for developing with Rails — you should declare it **a resource**:
```ruby
resources :articles
@ -301,13 +301,13 @@ When dealing with RESTful resources, calls to `form_for` can get significantly e
```ruby
## Creating a new article
# long-style:
form_for(@article, :url => articles_path)
form_for(@article, url: articles_path)
# same thing, short-style (record identification gets used):
form_for(@article)
## Editing an existing article
# long-style:
form_for(@article, :url => article_path(@article), :html => { :method => "patch" })
form_for(@article, url: article_path(@article), html: {method: "patch"})
# short-style:
form_for(@article)
```
@ -342,7 +342,7 @@ The Rails framework encourages RESTful design of your applications, which means
Rails works around this issue by emulating other methods over POST with a hidden input named `"_method"`, which is set to reflect the desired method:
```ruby
form_tag(search_path, :method => "patch")
form_tag(search_path, method: "patch")
```
output:
@ -379,7 +379,7 @@ Here you have a list of cities whose names are presented to the user. Internally
### The Select and Option Tags
The most generic helper is `select_tag`, which -- as the name implies -- simply generates the `SELECT` tag that encapsulates an options string:
The most generic helper is `select_tag`, which — as the name implies — simply generates the `SELECT` tag that encapsulates an options string:
```erb
<%= select_tag(:city_id, '<option value="1">Lisbon</option>...') %>
@ -419,14 +419,14 @@ output:
Whenever Rails sees that the internal value of an option being generated matches this value, it will add the `selected` attribute to that option.
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select` -- you must pass 2. Be aware of values extracted from the `params` hash as they are all strings.
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select` you must pass 2. Be aware of values extracted from the `params` hash as they are all strings.
WARNING: when `:inlude_blank` or `:prompt:` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
You can add arbitrary attributes to the options using hashes:
```html+erb
<%= options_for_select([['Lisbon', 1, :'data-size' => '2.8 million'], ['Madrid', 2, :'data-size' => '3.2 million']], 2) %>
<%= options_for_select([['Lisbon', 1, 'data-size': '2.8 million'], ['Madrid', 2, 'data-size': '3.2 million']], 2) %>
output:
@ -441,7 +441,7 @@ In most cases form controls will be tied to a specific database model and as you
```ruby
# controller:
@person = Person.new(:city_id => 2)
@person = Person.new(city_id: 2)
```
```erb
@ -449,7 +449,7 @@ In most cases form controls will be tied to a specific database model and as you
<%= select(:person, :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %>
```
Notice that the third parameter, the options array, is the same kind of argument you pass to `options_for_select`. One advantage here is that you don't have to worry about pre-selecting the correct city if the user already has one -- Rails will do this for you by reading from the `@person.city_id` attribute.
Notice that the third parameter, the options array, is the same kind of argument you pass to `options_for_select`. One advantage here is that you don't have to worry about pre-selecting the correct city if the user already has one Rails will do this for you by reading from the `@person.city_id` attribute.
As with other helpers, if you were to use the `select` helper on a form builder scoped to the `@person` object, the syntax would be:
@ -512,7 +512,7 @@ Both of these families of helpers will create a series of select boxes for the d
The `select_*` family of helpers take as their first argument an instance of Date, Time or DateTime that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example
```erb
<%= select_date Date.today, :prefix => :start_date %>
<%= select_date Date.today, prefix: :start_date %>
```
outputs (with actual option values omitted for brevity)
@ -585,7 +585,7 @@ A common task is uploading some sort of file, whether it's a picture of a person
The following two forms both upload a file.
```erb
<%= form_tag({:action => :upload}, :multipart => true) do %>
<%= form_tag({action: :upload}, multipart: true) do %>
<%= file_field_tag 'picture' %>
<% end %>
@ -617,7 +617,7 @@ NOTE: If the user has not selected a file the corresponding parameter will be an
### Dealing with Ajax
Unlike other forms making an asynchronous file upload form is not as simple as providing `form_for` with `:remote => true`. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
Unlike other forms making an asynchronous file upload form is not as simple as providing `form_for` with `remote: true`. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
Customizing Form Builders
-------------------------
@ -633,7 +633,7 @@ As mentioned previously the object yielded by `form_for` and `fields_for` is an
can be replaced with
```erb
<%= form_for @person, :builder => LabellingFormBuilder do |f| %>
<%= form_for @person, builder: LabellingFormBuilder do |f| %>
<%= f.text_field :first_name %>
<% end %>
```
@ -648,12 +648,12 @@ class LabellingFormBuilder < ActionView::Helpers::FormBuilder
end
```
If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `:builder => LabellingFormBuilder` option.
If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `builder: LabellingFormBuilder` option.
The form builder used also determines what happens when you do
```erb
<%= render :partial => f %>
<%= render partial: f %>
```
If `f` is an instance of FormBuilder then this will render the `form` partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the `labelling_form` partial would be rendered instead.
@ -737,7 +737,7 @@ You might want to render a form with a set of edit fields for each of a person's
<%= form_for @person do |person_form| %>
<%= person_form.text_field :name %>
<% @person.addresses.each do |address| %>
<%= person_form.fields_for address, :index => address do |address_form|%>
<%= person_form.fields_for address, index: address do |address_form|%>
<%= address_form.text_field :city %>
<% end %>
<% end %>
@ -765,7 +765,7 @@ Rails knows that all these inputs should be part of the person hash because you
To create more intricate nestings, you can specify the first part of the input name (`person[address]` in the previous example) explicitly, for example
```erb
<%= fields_for 'person[address][primary]', address, :index => address do |address_form| %>
<%= fields_for 'person[address][primary]', address, index: address do |address_form| %>
<%= address_form.text_field :city %>
<% end %>
```
@ -778,7 +778,7 @@ will create inputs like
As a general rule the final input name is the concatenation of the name given to `fields_for`/`form_for`, the index value and the name of the attribute. You can also pass an `:index` option directly to helpers such as `text_field`, but it is usually less repetitive to specify this at the form builder level rather than on individual input controls.
As a shortcut you can append [] to the name and omit the `:index` option. This is the same as specifying `:index => address` so
As a shortcut you can append [] to the name and omit the `:index` option. This is the same as specifying `index: address` so
```erb
<%= fields_for 'person[address][primary][]', address do |address_form| %>
@ -791,10 +791,10 @@ produces exactly the same output as the previous example.
Forms to external resources
---------------------------
If you need to post some data to an external resource it is still great to build your form using rails form helpers. But sometimes you need to set an `authenticity_token` for this resource. You can do it by passing an `:authenticity_token => 'your_external_token'` parameter to the `form_tag` options:
If you need to post some data to an external resource it is still great to build your form using rails form helpers. But sometimes you need to set an `authenticity_token` for this resource. You can do it by passing an `authenticity_token: 'your_external_token'` parameter to the `form_tag` options:
```erb
<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %>
<%= form_tag 'http://farfar.away/form', authenticity_token: 'external_token') do %>
Form contents
<% end %>
```
@ -802,7 +802,7 @@ If you need to post some data to an external resource it is still great to build
Sometimes when you submit data to an external resource, like payment gateway, fields you can use in your form are limited by an external API. So you may want not to generate an `authenticity_token` hidden field at all. For doing this just pass `false` to the `:authenticity_token` option:
```erb
<%= form_tag 'http://farfar.away/form', :authenticity_token => false) do %>
<%= form_tag 'http://farfar.away/form', authenticity_token: false) do %>
Form contents
<% end %>
```
@ -810,7 +810,7 @@ Sometimes when you submit data to an external resource, like payment gateway, fi
The same technique is available for the `form_for` too:
```erb
<%= form_for @invoice, :url => external_url, :authenticity_token => 'external_token' do |f| %>
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
Form contents
<% end %>
```
@ -818,7 +818,7 @@ The same technique is available for the `form_for` too:
Or if you don't want to render an `authenticity_token` field:
```erb
<%= form_for @invoice, :url => external_url, :authenticity_token => false do |f| %>
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %>
Form contents
<% end %>
```
@ -902,7 +902,7 @@ end
The keys of the `:addresses_attributes` hash are unimportant, they need merely be different for each address.
If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `:include_id => false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an id.
If the associated object is already saved, `fields_for` autogenerates a hidden input with the `id` of the saved record. You can disable this by passing `include_id: false` to `fields_for`. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an id.
### The Controller
@ -910,12 +910,12 @@ You do not need to write any specific controller code to use nested attributes.
### Removing Objects
You can allow users to delete associated objects by passing `allow_destroy => true` to `accepts_nested_attributes_for`
You can allow users to delete associated objects by passing `allow_destroy: true` to `accepts_nested_attributes_for`
```ruby
class Person < ActiveRecord::Base
has_many :addresses
accepts_nested_attributes_for :addresses, :allow_destroy => true
accepts_nested_attributes_for :addresses, allow_destroy: true
end
```
@ -944,7 +944,7 @@ It is often useful to ignore sets of fields that the user has not filled in. You
```ruby
class Person < ActiveRecord::Base
has_many :addresses
accepts_nested_attributes_for :addresses, :reject_if => lambda {|attributes| attributes['kind'].blank?}
accepts_nested_attributes_for :addresses, reject_if: lambda {|attributes| attributes['kind'].blank?}
end
```

View File

@ -164,7 +164,7 @@ Rails own generators are flexible enough to let you customize scaffolding. They
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :test_unit, :fixture => true
g.test_framework :test_unit, fixture: true
end
```
@ -206,7 +206,7 @@ Our first customization on the workflow will be to stop generating stylesheets a
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :test_unit, :fixture => false
g.test_framework :test_unit, fixture: false
g.stylesheets false
end
```
@ -253,7 +253,7 @@ Which is what we expected. We can now tell scaffold to use our new helper genera
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :test_unit, :fixture => false
g.test_framework :test_unit, fixture: false
g.stylesheets false
g.helper :my_helper
end
@ -292,7 +292,7 @@ Now, when the helper generator is invoked and TestUnit is configured as the test
```ruby
# Search for :helper instead of :my_helper
hook_for :test_framework, :as => :helper
hook_for :test_framework, as: :helper
```
And now you can re-run scaffold for another resource and see it generating tests as well!
@ -316,7 +316,7 @@ and revert the last change in `config/application.rb`:
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :test_unit, :fixture => false
g.test_framework :test_unit, fixture: false
g.stylesheets false
end
```
@ -334,7 +334,7 @@ We can easily simulate this behavior by changing our `config/application.rb` onc
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :shoulda, :fixture => false
g.test_framework :shoulda, fixture: false
g.stylesheets false
# Add a fallback!
@ -376,18 +376,18 @@ Fallbacks allow your generators to have a single responsibility, increasing code
Application Templates
---------------------
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template".
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template". This is a brief overview of the Templates API. For detailed documentation see the [Rails Application Templates guide](rails_application_templates.html).
```ruby
gem("rspec-rails", :group => "test")
gem("cucumber-rails", :group => "test")
gem "rspec-rails", group: "test"
gem "cucumber-rails", group: "test"
if yes?("Would you like to install Devise?")
gem("devise")
generate("devise:install")
gem "devise"
generate "devise:install"
model_name = ask("What would you like the user model to be called? [user]")
model_name = "user" if model_name.blank?
generate("devise", model_name)
generate "devise", model_name
end
```
@ -421,8 +421,8 @@ NOTE: Methods provided by Thor are not covered this guide and can be found in [T
Specifies a gem dependency of the application.
```ruby
gem("rspec", :group => "test", :version => "2.1.0")
gem("devise", "1.1.5")
gem "rspec", group: "test", version: "2.1.0"
gem "devise", "1.1.5"
```
Available options are:
@ -434,13 +434,13 @@ Available options are:
Any additional options passed to this method are put on the end of the line:
```ruby
gem("devise", :git => "git://github.com/plataformatec/devise", :branch => "master")
gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
```
The above code will put the following line into `Gemfile`:
```ruby
gem "devise", :git => "git://github.com/plataformatec/devise", :branch => "master"
gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
```
### `gem_group`
@ -466,7 +466,7 @@ add_source "http://gems.github.com"
Injects a block of code into a defined position in your file.
```ruby
inject_into_file 'name_of_file.rb', :after => "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY'
inject_into_file 'name_of_file.rb', after: "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY'
puts "Hello World"
RUBY
end
@ -503,7 +503,7 @@ Available options are:
* `:env` - Specify an environment for this configuration option. If you wish to use this option with the block syntax the recommended syntax is as follows:
```ruby
application(nil, :env => "development") do
application(nil, env: "development") do
"config.asset_host = 'http://localhost:3000'"
end
```
@ -514,9 +514,9 @@ Runs the specified git command:
```ruby
git :init
git :add => "."
git :commit => "-m First commit!"
git :add => "onefile.rb", :rm => "badfile.cxx"
git add: "."
git commit: "-m First commit!"
git add: "onefile.rb", rm: "badfile.cxx"
```
The values of the hash here being the arguments or options passed to the specific git command. As per the final example shown here, multiple git commands can be specified at a time, but the order of their running is not guaranteed to be the same as the order that they were specified in.
@ -526,13 +526,13 @@ The values of the hash here being the arguments or options passed to the specifi
Places a file into `vendor` which contains the specified code.
```ruby
vendor("sekrit.rb", '#top secret stuff')
vendor "sekrit.rb", '#top secret stuff'
```
This method also takes a block:
```ruby
vendor("seeds.rb") do
vendor "seeds.rb" do
"puts 'in ur app, seeding ur database'"
end
```
@ -542,13 +542,13 @@ end
Places a file into `lib` which contains the specified code.
```ruby
lib("special.rb", 'p Rails.root')
lib "special.rb", "p Rails.root"
```
This method also takes a block:
```ruby
lib("super_special.rb") do
lib "super_special.rb" do
puts "Super special!"
end
```
@ -558,15 +558,15 @@ end
Creates a Rake file in the `lib/tasks` directory of the application.
```ruby
rakefile("test.rake", 'hello there')
rakefile "test.rake", "hello there"
```
This method also takes a block:
```ruby
rakefile("test.rake") do
rakefile "test.rake" do
%Q{
task :rock => :environment do
task rock: :environment do
puts "Rockin'"
end
}
@ -578,13 +578,13 @@ end
Creates an initializer in the `config/initializers` directory of the application:
```ruby
initializer("begin.rb", "puts 'this is the beginning'")
initializer "begin.rb", "puts 'this is the beginning'"
```
This method also takes a block:
```ruby
initializer("begin.rb") do
initializer "begin.rb" do
puts "Almost done!"
end
```
@ -594,7 +594,7 @@ end
Runs the specified generator where the first argument is the generator name and the remaining arguments are passed directly to the generator.
```ruby
generate("scaffold", "forums title:string description:text")
generate "scaffold", "forums title:string description:text"
```
@ -603,7 +603,7 @@ generate("scaffold", "forums title:string description:text")
Runs the specified Rake task.
```ruby
rake("db:migrate")
rake "db:migrate"
```
Available options are:
@ -624,7 +624,7 @@ capify!
Adds text to the `config/routes.rb` file:
```ruby
route("resources :people")
route "resources :people"
```
### `readme`
@ -632,5 +632,5 @@ route("resources :people")
Output the contents of a file in the template's `source_path`, usually a README.
```ruby
readme("README")
readme "README"
```

View File

@ -263,11 +263,11 @@ It will look a little basic for now, but that's ok. We'll look at improving the
### Laying down the ground work
The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at `/posts/new`. If you attempt to navigate to that now -- by visiting <http://localhost:3000/posts/new> -- Rails will give you a routing error:
The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at `/posts/new`. If you attempt to navigate to that now by visiting <http://localhost:3000/posts/new> Rails will give you a routing error:
![A routing error, no route matches /posts/new](images/getting_started/routing_error_no_route_matches.png)
This is because there is nowhere inside the routes for the application -- defined inside `config/routes.rb` -- that defines this route. By default, Rails has no routes configured at all, besides the root route you defined earlier, and so you must define your routes as you need them.
This is because there is nowhere inside the routes for the application — defined inside `config/routes.rb` that defines this route. By default, Rails has no routes configured at all, besides the root route you defined earlier, and so you must define your routes as you need them.
To do this, you're going to need to create a route inside `config/routes.rb` file, on a new line between the `do` and the `end` for the `draw` method:
@ -325,7 +325,7 @@ That's quite a lot of text! Let's quickly go through and understand what each pa
The first part identifies what template is missing. In this case, it's the `posts/new` template. Rails will first look for this template. If not found, then it will attempt to load a template called `application/new`. It looks for one here because the `PostsController` inherits from `ApplicationController`.
The next part of the message contains a hash. The `:locale` key in this hash simply indicates what spoken language template should be retrieved. By default, this is the English -- or "en" -- template. The next key, `:formats` specifies the format of template to be served in response. The default format is `:html`, and so Rails is looking for an HTML template. The final key, `:handlers`, is telling us what _template handlers_ could be used to render our template. `:erb` is most commonly used for HTML templates, `:builder` is used for XML templates, and `:coffee` uses CoffeeScript to build JavaScript templates.
The next part of the message contains a hash. The `:locale` key in this hash simply indicates what spoken language template should be retrieved. By default, this is the English — or "en" — template. The next key, `:formats` specifies the format of template to be served in response. The default format is `:html`, and so Rails is looking for an HTML template. The final key, `:handlers`, is telling us what _template handlers_ could be used to render our template. `:erb` is most commonly used for HTML templates, `:builder` is used for XML templates, and `:coffee` uses CoffeeScript to build JavaScript templates.
The final part of this message tells us where Rails has looked for the templates. Templates within a basic Rails application like this are kept in a single location, but in more complex applications it could be many different paths.
@ -368,7 +368,7 @@ If you refresh the page now, you'll see the exact same form as in the example. B
When you call `form_for`, you pass it an identifying object for this
form. In this case, it's the symbol `:post`. This tells the `form_for`
helper what this form is for. Inside the block for this method, the
`FormBuilder` object -- represented by `f` -- is used to build two labels and two text fields, one each for the title and text of a post. Finally, a call to `submit` on the `f` object will create a submit button for the form.
`FormBuilder` object — represented by `f` is used to build two labels and two text fields, one each for the title and text of a post. Finally, a call to `submit` on the `f` object will create a submit button for the form.
There's one problem with this form though. If you inspect the HTML that is generated, by viewing the source of the page, you will see that the `action` attribute for the form is pointing at `/posts/new`. This is a problem because this route goes to the very page that you're on right at the moment, and that route should only be used to display the form for a new post.
@ -653,7 +653,7 @@ Let's add links to the other views as well, starting with adding this "New Post"
<%= link_to 'New post', action: :new %>
```
This link will allow you to bring up the form that lets you create a new post. You should also add a link to this template -- `app/views/posts/new.html.erb` -- to go back to the `index` action. Do this by adding this underneath the form in this template:
This link will allow you to bring up the form that lets you create a new post. You should also add a link to this template `app/views/posts/new.html.erb` to go back to the `index` action. Do this by adding this underneath the form in this template:
```erb
<%= form_for :post do |f| %>

View File

@ -13,8 +13,8 @@ So, in the process of _internationalizing_ your Rails application you have to:
In the process of _localizing_ your application you'll probably want to do the following three things:
* Replace or supplement Rails' default locale -- e.g. date and time formats, month names, Active Record model names, etc.
* Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc.
* Replace or supplement Rails' default locale e.g. date and time formats, month names, Active Record model names, etc.
* Abstract strings in your application into keyed dictionaries e.g. flash messages, static text in your views, etc.
* Store the resulting dictionaries somewhere
This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start.
@ -31,13 +31,13 @@ Internationalization is a complex problem. Natural languages differ in so many w
* providing support for English and similar languages out of the box
* making it easy to customize and extend everything for other languages
As part of this solution, **every static string in the Rails framework** -- e.g. Active Record validation messages, time and date formats -- **has been internationalized**, so _localization_ of a Rails application means "over-riding" these defaults.
As part of this solution, **every static string in the Rails framework** — e.g. Active Record validation messages, time and date formats — **has been internationalized**, so _localization_ of a Rails application means "over-riding" these defaults.
### The Overall Architecture of the Library
Thus, the Ruby I18n gem is split into two parts:
* The public API of the i18n framework -- a Ruby module with public methods that define how the library works
* The public API of the i18n framework a Ruby module with public methods that define how the library works
* A default backend (which is intentionally named _Simple_ backend) that implements these methods
As a user you should always only access the public methods on the I18n module, but it is useful to know about the capabilities of the backend.
@ -260,7 +260,7 @@ NOTE: Have a look at two plugins which simplify work with routes in this way: Sv
### Setting the Locale from the Client Supplied Information
In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' preferred language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites -- see the box about _sessions_, _cookies_ and RESTful architecture above.
In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' preferred language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites see the box about _sessions_, _cookies_ and RESTful architecture above.
#### Using `Accept-Language`
@ -285,11 +285,11 @@ Of course, in a production environment you would need much more robust code, and
#### Using GeoIP (or Similar) Database
Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as [GeoIP Lite Country](http://www.maxmind.com/app/geolitecountry). The mechanics of the code would be very similar to the code above -- you would need to query the database for the user's IP, and look up your preferred locale for the country/region/city returned.
Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as [GeoIP Lite Country](http://www.maxmind.com/app/geolitecountry). The mechanics of the code would be very similar to the code above you would need to query the database for the user's IP, and look up your preferred locale for the country/region/city returned.
#### User Profile
You can also provide users of your application with means to set (and possibly over-ride) the locale in your application interface, as well. Again, mechanics for this approach would be very similar to the code above -- you'd probably let users choose a locale from a dropdown list and save it to their profile in the database. Then you'd set the locale to this value.
You can also provide users of your application with means to set (and possibly over-ride) the locale in your application interface, as well. Again, mechanics for this approach would be very similar to the code above you'd probably let users choose a locale from a dropdown list and save it to their profile in the database. Then you'd set the locale to this value.
Internationalizing your Application
-----------------------------------
@ -392,7 +392,7 @@ en:
### Adding Date/Time Formats
OK! Now let's add a timestamp to the view, so we can demo the **date/time localization** feature as well. To localize the time format you pass the Time object to `I18n.l` or (preferably) use Rails' `#l` helper. You can pick a format by passing the `:format` option -- by default the `:default` format is used.
OK! Now let's add a timestamp to the view, so we can demo the **date/time localization** feature as well. To localize the time format you pass the Time object to `I18n.l` or (preferably) use Rails' `#l` helper. You can pick a format by passing the `:format` option by default the `:default` format is used.
```erb
# app/views/home/index.html.erb

View File

@ -9,8 +9,7 @@ Ruby on Rails Guides
<% content_for :index_section do %>
<div id="subCol">
<dl>
<dd class="kindle">Rails Guides are also available for the <%= link_to 'Kindle', 'https://kindle.amazon.com' %>
and <%= link_to 'Free Kindle Reading Apps', 'http://www.amazon.com/gp/kindle/kcp' %> for the iPad,
<dd class="kindle">Rails Guides are also available for Kindle and <%= link_to 'Free Kindle Reading Apps', 'http://www.amazon.com/gp/kindle/kcp' %> for the iPad,
iPhone, Mac, Android, etc. Download them from <%= link_to 'here', @mobi %>.
</dd>
<dd class="work-in-progress">Guides marked with this icon are currently being worked on and will not be available in the Guides Index menu. While still useful, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections.</dd>

View File

@ -81,7 +81,7 @@ If we want to display the properties of all the books in our view, we can do so
<td><%= book.content %></td>
<td><%= link_to "Show", book %></td>
<td><%= link_to "Edit", edit_book_path(book) %></td>
<td><%= link_to "Remove", book, :method => :delete, :data => { :confirm => "Are you sure?" } %></td>
<td><%= link_to "Remove", book, method: :delete, data: { confirm: "Are you sure?" } %></td>
</tr>
<% end %>
</table>
@ -104,7 +104,7 @@ TIP: If you want to see the exact results of a call to `render` without needing
Perhaps the simplest thing you can do with `render` is to render nothing at all:
```ruby
render :nothing => true
render nothing: true
```
If you look at the response for this using cURL, you will see the following:
@ -130,7 +130,7 @@ TIP: You should probably be using the `head` method, discussed later in this gui
#### Rendering an Action's View
If you want to render the view that corresponds to a different action within the same template, you can use `render` with the name of the view:
If you want to render the view that corresponds to a different template within the same controller, you can use `render` with the name of the view:
```ruby
def update
@ -166,7 +166,7 @@ def update
if @book.update_attributes(params[:book])
redirect_to(@book)
else
render :action => "edit"
render action: "edit"
end
end
```
@ -184,7 +184,7 @@ render "products/show"
Rails knows that this view belongs to a different controller because of the embedded slash character in the string. If you want to be explicit, you can use the `:template` option (which was required on Rails 2.2 and earlier):
```ruby
render :template => "products/show"
render template: "products/show"
```
#### Rendering an Arbitrary File
@ -198,13 +198,12 @@ render "/u/apps/warehouse_app/current/app/views/products/show"
Rails determines that this is a file render because of the leading slash character. To be explicit, you can use the `:file` option (which was required on Rails 2.2 and earlier):
```ruby
render :file =>
"/u/apps/warehouse_app/current/app/views/products/show"
render file: "/u/apps/warehouse_app/current/app/views/products/show"
```
The `:file` option takes an absolute file-system path. Of course, you need to have rights to the view that you're using to render the content.
NOTE: By default, the file is rendered without using the current layout. If you want Rails to put the file into the current layout, you need to add the `:layout => true` option.
NOTE: By default, the file is rendered without using the current layout. If you want Rails to put the file into the current layout, you need to add the `layout: true` option.
TIP: If you're running Rails on Microsoft Windows, you should use the `:file` option to render a file, because Windows filenames do not have the same format as Unix filenames.
@ -216,19 +215,19 @@ In fact, in the BooksController class, inside of the update action where we want
```ruby
render :edit
render :action => :edit
render action: :edit
render "edit"
render "edit.html.erb"
render :action => "edit"
render :action => "edit.html.erb"
render action: "edit"
render action: "edit.html.erb"
render "books/edit"
render "books/edit.html.erb"
render :template => "books/edit"
render :template => "books/edit.html.erb"
render template: "books/edit"
render template: "books/edit.html.erb"
render "/path/to/rails/app/views/books/edit"
render "/path/to/rails/app/views/books/edit.html.erb"
render :file => "/path/to/rails/app/views/books/edit"
render :file => "/path/to/rails/app/views/books/edit.html.erb"
render file: "/path/to/rails/app/views/books/edit"
render file: "/path/to/rails/app/views/books/edit.html.erb"
```
Which one you use is really a matter of style and convention, but the rule of thumb is to use the simplest one that makes sense for the code you are writing.
@ -238,8 +237,7 @@ Which one you use is really a matter of style and convention, but the rule of th
The `render` method can do without a view completely, if you're willing to use the `:inline` option to supply ERB as part of the method call. This is perfectly valid:
```ruby
render :inline =>
"<% products.each do |p| %><p><%= p.name %></p><% end %>"
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
```
WARNING: There is seldom any good reason to use this option. Mixing ERB into your controllers defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. Use a separate erb view instead.
@ -247,8 +245,7 @@ WARNING: There is seldom any good reason to use this option. Mixing ERB into you
By default, inline rendering uses ERB. You can force it to use Builder instead with the `:type` option:
```ruby
render :inline =>
"xml.p {'Horrid coding practice!'}", :type => :builder
render inline: "xml.p {'Horrid coding practice!'}", type: :builder
```
#### Rendering Text
@ -256,19 +253,19 @@ render :inline =>
You can send plain text - with no markup at all - back to the browser by using the `:text` option to `render`:
```ruby
render :text => "OK"
render text: "OK"
```
TIP: Rendering pure text is most useful when you're responding to Ajax or web service requests that are expecting something other than proper HTML.
NOTE: By default, if you use the `:text` option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the `:layout => true` option.
NOTE: By default, if you use the `:text` option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the `layout: true` option.
#### Rendering JSON
JSON is a JavaScript data format used by many Ajax libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:
```ruby
render :json => @product
render json: @product
```
TIP: You don't need to call `to_json` on the object that you want to render. If you use the `:json` option, `render` will automatically call `to_json` for you.
@ -278,7 +275,7 @@ TIP: You don't need to call `to_json` on the object that you want to render. If
Rails also has built-in support for converting objects to XML and rendering that XML back to the caller:
```ruby
render :xml => @product
render xml: @product
```
TIP: You don't need to call `to_xml` on the object that you want to render. If you use the `:xml` option, `render` will automatically call `to_xml` for you.
@ -288,7 +285,7 @@ TIP: You don't need to call `to_xml` on the object that you want to render. If y
Rails can render vanilla JavaScript:
```ruby
render :js => "alert('Hello Rails');"
render js: "alert('Hello Rails');"
```
This will send the supplied string to the browser with a MIME type of `text/javascript`.
@ -307,7 +304,7 @@ Calls to the `render` method generally accept four options:
By default, Rails will serve the results of a rendering operation with the MIME content-type of `text/html` (or `application/json` if you use the `:json` option, or `application/xml` for the `:xml` option.). There are times when you might like to change this, and you can do so by setting the `:content_type` option:
```ruby
render :file => filename, :content_type => "application/rss"
render file: filename, content_type: "application/rss"
```
##### The `:layout` Option
@ -317,13 +314,13 @@ With most of the options to `render`, the rendered content is displayed as part
You can use the `:layout` option to tell Rails to use a specific file as the layout for the current action:
```ruby
render :layout => "special_layout"
render layout: "special_layout"
```
You can also tell Rails to render with no layout at all:
```ruby
render :layout => false
render layout: false
```
##### The `:status` Option
@ -331,8 +328,8 @@ render :layout => false
Rails will automatically generate a response with the correct HTTP status code (in most cases, this is `200 OK`). You can use the `:status` option to change this:
```ruby
render :status => 500
render :status => :forbidden
render status: 500
render status: :forbidden
```
Rails understands both numeric and symbolic status codes.
@ -342,7 +339,7 @@ Rails understands both numeric and symbolic status codes.
You can use the `:location` option to set the HTTP `Location` header:
```ruby
render :xml => photo, :location => photo_url(photo)
render xml: photo, location: photo_url(photo)
```
#### Finding Layouts
@ -409,7 +406,7 @@ Layouts specified at the controller level support the `:only` and `:except` opti
```ruby
class ProductsController < ApplicationController
layout "product", :except => [:index, :rss]
layout "product", except: [:index, :rss]
end
```
@ -454,7 +451,7 @@ Layout declarations cascade downward in the hierarchy, and more specific layout
def index
@old_posts = Post.older
render :layout => "old"
render layout: "old"
end
# ...
end
@ -478,9 +475,9 @@ For example, here's some code that will trigger this error:
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show"
render action: "special_show"
end
render :action => "regular_show"
render action: "regular_show"
end
```
@ -490,9 +487,9 @@ If `@book.special?` evaluates to `true`, Rails will start the rendering process
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show" and return
render action: "special_show" and return
end
render :action => "regular_show"
render action: "regular_show"
end
```
@ -504,7 +501,7 @@ Note that the implicit render done by ActionController detects if `render` has b
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show"
render action: "special_show"
end
end
```
@ -530,7 +527,7 @@ redirect_to :back
Rails uses HTTP status code 302, a temporary redirect, when you call `redirect_to`. If you'd like to use a different status code, perhaps 301, a permanent redirect, you can use the `:status` option:
```ruby
redirect_to photos_path, :status => 301
redirect_to photos_path, status: 301
```
Just like the `:status` option for `render`, `:status` for `redirect_to` accepts both numeric and symbolic header designations.
@ -549,7 +546,7 @@ end
def show
@book = Book.find_by_id(params[:id])
if @book.nil?
render :action => "index"
render action: "index"
end
end
```
@ -564,7 +561,7 @@ end
def show
@book = Book.find_by_id(params[:id])
if @book.nil?
redirect_to :action => :index
redirect_to action: :index
end
end
```
@ -584,7 +581,7 @@ def show
@book = Book.find_by_id(params[:id])
if @book.nil?
@books = Book.all
render "index", :alert => "Your book was not found!"
render "index", alert: "Your book was not found!"
end
end
```
@ -615,7 +612,7 @@ Cache-Control: no-cache
Or you can use other HTTP headers to convey other information:
```ruby
head :created, :location => photo_path(@photo)
head :created, location: photo_path(@photo)
```
Which would produce:
@ -661,8 +658,8 @@ WARNING: The asset tag helpers do _not_ verify the existence of the assets at th
The `auto_discovery_link_tag` helper builds HTML that most browsers and newsreaders can use to detect the presence of RSS or Atom feeds. It takes the type of the link (`:rss` or `:atom`), a hash of options that are passed through to url_for, and a hash of options for the tag:
```erb
<%= auto_discovery_link_tag(:rss, {:action => "feed"},
{:title => "RSS Feed"}) %>
<%= auto_discovery_link_tag(:rss, {action: "feed"},
{title: "RSS Feed"}) %>
```
There are three tag options available for the `auto_discovery_link_tag`:
@ -759,20 +756,20 @@ Note that your defaults of choice will be included first, so they will be availa
You can supply the `:recursive` option to load files in subfolders of `public/javascripts` as well:
```erb
<%= javascript_include_tag :all, :recursive => true %>
<%= javascript_include_tag :all, recursive: true %>
```
If you're loading multiple JavaScript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify `:cache => true` in your `javascript_include_tag`:
If you're loading multiple JavaScript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify `cache: true` in your `javascript_include_tag`:
```erb
<%= javascript_include_tag "main", "columns", :cache => true %>
<%= javascript_include_tag "main", "columns", cache: true %>
```
By default, the combined file will be delivered as `javascripts/all.js`. You can specify a location for the cached asset file instead:
```erb
<%= javascript_include_tag "main", "columns",
:cache => "cache/main/display" %>
cache: "cache/main/display" %>
```
You can even use dynamic paths such as `cache/#{current_site}/main/display`.
@ -810,7 +807,7 @@ To include `http://example.com/main.css`:
By default, the `stylesheet_link_tag` creates links with `media="screen" rel="stylesheet"`. You can override any of these defaults by specifying an appropriate option (`:media`, `:rel`):
```erb
<%= stylesheet_link_tag "main_print", :media => "print" %>
<%= stylesheet_link_tag "main_print", media: "print" %>
```
If the asset pipeline is disabled, the `all` option links every CSS file in `public/stylesheets`:
@ -822,20 +819,20 @@ If the asset pipeline is disabled, the `all` option links every CSS file in `pub
You can supply the `:recursive` option to link files in subfolders of `public/stylesheets` as well:
```erb
<%= stylesheet_link_tag :all, :recursive => true %>
<%= stylesheet_link_tag :all, recursive: true %>
```
If you're loading multiple CSS files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify `:cache => true` in your `stylesheet_link_tag`:
If you're loading multiple CSS files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify `cache: true` in your `stylesheet_link_tag`:
```erb
<%= stylesheet_link_tag "main", "columns", :cache => true %>
<%= stylesheet_link_tag "main", "columns", cache: true %>
```
By default, the combined file will be delivered as `stylesheets/all.css`. You can specify a location for the cached asset file instead:
```erb
<%= stylesheet_link_tag "main", "columns",
:cache => "cache/main/display" %>
cache: "cache/main/display" %>
```
You can even use dynamic paths such as `cache/#{current_site}/main/display`.
@ -859,28 +856,28 @@ You can supply a path to the image if you like:
You can supply a hash of additional HTML options:
```erb
<%= image_tag "icons/delete.gif", {:height => 45} %>
<%= image_tag "icons/delete.gif", {height: 45} %>
```
You can supply alternate text for the image which will be used if the user has images turned off in their browser. If you do not specify an alt text explicitly, it defaults to the file name of the file, capitalized and with no extension. For example, these two image tags would return the same code:
```erb
<%= image_tag "home.gif" %>
<%= image_tag "home.gif", :alt => "Home" %>
<%= image_tag "home.gif", alt: "Home" %>
```
You can also specify a special size tag, in the format "{width}x{height}":
```erb
<%= image_tag "home.gif", :size => "50x20" %>
<%= image_tag "home.gif", size: "50x20" %>
```
In addition to the above special tags, you can supply a final hash of standard HTML options, such as `:class`, `:id` or `:name`:
```erb
<%= image_tag "home.gif", :alt => "Go Home",
:id => "HomeImage",
:class => "nav_bar" %>
<%= image_tag "home.gif", alt: "Go Home",
id: "HomeImage",
class: "nav_bar" %>
```
#### Linking to Videos with the `video_tag`
@ -897,15 +894,15 @@ Produces
<video src="/videos/movie.ogg" />
```
Like an `image_tag` you can supply a path, either absolute, or relative to the `public/videos` directory. Additionally you can specify the `:size => "#{width}x#{height}"` option just like an `image_tag`. Video tags can also have any of the HTML options specified at the end (`id`, `class` et al).
Like an `image_tag` you can supply a path, either absolute, or relative to the `public/videos` directory. Additionally you can specify the `size: "#{width}x#{height}"` option just like an `image_tag`. Video tags can also have any of the HTML options specified at the end (`id`, `class` et al).
The video tag also supports all of the `<video>` HTML options through the HTML options hash, including:
* `:poster => "image_name.png"`, provides an image to put in place of the video before it starts playing.
* `:autoplay => true`, starts playing the video on page load.
* `:loop => true`, loops the video once it gets to the end.
* `:controls => true`, provides browser supplied controls for the user to interact with the video.
* `:autobuffer => true`, the video will pre load the file for the user on page load.
* `poster: "image_name.png"`, provides an image to put in place of the video before it starts playing.
* `autoplay: true`, starts playing the video on page load.
* `loop: true`, loops the video once it gets to the end.
* `controls: true`, provides browser supplied controls for the user to interact with the video.
* `autobuffer: true`, the video will pre load the file for the user on page load.
You can also specify multiple videos to play by passing an array of videos to the `video_tag`:
@ -937,9 +934,9 @@ You can also supply a hash of additional options, such as `:id`, `:class` etc.
Like the `video_tag`, the `audio_tag` has special options:
* `:autoplay => true`, starts playing the audio on page load
* `:controls => true`, provides browser supplied controls for the user to interact with the audio.
* `:autobuffer => true`, the audio will pre load the file for the user on page load.
* `autoplay: true`, starts playing the audio on page load
* `controls: true`, provides browser supplied controls for the user to interact with the audio.
* `autobuffer: true`, the audio will pre load the file for the user on page load.
### Understanding `yield`
@ -1041,7 +1038,7 @@ TIP: For content that is shared among all pages in your application, you can use
A partial can use its own layout file, just as a view can use a layout. For example, you might call a partial like this:
```erb
<%= render :partial => "link_area", :layout => "graybar" %>
<%= render partial: "link_area", layout: "graybar" %>
```
This would look for a partial named `_link_area.html.erb` and render it using the layout `_graybar.html.erb`. Note that layouts for partials follow the same leading-underscore naming as regular partials, and are placed in the same folder with the partial that they belong to (not in the master `layouts` folder).
@ -1057,7 +1054,7 @@ You can also pass local variables into partials, making them even more powerful
```html+erb
<h1>New zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
<%= render partial: "form", locals: {zone: @zone} %>
```
* `edit.html.erb`
@ -1065,7 +1062,7 @@ You can also pass local variables into partials, making them even more powerful
```html+erb
<h1>Editing zone</h1>
<%= error_messages_for :zone %>
<%= render :partial => "form", :locals => { :zone => @zone } %>
<%= render partial: "form", locals: {zone: @zone} %>
```
* `_form.html.erb`
@ -1087,7 +1084,7 @@ Although the same partial will be rendered into both views, Action View's submit
Every partial also has a local variable with the same name as the partial (minus the underscore). You can pass an object in to this local variable via the `:object` option:
```erb
<%= render :partial => "customer", :object => @new_customer %>
<%= render partial: "customer", object: @new_customer %>
```
Within the `customer` partial, the `customer` variable will refer to `@new_customer` from the parent view.
@ -1110,7 +1107,7 @@ Partials are very useful in rendering collections. When you pass a collection to
```html+erb
<h1>Products</h1>
<%= render :partial => "product", :collection => @products %>
<%= render partial: "product", collection: @products %>
```
* `_product.html.erb`
@ -1163,28 +1160,28 @@ In the event that the collection is empty, `render` will return nil, so it shoul
To use a custom local variable name within the partial, specify the `:as` option in the call to the partial:
```erb
<%= render :partial => "product", :collection => @products, :as => :item %>
<%= render partial: "product", collection: @products, as: :item %>
```
With this change, you can access an instance of the `@products` collection as the `item` local variable within the partial.
You can also pass in arbitrary local variables to any partial you are rendering with the `:locals => {}` option:
You can also pass in arbitrary local variables to any partial you are rendering with the `locals: {}` option:
```erb
<%= render :partial => "products", :collection => @products,
:as => :item, :locals => {:title => "Products Page"} %>
<%= render partial: "products", collection: @products,
as: :item, locals: {title: "Products Page"} %>
```
Would render a partial `_products.html.erb` once for each instance of `product` in the `@products` instance variable passing the instance to the partial as a local variable called `item` and to each partial, make the local variable `title` available with the value `Products Page`.
TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by `_counter`. For example, if you're rendering `@products`, within the partial you can refer to `product_counter` to tell you how many times the partial has been rendered. This does not work in conjunction with the `:as => :value` option.
TIP: Rails also makes a counter variable available within a partial called by the collection, named after the member of the collection followed by `_counter`. For example, if you're rendering `@products`, within the partial you can refer to `product_counter` to tell you how many times the partial has been rendered. This does not work in conjunction with the `as: :value` option.
You can also specify a second partial to be rendered between instances of the main partial by using the `:spacer_template` option:
#### Spacer Templates
```erb
<%= render :partial => @products, :spacer_template => "product_ruler" %>
<%= render partial: @products, spacer_template: "product_ruler" %>
```
Rails will render the `_product_ruler` partial (with no data passed in to it) between each pair of `_product` partials.
@ -1194,7 +1191,7 @@ Rails will render the `_product_ruler` partial (with no data passed in to it) be
When rendering collections it is also possible to use the `:layout` option:
```erb
<%= render :partial => "product", :collection => @products, :layout => "special_layout" %>
<%= render partial: "product", collection: @products, layout: "special_layout" %>
```
The layout will be rendered together with the partial for each item in the collection. The current object and object_counter variables will be available in the layout as well, the same way they do within the partial.
@ -1235,9 +1232,9 @@ On pages generated by `NewsController`, you want to hide the top menu and add a
<div id="right_menu">Right menu items here</div>
<%= content_for?(:news_content) ? yield(:news_content) : yield %>
<% end %>
<%= render :template => "layouts/application" %>
<%= render template: "layouts/application" %>
```
That's it. The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div.
There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the `ActionView::render` method via `render :template => 'layouts/news'` to base a new layout on the News layout. If you are sure you will not subtemplate the `News` layout, you can replace the `content_for?(:news_content) ? yield(:news_content) : yield` with simply `yield`.
There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the `ActionView::render` method via `render template: 'layouts/news'` to base a new layout on the News layout. If you are sure you will not subtemplate the `News` layout, you can replace the `content_for?(:news_content) ? yield(:news_content) : yield` with simply `yield`.

View File

@ -64,9 +64,9 @@ bad data in the database or populate new fields:
class AddReceiveNewsletterToUsers < ActiveRecord::Migration
def up
change_table :users do |t|
t.boolean :receive_newsletter, :default => false
t.boolean :receive_newsletter, default: false
end
User.update_all :receive_newsletter => true
User.update_all receive_newsletter: true
end
def down
@ -215,7 +215,7 @@ columns of types not supported by Active Record when using the non-sexy syntax s
```ruby
create_table :products do |t|
t.column :name, 'polygon', :null => false
t.column :name, 'polygon', null: false
end
```
@ -349,7 +349,7 @@ generates
```ruby
class AddUserRefToProducts < ActiveRecord::Migration
def change
add_reference :products, :user, :index => true
add_reference :products, :user, index: true
end
end
```
@ -377,8 +377,8 @@ will produce a migration that looks like this
```ruby
class AddDetailsToProducts < ActiveRecord::Migration
def change
add_column :products, :price, :precision => 5, :scale => 2
add_reference :products, :user, :polymorphic => true, :index => true
add_column :products, :price, precision: 5, scale: 2
add_reference :products, :user, polymorphic: true, index: true
end
end
```
@ -408,7 +408,7 @@ are two ways of doing it. The first (traditional) form looks like
```ruby
create_table :products do |t|
t.column :name, :string, :null => false
t.column :name, :string, null: false
end
```
@ -418,20 +418,20 @@ of that type. Subsequent parameters are the same.
```ruby
create_table :products do |t|
t.string :name, :null => false
t.string :name, null: false
end
```
By default, `create_table` will create a primary key called `id`. You can change
the name of the primary key with the `:primary_key` option (don't forget to
update the corresponding model) or, if you don't want a primary key at all (for
example for a HABTM join table), you can pass the option `:id => false`. If you
example for a HABTM join table), you can pass the option `id: false`. If you
need to pass database specific options you can place an SQL fragment in the
`:options` option. For example,
```ruby
create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
t.string :name, :null => false
create_table :products, options: "ENGINE=BLACKHOLE" do |t|
t.string :name, null: false
end
```
@ -453,7 +453,7 @@ These columns have the option `:null` set to `false` by default.
You can pass the option `:table_name` with you want to customize the table name. For example,
```ruby
create_join_table :products, :categories, :table_name => :categorization
create_join_table :products, :categories, table_name: :categorization
```
will create a `categorization` table.
@ -462,7 +462,7 @@ By default, `create_join_table` will create two columns with no options, but you
options using the `:column_options` option. For example,
```ruby
create_join_table :products, :categories, :column_options => {:null => true}
create_join_table :products, :categories, column_options: {null: true}
```
will create the `product_id` and `category_id` with the `:null` option as `true`.
@ -523,7 +523,7 @@ of the columns required:
```ruby
create_table :products do |t|
t.references :attachment, :polymorphic => {:default => 'Photo'}
t.references :attachment, polymorphic: {default: 'Photo'}
end
```
@ -533,7 +533,7 @@ index directly, instead of using `add_index` after the `create_table` call:
```ruby
create_table :products do |t|
t.references :category, :index => true
t.references :category, index: true
end
```
@ -795,7 +795,7 @@ column.
class AddFlagToProduct < ActiveRecord::Migration
def change
add_column :products, :flag, :boolean
Product.update_all :flag => false
Product.update_all flag: false
end
end
```
@ -804,7 +804,7 @@ end
# app/model/product.rb
class Product < ActiveRecord::Base
validates :flag, :presence => true
validates :flag, presence: true
end
```
@ -818,7 +818,7 @@ column.
class AddFuzzToProduct < ActiveRecord::Migration
def change
add_column :products, :fuzz, :string
Product.update_all :fuzz => 'fuzzy'
Product.update_all fuzz: 'fuzzy'
end
end
```
@ -827,7 +827,7 @@ end
# app/model/product.rb
class Product < ActiveRecord::Base
validates :flag, :fuzz, :presence => true
validates :flag, :fuzz, presence: true
end
```
@ -870,7 +870,7 @@ class AddFlagToProduct < ActiveRecord::Migration
def change
add_column :products, :flag, :boolean
Product.reset_column_information
Product.update_all :flag => false
Product.update_all flag: false
end
end
```
@ -885,7 +885,7 @@ class AddFuzzToProduct < ActiveRecord::Migration
def change
add_column :products, :fuzz, :string
Product.reset_column_information
Product.update_all :fuzz => 'fuzzy'
Product.update_all fuzz: 'fuzzy'
end
end
```
@ -1000,7 +1000,7 @@ the database. As such, features such as triggers or foreign key constraints,
which push some of that intelligence back into the database, are not heavily
used.
Validations such as `validates :foreign_key, :uniqueness => true` are one way in
Validations such as `validates :foreign_key, uniqueness: true` are one way in
which models can enforce data integrity. The `:dependent` option on associations
allows models to automatically destroy child objects when the parent is
destroyed. Like anything which operates at the application level, these cannot

View File

@ -515,7 +515,7 @@ Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile
under MRI or REE:
```ruby
gem 'ruby-prof', git: 'git://github.com/wycats/ruby-prof.git'
gem 'ruby-prof'
```
Now run `bundle install` and you're ready to go.

View File

@ -237,7 +237,7 @@ end
# test/dummy/app/models/wickwall.rb
class Wickwall < ActiveRecord::Base
acts_as_yaffle :yaffle_text_field => :last_tweet
acts_as_yaffle yaffle_text_field: :last_tweet
end
```
@ -402,7 +402,7 @@ Gem plugins currently in development can easily be shared from any Git repositor
commit the code to a Git repository (like GitHub) and add a line to the Gemfile of the application in question:
```ruby
gem 'yaffle', :git => 'git://github.com/yaffle_watcher/yaffle.git'
gem 'yaffle', git: 'git://github.com/yaffle_watcher/yaffle.git'
```
After running `bundle install`, your gem functionality will be available to the application.

View File

@ -36,17 +36,17 @@ Rails templates API is very self explanatory and easy to understand. Here's an e
# template.rb
run "rm public/index.html"
generate(:scaffold, "person name:string")
route "root :to => 'people#index'"
route "root to: 'people#index'"
rake("db:migrate")
git :init
git :add => "."
git :commit => %Q{ -m 'Initial commit' }
git add: "."
git commit: %Q{ -m 'Initial commit' }
```
The following sections outlines the primary methods provided by the API:
### gem(name, options = {})
### gem(*args)
Adds a `gem` entry for the supplied gem to the generated applications `Gemfile`.
@ -85,6 +85,18 @@ For example, if you need to source a gem from "http://code.whytheluckystiff.net"
add_source "http://code.whytheluckystiff.net"
```
### environment/application(data=nil, options={}, &block)
Adds a line inside the `Application` class for `config/application.rb`.
If `options[:env]` is specified, the line is appended to the corresponding file in `config/environments`.
```ruby
environment 'config.action_mailer.default_url_options = {host: 'http://yourwebsite.example.com'}, env: 'production'
```
A block can be used in place of the `data` argument.
### vendor/lib/file/initializer(filename, data = nil, &block)
Adds an initializer to the generated applications `config/initializers` directory.
@ -136,7 +148,7 @@ end
The above creates `lib/tasks/bootstrap.rake` with a `boot:strap` rake task.
### generate(what, args)
### generate(what, *args)
Runs the supplied rails generator with given arguments.
@ -163,15 +175,15 @@ rake "db:migrate"
You can also run rake tasks with a different Rails environment:
```ruby
rake "db:migrate", :env => 'production'
rake "db:migrate", env: 'production'
```
### route(routing_code)
This adds a routing entry to the `config/routes.rb` file. In above steps, we generated a person scaffold and also removed `public/index.html`. Now to make `PeopleController#index` as the default page for the application:
Adds a routing entry to the `config/routes.rb` file. In above steps, we generated a person scaffold and also removed `public/index.html`. Now to make `PeopleController#index` as the default page for the application:
```ruby
route "root :to => 'person#index'"
route "root to: 'person#index'"
```
### inside(dir)
@ -203,7 +215,7 @@ CODE
These methods let you ask questions from templates and decide the flow based on the users answer. Lets say you want to freeze rails only if the user want to:
```ruby
rake("rails:freeze:gems") if yes?("Freeze rails gems ?")
rake("rails:freeze:gems") if yes?("Freeze rails gems?")
# no?(question) acts just the opposite.
```
@ -213,6 +225,6 @@ Rails templates let you run any git command:
```ruby
git :init
git :add => "."
git :commit => "-a -m 'Initial commit'"
git add: "."
git commit: "-a -m 'Initial commit'"
```

View File

@ -15,7 +15,7 @@ WARNING: This guide assumes a working knowledge of Rack protocol and Rack concep
Introduction to Rack
--------------------
bq. Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
- [Rack API Documentation](http://rack.rubyforge.org/doc/)
@ -58,7 +58,7 @@ Here's how it loads the middlewares:
```ruby
def middleware
middlewares = []
middlewares << [Rails::Rack::Debugger] if options[:debugger]
middlewares << [Rails::Rack::Debugger] if options[:debugger]
middlewares << [::Rack::ContentLength]
Hash.new(middlewares)
end
@ -101,7 +101,7 @@ Action Dispatcher Middleware Stack
Many of Action Dispatchers's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application.
NOTE: `ActionDispatch::MiddlewareStack` is Rails' equivalent of `Rack::Builder`, but built for better flexibility and more features to meet Rails' requirements.
NOTE: `ActionDispatch::MiddlewareStack` is Rails equivalent of `Rack::Builder`, but built for better flexibility and more features to meet Rails' requirements.
### Inspecting Middleware Stack
@ -132,11 +132,11 @@ use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use ActionDispatch::BestStandardsSupport
run ApplicationName::Application.routes
run MyApp::Application.routes
```
Purpose of each of this middlewares is explained in the [Internal Middlewares](#internal-middleware-stack) section.

View File

@ -27,17 +27,17 @@ GET /patients/17
it asks the router to match it to a controller action. If the first matching route is
```ruby
get "/patients/:id" => "patients#show"
get '/patients/:id', to: 'patients#show'
```
the request is dispatched to the `patients` controller's `show` action with `{ id: "17" }` in `params`.
the request is dispatched to the `patients` controller's `show` action with `{ id: '17' }` in `params`.
### Generating Paths and URLs from Code
You can also generate paths and URLs. If the route above is modified to be
```ruby
get "/patients/:id" => "patients#show", as: "patient"
get '/patients/:id', to: 'patients#show', as: 'patient'
```
If your application contains this code:
@ -47,7 +47,7 @@ If your application contains this code:
```
```erb
<%= link_to "Patient Record", patient_path(@patient) %>
<%= link_to 'Patient Record', patient_path(@patient) %>
```
The router will generate the path `/patients/17`. This reduces the brittleness of your view and makes your code easier to understand. Note that the id does not need to be specified in the route helper.
@ -73,7 +73,7 @@ it asks the router to map it to a controller action. If the first matching route
resources :photos
```
Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: "17" }` in `params`.
Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: '17' }` in `params`.
### CRUD, Verbs, and Actions
@ -131,7 +131,7 @@ resources :videos
Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like `/profile` to always show the profile of the currently logged in user. In this case, you can use a singular resource to map `/profile` (rather than `/profile/:id`) to the `show` action.
```ruby
get "profile" => "users#show"
get 'profile', to: 'users#show'
```
This resourceful route
@ -186,7 +186,7 @@ This will create a number of routes for each of the `posts` and `comments` contr
If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use
```ruby
scope module: "admin" do
scope module: 'admin' do
resources :posts, :comments
end
```
@ -194,13 +194,13 @@ end
or, for a single case
```ruby
resources :posts, module: "admin"
resources :posts, module: 'admin'
```
If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use
```ruby
scope "/admin" do
scope '/admin' do
resources :posts, :comments
end
```
@ -208,7 +208,7 @@ end
or, for a single case
```ruby
resources :posts, path: "/admin/posts"
resources :posts, path: '/admin/posts'
```
In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `PostsController`:
@ -324,31 +324,31 @@ end
When using `magazine_ad_path`, you can pass in instances of `Magazine` and `Ad` instead of the numeric IDs.
```erb
<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
```
You can also use `url_for` with a set of objects, and Rails will automatically determine which route you want:
```erb
<%= link_to "Ad details", url_for([@magazine, @ad]) %>
<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
```
In this case, Rails will see that `@magazine` is a `Magazine` and `@ad` is an `Ad` and will therefore use the `magazine_ad_path` helper. In helpers like `link_to`, you can specify just the object in place of the full `url_for` call:
```erb
<%= link_to "Ad details", [@magazine, @ad] %>
<%= link_to 'Ad details', [@magazine, @ad] %>
```
If you wanted to link to just a magazine:
```erb
<%= link_to "Magazine details", @magazine %>
<%= link_to 'Magazine details', @magazine %>
```
For other actions, you just need to insert the action name as the first element of the array:
```erb
<%= link_to "Edit Ad", [:edit, @magazine, @ad] %>
<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
```
This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style.
@ -462,7 +462,7 @@ You can specify static segments when creating a route:
get ':controller/:action/:id/with_user/:user_id'
```
This route would respond to paths such as `/photos/show/1/with_user/2`. In this case, `params` would be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`.
This route would respond to paths such as `/photos/show/1/with_user/2`. In this case, `params` would be `{ controller: 'photos', action: 'show', id: '1', user_id: '2' }`.
### The Query String
@ -472,14 +472,14 @@ The `params` will also include any parameters from the query string. For example
get ':controller/:action/:id'
```
An incoming path of `/photos/show/1?user_id=2` will be dispatched to the `show` action of the `Photos` controller. `params` will be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`.
An incoming path of `/photos/show/1?user_id=2` will be dispatched to the `show` action of the `Photos` controller. `params` will be `{ controller: 'photos', action: 'show', id: '1', user_id: '2' }`.
### Defining Defaults
You do not need to explicitly use the `:controller` and `:action` symbols within a route. You can supply them as defaults:
```ruby
get 'photos/:id' => 'photos#show'
get 'photos/:id', to: 'photos#show'
```
With this route, Rails will match an incoming path of `/photos/12` to the `show` action of `PhotosController`.
@ -487,7 +487,7 @@ With this route, Rails will match an incoming path of `/photos/12` to the `show`
You can also define other defaults in a route by supplying a hash for the `:defaults` option. This even applies to parameters that you do not specify as dynamic segments. For example:
```ruby
get 'photos/:id' => 'photos#show', defaults: { format: 'jpg' }
get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
```
Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`.
@ -497,7 +497,7 @@ Rails would match `photos/12` to the `show` action of `PhotosController`, and se
You can specify a name for any route using the `:as` option.
```ruby
get 'exit' => 'sessions#destroy', as: :logout
get 'exit', to: 'sessions#destroy', as: :logout
```
This will create `logout_path` and `logout_url` as named helpers in your application. Calling `logout_path` will return `/exit`
@ -505,7 +505,7 @@ This will create `logout_path` and `logout_url` as named helpers in your applica
You can also use this to override routing methods defined by resources, like this:
```ruby
get ':username', to: "users#show", as: :user
get ':username', to: 'users#show', as: :user
```
This will define a `user_path` method that will be available in controllers, helpers and views that will go to a route such as `/bob`. Inside the `show` action of `UsersController`, `params[:username]` will contain the username for the user. Change `:username` in the route definition if you do not want your parameter name to be `:username`.
@ -515,13 +515,13 @@ This will define a `user_path` method that will be available in controllers, hel
In general, you should use the `get`, `post`, `put` and `delete` methods to constrain a route to a particular verb. You can use the `match` method with the `:via` option to match multiple verbs at once:
```ruby
match 'photos' => 'photos#show', via: [:get, :post]
match 'photos', to: 'photos#show', via: [:get, :post]
```
You can match all verbs to a particular route using `via: :all`:
```ruby
match 'photos' => 'photos#show', via: :all
match 'photos', to: 'photos#show', via: :all
```
You should avoid routing all verbs to an action unless you have a good reason to, as routing both `GET` requests and `POST` requests to a single action has security implications.
@ -531,19 +531,19 @@ You should avoid routing all verbs to an action unless you have a good reason to
You can use the `:constraints` option to enforce a format for a dynamic segment:
```ruby
get 'photos/:id' => 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
```
This route would match paths such as `/photos/A12345`. You can more succinctly express the same route this way:
```ruby
get 'photos/:id' => 'photos#show', id: /[A-Z]\d{5}/
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
```
`:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work:
```ruby
get '/:id' => 'posts#show', constraints: {id: /^\d/}
get '/:id', to: 'posts#show', constraints: {id: /^\d/}
```
However, note that you don't need to use anchors because all routes are anchored at the start.
@ -551,8 +551,8 @@ However, note that you don't need to use anchors because all routes are anchored
For example, the following routes would allow for `posts` with `to_param` values like `1-hello-world` that always begin with a number and `users` with `to_param` values like `david` that never begin with a number to share the root namespace:
```ruby
get '/:id' => 'posts#show', constraints: { id: /\d.+/ }
get '/:username' => 'users#show'
get '/:id', to: 'posts#show', constraints: { id: /\d.+/ }
get '/:username', to: 'users#show'
```
### Request-Based Constraints
@ -562,14 +562,14 @@ You can also constrain a route based on any method on the <a href="action_contro
You specify a request-based constraint the same way that you specify a segment constraint:
```ruby
get "photos", constraints: {subdomain: "admin"}
get 'photos', constraints: {subdomain: 'admin'}
```
You can also specify constraints in a block form:
```ruby
namespace :admin do
constraints subdomain: "admin" do
constraints subdomain: 'admin' do
resources :photos
end
end
@ -591,7 +591,7 @@ class BlacklistConstraint
end
TwitterClone::Application.routes.draw do
get "*path" => "blacklist#index",
get '*path', to: 'blacklist#index',
constraints: BlacklistConstraint.new
end
```
@ -600,7 +600,7 @@ You can also specify constraints as a lambda:
```ruby
TwitterClone::Application.routes.draw do
get "*path" => "blacklist#index",
get '*path', to: 'blacklist#index',
constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
end
```
@ -612,7 +612,7 @@ Both the `matches?` method and the lambda gets the `request` object as an argume
Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
```ruby
get 'photos/*other' => 'photos#unknown'
get 'photos/*other', to: 'photos#unknown'
```
This route would match `photos/12` or `/photos/long/path/to/12`, setting `params[:other]` to `"12"` or `"long/path/to/12"`.
@ -620,35 +620,35 @@ This route would match `photos/12` or `/photos/long/path/to/12`, setting `params
Wildcard segments can occur anywhere in a route. For example,
```ruby
get 'books/*section/:title' => 'books#show'
get 'books/*section/:title', to: 'books#show'
```
would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `"some/section"`, and `params[:title]` equals `"last-words-a-memoir"`.
would match `books/some/section/last-words-a-memoir` with `params[:section]` equals `'some/section'`, and `params[:title]` equals `'last-words-a-memoir'`.
Technically a route can have even more than one wildcard segment. The matcher assigns segments to parameters in an intuitive way. For example,
```ruby
get '*a/foo/*b' => 'test#index'
get '*a/foo/*b', to: 'test#index'
```
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `"zoo/woo"`, and `params[:b]` equals `"bar/baz"`.
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `'zoo/woo'`, and `params[:b]` equals `'bar/baz'`.
NOTE: Starting from Rails 3.1, wildcard routes will always match the optional format segment by default. For example if you have this route:
```ruby
get '*pages' => 'pages#show'
get '*pages', to: 'pages#show'
```
NOTE: By requesting `"/foo/bar.json"`, your `params[:pages]` will be equals to `"foo/bar"` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be equals to `'foo/bar'` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
```ruby
get '*pages' => 'pages#show', format: false
get '*pages', to: 'pages#show', format: false
```
NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply `format: true` like this:
```ruby
get '*pages' => 'pages#show', format: true
get '*pages', to: 'pages#show', format: true
```
### Redirection
@ -656,20 +656,20 @@ get '*pages' => 'pages#show', format: true
You can redirect any path to another path using the `redirect` helper in your router:
```ruby
get "/stories" => redirect("/posts")
get '/stories', to: redirect('/posts')
```
You can also reuse dynamic segments from the match in the path to redirect to:
```ruby
get "/stories/:name" => redirect("/posts/%{name}")
get '/stories/:name', to: redirect('/posts/%{name}')
```
You can also provide a block to redirect, which receives the params and the request object:
```ruby
get "/stories/:name" => redirect {|params, req| "/posts/#{params[:name].pluralize}" }
get "/stories" => redirect {|p, req| "/posts/#{req.subdomain}" }
get '/stories/:name', to: redirect {|params, req| "/posts/#{params[:name].pluralize}" }
get '/stories', to: redirect {|p, req| "/posts/#{req.subdomain}" }
```
Please note that this redirection is a 301 "Moved Permanently" redirect. Keep in mind that some web browsers or proxy servers will cache this type of redirect, making the old page inaccessible.
@ -678,19 +678,19 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl
### Routing to Rack Applications
Instead of a String, like `"posts#index"`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher.
Instead of a String, like `'posts#index'`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher.
```ruby
match "/application.js" => Sprockets, via: :all
match '/application.js', to: Sprockets, via: :all
```
As long as `Sprockets` responds to `call` and returns a `[status, headers, body]`, the router won't know the difference between the Rack application and an action. This is an appropriate use of `via: :all`, as you will want to allow your Rack application to handle all verbs as it considers appropriate.
NOTE: For the curious, `"posts#index"` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application.
NOTE: For the curious, `'posts#index'` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application.
### Using `root`
You can specify what Rails should route `"/"` to with the `root` method:
You can specify what Rails should route `'/'` to with the `root` method:
```ruby
root to: 'pages#main'
@ -706,7 +706,7 @@ NOTE: The `root` route only routes `GET` requests to the action.
You can specify unicode character routes directly. For example
```ruby
match 'こんにちは' => 'welcome#index'
get 'こんにちは', to: 'welcome#index'
```
Customizing Resourceful Routes
@ -719,7 +719,7 @@ While the default routes and helpers generated by `resources :posts` will usuall
The `:controller` option lets you explicitly specify a controller to use for the resource. For example:
```ruby
resources :photos, controller: "images"
resources :photos, controller: 'images'
```
will recognize incoming paths beginning with `/photos` but route to the `Images` controller:
@ -764,7 +764,7 @@ TIP: By default the `:id` parameter doesn't accept dots - this is because the do
The `:as` option lets you override the normal naming for the named route helpers. For example:
```ruby
resources :photos, as: "images"
resources :photos, as: 'images'
```
will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the :as option to name the helpers.
@ -799,7 +799,7 @@ NOTE: The actual action names aren't changed by this option. The two paths shown
TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can use a scope.
```ruby
scope path_names: { new: "make" } do
scope path_names: { new: 'make' } do
# rest of your routes
end
```
@ -809,8 +809,8 @@ end
You can use the `:as` option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope.
```ruby
scope "admin" do
resources :photos, as: "admin_photos"
scope 'admin' do
resources :photos, as: 'admin_photos'
end
resources :photos
@ -821,7 +821,7 @@ This will provide route helpers such as `admin_photos_path`, `new_admin_photo_pa
To prefix a group of route helpers, use `:as` with `scope`:
```ruby
scope "admin", as: "admin" do
scope 'admin', as: 'admin' do
resources :photos, :accounts
end
@ -835,7 +835,7 @@ NOTE: The `namespace` scope will automatically add `:as` as well as `:module` an
You can prefix routes with a named parameter also:
```ruby
scope ":username" do
scope ':username' do
resources :posts
end
```
@ -867,8 +867,8 @@ TIP: If your application has many RESTful routes, using `:only` and `:except` to
Using `scope`, we can alter path names generated by resources:
```ruby
scope(path_names: { new: "neu", edit: "bearbeiten" }) do
resources :categories, path: "kategorien"
scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
resources :categories, path: 'kategorien'
end
```
@ -952,8 +952,8 @@ Routes should be included in your testing strategy (just like the rest of your a
`assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes.
```ruby
assert_generates "/photos/1", { controller: "photos", action: "show", id: "1" }
assert_generates "/about", controller: "pages", action: "about"
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/about', controller: 'pages', action: 'about'
```
#### The `assert_recognizes` Assertion
@ -961,13 +961,13 @@ assert_generates "/about", controller: "pages", action: "about"
`assert_recognizes` is the inverse of `assert_generates`. It asserts that a given path is recognized and routes it to a particular spot in your application.
```ruby
assert_recognizes({ controller: "photos", action: "show", id: "1" }, "/photos/1")
assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
```
You can supply a `:method` argument to specify the HTTP verb:
```ruby
assert_recognizes({ controller: "photos", action: "create" }, { path: "photos", method: :post })
assert_recognizes({ controller: 'photos', action: 'create' }, { path: 'photos', method: :post })
```
#### The `assert_routing` Assertion
@ -975,5 +975,5 @@ assert_recognizes({ controller: "photos", action: "create" }, { path: "photos",
The `assert_routing` assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of `assert_generates` and `assert_recognizes`.
```ruby
assert_routing({ path: "photos", method: :post }, { controller: "photos", action: "create" })
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
```

View File

@ -187,11 +187,11 @@ In the <a href="#sessions">session chapter</a> you have learned that most Rails
* Bob's session at www.webapp.com is still alive, because he didn't log out a few minutes ago.
* By viewing the post, the browser finds an image tag. It tries to load the suspected image from www.webapp.com. As explained before, it will also send along the cookie with the valid session id.
* The web application at www.webapp.com verifies the user information in the corresponding session hash and destroys the project with the ID 1. It then returns a result page which is an unexpected result for the browser, so it will not display the image.
* Bob doesn't notice the attack -- but a few days later he finds out that project number one is gone.
* Bob doesn't notice the attack but a few days later he finds out that project number one is gone.
It is important to notice that the actual crafted image or link doesn't necessarily have to be situated in the web application's domain, it can be anywhere in a forum, blog post or email.
CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures) -- less than 0.1% in 2006 -- but it really is a 'sleeping giant' [Grossman]. This is in stark contrast to the results in my (and others) security contract work _CSRF is an important security issue_.
CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures) — less than 0.1% in 2006 — but it really is a 'sleeping giant' [Grossman]. This is in stark contrast to the results in my (and others) security contract work _CSRF is an important security issue_.
### CSRF Countermeasures

View File

@ -299,7 +299,7 @@ Now to get this test to pass we can add a model level validation for the _title_
```ruby
class Post < ActiveRecord::Base
validates :title, :presence => true
validates :title, presence: true
end
```
@ -397,7 +397,7 @@ Rails adds some custom assertions of its own to the `test/unit` framework:
| `assert_recognizes(expected_options, path, extras={}, message=nil)` | Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.|
| `assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)` | Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
| `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range|
| `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(:controller => "weblog")` will also match the redirection of `redirect_to(:controller => "weblog", :action => "show")` and so on.|
| `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on.|
| `assert_template(expected = nil, message=nil)` | Asserts that the request was rendered with the appropriate template file.|
You'll see the usage of some of these assertions in the next chapter.
@ -457,7 +457,7 @@ Let us modify `test_should_create_post` test in `posts_controller_test.rb` so th
```ruby
test "should create post" do
assert_difference('Post.count') do
post :create, :post => { :title => 'Some title'}
post :create, post: {title: 'Some title'}
end
assert_redirected_to post_path(assigns(:post))
@ -518,7 +518,7 @@ method:
test "index should render correct template and layout" do
get :index
assert_template :index
assert_template :layout => "layouts/application"
assert_template layout: "layouts/application"
end
```
@ -528,7 +528,7 @@ things clearer. On the other hand, you have to include the "layouts" directory n
file in this standard layout directory. Hence,
```ruby
assert_template :layout => "application"
assert_template layout: "application"
```
will not work.
@ -541,7 +541,7 @@ Hence:
```ruby
test "new should render correct layout" do
get :new
assert_template :layout => "layouts/application", :partial => "_form"
assert_template layout: "layouts/application", partial: "_form"
end
```
@ -554,7 +554,7 @@ Here's another example that uses `flash`, `assert_redirected_to`, and `assert_di
```ruby
test "should create post" do
assert_difference('Post.count') do
post :create, :post => { :title => 'Hi', :body => 'This is my first post.'}
post :create, post: {title: 'Hi', body: 'This is my first post.'}
end
assert_redirected_to post_path(assigns(:post))
assert_equal 'Post was successfully created.', flash[:notice]
@ -686,7 +686,7 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
get "/login"
assert_response :success
post_via_redirect "/login", :username => users(:avs).username, :password => users(:avs).password
post_via_redirect "/login", username: users(:avs).username, password: users(:avs).password
assert_equal '/welcome', path
assert_equal 'Welcome avs!', flash[:notice]
@ -742,7 +742,7 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
sess.extend(CustomDsl)
u = users(user)
sess.https!
sess.post "/login", :username => u.username, :password => u.password
sess.post "/login", username: u.username, password: u.password
assert_equal '/welcome', path
sess.https!(false)
end
@ -803,13 +803,13 @@ class PostsControllerTest < ActionController::TestCase
end
test "should show post" do
get :show, :id => @post.id
get :show, id: @post.id
assert_response :success
end
test "should destroy post" do
assert_difference('Post.count', -1) do
delete :destroy, :id => @post.id
delete :destroy, id: @post.id
end
assert_redirected_to posts_path
@ -841,18 +841,18 @@ class PostsControllerTest < ActionController::TestCase
end
test "should show post" do
get :show, :id => @post.id
get :show, id: @post.id
assert_response :success
end
test "should update post" do
patch :update, :id => @post.id, :post => { }
patch :update, id: @post.id, post: {}
assert_redirected_to post_path(assigns(:post))
end
test "should destroy post" do
assert_difference('Post.count', -1) do
delete :destroy, :id => @post.id
delete :destroy, id: @post.id
end
assert_redirected_to posts_path
@ -874,7 +874,7 @@ Like everything else in your Rails application, it is recommended that you test
```ruby
test "should route to post" do
assert_routing '/posts/1', { :controller => "posts", :action => "show", :id => "1" }
assert_routing '/posts/1', {controller: "posts", action: "show", id: "1"}
end
```
@ -885,7 +885,7 @@ Testing mailer classes requires some specific tools to do a thorough job.
### Keeping the Postman in Check
Your mailer classes -- like every other part of your Rails application -- should be tested to ensure that it is working as expected.
Your mailer classes — like every other part of your Rails application — should be tested to ensure that it is working as expected.
The goals of testing your mailer classes are to ensure that:
@ -955,7 +955,7 @@ require 'test_helper'
class UserControllerTest < ActionController::TestCase
test "invite friend" do
assert_difference 'ActionMailer::Base.deliveries.size', +1 do
post :invite_friend, :email => 'friend@example.com'
post :invite_friend, email: 'friend@example.com'
end
invite_email = ActionMailer::Base.deliveries.last

View File

@ -83,13 +83,13 @@ Rails 4.0 changed how `assert_generates`, `assert_recognizes`, and `assert_routi
Rails 4.0 also changed the way unicode character routes are drawn. Now you can draw unicode character routes directly. If you already draw such routes, you must change them, for example:
```ruby
get Rack::Utils.escape('こんにちは'), :controller => 'welcome', :action => 'index'
get Rack::Utils.escape('こんにちは'), controller: 'welcome', action: 'index'
```
becomes
```ruby
get 'こんにちは', :controller => 'welcome', :action => 'index'
get 'こんにちは', controller: 'welcome', action: 'index'
```
### Active Support
@ -248,7 +248,7 @@ Add this file with the following contents, if you wish to wrap parameters into a
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters :format => [:json]
wrap_parameters format: [:json]
end
# Disable root element in JSON by default.
@ -263,7 +263,7 @@ You need to change your session key to something new, or remove all sessions:
```ruby
# in config/initializers/session_store.rb
AppName::Application.config.session_store :cookie_store, :key => 'SOMETHINGNEW'
AppName::Application.config.session_store :cookie_store, key: 'SOMETHINGNEW'
```
or

View File

@ -57,7 +57,8 @@
# config.action_controller.asset_host = "http://assets.example.com"
<%- unless options.skip_sprockets? -%>
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added).
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# config.assets.precompile += %w( search.js )
<%- end -%>