mirror of https://github.com/rails/rails
Merge branch 'master' of github.com:lifo/docrails
Conflicts: actionpack/lib/action_dispatch/routing/redirection.rb
This commit is contained in:
commit
7b70eeed43
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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? }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
#
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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!)
|
||||
#
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
------------------------
|
||||
|
||||
|
|
|
@ -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)
|
||||
...
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
@ -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"
|
||||
```
|
||||
|
|
|
@ -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| %>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 application’s `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 application’s `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 user’s 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'"
|
||||
```
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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' })
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 -%>
|
||||
|
||||
|
|
Loading…
Reference in New Issue