提交 d2c64009 编写于 作者: V Vijay Dev

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

...@@ -76,4 +76,3 @@ to proceed. {Join us}[http://contributors.rubyonrails.org]! ...@@ -76,4 +76,3 @@ to proceed. {Join us}[http://contributors.rubyonrails.org]!
Ruby on Rails is released under the MIT license: Ruby on Rails is released under the MIT license:
* http://www.opensource.org/licenses/MIT * http://www.opensource.org/licenses/MIT
...@@ -47,7 +47,8 @@ module Caching ...@@ -47,7 +47,8 @@ module Caching
# And you can also use <tt>:if</tt> (or <tt>:unless</tt>) to pass a # And you can also use <tt>:if</tt> (or <tt>:unless</tt>) to pass a
# proc that specifies when the action should be cached. # proc that specifies when the action should be cached.
# #
# Finally, if you are using memcached, you can also pass <tt>:expires_in</tt>. # As of Rails 3.0, you can also pass <tt>:expires_in</tt> with a time
# interval (in seconds) to schedule expiration of the cached item.
# #
# The following example depicts some of the points made above: # The following example depicts some of the points made above:
# #
......
...@@ -190,7 +190,7 @@ module ActionDispatch ...@@ -190,7 +190,7 @@ module ActionDispatch
# Examples: # Examples:
# #
# match 'post/:id' => 'posts#show', :via => :get # match 'post/:id' => 'posts#show', :via => :get
# match 'post/:id' => "posts#create_comment', :via => :post # match 'post/:id' => 'posts#create_comment', :via => :post
# #
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
# URL will route to the <tt>show</tt> action. # URL will route to the <tt>show</tt> action.
...@@ -203,7 +203,7 @@ module ActionDispatch ...@@ -203,7 +203,7 @@ module ActionDispatch
# Examples: # Examples:
# #
# get 'post/:id' => 'posts#show' # get 'post/:id' => 'posts#show'
# post 'post/:id' => "posts#create_comment' # post 'post/:id' => 'posts#create_comment'
# #
# This syntax is less verbose and the intention is more apparent to someone else reading your code, # This syntax is less verbose and the intention is more apparent to someone else reading your code,
# however if your route needs to respond to more than one HTTP method (or all methods) then using the # however if your route needs to respond to more than one HTTP method (or all methods) then using the
......
...@@ -40,11 +40,13 @@ module Locking ...@@ -40,11 +40,13 @@ module Locking
# This locking mechanism will function inside a single Ruby process. To make it work across all # This locking mechanism will function inside a single Ruby process. To make it work across all
# web requests, the recommended approach is to add +lock_version+ as a hidden field to your form. # web requests, the recommended approach is to add +lock_version+ as a hidden field to your form.
# #
# You must ensure that your database schema defaults the +lock_version+ column to 0.
#
# This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>. # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
# To override the name of the +lock_version+ column, invoke the <tt>set_locking_column</tt> method. # To override the name of the +lock_version+ column, set the <tt>locking_column</tt> class attribute:
# This method uses the same syntax as <tt>set_table_name</tt> #
# class Person < ActiveRecord::Base
# self.locking_column = :lock_person
# end
#
module Optimistic module Optimistic
extend ActiveSupport::Concern extend ActiveSupport::Concern
......
...@@ -9,6 +9,11 @@ module ActiveSupport ...@@ -9,6 +9,11 @@ module ActiveSupport
# #
# This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't # This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't
# want users to be able to determine the value of the payload. # want users to be able to determine the value of the payload.
#
# key = OpenSSL::Digest::SHA256.new('password').digest # => "\x89\xE0\x156\xAC..."
# crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
# encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
# crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
class MessageEncryptor class MessageEncryptor
module NullSerializer #:nodoc: module NullSerializer #:nodoc:
def self.load(value) def self.load(value)
...@@ -23,6 +28,15 @@ def self.dump(value) ...@@ -23,6 +28,15 @@ def self.dump(value)
class InvalidMessage < StandardError; end class InvalidMessage < StandardError; end
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
# Initialize a new MessageEncryptor.
# +secret+ must be at least as long as the cipher key size. For the default 'aes-256-cbc' cipher,
# this is 256 bits. If you are using a user-entered secret, you can generate a suitable key with
# <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or similar.
#
# Options:
# * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'
# * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
#
def initialize(secret, options = {}) def initialize(secret, options = {})
@secret = secret @secret = secret
@cipher = options[:cipher] || 'aes-256-cbc' @cipher = options[:cipher] || 'aes-256-cbc'
......
...@@ -8,4 +8,4 @@ ...@@ -8,4 +8,4 @@
puts "Installing Rails..." puts "Installing Rails..."
`gem build rails.gemspec` `gem build rails.gemspec`
`gem install rails-#{version}.gem --no-ri --no-rdoc ` `gem install rails-#{version}.gem --no-ri --no-rdoc `
`rm rails-#{version}.gem` `rm rails-#{version}.gem`
\ No newline at end of file
# bust gem prelude # bust gem prelude
require 'rubygems' unless defined? Gem require 'rubygems' unless defined? Gem
require 'bundler' require 'bundler'
Bundler.setup Bundler.setup
\ No newline at end of file
...@@ -404,6 +404,8 @@ Or ordering by multiple fields: ...@@ -404,6 +404,8 @@ Or ordering by multiple fields:
<ruby> <ruby>
Client.order("orders_count ASC, created_at DESC") Client.order("orders_count ASC, created_at DESC")
# OR
Client.order("orders_count ASC", "created_at DESC")
</ruby> </ruby>
h3. Selecting Specific Fields h3. Selecting Specific Fields
...@@ -608,7 +610,7 @@ This method accepts *no* arguments. ...@@ -608,7 +610,7 @@ This method accepts *no* arguments.
h3. Readonly Objects h3. Readonly Objects
Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception. Active Record provides +readonly+ method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
<ruby> <ruby>
client = Client.readonly.first client = Client.readonly.first
...@@ -648,15 +650,13 @@ c2.save # Raises an ActiveRecord::StaleObjectError ...@@ -648,15 +650,13 @@ c2.save # Raises an ActiveRecord::StaleObjectError
You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict. You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.
NOTE: You must ensure that your database schema defaults the +lock_version+ column to +0+.
This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>. This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
To override the name of the +lock_version+ column, +ActiveRecord::Base+ provides a class method called +set_locking_column+: To override the name of the +lock_version+ column, +ActiveRecord::Base+ provides a class attribute called +locking_column+:
<ruby> <ruby>
class Client < ActiveRecord::Base class Client < ActiveRecord::Base
set_locking_column :lock_client_column self.locking_column = :lock_client_column
end end
</ruby> </ruby>
......
...@@ -1120,7 +1120,7 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt> ...@@ -1120,7 +1120,7 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+.
<ruby> <ruby>
@open_orders = @customer.orders.where(:open => 1) @open_orders = @customer.orders.find(1)
</ruby> </ruby>
h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt> h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt>
...@@ -1242,7 +1242,7 @@ h6(#has_many-counter_sql). +:counter_sql+ ...@@ -1242,7 +1242,7 @@ h6(#has_many-counter_sql). +:counter_sql+
Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself. Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself.
NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting +SELECT COUNT(*) FROM+ for the +SELECT ... FROM+ clause of your +:finder_sql+ statement. NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting the +SELECT ... FROM+ clause of your +:finder_sql+ statement by +SELECT COUNT(*) FROM+.
h6(#has_many-dependent). +:dependent+ h6(#has_many-dependent). +:dependent+
...@@ -1545,12 +1545,9 @@ h6(#has_and_belongs_to_many-collection-find). <tt><em>collection</em>.find(...)< ...@@ -1545,12 +1545,9 @@ h6(#has_and_belongs_to_many-collection-find). <tt><em>collection</em>.find(...)<
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. It also adds the additional condition that the object must be in the collection. The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. It also adds the additional condition that the object must be in the collection.
<ruby> <ruby>
@new_assemblies = @part.assemblies.all( @assembly = @part.assemblies.find(1)
:conditions => ["created_at > ?", 2.days.ago])
</ruby> </ruby>
NOTE: Beginning with Rails 3, supplying options to the +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
h6(#has_and_belongs_to_many-collection-where). <tt><em>collection</em>.where(...)</tt> h6(#has_and_belongs_to_many-collection-where). <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> 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. It also adds the additional condition that the object must be in the collection. The <tt><em>collection</em>.where</tt> 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. It also adds the additional condition that the object must be in the collection.
...@@ -1669,7 +1666,7 @@ h6(#has_and_belongs_to_many-counter_sql). +:counter_sql+ ...@@ -1669,7 +1666,7 @@ h6(#has_and_belongs_to_many-counter_sql). +:counter_sql+
Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself. Normally Rails automatically generates the proper SQL to count the association members. With the +:counter_sql+ option, you can specify a complete SQL statement to count them yourself.
NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting +SELECT COUNT(*) FROM+ for the +SELECT ... FROM+ clause of your +:finder_sql+ statement. NOTE: If you specify +:finder_sql+ but not +:counter_sql+, then the counter SQL will be generated by substituting the +SELECT ... FROM+ clause of your +:finder_sql+ statement by +SELECT COUNT(*) FROM+.
h6(#has_and_belongs_to_many-delete_sql). +:delete_sql+ h6(#has_and_belongs_to_many-delete_sql). +:delete_sql+
......
...@@ -754,7 +754,7 @@ produces exactly the same output as the previous example. ...@@ -754,7 +754,7 @@ produces exactly the same output as the previous example.
h3. Forms to external resources h3. Forms to external resources
If you need to post some data to an external resource it is still great to build your from 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> <erb>
<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %> <%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %>
......
...@@ -385,7 +385,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true} ...@@ -385,7 +385,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true}
So if you create a new user using mass-assignment, it may be too easy to become an administrator. So if you create a new user using mass-assignment, it may be too easy to become an administrator.
Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3+. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example: Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3<plus>. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
<ruby> <ruby>
class Person < ActiveRecord::Base class Person < ActiveRecord::Base
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册