mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge remote branch 'docrails/master'
This commit is contained in:
@@ -48,12 +48,12 @@ more separate. Each of these packages can be used independently outside of
|
||||
|
||||
"Welcome aboard: You're riding Ruby on Rails!"
|
||||
|
||||
5. Follow the guidelines to start developing your application. You can find
|
||||
the following resources handy:
|
||||
5. Follow the guidelines to start developing your application. You can find the following resources handy:
|
||||
|
||||
* The README file created within your application.
|
||||
* The {Getting Started Guide}[http://guides.rubyonrails.org/getting_started.html].
|
||||
* The {Ruby on Rails Tutorial Book}[http://railstutorial.org/book].
|
||||
* The {API documentation}[http://api.rubyonrails.org].
|
||||
|
||||
|
||||
== Contributing
|
||||
|
||||
@@ -6,6 +6,10 @@ module AbstractController
|
||||
class Error < StandardError; end
|
||||
class ActionNotFound < StandardError; end
|
||||
|
||||
# <tt>AbstractController::Base</tt> is a low-level API. Nobody should be
|
||||
# using it directly, and subclasses (like ActionController::Base) are
|
||||
# expected to provide their own +render+ method, since rendering means
|
||||
# different things depending on the context.
|
||||
class Base
|
||||
attr_internal :response_body
|
||||
attr_internal :action_name
|
||||
@@ -36,13 +40,12 @@ module AbstractController
|
||||
controller.public_instance_methods(true)
|
||||
end
|
||||
|
||||
# The list of hidden actions to an empty Array. Defaults to an
|
||||
# empty Array. This can be modified by other modules or subclasses
|
||||
# The list of hidden actions to an empty array. Defaults to an
|
||||
# empty array. This can be modified by other modules or subclasses
|
||||
# to specify particular actions as hidden.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[String]:: An array of method names that should not be
|
||||
# considered actions.
|
||||
# * <tt>array</tt> - An array of method names that should not be considered actions.
|
||||
def hidden_actions
|
||||
[]
|
||||
end
|
||||
@@ -54,8 +57,7 @@ module AbstractController
|
||||
# itself. Finally, #hidden_actions are removed.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[String]:: A list of all methods that should be considered
|
||||
# actions.
|
||||
# * <tt>array</tt> - A list of all methods that should be considered actions.
|
||||
def action_methods
|
||||
@action_methods ||= begin
|
||||
# All public instance methods of this class, including ancestors
|
||||
@@ -84,7 +86,7 @@ module AbstractController
|
||||
# controller_name.
|
||||
#
|
||||
# ==== Returns
|
||||
# String
|
||||
# * <tt>string</tt>
|
||||
def controller_path
|
||||
@controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
|
||||
end
|
||||
@@ -104,7 +106,7 @@ module AbstractController
|
||||
# ActionNotFound error is raised.
|
||||
#
|
||||
# ==== Returns
|
||||
# self
|
||||
# * <tt>self</tt>
|
||||
def process(action, *args)
|
||||
@_action_name = action_name = action.to_s
|
||||
|
||||
@@ -133,10 +135,10 @@ module AbstractController
|
||||
# can be considered an action.
|
||||
#
|
||||
# ==== Parameters
|
||||
# name<String>:: The name of an action to be tested
|
||||
# * <tt>name</tt> - The name of an action to be tested
|
||||
#
|
||||
# ==== Returns
|
||||
# TrueClass, FalseClass
|
||||
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
|
||||
def action_method?(name)
|
||||
self.class.action_methods.include?(name)
|
||||
end
|
||||
@@ -180,11 +182,11 @@ module AbstractController
|
||||
# returns nil, an ActionNotFound exception will be raised.
|
||||
#
|
||||
# ==== Parameters
|
||||
# action_name<String>:: An action name to find a method name for
|
||||
# * <tt>action_name</tt> - An action name to find a method name for
|
||||
#
|
||||
# ==== Returns
|
||||
# String:: The name of the method that handles the action
|
||||
# nil:: No method name could be found. Raise ActionNotFound.
|
||||
# * <tt>string</tt> - The name of the method that handles the action
|
||||
# * <tt>nil</tt> - No method name could be found. Raise ActionNotFound.
|
||||
def method_for_action(action_name)
|
||||
if action_method?(action_name) then action_name
|
||||
elsif respond_to?(:action_missing, true) then "_handle_action_missing"
|
||||
|
||||
@@ -28,9 +28,8 @@ module AbstractController
|
||||
# a Rails process.
|
||||
#
|
||||
# ==== Options
|
||||
# :only<#to_s>:: The callback should be run only for this action
|
||||
# :except<#to_s>:: The callback should be run for all actions
|
||||
# except this action
|
||||
# * <tt>only</tt> - The callback should be run only for this action
|
||||
# * <tt>except<tt> - The callback should be run for all actions except this action
|
||||
def _normalize_callback_options(options)
|
||||
if only = options[:only]
|
||||
only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ")
|
||||
@@ -45,7 +44,7 @@ module AbstractController
|
||||
# Skip before, after, and around filters matching any of the names
|
||||
#
|
||||
# ==== Parameters
|
||||
# *names<Object>:: A list of valid names that could be used for
|
||||
# * <tt>names</tt> - A list of valid names that could be used for
|
||||
# callbacks. Note that skipping uses Ruby equality, so it's
|
||||
# impossible to skip a callback defined using an anonymous proc
|
||||
# using #skip_filter
|
||||
@@ -60,13 +59,13 @@ module AbstractController
|
||||
# the normalization across several methods that use it.
|
||||
#
|
||||
# ==== Parameters
|
||||
# callbacks<Array[*Object, Hash]>:: A list of callbacks, with an optional
|
||||
# * <tt>callbacks</tt> - An array of callbacks, with an optional
|
||||
# options hash as the last parameter.
|
||||
# block<Proc>:: A proc that should be added to the callbacks.
|
||||
# * <tt>block</tt> - A proc that should be added to the callbacks.
|
||||
#
|
||||
# ==== Block Parameters
|
||||
# name<Symbol>:: The callback to be added
|
||||
# options<Hash>:: A list of options to be used when adding the callback
|
||||
# * <tt>name</tt> - The callback to be added
|
||||
# * <tt>options</tt> - A hash of options to be used when adding the callback
|
||||
def _insert_callbacks(callbacks, block)
|
||||
options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
|
||||
_normalize_callback_options(options)
|
||||
@@ -82,27 +81,27 @@ module AbstractController
|
||||
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
||||
# Append a before, after or around filter. See _insert_callbacks
|
||||
# for details on the allowed parameters.
|
||||
def #{filter}_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options|
|
||||
set_callback(:process_action, :#{filter}, name, options)
|
||||
end
|
||||
end
|
||||
def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options}
|
||||
set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before_filter, name, options)
|
||||
end # end
|
||||
end # end
|
||||
|
||||
# Prepend a before, after or around filter. See _insert_callbacks
|
||||
# for details on the allowed parameters.
|
||||
def prepend_#{filter}_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options|
|
||||
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
|
||||
end
|
||||
end
|
||||
def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
||||
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
|
||||
end # end
|
||||
end # end
|
||||
|
||||
# Skip a before, after or around filter. See _insert_callbacks
|
||||
# for details on the allowed parameters.
|
||||
def skip_#{filter}_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options|
|
||||
skip_callback(:process_action, :#{filter}, name, options)
|
||||
end
|
||||
end
|
||||
def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
|
||||
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
||||
skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
|
||||
end # end
|
||||
end # end
|
||||
|
||||
# *_filter is the same as append_*_filter
|
||||
alias_method :append_#{filter}_filter, :#{filter}_filter
|
||||
|
||||
@@ -40,7 +40,7 @@ module AbstractController
|
||||
# <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
|
||||
#
|
||||
# ==== Parameters
|
||||
# meths<Array[#to_s]>:: The name of a method on the controller
|
||||
# * <tt>method[, method]</tt> - A name or names of a method on the controller
|
||||
# to be made available on the view.
|
||||
def helper_method(*meths)
|
||||
meths.flatten.each do |meth|
|
||||
@@ -55,8 +55,8 @@ module AbstractController
|
||||
# The +helper+ class method can take a series of helper module names, a block, or both.
|
||||
#
|
||||
# ==== Parameters
|
||||
# *args<Array[Module, Symbol, String, :all]>
|
||||
# block<Block>:: A block defining helper methods
|
||||
# * <tt>*args</tt> - Module, Symbol, String, :all
|
||||
# * <tt>block</tt> - A block defining helper methods
|
||||
#
|
||||
# ==== Examples
|
||||
# When the argument is a module it will be included directly in the template class.
|
||||
@@ -100,7 +100,7 @@ module AbstractController
|
||||
# rendered through this controller.
|
||||
#
|
||||
# ==== Parameters
|
||||
# mod<Module>:: The module to include into the current helper module
|
||||
# * <tt>module</tt> - The module to include into the current helper module
|
||||
# for the class
|
||||
def add_template_helper(mod)
|
||||
_helpers.module_eval { include mod }
|
||||
@@ -118,10 +118,10 @@ module AbstractController
|
||||
# are returned.
|
||||
#
|
||||
# ==== Parameters
|
||||
# args<Array[String, Symbol, Module]>:: A list of helpers
|
||||
# * <tt>args</tt> - An array of helpers
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[Module]:: A normalized list of modules for the list of
|
||||
# * <tt>Array</tt> - A normalized list of modules for the list of
|
||||
# helpers provided.
|
||||
def modules_for_helpers(args)
|
||||
args.flatten.map! do |arg|
|
||||
|
||||
@@ -114,11 +114,13 @@ module AbstractController
|
||||
#
|
||||
# class WeblogController < ActionController::Base
|
||||
# layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
|
||||
# end
|
||||
#
|
||||
# Of course, the most common way of specifying a layout is still just as a plain template name:
|
||||
#
|
||||
# class WeblogController < ActionController::Base
|
||||
# layout "weblog_standard"
|
||||
# end
|
||||
#
|
||||
# If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
|
||||
# Otherwise, it will be looked up relative to the template root.
|
||||
@@ -183,7 +185,7 @@ module AbstractController
|
||||
# layout.
|
||||
#
|
||||
# ==== Returns
|
||||
# Boolean:: True if the action has a layout, false otherwise.
|
||||
# * <tt> Boolean</tt> - True if the action has a layout, false otherwise.
|
||||
def action_has_layout?
|
||||
return unless super
|
||||
|
||||
@@ -209,11 +211,11 @@ module AbstractController
|
||||
# true:: raise an ArgumentError
|
||||
#
|
||||
# ==== Parameters
|
||||
# layout<String, Symbol, false)>:: The layout to use.
|
||||
# * <tt>String, Symbol, false</tt> - The layout to use.
|
||||
#
|
||||
# ==== Options (conditions)
|
||||
# :only<#to_s, Array[#to_s]>:: A list of actions to apply this layout to.
|
||||
# :except<#to_s, Array[#to_s]>:: Apply this layout to all actions but this one
|
||||
# * :only - A list of actions to apply this layout to.
|
||||
# * :except - Apply this layout to all actions but this one.
|
||||
def layout(layout, conditions = {})
|
||||
include LayoutConditions unless conditions.empty?
|
||||
|
||||
@@ -228,7 +230,7 @@ module AbstractController
|
||||
# value of this method.
|
||||
#
|
||||
# ==== Returns
|
||||
# String:: A template name
|
||||
# * <tt>String</tt> - A template name
|
||||
def _implied_layout_name
|
||||
controller_path
|
||||
end
|
||||
@@ -313,8 +315,8 @@ module AbstractController
|
||||
# the name type.
|
||||
#
|
||||
# ==== Parameters
|
||||
# name<String|TrueClass|FalseClass|Symbol>:: The name of the template
|
||||
# details<Hash{Symbol => Object}>:: A list of details to restrict
|
||||
# * <tt>name</tt> - The name of the template
|
||||
# * <tt>details</tt> - A list of details to restrict
|
||||
# the lookup to. By default, layout lookup is limited to the
|
||||
# formats specified for the current request.
|
||||
def _layout_for_option(name)
|
||||
@@ -333,14 +335,14 @@ module AbstractController
|
||||
# Optionally raises an exception if the layout could not be found.
|
||||
#
|
||||
# ==== Parameters
|
||||
# details<Hash>:: A list of details to restrict the search by. This
|
||||
# * <tt>details</tt> - A list of details to restrict the search by. This
|
||||
# might include details like the format or locale of the template.
|
||||
# require_layout<Boolean>:: If this is true, raise an ArgumentError
|
||||
# * <tt>require_logout</tt> - If this is true, raise an ArgumentError
|
||||
# with details about the fact that the exception could not be
|
||||
# found (defaults to false)
|
||||
#
|
||||
# ==== Returns
|
||||
# Template:: The template object for the default layout (or nil)
|
||||
# * <tt>template</tt> - The template object for the default layout (or nil)
|
||||
def _default_layout(require_layout = false)
|
||||
begin
|
||||
layout_name = _layout if action_has_layout?
|
||||
|
||||
@@ -34,9 +34,9 @@ module AbstractController
|
||||
# Append a path to the list of view paths for this controller.
|
||||
#
|
||||
# ==== Parameters
|
||||
# path<String, ViewPath>:: If a String is provided, it gets converted into
|
||||
# the default view path. You may also provide a custom view path
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
# * <tt>path</tt> - If a String is provided, it gets converted into
|
||||
# the default view path. You may also provide a custom view path
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
def append_view_path(path)
|
||||
self.view_paths = view_paths.dup + Array(path)
|
||||
end
|
||||
@@ -44,9 +44,9 @@ module AbstractController
|
||||
# Prepend a path to the list of view paths for this controller.
|
||||
#
|
||||
# ==== Parameters
|
||||
# path<String, ViewPath>:: If a String is provided, it gets converted into
|
||||
# the default view path. You may also provide a custom view path
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
# * <tt>path</tt> - If a String is provided, it gets converted into
|
||||
# the default view path. You may also provide a custom view path
|
||||
# (see ActionView::ViewPathSet for more information)
|
||||
def prepend_view_path(path)
|
||||
self.view_paths = Array(path) + view_paths.dup
|
||||
end
|
||||
@@ -59,7 +59,7 @@ module AbstractController
|
||||
# Set the view paths.
|
||||
#
|
||||
# ==== Parameters
|
||||
# paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that;
|
||||
# * <tt>paths</tt> - If a ViewPathSet is provided, use that;
|
||||
# otherwise, process the parameter into a ViewPathSet.
|
||||
def view_paths=(paths)
|
||||
self._view_paths = ActionView::Base.process_view_paths(paths)
|
||||
|
||||
@@ -1,6 +1,169 @@
|
||||
require "action_controller/log_subscriber"
|
||||
|
||||
module ActionController
|
||||
# Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
|
||||
# on request and then either render a template or redirect to another action. An action is defined as a public method
|
||||
# on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
|
||||
#
|
||||
# By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
|
||||
# controllers in turn inherit from ApplicationController. This gives you one class to configure things such as
|
||||
# request forgery protection and filtering of sensitive request parameters.
|
||||
#
|
||||
# A sample controller could look like this:
|
||||
#
|
||||
# class PostsController < ApplicationController
|
||||
# def index
|
||||
# @posts = Post.all
|
||||
# end
|
||||
#
|
||||
# def create
|
||||
# @post = Post.create params[:post]
|
||||
# redirect_to posts_path
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
|
||||
# after executing code in the action. For example, the +index+ action of the PostsController would render the
|
||||
# template <tt>app/views/posts/index.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
|
||||
#
|
||||
# Unlike index, the create action will not render a template. After performing its main purpose (creating a
|
||||
# new post), it initiates a redirect instead. This redirect works by returning an external
|
||||
# "302 Moved" HTTP response that takes the user to the index action.
|
||||
#
|
||||
# These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
|
||||
# Most actions are variations of these themes.
|
||||
#
|
||||
# == Requests
|
||||
#
|
||||
# For every request, the router determines the value of the +controller+ and +action+ keys. These determine which controller
|
||||
# and action are called. The remaining request parameters, the session (if one is available), and the full request with
|
||||
# all the HTTP headers are made available to the action through accessor methods. Then the action is performed.
|
||||
#
|
||||
# The full request object is available via the request accessor and is primarily used to query for HTTP headers:
|
||||
#
|
||||
# def server_ip
|
||||
# location = request.env["SERVER_ADDR"]
|
||||
# render :text => "This server hosted at #{location}"
|
||||
# end
|
||||
#
|
||||
# == Parameters
|
||||
#
|
||||
# All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method
|
||||
# which returns a hash. For example, an action that was performed through <tt>/posts?category=All&limit=5</tt> will include
|
||||
# <tt>{ "category" => "All", "limit" => 5 }</tt> in params.
|
||||
#
|
||||
# It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
|
||||
#
|
||||
# <input type="text" name="post[name]" value="david">
|
||||
# <input type="text" name="post[address]" value="hyacintvej">
|
||||
#
|
||||
# A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
|
||||
# If the address input had been named "post[address][street]", the params would have included
|
||||
# <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
|
||||
#
|
||||
# == Sessions
|
||||
#
|
||||
# Sessions allows you to store objects in between requests. This is useful for objects that are not yet ready to be persisted,
|
||||
# such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such
|
||||
# as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely
|
||||
# they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at.
|
||||
#
|
||||
# You can place objects in the session by using the <tt>session</tt> method, which accesses a hash:
|
||||
#
|
||||
# session[:person] = Person.authenticate(user_name, password)
|
||||
#
|
||||
# And retrieved again through the same hash:
|
||||
#
|
||||
# Hello #{session[:person]}
|
||||
#
|
||||
# For removing objects from the session, you can either assign a single key to +nil+:
|
||||
#
|
||||
# # removes :person from session
|
||||
# session[:person] = nil
|
||||
#
|
||||
# or you can remove the entire session with +reset_session+.
|
||||
#
|
||||
# Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
|
||||
# This prevents the user from tampering with the session but also allows him to see its contents.
|
||||
#
|
||||
# Do not put secret information in cookie-based sessions!
|
||||
#
|
||||
# Other options for session storage:
|
||||
#
|
||||
# * ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
|
||||
# unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
|
||||
#
|
||||
# config.action_controller.session_store = :active_record_store
|
||||
#
|
||||
# in your <tt>config/environment.rb</tt> and run <tt>rake db:sessions:create</tt>.
|
||||
#
|
||||
# == Responses
|
||||
#
|
||||
# Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
|
||||
# object is generated automatically through the use of renders and redirects and requires no user intervention.
|
||||
#
|
||||
# == Renders
|
||||
#
|
||||
# Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
|
||||
# of a template. Included in the Action Pack is the Action View, which enables rendering of ERb templates. It's automatically configured.
|
||||
# The controller passes objects to the view by assigning instance variables:
|
||||
#
|
||||
# def show
|
||||
# @post = Post.find(params[:id])
|
||||
# end
|
||||
#
|
||||
# Which are then automatically available to the view:
|
||||
#
|
||||
# Title: <%= @post.title %>
|
||||
#
|
||||
# You don't have to rely on the automated rendering. Especially actions that could result in the rendering of different templates will use
|
||||
# the manual rendering methods:
|
||||
#
|
||||
# def search
|
||||
# @results = Search.find(params[:query])
|
||||
# case @results
|
||||
# when 0 then render :action => "no_results"
|
||||
# when 1 then render :action => "show"
|
||||
# when 2..10 then render :action => "show_many"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Read more about writing ERb and Builder templates in ActionView::Base.
|
||||
#
|
||||
# == Redirects
|
||||
#
|
||||
# Redirects are used to move from one action to another. For example, after a <tt>create</tt> action, which stores a blog entry to a database,
|
||||
# we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're going to reuse (and redirect to)
|
||||
# a <tt>show</tt> action that we'll assume has already been created. The code might look like this:
|
||||
#
|
||||
# def create
|
||||
# @entry = Entry.new(params[:entry])
|
||||
# if @entry.save
|
||||
# # The entry was saved correctly, redirect to show
|
||||
# redirect_to :action => 'show', :id => @entry.id
|
||||
# else
|
||||
# # things didn't go so well, do something else
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# In this case, after saving our new entry to the database, the user is redirected to the <tt>show</tt> method which is then executed.
|
||||
#
|
||||
# == Calling multiple redirects or renders
|
||||
#
|
||||
# An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
|
||||
#
|
||||
# def do_something
|
||||
# redirect_to :action => "elsewhere"
|
||||
# render :action => "overthere" # raises DoubleRenderError
|
||||
# end
|
||||
#
|
||||
# If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
|
||||
#
|
||||
# def do_something
|
||||
# redirect_to(:action => "elsewhere") and return if monkeys.nil?
|
||||
# render :action => "overthere" # won't be called if monkeys is nil
|
||||
# end
|
||||
#
|
||||
class Base < Metal
|
||||
abstract!
|
||||
|
||||
|
||||
@@ -367,8 +367,8 @@ module ActionView
|
||||
# "Go Back" link instead of a link to the comments page, we could do something like this...
|
||||
#
|
||||
# <%=
|
||||
# link_to_unless_current("Comment", { :controller => 'comments', :action => 'new}) do
|
||||
# link_to("Go back", { :controller => 'posts', :action => 'index' })
|
||||
# link_to_unless_current("Comment", { :controller => "comments", :action => "new" }) do
|
||||
# link_to("Go back", { :controller => "posts", :action => "index" })
|
||||
# end
|
||||
# %>
|
||||
def link_to_unless_current(name, options = {}, html_options = {}, &block)
|
||||
|
||||
@@ -54,12 +54,12 @@ module ActiveModel
|
||||
#
|
||||
# person = Person.new
|
||||
# person.serializable_hash # => {"name"=>nil}
|
||||
# person.to_json # => "{\"name\":null}"
|
||||
# person.as_json # => "{\"name\":null}"
|
||||
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
||||
#
|
||||
# person.name = "Bob"
|
||||
# person.serializable_hash # => {"name"=>"Bob"}
|
||||
# person.to_json # => "{\"name\":\"Bob\"}"
|
||||
# person.as_json # => "{\"name\":\"Bob\"}"
|
||||
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
||||
#
|
||||
# Valid options are <tt>:only</tt>, <tt>:except</tt> and <tt>:methods</tt> .
|
||||
|
||||
@@ -19,16 +19,16 @@ module ActiveModel
|
||||
# passed through +options+.
|
||||
#
|
||||
# The option <tt>include_root_in_json</tt> controls the top-level behavior
|
||||
# of +to_json+. If true (the default) +to_json+ will emit a single root
|
||||
# of +as_json+. If true (the default) +as_json+ will emit a single root
|
||||
# node named after the object's type. For example:
|
||||
#
|
||||
# konata = User.find(1)
|
||||
# konata.to_json
|
||||
# konata.as_json
|
||||
# # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
|
||||
# "created_at": "2006/08/01", "awesome": true} }
|
||||
#
|
||||
# ActiveRecord::Base.include_root_in_json = false
|
||||
# konata.to_json
|
||||
# konata.as_json
|
||||
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
|
||||
# "created_at": "2006/08/01", "awesome": true}
|
||||
#
|
||||
@@ -39,29 +39,29 @@ module ActiveModel
|
||||
# attributes. For example:
|
||||
#
|
||||
# konata = User.find(1)
|
||||
# konata.to_json
|
||||
# konata.as_json
|
||||
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
|
||||
# "created_at": "2006/08/01", "awesome": true}
|
||||
#
|
||||
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
|
||||
# included, and work similar to the +attributes+ method. For example:
|
||||
#
|
||||
# konata.to_json(:only => [ :id, :name ])
|
||||
# konata.as_json(:only => [ :id, :name ])
|
||||
# # => {"id": 1, "name": "Konata Izumi"}
|
||||
#
|
||||
# konata.to_json(:except => [ :id, :created_at, :age ])
|
||||
# konata.as_json(:except => [ :id, :created_at, :age ])
|
||||
# # => {"name": "Konata Izumi", "awesome": true}
|
||||
#
|
||||
# To include the result of some method calls on the model use <tt>:methods</tt>:
|
||||
#
|
||||
# konata.to_json(:methods => :permalink)
|
||||
# konata.as_json(:methods => :permalink)
|
||||
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
|
||||
# "created_at": "2006/08/01", "awesome": true,
|
||||
# "permalink": "1-konata-izumi"}
|
||||
#
|
||||
# To include associations use <tt>:include</tt>:
|
||||
#
|
||||
# konata.to_json(:include => :posts)
|
||||
# konata.as_json(:include => :posts)
|
||||
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
|
||||
# "created_at": "2006/08/01", "awesome": true,
|
||||
# "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
|
||||
@@ -69,7 +69,7 @@ module ActiveModel
|
||||
#
|
||||
# Second level and higher order associations work as well:
|
||||
#
|
||||
# konata.to_json(:include => { :posts => {
|
||||
# konata.as_json(:include => { :posts => {
|
||||
# :include => { :comments => {
|
||||
# :only => :body } },
|
||||
# :only => :title } })
|
||||
|
||||
@@ -7,18 +7,17 @@ module ActiveRecord
|
||||
#
|
||||
# * Count all: By not passing any parameters to count, it will return a count of all the rows for the model.
|
||||
# * Count using column: By passing a column name to count, it will return a count of all the
|
||||
# rows for the model with supplied column present
|
||||
# rows for the model with supplied column present.
|
||||
# * Count using options will find the row count matched by the options used.
|
||||
#
|
||||
# The third approach, count using options, accepts an option hash as the only parameter. The options are:
|
||||
#
|
||||
# * <tt>:conditions</tt>: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
|
||||
# See conditions in the intro to ActiveRecord::Base.
|
||||
# * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed)
|
||||
# or named associations in the same form used for the <tt>:include</tt> option, which will
|
||||
# perform an INNER JOIN on the associated table(s).
|
||||
# If the value is a string, then the records will be returned read-only since they will have
|
||||
# attributes that do not correspond to the table's columns.
|
||||
# * <tt>:joins</tt>: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id"
|
||||
# (rarely needed) or named associations in the same form used for the <tt>:include</tt> option, which will
|
||||
# perform an INNER JOIN on the associated table(s). If the value is a string, then the records
|
||||
# will be returned read-only since they will have attributes that do not correspond to the table's columns.
|
||||
# Pass <tt>:readonly => false</tt> to override.
|
||||
# * <tt>:include</tt>: Named associations that should be loaded alongside using LEFT OUTER JOINs.
|
||||
# The symbols named refer to already defined associations. When using named associations, count
|
||||
@@ -27,8 +26,7 @@ module ActiveRecord
|
||||
# * <tt>:order</tt>: An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations).
|
||||
# * <tt>:group</tt>: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
|
||||
# * <tt>:select</tt>: By default, this is * as in SELECT * FROM, but can be changed if you, for example,
|
||||
# want to do a join but not
|
||||
# include the joined columns.
|
||||
# want to do a join but not include the joined columns.
|
||||
# * <tt>:distinct</tt>: Set this to true to make this a distinct calculation, such as
|
||||
# SELECT COUNT(DISTINCT posts.id) ...
|
||||
# * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/ordered_hash'
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
|
||||
module RailsGuides
|
||||
class Indexer
|
||||
@@ -58,7 +59,7 @@ module RailsGuides
|
||||
end
|
||||
|
||||
def title_to_idx(title)
|
||||
idx = title.strip.downcase.gsub(/\s+|_/, '-').delete('^a-z0-9-').sub(/^[^a-z]*/, '')
|
||||
idx = title.strip.parameterize.sub(/^\d+/, '')
|
||||
if warnings && idx.blank?
|
||||
puts "BLANK ID: please put an explicit ID for section #{title}, as in h5(#my-id)"
|
||||
end
|
||||
|
||||
@@ -201,9 +201,9 @@ Finally a couple of enhancements were added to the rake tasks:
|
||||
|
||||
Railties now deprecates:
|
||||
|
||||
* <tt>RAILS_ROOT</tt> in favour of <tt>Rails.root</tt>,
|
||||
* <tt>RAILS_ENV</tt> in favour of <tt>Rails.env</tt>, and
|
||||
* <tt>RAILS_DEFAULT_LOGGER</tt> in favour of <tt>Rails.logger</tt>.
|
||||
* <tt>RAILS_ROOT</tt> in favor of <tt>Rails.root</tt>,
|
||||
* <tt>RAILS_ENV</tt> in favor of <tt>Rails.env</tt>, and
|
||||
* <tt>RAILS_DEFAULT_LOGGER</tt> in favor of <tt>Rails.logger</tt>.
|
||||
|
||||
<tt>PLUGIN/rails/tasks</tt>, and <tt>PLUGIN/tasks</tt> are no longer loaded all tasks now must be in <tt>PLUGIN/lib/tasks</tt>.
|
||||
|
||||
@@ -241,7 +241,7 @@ h4. Action Controller
|
||||
|
||||
Deprecations:
|
||||
|
||||
* <tt>filter_parameter_logging</tt> is deprecated in favour of <tt>config.filter_parameters << :password</tt>.
|
||||
* <tt>filter_parameter_logging</tt> is deprecated in favor of <tt>config.filter_parameters << :password</tt>.
|
||||
|
||||
More Information:
|
||||
* "Render Options in Rails 3":http://www.engineyard.com/blog/2010/render-options-in-rails-3/
|
||||
@@ -363,8 +363,8 @@ Validations have been moved from Active Record into Active Model, providing an i
|
||||
* The +validates+ method has the following options:
|
||||
* <tt>:acceptance => Boolean</tt>.
|
||||
* <tt>:confirmation => Boolean</tt>.
|
||||
* <tt>:exclusion => { :in => Ennumerable }</tt>.
|
||||
* <tt>:inclusion => { :in => Ennumerable }</tt>.
|
||||
* <tt>:exclusion => { :in => Enumerable }</tt>.
|
||||
* <tt>:inclusion => { :in => Enumerable }</tt>.
|
||||
* <tt>:format => { :with => Regexp, :on => :create }</tt>.
|
||||
* <tt>:length => { :maximum => Fixnum }</tt>.
|
||||
* <tt>:numericality => Boolean</tt>.
|
||||
@@ -452,7 +452,7 @@ h4. Patches and Deprecations
|
||||
|
||||
Additionally, many fixes in the Active Record branch:
|
||||
|
||||
* SQLite 2 support has been dropped in favour of SQLite 3.
|
||||
* SQLite 2 support has been dropped in favor of SQLite 3.
|
||||
* MySQL support for column order.
|
||||
* PostgreSQL adapter has had its +TIME ZONE+ support fixed so it no longer inserts incorrect values.
|
||||
* Support multiple schemas in table names for PostgreSQL.
|
||||
@@ -464,11 +464,11 @@ As well as the following deprecations:
|
||||
|
||||
* +named_scope+ in an Active Record class is deprecated and has been renamed to just +scope+.
|
||||
* In +scope+ methods, you should move to using the relation methods, instead of a <tt>:conditions => {}</tt> finder method, for example <tt>scope :since, lambda {|time| where("created_at > ?", time) }</tt>.
|
||||
* <tt>save(false)</tt> is deprecated, in favour of <tt>save(:validate => false)</tt>.
|
||||
* <tt>save(false)</tt> is deprecated, in favor of <tt>save(:validate => false)</tt>.
|
||||
* I18n error messages for ActiveRecord should be changed from :en.activerecord.errors.template to <tt>:en.errors.template</tt>.
|
||||
* <tt>model.errors.on</tt> is deprecated in favour of <tt>model.errors[]</tt>
|
||||
* <tt>model.errors.on</tt> is deprecated in favor of <tt>model.errors[]</tt>
|
||||
* validates_presence_of => validates... :presence => true
|
||||
* <tt>ActiveRecord::Base.colorize_logging</tt> and <tt>config.active_record.colorize_logging</tt> are deprecated in favour of <tt>Rails::LogSubscriber.colorize_logging</tt> or <tt>config.colorize_logging</tt>
|
||||
* <tt>ActiveRecord::Base.colorize_logging</tt> and <tt>config.active_record.colorize_logging</tt> are deprecated in favor of <tt>Rails::LogSubscriber.colorize_logging</tt> or <tt>config.colorize_logging</tt>
|
||||
|
||||
NOTE: While an implementation of State Machine has been in Active Record edge for some months now, it has been removed from the Rails 3.0 release.
|
||||
|
||||
@@ -491,7 +491,7 @@ Active Resource was also extracted out to Active Model allowing you to use Activ
|
||||
* Renamed <tt>SchemaDefinition</tt> to <tt>Schema</tt> and <tt>define_schema</tt> to <tt>schema</tt>.
|
||||
* Use the <tt>format</tt> of Active Resources rather than the <tt>content-type</tt> of remote errors to load errors.
|
||||
* Use <tt>instance_eval</tt> for schema block.
|
||||
* Fix <tt>ActiveResource::ConnectionError#to_s</tt> when +@response+ does not respond to #code or #message, handles Ruby 1.9 compat.
|
||||
* Fix <tt>ActiveResource::ConnectionError#to_s</tt> when +@response+ does not respond to #code or #message, handles Ruby 1.9 compatibility.
|
||||
* Add support for errors in JSON format.
|
||||
* Ensure <tt>load</tt> works with numeric arrays.
|
||||
* Recognizes a 410 response from remote resource as the resource has been deleted.
|
||||
@@ -500,7 +500,7 @@ Active Resource was also extracted out to Active Model allowing you to use Activ
|
||||
|
||||
Deprecations:
|
||||
|
||||
* <tt>save(false)</tt> is deprecated, in favour of <tt>save(:validate => false)</tt>.
|
||||
* <tt>save(false)</tt> is deprecated, in favor of <tt>save(:validate => false)</tt>.
|
||||
* Ruby 1.9.2: <tt>URI.parse</tt> and <tt>.decode</tt> are deprecated and are no longer used in the library.
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ The following methods have been removed because they are now available in Ruby 1
|
||||
* <tt>Object#instance_variable_defined?</tt>
|
||||
* <tt>Enumerable#none?</tt>
|
||||
|
||||
The security patch for REXML remains in Active Support because early patchlevels of Ruby 1.8.7 still need it. Active Support knows whether it has to apply it or not.
|
||||
The security patch for REXML remains in Active Support because early patch-levels of Ruby 1.8.7 still need it. Active Support knows whether it has to apply it or not.
|
||||
|
||||
The following methods have been removed because they are no longer used in the framework:
|
||||
|
||||
@@ -579,7 +579,7 @@ Action Mailer has been given a new API with TMail being replaced out with the ne
|
||||
|
||||
Deprecations:
|
||||
|
||||
* <tt>:charset</tt>, <tt>:content_type</tt>, <tt>:mime_version</tt>, <tt>:implicit_parts_order</tt> are all deprecated in favour of <tt>ActionMailer.default :key => value</tt> style declarations.
|
||||
* <tt>:charset</tt>, <tt>:content_type</tt>, <tt>:mime_version</tt>, <tt>:implicit_parts_order</tt> are all deprecated in favor of <tt>ActionMailer.default :key => value</tt> style declarations.
|
||||
* Mailer dynamic <tt>create_method_name</tt> and <tt>deliver_method_name</tt> are deprecated, just call <tt>method_name</tt> which now returns a <tt>Mail::Message</tt> object.
|
||||
* <tt>ActionMailer.deliver(message)</tt> is deprecated, just call <tt>message.deliver</tt>.
|
||||
* <tt>template_root</tt> is deprecated, pass options to a render call inside a proc from the <tt>format.mime_type</tt> method inside the <tt>mail</tt> generation block
|
||||
|
||||
@@ -1380,7 +1380,7 @@ page.insert_html :bottom, 'my_list', '<li>Last item</li>'
|
||||
|
||||
h5. literal
|
||||
|
||||
Returns an object whose to_json evaluates to the code provided. Use this to pass a literal JavaScript expression as an argument to another JavaScriptGenerator method.
|
||||
Returns an object whose as_json evaluates to the code provided. Use this to pass a literal JavaScript expression as an argument to another JavaScriptGenerator method.
|
||||
|
||||
h5. redirect_to
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ If you choose to use MySQL instead of the shipped Sqlite3 database, your +config
|
||||
|
||||
<yaml>
|
||||
development:
|
||||
adapter: mysql
|
||||
adapter: mysql2
|
||||
encoding: utf8
|
||||
database: blog_development
|
||||
pool: 5
|
||||
@@ -1017,7 +1017,7 @@ Once we have made the new comment, we send the user back to the original post us
|
||||
|
||||
Now you can add posts and comments to your blog and have them show up in the right places.
|
||||
|
||||
h3. Refactorization
|
||||
h3. Refactoring
|
||||
|
||||
Now that we have Posts and Comments working, if we take a look at the +app/views/posts/show.html.erb+ template, it's getting long and awkward. We can use partials to clean this up.
|
||||
|
||||
@@ -1141,7 +1141,7 @@ Then you make the +app/views/posts/show.html.erb+ look like the following:
|
||||
<%= link_to 'Back to Posts', posts_path %> |
|
||||
</erb>
|
||||
|
||||
The second render just defines the partial template we want to render, <tt>comments/form</tt>, Rails is smart enough to spot the forward slash in that string and realise that you want to render the <tt>_form.html.erb</tt> file in the <tt>app/views/comments</tt> directory.
|
||||
The second render just defines the partial template we want to render, <tt>comments/form</tt>, Rails is smart enough to spot the forward slash in that string and realize that you want to render the <tt>_form.html.erb</tt> file in the <tt>app/views/comments</tt> directory.
|
||||
|
||||
The +@post+ object is available to any partials rendered in the view because we defined it as an instance variable.
|
||||
|
||||
@@ -1279,7 +1279,7 @@ Again, run the migration to create the database table:
|
||||
$ rake db:migrate
|
||||
</shell>
|
||||
|
||||
Next, edit the +post.rb+ file to create the other side of the association, and to tell Rails (via the +accepts_nested_attributes+ macro) that you intend to edit tags via posts:
|
||||
Next, edit the +post.rb+ file to create the other side of the association, and to tell Rails (via the +accepts_nested_attributes_for+ macro) that you intend to edit tags via posts:
|
||||
|
||||
<ruby>
|
||||
class Post < ActiveRecord::Base
|
||||
|
||||
@@ -285,7 +285,7 @@ JSON is a javascript data format used by many AJAX libraries. Rails has built-in
|
||||
render :json => @product
|
||||
</ruby>
|
||||
|
||||
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.
|
||||
TIP: You don't need to call +as_json+ on the object that you want to render. If you use the +:json+ option, +render+ will automatically call +as_json+ for you.
|
||||
|
||||
h5. Rendering XML
|
||||
|
||||
|
||||
Reference in New Issue
Block a user