提交 35ee8fa3 编写于 作者: V Vijay Dev

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

......@@ -348,7 +348,7 @@ module ActionMailer #:nodoc:
#
# * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default),
# <tt>:sendmail</tt>, <tt>:test</tt>, and <tt>:file</tt>. Or you may provide a custom delivery method
# object eg. MyOwnDeliveryMethodClass.new. See the Mail gem documentation on the interface you need to
# object e.g. MyOwnDeliveryMethodClass. See the Mail gem documentation on the interface you need to
# implement for a custom delivery agent.
#
# * <tt>perform_deliveries</tt> - Determines whether emails are actually sent from Action Mailer when you
......
......@@ -979,6 +979,7 @@ def search_field(object_name, method, options = {})
def telephone_field(object_name, method, options = {})
Tags::TelField.new(object_name, method, self, options).render
end
# aliases telephone_field
alias phone_field telephone_field
# Returns a text_field of type "date".
......
......@@ -23,7 +23,7 @@ module UrlHelper
include ActionDispatch::Routing::UrlFor
include TagHelper
# We need to override url_optoins, _routes_context
# We need to override url_options, _routes_context
# and optimize_routes_generation? to consider the controller.
def url_options #:nodoc:
......
......@@ -3,32 +3,32 @@
require 'active_support/deprecation'
module ActiveModel
# Raised when an attribute is not defined.
class MissingAttributeError < NoMethodError
end
# == Active Model Attribute Methods
#
# <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and suffixes
# to your methods as well as handling the creation of Active Record like class methods
# such as +table_name+.
# <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and
# suffixes to your methods as well as handling the creation of Active Record
# like class methods such as +table_name+.
#
# The requirements to implement ActiveModel::AttributeMethods are to:
#
# * <tt>include ActiveModel::AttributeMethods</tt> in your object
# * <tt>include ActiveModel::AttributeMethods</tt> in your object.
# * Call each Attribute Method module method you want to add, such as
# attribute_method_suffix or attribute_method_prefix
# * Call <tt>define_attribute_methods</tt> after the other methods are
# called.
# * Define the various generic +_attribute+ methods that you have declared
# +attribute_method_suffix+ or +attribute_method_prefix+.
# * Call +define_attribute_methods+ after the other methods are called.
# * Define the various generic +_attribute+ methods that you have declared.
#
# A minimal implementation could be:
#
# class Person
# include ActiveModel::AttributeMethods
#
# attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
# attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
# attribute_method_suffix '_contrived?'
# attribute_method_prefix 'clear_'
# define_attribute_methods 'name'
# define_attribute_methods :name
#
# attr_accessor :name
#
......@@ -43,17 +43,16 @@ class MissingAttributeError < NoMethodError
# end
#
# def reset_attribute_to_default!(attr)
# send("#{attr}=", "Default Name")
# send("#{attr}=", 'Default Name')
# end
# end
#
# Note that whenever you include ActiveModel::AttributeMethods in your class,
# it requires you to implement an <tt>attributes</tt> method which returns a hash
# it requires you to implement an +attributes+ method which returns a hash
# with each attribute name in your model as hash key and the attribute value as
# hash value.
#
# Hash keys must be strings.
#
module AttributeMethods
extend ActiveSupport::Concern
......@@ -79,11 +78,9 @@ module ClassMethods
# An instance method <tt>#{prefix}attribute</tt> must exist and accept
# at least the +attr+ argument.
#
# For example:
#
# class Person
#
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_prefix 'clear_'
# define_attribute_methods :name
......@@ -96,7 +93,7 @@ module ClassMethods
# end
#
# person = Person.new
# person.name = "Bob"
# person.name = 'Bob'
# person.name # => "Bob"
# person.clear_name
# person.name # => nil
......@@ -114,14 +111,12 @@ def attribute_method_prefix(*prefixes)
#
# attribute#{suffix}(#{attr}, *args, &block)
#
# An <tt>attribute#{suffix}</tt> instance method must exist and accept at least
# the +attr+ argument.
#
# For example:
# An <tt>attribute#{suffix}</tt> instance method must exist and accept at
# least the +attr+ argument.
#
# class Person
#
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_suffix '_short?'
# define_attribute_methods :name
......@@ -134,7 +129,7 @@ def attribute_method_prefix(*prefixes)
# end
#
# person = Person.new
# person.name = "Bob"
# person.name = 'Bob'
# person.name # => "Bob"
# person.name_short? # => true
def attribute_method_suffix(*suffixes)
......@@ -155,13 +150,11 @@ def attribute_method_suffix(*suffixes)
# An <tt>#{prefix}attribute#{suffix}</tt> instance method must exist and
# accept at least the +attr+ argument.
#
# For example:
#
# class Person
#
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
# attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
# define_attribute_methods :name
#
# private
......@@ -184,14 +177,27 @@ def attribute_method_affix(*affixes)
# Allows you to make aliases for attributes.
#
# class Person
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_suffix '_short?'
# define_attribute_methods :name
#
# alias_attribute :nickname, :name
#
# private
#
# def attribute_short?(attr)
# send(attr).length < 5
# end
# end
#
# person = Person.new
# person.nickname = "Bob"
# person.nickname # => "Bob"
# person.name # => "Bob"
# person.name = 'Bob'
# person.name # => "Bob"
# person.nickname # => "Bob"
# person.name_short? # => true
# person.nickname_short? # => true
def alias_attribute(new_name, old_name)
self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s)
attribute_method_matchers.each do |matcher|
......@@ -204,13 +210,13 @@ def alias_attribute(new_name, old_name)
# Declares the attributes that should be prefixed and suffixed by
# ActiveModel::AttributeMethods.
#
# To use, pass in an array of attribute names (as strings or symbols),
# be sure to declare +define_attribute_methods+ after you define any
# prefix, suffix or affix methods, or they will not hook in.
# To use, pass attribute names (as strings or symbols), be sure to declare
# +define_attribute_methods+ after you define any prefix, suffix or affix
# methods, or they will not hook in.
#
# class Person
#
# include ActiveModel::AttributeMethods
#
# attr_accessor :name, :age, :address
# attribute_method_prefix 'clear_'
#
......@@ -229,6 +235,35 @@ def define_attribute_methods(*attr_names)
attr_names.flatten.each { |attr_name| define_attribute_method(attr_name) }
end
# Declares an attribute that should be prefixed and suffixed by
# ActiveModel::AttributeMethods.
#
# To use, pass an attribute name (as string or symbol), be sure to declare
# +define_attribute_method+ after you define any prefix, suffix or affix
# method, or they will not hook in.
#
# class Person
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_suffix '_short?'
#
# # Call to define_attribute_method must appear after the
# # attribute_method_prefix, attribute_method_suffix or
# # attribute_method_affix declares.
# define_attribute_method :name
#
# private
#
# def attribute_short?(attr)
# send(attr).length < 5
# end
# end
#
# person = Person.new
# person.name = 'Bob'
# person.name # => "Bob"
# person.name_short? # => true
def define_attribute_method(attr_name)
attribute_method_matchers.each do |matcher|
method_name = matcher.method_name(attr_name)
......@@ -246,7 +281,29 @@ def define_attribute_method(attr_name)
attribute_method_matchers_cache.clear
end
# Removes all the previously dynamically defined methods from the class
# Removes all the previously dynamically defined methods from the class.
#
# class Person
# include ActiveModel::AttributeMethods
#
# attr_accessor :name
# attribute_method_suffix '_short?'
# define_attribute_method :name
#
# private
#
# def attribute_short?(attr)
# send(attr).length < 5
# end
# end
#
# person = Person.new
# person.name = 'Bob'
# person.name_short? # => true
#
# Person.undefine_attribute_methods
#
# person.name_short? # => NoMethodError
def undefine_attribute_methods
generated_attribute_methods.module_eval do
instance_methods.each { |m| undef_method(m) }
......
......@@ -6,7 +6,7 @@ module ActiveModel
# Provides an interface for any class to have Active Record like callbacks.
#
# Like the Active Record methods, the callback chain is aborted as soon as
# one of the methods in the chain returns false.
# one of the methods in the chain returns +false+.
#
# First, extend ActiveModel::Callbacks from the class you are creating:
#
......@@ -18,9 +18,10 @@ module ActiveModel
#
# define_model_callbacks :create, :update
#
# This will provide all three standard callbacks (before, around and after) for
# both the :create and :update methods. To implement, you need to wrap the methods
# you want callbacks on in a block so that the callbacks get a chance to fire:
# This will provide all three standard callbacks (before, around and after)
# for both the <tt>:create</tt> and <tt>:update</tt> methods. To implement,
# you need to wrap the methods you want callbacks on in a block so that the
# callbacks get a chance to fire:
#
# def create
# run_callbacks :create do
......@@ -28,8 +29,8 @@ module ActiveModel
# end
# end
#
# Then in your class, you can use the +before_create+, +after_create+ and +around_create+
# methods, just as you would in an Active Record module.
# Then in your class, you can use the +before_create+, +after_create+ and
# +around_create+ methods, just as you would in an Active Record module.
#
# before_create :action_before_create
#
......@@ -38,12 +39,12 @@ module ActiveModel
# end
#
# You can choose not to have all three callbacks by passing a hash to the
# define_model_callbacks method.
# +define_model_callbacks+ method.
#
# define_model_callbacks :create, :only => [:after, :before]
# define_model_callbacks :create, only: [:after, :before]
#
# Would only create the after_create and before_create callback methods in your
# class.
# Would only create the +after_create+ and +before_create+ callback methods in
# your class.
module Callbacks
def self.extended(base)
base.class_eval do
......@@ -51,25 +52,27 @@ def self.extended(base)
end
end
# define_model_callbacks accepts the same options define_callbacks does, in case
# you want to overwrite a default. Besides that, it also accepts an :only option,
# where you can choose if you want all types (before, around or after) or just some.
# define_model_callbacks accepts the same options +define_callbacks+ does,
# in case you want to overwrite a default. Besides that, it also accepts an
# <tt>:only</tt> option, where you can choose if you want all types (before,
# around or after) or just some.
#
# define_model_callbacks :initializer, :only => :after
# define_model_callbacks :initializer, only: :after
#
# Note, the <tt>:only => <type></tt> hash will apply to all callbacks defined on
# that method call. To get around this you can call the define_model_callbacks
# Note, the <tt>only: <type></tt> hash will apply to all callbacks defined
# on that method call. To get around this you can call the define_model_callbacks
# method as many times as you need.
#
# define_model_callbacks :create, :only => :after
# define_model_callbacks :update, :only => :before
# define_model_callbacks :destroy, :only => :around
# define_model_callbacks :create, only: :after
# define_model_callbacks :update, only: :before
# define_model_callbacks :destroy, only: :around
#
# Would create +after_create+, +before_update+ and +around_destroy+ methods only.
# Would create +after_create+, +before_update+ and +around_destroy+ methods
# only.
#
# You can pass in a class to before_<type>, after_<type> and around_<type>, in which
# case the callback will call that class's <action>_<type> method passing the object
# that the callback is being called on.
# You can pass in a class to before_<type>, after_<type> and around_<type>,
# in which case the callback will call that class's <action>_<type> method
# passing the object that the callback is being called on.
#
# class MyModel
# extend ActiveModel::Callbacks
......@@ -83,7 +86,6 @@ def self.extended(base)
# # obj is the MyModel instance that the callback is being called on
# end
# end
#
def define_model_callbacks(*callbacks)
options = callbacks.extract_options!
options = {
......
......@@ -38,7 +38,6 @@ module ActiveModel
# Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method
# to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so
# there is no need for you to do this manually.
#
module Validations
extend ActiveSupport::Concern
......@@ -153,6 +152,21 @@ def validate(*args, &block)
# List all validators that are being used to validate the model using
# +validates_with+ method.
#
# class Person
# include ActiveModel::Validations
#
# validates_with MyValidator
# validates_with OtherValidator, on: :create
# validates_with StrictValidator, strict: true
# end
#
# Person.validators
# # => [
# # #<MyValidator:0x007fbff403e808 @options={}>,
# # #<OtherValidator:0x007fbff403d930 @options={:on=>:create}>,
# # #<StrictValidator:0x007fbff3204a30 @options={:strict=>true}>
# # ]
def validators
_validators.values.flatten.uniq
end
......@@ -221,7 +235,6 @@ def invalid?(context = nil)
# @data[key]
# end
# end
#
alias :read_attribute_for_validation :send
protected
......
......@@ -34,7 +34,7 @@ module ActiveRecord
# Examples:
# class CreditCard < ActiveRecord::Base
# # Strip everything but digits, so the user can specify "555 234 34" or
# # "5552-3434" or both will mean "55523434"
# # "5552-3434" and both will mean "55523434"
# before_validation(:on => :create) do
# self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
# end
......
......@@ -73,8 +73,6 @@ def preload!(*args)
# Used to indicate that an association is referenced by an SQL string, and should
# therefore be JOINed in any query rather than loaded separately.
#
# For example:
#
# User.includes(:posts).where("posts.name = 'foo'")
# # => Doesn't JOIN the posts table, resulting in an error.
#
......@@ -165,7 +163,6 @@ def order!(*args)
# User.order('email DESC').reorder('id ASC').order('name ASC')
#
# generates a query with 'ORDER BY id ASC, name ASC'.
#
def reorder(*args)
args.blank? ? self : spawn.reorder!(*args)
end
......@@ -310,6 +307,11 @@ def having!(opts, *rest)
self
end
# Specifies a limit for the number of records to retrieve.
#
# User.limit(10) # generated SQL has 'LIMIT 10'
#
# User.limit(10).limit(20) # generated SQL has 'LIMIT 20'
def limit(value)
spawn.limit!(value)
end
......@@ -319,6 +321,13 @@ def limit!(value)
self
end
# Specifies the number of rows to skip before returning rows.
#
# User.offset(10) # generated SQL has "OFFSET 10"
#
# Should be used with order.
#
# User.offset(10).order("name ASC")
def offset(value)
spawn.offset!(value)
end
......@@ -488,6 +497,9 @@ def extending!(*modules, &block)
self
end
# Reverse the existing order clause on the relation.
#
# User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
def reverse_order
spawn.reverse_order!
end
......
......@@ -4,6 +4,26 @@
module ActiveSupport
module Deprecation
# Declare that a method has been deprecated.
#
# module Fred
# extend self
#
# def foo; end
# def bar; end
# def baz; end
# end
#
# ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
# # => [:foo, :bar, :baz]
#
# Fred.foo
# # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
#
# Fred.bar
# # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
#
# Fred.baz
# # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
def self.deprecate_methods(target_module, *method_names)
options = method_names.extract_options!
method_names += options.keys
......
......@@ -3,7 +3,8 @@ module Deprecation
class << self
attr_accessor :silenced
# Outputs a deprecation warning to the output configured by <tt>ActiveSupport::Deprecation.behavior</tt>
# Outputs a deprecation warning to the output configured by
# <tt>ActiveSupport::Deprecation.behavior</tt>.
#
# ActiveSupport::Deprecation.warn("something broke!")
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
......@@ -15,6 +16,14 @@ def warn(message = nil, callstack = caller)
end
# Silence deprecation warnings within the block.
#
# ActiveSupport::Deprecation.warn("something broke!")
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
#
# ActiveSupport::Deprecation.silence do
# ActiveSupport::Deprecation.warn("something broke!")
# end
# # => nil
def silence
old_silenced, @silenced = @silenced, true
yield
......
......@@ -47,6 +47,11 @@ def self.test_order # :nodoc:
alias :assert_no_match :refute_match
alias :assert_not_same :refute_same
# Fails if the block raises an exception.
#
# assert_nothing_raised do
# ...
# end
def assert_nothing_raised(*args)
yield
end
......
......@@ -3,45 +3,46 @@
module ActiveSupport
module Testing
module Assertions
# Test numeric difference between the return value of an expression as a result of what is evaluated
# in the yielded block.
# Test numeric difference between the return value of an expression as a
# result of what is evaluated in the yielded block.
#
# assert_difference 'Article.count' do
# post :create, :article => {...}
# post :create, article: {...}
# end
#
# An arbitrary expression is passed in and evaluated.
#
# assert_difference 'assigns(:article).comments(:reload).size' do
# post :create, :comment => {...}
# post :create, comment: {...}
# end
#
# An arbitrary positive or negative difference can be specified. The default is +1.
# An arbitrary positive or negative difference can be specified.
# The default is <tt>1</tt>.
#
# assert_difference 'Article.count', -1 do
# post :delete, :id => ...
# post :delete, id: ...
# end
#
# An array of expressions can also be passed in and evaluated.
#
# assert_difference [ 'Article.count', 'Post.count' ], +2 do
# post :create, :article => {...}
# assert_difference [ 'Article.count', 'Post.count' ], 2 do
# post :create, article: {...}
# end
#
# A lambda or a list of lambdas can be passed in and evaluated:
#
# assert_difference lambda { Article.count }, 2 do
# post :create, :article => {...}
# post :create, article: {...}
# end
#
# assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
# post :create, :article => {...}
# post :create, article: {...}
# end
#
# A error message can be specified.
# An error message can be specified.
#
# assert_difference 'Article.count', -1, "An Article should be destroyed" do
# post :delete, :id => ...
# assert_difference 'Article.count', -1, 'An Article should be destroyed' do
# post :delete, id: ...
# end
def assert_difference(expression, difference = 1, message = nil, &block)
expressions = Array(expression)
......@@ -60,33 +61,43 @@ def assert_difference(expression, difference = 1, message = nil, &block)
end
end
# Assertion that the numeric result of evaluating an expression is not changed before and after
# invoking the passed in block.
# Assertion that the numeric result of evaluating an expression is not
# changed before and after invoking the passed in block.
#
# assert_no_difference 'Article.count' do
# post :create, :article => invalid_attributes
# post :create, article: invalid_attributes
# end
#
# A error message can be specified.
# An error message can be specified.
#
# assert_no_difference 'Article.count', "An Article should not be created" do
# post :create, :article => invalid_attributes
# assert_no_difference 'Article.count', 'An Article should not be created' do
# post :create, article: invalid_attributes
# end
def assert_no_difference(expression, message = nil, &block)
assert_difference expression, 0, message, &block
end
# Test if an expression is blank. Passes if object.blank? is true.
# Test if an expression is blank. Passes if <tt>object.blank?</tt> is +true+.
#
# assert_blank [] # => true
# assert_blank [] # => true
# assert_blank [[]] # => [[]] is not blank
#
# An error message can be specified.
#
# assert_blank [], 'this should be blank'
def assert_blank(object, message=nil)
message ||= "#{object.inspect} is not blank"
assert object.blank?, message
end
# Test if an expression is not blank. Passes if object.present? is true.
# Test if an expression is not blank. Passes if <tt>object.present?</tt> is +true+.
#
# assert_present({ data: 'x' }) # => true
# assert_present({}) # => {} is blank
#
# An error message can be specified.
#
# assert_present({:data => 'x' }) # => true
# assert_present({ data: 'x' }, 'this should not be blank')
def assert_present(object, message=nil)
message ||= "#{object.inspect} is blank"
assert object.present?, message
......
h2. AJAX on Rails
This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic AJAX applications with ease! We will cover the following topics:
This guide covers the built-in Ajax/JavaScript functionality of Rails (and more);
it will enable you to create rich and dynamic AJAX applications with ease! We will
cover the following topics:
* Quick introduction to AJAX and related technologies
* Unobtrusive JavaScript helpers with drivers for Prototype, jQuery etc
......@@ -10,34 +12,99 @@ endprologue.
h3. Hello AJAX - a Quick Intro
You'll need the basics of DOM, HTTP requests and other topics discussed here to really understand Ajax on Rails.
AJAX is about updating parts of a web page without reloading the page. An AJAX
call happens as a response to an event, like when the page finished loading or
when a user clicks on an element. For example, let say you click on a link, which
would usually take you to a new page, but instead of doing that, an asynchronous
HTTP request is made and the response is evaluated with JavaScript. That way the
page is not reloaded and new information can be dynamically included in the page.
The way that happens is by inserting, removing or changing parts of the DOM. The
DOM, or Document Object Model, is a convention to represent the HTML document as
a set of nodes that contain other nodes. For example, a list of names is represented
as a +ul+ element node containing several +li+ element nodes. An AJAX call can
be made to obtain a new list item to include, and append it inside a +li+ node to
the +ul+ node.
h4. Asynchronous JavaScript + XML
Basic terminology, new style of creating web apps
AJAX means Asynchronous JavaScript + XML. Asynchronous means that the page is not
reloaded, the request made is separate from the regular page request. Javascript
is used to evaluate the response and the XML part is a bit misleading as XML is
not required, you respond to the HTTP request with JSON or regular HTML as well.
h4. The DOM
basics of the DOM, how is it built, properties, features, why is it central to AJAX
The DOM (Document Object Model) is a convention to represent HTML (or XML)
documents, as a set of nodes that act as objects and contain other nodes. You can
have a +div+ element that contains other +div+ elements as well as +p+ elements
that contain text.
h4. Standard HTML communication vs AJAX
How do 'standard' and AJAX requests differ, why does this matter for understanding AJAX on Rails (tie in for *_remote helpers, the next section)
In regular HTML comunications, when you click on a link, the browser makes an HTTP
+GET+ request, the server responds with a new HTML document that the browsers renders
and then replaces the previous one. The same thing happens when you click a button to
submit a form, except that you make and HTTP +POST+ request, but you also get a new
HTML document that the browser renders and replaces the current one. In AJAX
communications, the request is separate, and the response is evaluated in JavaScript
instead of rendered by the browser. That way you can have more control over the content
that gets returned, and the page is not reloaded.
h3. Built-in Rails Helpers
Rails 3.1 ships with "jQuery":http://jquery.com as the default JavaScript library. The Gemfile contains <tt>gem 'jquery-rails'</tt> which makes the jQuery files available to the application automatically. This can be accessed as:
Rails 4.0 ships with "jQuery":http://jquery.com as the default JavaScript library.
The Gemfile contains +gem 'jquery-rails'+ which provides the +jquery.js+ and
+jquery_ujs.js+ files via the asset pipeline.
You will have to use the +require+ directive to tell Sprockets to load +jquery.js+
and +jquery.js+. For example, a new Rails application includes a default
+app/assets/javascripts/application.js+ file which contains the following lines:
<plain>
// ...
//= require jquery
//= require jquery_ujs
// ...
</plain>
The +application.js+ file acts like a manifest and is used to tell Sprockets the
files that you wish to require. In this case, you are requiring the files +jquery.js+
and +jquery_ujs.js+ provided by the +jquery-rails+ gem.
If the application is not using the asset pipeline, this can be accessed as:
<ruby>
javascript_include_tag :defaults
</ruby>
By default, +:defaults+ loads jQuery.
You can also choose to use Prototype instead of jQuery and specify the option
using +-j+ switch while generating the application.
<shell>
rails new app_name -j prototype
</shell>
This will add the +prototype-rails+ gem to the Gemfile and modify the
+app/assets/javascripts/application.js+ file:
<plain>
// ...
//= require prototype
//= require prototype_ujs
// ...
</plain>
You are ready to add some AJAX love to your Rails app!
h4. Examples
All the remote_method helpers has been removed. To make them working with AJAX, simply pass the <tt>:remote => true</tt> option to the original non-remote method.
To make them working with AJAX, simply pass the <tt>remote: true</tt> option to
the original non-remote method.
<ruby>
button_to "New", :action => "new", :form_class => "new-thing"
button_to 'New', action: 'new', form_class: 'new-thing'
</ruby>
will produce
......@@ -49,7 +116,7 @@ will produce
</html>
<ruby>
button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" }
button_to 'Create', action: 'create', remote: true, form: { 'data-type' => 'json' }
</ruby>
will produce
......@@ -61,8 +128,8 @@ will produce
</html>
<ruby>
button_to "Delete Image", { :action => "delete", :id => @image.id },
:confirm => "Are you sure?", :method => :delete
button_to 'Delete Image', { action: 'delete', id: @image.id },
confirm: 'Are you sure?', method: :delete
</ruby>
will produce
......@@ -77,8 +144,8 @@ will produce
</html>
<ruby>
button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
:method => "delete", :remote => true, 'data-disable-with' => 'loading...')
button_to 'Destroy', 'http://www.example.com', confirm: 'Are you sure?',
method: 'delete', remote: true, data: { disable_with: 'loading...' }
</ruby>
will produce
......@@ -92,14 +159,6 @@ will produce
</form>
</html>
You can also choose to use Prototype instead of jQuery and specify the option using +-j+ switch while generating the application.
<shell>
rails new app_name -j prototype
</shell>
You are ready to add some AJAX love to your Rails app!
h4. The Quintessential AJAX Rails Helper: link_to_remote
Let's start with what is probably the most often used helper: +link_to_remote+. It has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
......@@ -223,23 +282,6 @@ h5. +form_remote_tag+
h5. +submit_to_remote+
h4. Observing Elements
h5. +observe_field+
h5. +observe_form+
h4. Calling a Function Periodically
h5. +periodically_call_remote+
h4. Miscellaneous Functionality
h5. +remote_function+
h5. +update_page+
h4. Serving JavaScript
First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood.
......@@ -265,4 +307,4 @@ JavaScript testing reminds me the definition of the world 'classic' by Mark Twai
* Cucumber+Webrat
* Mention stuff like screw.unit/jsSpec
Note to self: check out the RailsConf JS testing video
Note to self: check out the RailsConf JS testing video
\ No newline at end of file
......@@ -649,11 +649,19 @@ Apache and nginx support this option, which can be enabled in <tt>config/environ
WARNING: If you are upgrading an existing application and intend to use this option, take care to paste this configuration option only into +production.rb+ and any other environments you define with production behavior (not +application.rb+).
h3. How Caching Works
h3. Assets Cache Store
Sprockets uses the default Rails cache store to cache assets in development and production.
Sprockets uses the default Rails cache store will be used to cache assets in development and production. This can be changed by setting +config.assets.cache_store+.
TODO: Add more about changing the default store.
<ruby>
config.assets.cache_store = :memory_store
</ruby>
The options accepted by the assets cache store are the same as the application's cache store.
<ruby>
config.assets.cache_store = :memory_store, { :size => 32.megabytes }
</ruby>
h3. Adding Assets to Your Gems
......@@ -667,9 +675,11 @@ TODO: Registering gems on "Tilt":https://github.com/rtomayko/tilt enabling Sproc
h3. Upgrading from Old Versions of Rails
There are two issues when upgrading. The first is moving the files from +public/+ to the new locations. See "Asset Organization":#asset-organization above for guidance on the correct locations for different file types.
There are a few issues when upgrading. The first is moving the files from +public/+ to the new locations. See "Asset Organization":#asset-organization above for guidance on the correct locations for different file types.
Next will be avoiding duplicate JavaScript files. Since jQuery is the default JavaScript library from Rails 3.1 onwards, you don't need to copy +jquery.js+ into +app/assets+ and it will be included automatically.
The second is updating the various environment files with the correct default options. The following changes reflect the defaults in version 3.1.0.
The third is updating the various environment files with the correct default options. The following changes reflect the defaults in version 3.1.0.
In +application.rb+:
......@@ -725,8 +735,8 @@ The following should also be added to +Gemfile+:
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', "~> 3.1.0"
gem 'coffee-rails', "~> 3.1.0"
gem 'sass-rails', "~> 3.2.3"
gem 'coffee-rails', "~> 3.2.1"
gem 'uglifier'
end
</plain>
......
......@@ -474,7 +474,7 @@ h4. Backporting
Changes that are merged into master are intended for the next major release of Rails. Sometimes, it might be beneficial for your changes to propagate back to the maintenance releases for older stable branches. Generally, security fixes and bug fixes are good candidates for a backport, while new features and patches that introduce a change in behavior will not be accepted. When in doubt, it is best to consult a rails team member before backporting your changes to avoid wasted effort.
For simple fixes, the easiest way to backport your change is to "extract a diff from your changes in master and apply them to the target branch":http://ariejan.net/2009/10/26/how-to-create-and-apply-a-patch-with-git.
For simple fixes, the easiest way to backport your changes is to "extract a diff from your changes in master and apply them to the target branch":http://ariejan.net/2009/10/26/how-to-create-and-apply-a-patch-with-git.
First make sure your changes are the only difference between your current branch and master:
......
......@@ -4,15 +4,22 @@ This guide explains the internals of the initialization process in Rails
as of Rails 4. It is an extremely in-depth guide and recommended for advanced Rails developers.
* Using +rails server+
* Using Passenger
endprologue.
This guide goes through every method call that is
required to boot up the Ruby on Rails stack for a default Rails 4 application, explaining each part in detail along the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application.
required to boot up the Ruby on Rails stack for a default Rails 4
application, explaining each part in detail along the way. For this
guide, we will be focusing on what happens when you execute +rails
server+ to boot your app.
NOTE: Paths in this guide are relative to Rails or a Rails application unless otherwise specified.
TIP: If you want to follow along while browsing the Rails "source
code":https://github.com/rails/rails, we recommend that you use the +t+
key binding to open the file finder inside github and find files
quickly.
h3. Launch!
A Rails application is usually started with the command +rails server+.
......@@ -32,7 +39,7 @@ require "rails/cli"
</ruby>
This file will first attempt to push the +railties/lib+ directory if
present, and then require +rails/cli+.
present, and then requires +rails/cli+.
h4. +railties/lib/rails/cli.rb+
......@@ -121,8 +128,13 @@ exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
This is effectively the same as running +ruby script/rails [arguments]+, where +[arguments]+ at this point in time is simply "server".
h3. Rails Initialization
Only now we finally start the real initialization process, beginning
with +script/rails+.
TIP: If you execute +script/rails+ directly from your Rails app you will
avoid executing the code that we just described.
skip executing all the code that we've just described.
h4. +script/rails+
......@@ -239,12 +251,8 @@ module Rails
h4. +actionpack/lib/action_dispatch.rb+
Action Dispatch is the routing component of the Rails framework. Other
than the rouing itself, it adds
functionalities like routing, session, and common middlewares.
Action Dispatch itself is also responsible for loading Active Support, Action
Pack, Active Model, and Rack.
Action Dispatch is the routing component of the Rails framework.
It adds functionalities like routing, session, and common middlewares.
h4. +rails/commands/server.rb+
......@@ -352,8 +360,7 @@ h4. +config/application+
When +require APP_PATH+ is executed, +config/application.rb+ is loaded.
This is a file exists in your app and it's free for you to change based
on your needs. Among other things, inside this file you load gems with
bundler, and create your application namespace.
on your needs.
h4. +Rails::Server#start+
......@@ -513,7 +520,7 @@ require 'rails/all'
h4. +railties/lib/rails/all.rb+
This file is responsible for requiring all the individual parts of Rails like so:
This file is responsible for requiring all the individual frameworks of Rails:
<ruby>
require "rails"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册