提交 f826e058 编写于 作者: X Xavier Noria

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

......@@ -48,6 +48,7 @@ def instantiate_observers
observers.each { |o| instantiate_observer(o) }
end
# Add a new observer to the pool.
def add_observer(observer)
unless observer.respond_to? :update
raise ArgumentError, "observer needs to respond to `update'"
......@@ -55,12 +56,14 @@ def add_observer(observer)
observer_instances << observer
end
# Notify list of observers of a change.
def notify_observers(*arg)
for observer in observer_instances
observer.update(*arg)
end
end
# Total number of observers.
def count_observers
observer_instances.size
end
......
......@@ -134,6 +134,29 @@ def add_procs
# Returns XML representing the model. Configuration can be
# passed through +options+.
#
# Without any +options+, the returned XML string will include all the model's
# attributes. For example:
#
# konata = User.find(1)
# konata.to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <user>
# <id type="integer">1</id>
# <name>David</name>
# <age type="integer">16</age>
# <created-at type="datetime">2011-01-30T22:29:23Z</created-at>
# </user>
#
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
# included, and work similar to the +attributes+ method.
#
# To include the result of some method calls on the model use <tt>:methods</tt>.
#
# To include associations use <tt>:include</tt>.
#
# For further documentation see activerecord/lib/active_record/serializers/xml_serializer.xml.
def to_xml(options = {}, &block)
Serializer.new(self, options).serialize(&block)
end
......
......@@ -71,8 +71,8 @@ module ClassMethods
# end
#
# Options:
# * <tt>:on</tt> - Specifies when this validation is active (default is
# <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies the context where this validation is active
# (e.g. <tt>:on => :create</tt> or <tt>:on => :custom_validation_context</tt>)
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
# * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
......
......@@ -37,9 +37,9 @@ module HelperMethods
# Configuration options:
# * <tt>:message</tt> - A custom error message (default is: "must be
# accepted").
# * <tt>:on</tt> - Specifies when this validation is active (default is
# <tt>:save</tt>, other options are <tt>:create</tt> and
# <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default
# is true).
# * <tt>:accept</tt> - Specifies value that is considered accepted.
......
......@@ -45,8 +45,9 @@ module HelperMethods
# Configuration options:
# * <tt>:message</tt> - A custom error message (default is: "doesn't match
# confirmation").
# * <tt>:on</tt> - Specifies when this validation is active (default is
# <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
# if the validation should occur (e.g. <tt>:if => :allow_validation</tt>,
# or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
......
......@@ -29,6 +29,9 @@ module HelperMethods
# * <tt>:message</tt> - Specifies a custom error message (default is: "is reserved").
# * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
......
......@@ -51,7 +51,9 @@ module HelperMethods
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
# * <tt>:with</tt> - Regular expression that if the attribute matches will result in a successful validation.
# * <tt>:without</tt> - Regular expression that if the attribute does not match will result in a successful validation.
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
......
......@@ -38,6 +38,9 @@ module HelperMethods
# * <tt>:message</tt> - Specifies a custom error message (default is: "is not included in the list").
# * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
......
......@@ -83,7 +83,9 @@ module HelperMethods
# * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is %{count} characters)").
# * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be %{count} characters)").
# * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
......
......@@ -93,7 +93,9 @@ module HelperMethods
#
# Configuration options:
# * <tt>:message</tt> - A custom error message (default is: "is not a number").
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:only_integer</tt> - Specifies whether the value has to be an integer, e.g. an integral value (default is +false+).
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is +false+). Notice that for fixnum and float columns empty strings are converted to +nil+.
# * <tt>:greater_than</tt> - Specifies the value must be greater than the supplied value.
......
......@@ -26,8 +26,9 @@ module HelperMethods
#
# Configuration options:
# * <tt>message</tt> - A custom error message (default is: "can't be blank").
# * <tt>on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>,
# <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
# The method, proc or string should return or evaluate to a true or false value.
......
......@@ -176,6 +176,12 @@ def scoping
#
# # Update all books that match conditions, but limit it to 5 ordered by date
# Book.update_all "author = 'David'", "title LIKE '%Rails%'", :order => 'created_at', :limit => 5
#
# # Conditions from the current relation also works
# Book.where('title LIKE ?', '%Rails%').update_all(:author => 'David')
#
# # The same idea applies to limit and order
# Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(:author => 'David')
def update_all(updates, conditions = nil, options = {})
if conditions || options.present?
where(conditions).apply_finder_options(options.slice(:limit, :order)).update_all(updates)
......@@ -249,6 +255,7 @@ def update(id, attributes)
#
# Person.destroy_all("last_login < '2004-04-04'")
# Person.destroy_all(:status => "inactive")
# Person.where(:age => 0..18).destroy_all
def destroy_all(conditions = nil)
if conditions
where(conditions).destroy_all
......@@ -298,6 +305,7 @@ def destroy(id)
#
# Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
# Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])
# Post.where(:person_id => 5).where(:category => ['Something', 'Else']).delete_all
#
# Both calls delete the affected posts all at once with a single DELETE statement.
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
......
module ActiveRecord
# = Active Record Validations
# = Active Record RecordInvalid
#
# Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
# +record+ method to retrieve the record which did not validate.
......@@ -18,6 +18,13 @@ def initialize(record)
end
end
# = Active Record Validations
#
# Active Record includes the majority of its validations from <tt>ActiveModel::Validations</tt>
# all of which accept the <tt>:on</tt> argument to define the context where the
# validations are active. Active Record will always supply either the context of
# <tt>:create</tt> or <tt>:update</tt> dependent on whether the model is a
# <tt>new_record?</tt>.
module Validations
extend ActiveSupport::Concern
include ActiveModel::Validations
......@@ -49,7 +56,14 @@ def save!(options={})
perform_validations(options) ? super : raise(RecordInvalid.new(self))
end
# Runs all the specified validations and returns true if no errors were added otherwise false.
# 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.
#
# 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)
context ||= (new_record? ? :create : :update)
output = super(context)
......
......@@ -33,7 +33,9 @@ module ClassMethods
#
# Configuration options:
# * <tt>:message</tt> - A custom error message (default is: "is invalid")
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
# * <tt>:on</tt> - Specifies when this validation is active. Runs in all
# validation contexts by default (+nil+), other options are <tt>:create</tt>
# and <tt>:update</tt>.
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
# method, proc or string should return or evaluate to a true or false value.
......
......@@ -743,7 +743,7 @@ def test_should_rollback_destructions_if_an_exception_occurred_while_saving_has_
2.times { |i| @pirate.birds.create!(:name => "birds_#{i}") }
before = @pirate.birds.map { |c| c.mark_for_destruction ; c }
# Stub the destroy method of the the second child to raise an exception
# Stub the destroy method of the second child to raise an exception
class << before.last
def destroy(*args)
super
......
......@@ -7,11 +7,11 @@ class Module
# attr_accessor_with_default :age, 25
# end
#
# some_person.age
# => 25
# some_person.age = 26
# some_person.age
# => 26
# person = Person.new
# person.age # => 25
#
# person.age = 26
# person.age # => 26
#
# To give attribute <tt>:element_name</tt> a dynamic default value, evaluated
# in scope of self:
......
......@@ -7,13 +7,27 @@ class Object
# provided. Each method called on the block variable must take an options
# hash as its final argument.
#
# with_options :order => 'created_at', :class_name => 'Comment' do |post|
# post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
# post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
# post.has_many :all_comments
# Without with_options, this code contains duplication:
#
# class Account < ActiveRecord::Base
# has_many :customers, :dependent => :destroy
# has_many :products, :dependent => :destroy
# has_many :invoices, :dependent => :destroy
# has_many :expenses, :dependent => :destroy
# end
#
# Using with_options, we can remove the duplication:
#
# class Account < ActiveRecord::Base
# with_options :dependent => :destroy do |assoc|
# assoc.has_many :customers
# assoc.has_many :products
# assoc.has_many :invoices
# assoc.has_many :expenses
# end
# end
#
# Can also be used with an explicit receiver:
# It can also be used with an explicit receiver:
#
# map.with_options :controller => "people" do |people|
# people.connect "/people", :action => "index"
......
......@@ -20,7 +20,7 @@ Thus, after a simple require like:
require 'active_support'
</ruby>
objects do not even respond to +blank?+, let's see how to load its definition.
objects do not even respond to +blank?+. Let's see how to load its definition.
h5. Cherry-picking a Definition
......@@ -42,7 +42,7 @@ h5. Loading Grouped Core Extensions
The next level is to simply load all extensions to +Object+. As a rule of thumb, extensions to +SomeClass+ are available in one shot by loading +active_support/core_ext/some_class+.
Thus, if that would do, to have +blank?+ available we could just load all extensions to +Object+:
Thus, to load all extensions to +Object+ (including +blank?+):
<ruby>
require 'active_support/core_ext/object'
......@@ -432,7 +432,7 @@ h4. +require_library_or_gem+
The convenience method +require_library_or_gem+ tries to load its argument with a regular +require+ first. If it fails loads +rubygems+ and tries again.
If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. On the other hand, if +rubygems+ is available but the argument is not loadable as a gem, the method gives up and +LoadError+ is also raised.
If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. A +LoadError+ is also raised if +rubygems+ is available but the argument is not loadable as a gem.
For example, that's the way the MySQL adapter loads the MySQL library:
......@@ -503,7 +503,7 @@ Model attributes have a reader, a writer, and a predicate. You can alias a model
<ruby>
class User < ActiveRecord::Base
# let me refer to the email column as "login",
# much meaningful for authentication code
# possibly meaningful for authentication code
alias_attribute :login, :email
end
</ruby>
......
......@@ -809,6 +809,12 @@ That does not mean you're stuck with these limitations, though. The Ruby I18n ge
I18n.backend = Globalize::Backend::Static.new
</ruby>
You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the ActiveRecord backend and fall back to the (default) Simple backend:
<ruby>
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
</ruby>
h4. Using Different Exception Handlers
The I18n API defines the following exceptions that will be raised by backends when the corresponding unexpected conditions occur:
......
......@@ -1006,11 +1006,13 @@ h5. Partial Layouts
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 "link_area", :layout => "graybar" %>
<%= render :partial => "link_area", :layout => "graybar" %>
</erb>
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).
Also note that explicitly specifying +:partial+ is required when passing additional options such as +:layout+.
h5. Passing Local Variables
You can also pass local variables into partials, making them even more powerful and flexible. For example, you can use this technique to reduce duplication between new and edit pages, while still keeping a bit of distinct content:
......
......@@ -316,16 +316,16 @@ Compile Ruby and apply this "GC Patch":http://rubyforge.org/tracker/download.php
h5. Download and Extract
<shell>
[lifo@null ~]$ mkdir rubygc
[lifo@null ~]$ wget <download the latest stable ruby from ftp://ftp.ruby-lang.org/pub/ruby>
[lifo@null ~]$ tar -xzvf <ruby-version.tar.gz>
[lifo@null ~]$ cd <ruby-version>
$ mkdir rubygc
$ wget <download the latest stable ruby from ftp://ftp.ruby-lang.org/pub/ruby>
$ tar -xzvf <ruby-version.tar.gz>
$ cd <ruby-version>
</shell>
h5. Apply the Patch
<shell>
[lifo@null ruby-version]$ curl http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch | patch -p0
$ curl http://rubyforge.org/tracker/download.php/1814/7062/17676/3291/ruby186gc.patch | patch -p0
</shell>
h5. Configure and Install
......@@ -333,8 +333,8 @@ h5. Configure and Install
The following will install ruby in your home directory's +/rubygc+ directory. Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home directory.
<shell>
[lifo@null ruby-version]$ ./configure --prefix=/<homedir>/rubygc
[lifo@null ruby-version]$ make && make install
$ ./configure --prefix=/<homedir>/rubygc
$ make && make install
</shell>
h5. Prepare Aliases
......@@ -364,8 +364,8 @@ Additionally, install the following gems:
If installing +mysql+ fails, you can try to install it manually:
<shell>
[lifo@null mysql]$ gcruby extconf.rb --with-mysql-config
[lifo@null mysql]$ make && make install
$ gcruby extconf.rb --with-mysql-config
$ make && make install
</shell>
And you're ready to go. Don't forget to use +gcruby+ and +gcrake+ aliases when running the performance tests.
......
......@@ -198,7 +198,7 @@ route "root :to => 'person#index'"
h4. inside(dir)
I have my edge rails lying at +~/commit-rails/rails+. So every time i have to manually symlink edge from my new app. But now :
Enables you to run a command from the given directory. For example, if you have a copy of edge rails that you wish to symlink from your new apps, you can do this:
<ruby>
inside('vendor') do
......@@ -206,8 +206,6 @@ inside('vendor') do
end
</ruby>
So +inside()+ runs the command from the given directory.
h4. ask(question)
+ask()+ gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding :
......
......@@ -63,13 +63,13 @@ run ActionController::Dispatcher.new
And start the server:
<shell>
[lifo@null application]$ rackup config.ru
$ rackup config.ru
</shell>
To find out more about different +rackup+ options:
<shell>
[lifo@null application]$ rackup --help
$ rackup --help
</shell>
h3. Action Controller Middleware Stack
......
......@@ -240,7 +240,7 @@ There are many other possibilities, including Ajax to attack the victim in the b
protect_from_forgery :secret => "123456789012345678901234567890..."
</ruby>
This will automatically include a security token, calculated from the current session and the server-side secret, in all forms and Ajax requests generated by Rails. You won't need the secret, if you use CookieStorage as session storage. It will raise an ActionController::InvalidAuthenticityToken error, if the security token doesn't match what was expected.
This will automatically include a security token, calculated from the current session and the server-side secret, in all forms and Ajax requests generated by Rails. You won't need the secret, if you use CookieStorage as session storage. If the security token doesn't match what was expected, the session will be reset. *Note:* In Rails versions prior to 3.0.4, this raised an <tt>ActionController::InvalidAuthenticityToken</tt> error.
Note that _(highlight)cross-site scripting (XSS) vulnerabilities bypass all CSRF protections_. XSS gives the attacker access to all elements on a page, so he can read the CSRF security token from a form or directly submit the form. Read <a href="#cross-site-scripting-xss">more about XSS</a> later.
......
......@@ -2136,7 +2136,7 @@ jQuery.event = {
eventHandle = elemData.handle;
if ( typeof events === "function" ) {
// On plain objects events is a fn that holds the the data
// On plain objects events is a fn that holds the data
// which prevents this data from being JSON serialized
// the function does not need to be called, it just contains the data
eventHandle = events.handle;
......
......@@ -3,55 +3,43 @@
require 'active_support/inflector'
module Rails
# Railtie is the core of the Rails Framework and provides several hooks to extend
# Railtie is the core of the Rails framework and provides several hooks to extend
# Rails and/or modify the initialization process.
#
# Every major component of Rails (Action Mailer, Action Controller,
# Action View, Active Record and Active Resource) are all Railties, so each of
# them is responsible to set their own initialization. This makes, for example,
# Rails absent of any Active Record hook, allowing any other ORM framework to hook in.
# Action View, Active Record and Active Resource) is a Railtie. Each of
# them is responsible for their own initialization. This makes Rails itself
# absent of any component hooks, allowing other components to be used in
# place of any of the Rails defaults.
#
# Developing a Rails extension does _not_ require any implementation of
# Railtie, but if you need to interact with the Rails framework during
# or after boot, then Railtie is what you need to do that interaction.
# or after boot, then Railtie is needed.
#
# For example, the following would need you to implement Railtie in your
# plugin:
# For example, an extension doing any of the following would require Railtie:
#
# * creating initializers
# * configuring a Rails framework or the Application, like setting a generator
# * adding Rails config.* keys to the environment
# * setting up a subscriber to the Rails +ActiveSupport::Notifications+
# * adding rake tasks into rails
# * configuring a Rails framework for the application, like setting a generator
# * adding config.* keys to the environment
# * setting up a subscriber with ActiveSupport::Notifications
# * adding rake tasks
#
# == Creating your Railtie
#
# Implementing Railtie in your Rails extension is done by creating a class
# Railtie that has your extension name and making sure that this gets loaded
# during boot time of the Rails stack.
# To extend Rails using Railtie, create a Railtie class which inherits
# from Rails::Railtie within your extension's namespace. This class must be
# loaded during the Rails boot process.
#
# You can do this however you wish, but here is an example if you want to provide
# it for a gem that can be used with or without Rails:
# The following example demonstrates an extension which can be used with or without Rails.
#
# * Create a file (say, lib/my_gem/railtie.rb) which contains class Railtie inheriting from
# Rails::Railtie and is namespaced to your gem:
#
# # lib/my_gem/railtie.rb
# module MyGem
# class Railtie < Rails::Railtie
# end
# # lib/my_gem/railtie.rb
# module MyGem
# class Railtie < Rails::Railtie
# end
# end
#
# * Require your own gem as well as rails in this file:
#
# # lib/my_gem/railtie.rb
# require 'my_gem'
# require 'rails'
#
# module MyGem
# class Railtie < Rails::Railtie
# end
# end
# # lib/my_gem.rb
# require 'my_gem/railtie' if defined?(Rails)
#
# == Initializers
#
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册