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

Conflicts:
	activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
	activerecord/test/cases/adapter_test.rb
	guides/source/testing.md

[ci skip]
This commit is contained in:
Vijay Dev 2013-03-30 15:46:14 +05:30
commit 6d8c070821
44 changed files with 274 additions and 208 deletions

@ -1,6 +1,6 @@
= Action Mailer -- Easy email delivery and testing = Action Mailer -- Easy email delivery and testing
Action Mailer is a framework for designing email-service layers. These layers Action Mailer is a framework for designing email service layers. These layers
are used to consolidate code for sending out forgotten passwords, welcome are used to consolidate code for sending out forgotten passwords, welcome
wishes on signup, invoices for billing, and any other use case that requires wishes on signup, invoices for billing, and any other use case that requires
a written notification to either a person or another system. a written notification to either a person or another system.

@ -35,7 +35,7 @@ def abstract!
end end
def inherited(klass) # :nodoc: def inherited(klass) # :nodoc:
# define the abstract ivar on subclasses so that we don't get # Define the abstract ivar on subclasses so that we don't get
# uninitialized ivar warnings # uninitialized ivar warnings
unless klass.instance_variable_defined?(:@abstract) unless klass.instance_variable_defined?(:@abstract)
klass.instance_variable_set(:@abstract, false) klass.instance_variable_set(:@abstract, false)

@ -59,7 +59,7 @@ def #{meth}(*args, &blk) # def current_user(*args,
# The +helper+ class method can take a series of helper module names, a block, or both. # The +helper+ class method can take a series of helper module names, a block, or both.
# #
# ==== Options # ==== Options
# * <tt>*args</tt> - Module, Symbol, String, :all # * <tt>*args</tt> - Module, Symbol, String
# * <tt>block</tt> - A block defining helper methods # * <tt>block</tt> - A block defining helper methods
# #
# When the argument is a module it will be included directly in the template class. # When the argument is a module it will be included directly in the template class.

@ -6,7 +6,7 @@ module Http
# of its interface is available directly for convenience. # of its interface is available directly for convenience.
# #
# Uploaded files are temporary files whose lifespan is one request. When # Uploaded files are temporary files whose lifespan is one request. When
# the object is finalized Ruby unlinks the file, so there is not need to # the object is finalized Ruby unlinks the file, so there is no need to
# clean them with a separate maintenance task. # clean them with a separate maintenance task.
class UploadedFile class UploadedFile
# The basename of the file in the client. # The basename of the file in the client.

@ -69,6 +69,22 @@ module ActionDispatch
# <tt>Routing::Mapper::Scoping#namespace</tt>, and # <tt>Routing::Mapper::Scoping#namespace</tt>, and
# <tt>Routing::Mapper::Scoping#scope</tt>. # <tt>Routing::Mapper::Scoping#scope</tt>.
# #
# == Non-resourceful routes
#
# For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
# methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
#
# get 'post/:id' => 'posts#show'
# post 'post/:id' => 'posts#create_comment'
#
# If your route needs to respond to more than one HTTP method (or all methods) then using the
# <tt>:via</tt> option on <tt>match</tt> is preferable.
#
# match 'post/:id' => 'posts#show', via: [:get, :post]
#
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
# URL will route to the <tt>show</tt> action.
#
# == Named routes # == Named routes
# #
# Routes can be named by passing an <tt>:as</tt> option, # Routes can be named by passing an <tt>:as</tt> option,
@ -78,7 +94,7 @@ module ActionDispatch
# Example: # Example:
# #
# # In routes.rb # # In routes.rb
# match '/login' => 'accounts#login', as: 'login' # get '/login' => 'accounts#login', as: 'login'
# #
# # With render, redirect_to, tests, etc. # # With render, redirect_to, tests, etc.
# redirect_to login_url # redirect_to login_url
@ -104,9 +120,9 @@ module ActionDispatch
# #
# # In routes.rb # # In routes.rb
# controller :blog do # controller :blog do
# match 'blog/show' => :list # get 'blog/show' => :list
# match 'blog/delete' => :delete # get 'blog/delete' => :delete
# match 'blog/edit/:id' => :edit # get 'blog/edit/:id' => :edit
# end # end
# #
# # provides named routes for show, delete, and edit # # provides named routes for show, delete, and edit
@ -116,7 +132,7 @@ module ActionDispatch
# #
# Routes can generate pretty URLs. For example: # Routes can generate pretty URLs. For example:
# #
# match '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: { # get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
# year: /\d{4}/, # year: /\d{4}/,
# month: /\d{1,2}/, # month: /\d{1,2}/,
# day: /\d{1,2}/ # day: /\d{1,2}/
@ -131,7 +147,7 @@ module ActionDispatch
# You can specify a regular expression to define a format for a parameter. # You can specify a regular expression to define a format for a parameter.
# #
# controller 'geocode' do # controller 'geocode' do
# match 'geocode/:postalcode' => :show, constraints: { # get 'geocode/:postalcode' => :show, constraints: {
# postalcode: /\d{5}(-\d{4})?/ # postalcode: /\d{5}(-\d{4})?/
# } # }
# #
@ -139,13 +155,13 @@ module ActionDispatch
# expression modifiers: # expression modifiers:
# #
# controller 'geocode' do # controller 'geocode' do
# match 'geocode/:postalcode' => :show, constraints: { # get 'geocode/:postalcode' => :show, constraints: {
# postalcode: /hx\d\d\s\d[a-z]{2}/i # postalcode: /hx\d\d\s\d[a-z]{2}/i
# } # }
# end # end
# #
# controller 'geocode' do # controller 'geocode' do
# match 'geocode/:postalcode' => :show, constraints: { # get 'geocode/:postalcode' => :show, constraints: {
# postalcode: /# Postcode format # postalcode: /# Postcode format
# \d{5} #Prefix # \d{5} #Prefix
# (-\d{4})? #Suffix # (-\d{4})? #Suffix
@ -153,73 +169,21 @@ module ActionDispatch
# } # }
# end # end
# #
# Using the multiline match modifier will raise an +ArgumentError+. # Using the multiline modifier will raise an +ArgumentError+.
# Encoding regular expression modifiers are silently ignored. The # Encoding regular expression modifiers are silently ignored. The
# match will always use the default encoding or ASCII. # match will always use the default encoding or ASCII.
# #
# == Default route
#
# Consider the following route, which you will find commented out at the
# bottom of your generated <tt>config/routes.rb</tt>:
#
# match ':controller(/:action(/:id))(.:format)'
#
# This route states that it expects requests to consist of a
# <tt>:controller</tt> followed optionally by an <tt>:action</tt> that in
# turn is followed optionally by an <tt>:id</tt>, which in turn is followed
# optionally by a <tt>:format</tt>.
#
# Suppose you get an incoming request for <tt>/blog/edit/22</tt>, you'll end
# up with:
#
# params = { controller: 'blog',
# action: 'edit',
# id: '22'
# }
#
# By not relying on default routes, you improve the security of your
# application since not all controller actions, which includes actions you
# might add at a later time, are exposed by default.
#
# == HTTP Methods
#
# Using the <tt>:via</tt> option when specifying a route allows you to
# restrict it to a specific HTTP method. Possible values are <tt>:post</tt>,
# <tt>:get</tt>, <tt>:patch</tt>, <tt>:put</tt>, <tt>:delete</tt> and
# <tt>:any</tt>. If your route needs to respond to more than one method you
# can use an array, e.g. <tt>[ :get, :post ]</tt>. The default value is
# <tt>:any</tt> which means that the route will respond to any of the HTTP
# methods.
#
# match 'post/:id' => 'posts#show', via: :get
# match 'post/:id' => 'posts#create_comment', via: :post
#
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
# URL will route to the <tt>show</tt> action.
#
# === HTTP helper methods
#
# An alternative method of specifying which HTTP method a route should respond to is to use the helper
# methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
#
# get 'post/:id' => 'posts#show'
# post 'post/:id' => 'posts#create_comment'
#
# This syntax is less verbose and the intention is more apparent to someone else reading your code,
# however if your route needs to respond to more than one HTTP method (or all methods) then using the
# <tt>:via</tt> option on <tt>match</tt> is preferable.
#
# == External redirects # == External redirects
# #
# You can redirect any path to another path using the redirect helper in your router: # You can redirect any path to another path using the redirect helper in your router:
# #
# match "/stories" => redirect("/posts") # get "/stories" => redirect("/posts")
# #
# == Unicode character routes # == Unicode character routes
# #
# You can specify unicode character routes in your router: # You can specify unicode character routes in your router:
# #
# match "こんにちは" => "welcome#index" # get "こんにちは" => "welcome#index"
# #
# == Routing to Rack Applications # == Routing to Rack Applications
# #
@ -227,7 +191,7 @@ module ActionDispatch
# index action in the PostsController, you can specify any Rack application # index action in the PostsController, you can specify any Rack application
# as the endpoint for a matcher: # as the endpoint for a matcher:
# #
# match "/application.js" => Sprockets # get "/application.js" => Sprockets
# #
# == Reloading routes # == Reloading routes
# #

@ -655,14 +655,6 @@ def apply_form_for_options!(record, object, options) #:nodoc:
# ... # ...
# <% end %> # <% end %>
# #
# When projects is already an association on Person you can use
# +accepts_nested_attributes_for+ to define the writer method for you:
#
# class Person < ActiveRecord::Base
# has_many :projects
# accepts_nested_attributes_for :projects
# end
#
# If you want to destroy any of the associated models through the # If you want to destroy any of the associated models through the
# form, you have to enable it first using the <tt>:allow_destroy</tt> # form, you have to enable it first using the <tt>:allow_destroy</tt>
# option for +accepts_nested_attributes_for+: # option for +accepts_nested_attributes_for+:
@ -1425,14 +1417,6 @@ def #{selector}(method, options = {}) # def text_field(method, options = {})
# ... # ...
# <% end %> # <% end %>
# #
# When projects is already an association on Person you can use
# +accepts_nested_attributes_for+ to define the writer method for you:
#
# class Person < ActiveRecord::Base
# has_many :projects
# accepts_nested_attributes_for :projects
# end
#
# If you want to destroy any of the associated models through the # If you want to destroy any of the associated models through the
# form, you have to enable it first using the <tt>:allow_destroy</tt> # form, you have to enable it first using the <tt>:allow_destroy</tt>
# option for +accepts_nested_attributes_for+: # option for +accepts_nested_attributes_for+:

@ -255,7 +255,7 @@ def extract_handler_and_format(path, default_formats)
# #
# FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}") # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}")
# #
# This one allows you to keep files with different formats in seperated subdirectories, # This one allows you to keep files with different formats in separate subdirectories,
# eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`, # eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`,
# `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc. # `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc.
# #

@ -2,7 +2,7 @@
Active Model provides a known set of interfaces for usage in model classes. Active Model provides a known set of interfaces for usage in model classes.
They allow for Action Pack helpers to interact with non-Active Record models, They allow for Action Pack helpers to interact with non-Active Record models,
for example. Active Model also helps building custom ORMs for use outside of for example. Active Model also helps with building custom ORMs for use outside of
the Rails framework. the Rails framework.
Prior to Rails 3.0, if a plugin or gem developer wanted to have an object Prior to Rails 3.0, if a plugin or gem developer wanted to have an object

@ -190,7 +190,7 @@ The latest version of Active Record can be installed with RubyGems:
% [sudo] gem install activerecord % [sudo] gem install activerecord
Source code can be downloaded as part of the Rails project on GitHub Source code can be downloaded as part of the Rails project on GitHub:
* https://github.com/rails/rails/tree/master/activerecord * https://github.com/rails/rails/tree/master/activerecord
@ -204,7 +204,7 @@ Active Record is released under the MIT license:
== Support == Support
API documentation is at API documentation is at:
* http://api.rubyonrails.org * http://api.rubyonrails.org

@ -1115,11 +1115,11 @@ module ClassMethods
# similar callbacks may affect the :dependent behavior, and the # similar callbacks may affect the :dependent behavior, and the
# :dependent behavior may affect other callbacks. # :dependent behavior may affect other callbacks.
# #
# * <tt>:destroy</tt> causes all the associated objects to also be destroyed # * <tt>:destroy</tt> causes all the associated objects to also be destroyed.
# * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not execute) # * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Callbacks are not executed. # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Callbacks are not executed.
# * <tt>:restrict_with_exception</tt> causes an exception to be raised if there are any associated records # * <tt>:restrict_with_exception</tt> causes an exception to be raised if there are any associated records.
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
# #
# If using with the <tt>:through</tt> option, the association on the join model must be # If using with the <tt>:through</tt> option, the association on the join model must be
# a +belongs_to+, and the records which get deleted are the join records, rather than # a +belongs_to+, and the records which get deleted are the join records, rather than

@ -217,7 +217,8 @@ def inverse_reflection_for(record)
reflection.inverse_of reflection.inverse_of
end end
# Is this association invertible? Can be redefined by subclasses. # Returns true if inverse association on the given record needs to be set.
# This method is redefined by subclasses.
def invertible_for?(record) def invertible_for?(record)
inverse_reflection_for(record) inverse_reflection_for(record)
end end

@ -4,7 +4,7 @@
require 'mysql2' require 'mysql2'
module ActiveRecord module ActiveRecord
module ConnectionHandling module ConnectionHandling # :nodoc:
# Establishes a connection to the database that's used by all Active Record objects. # Establishes a connection to the database that's used by all Active Record objects.
def mysql2_connection(config) def mysql2_connection(config)
config = config.symbolize_keys config = config.symbolize_keys

@ -16,9 +16,9 @@ class Result; include Enumerable end
end end
module ActiveRecord module ActiveRecord
module ConnectionHandling module ConnectionHandling # :nodoc:
# Establishes a connection to the database that's used by all Active Record objects. # Establishes a connection to the database that's used by all Active Record objects.
def mysql_connection(config) # :nodoc: def mysql_connection(config)
config = config.symbolize_keys config = config.symbolize_keys
host = config[:host] host = config[:host]
port = config[:port] port = config[:port]

@ -16,7 +16,7 @@
require 'ipaddr' require 'ipaddr'
module ActiveRecord module ActiveRecord
module ConnectionHandling module ConnectionHandling # :nodoc:
VALID_CONN_PARAMS = [:host, :hostaddr, :port, :dbname, :user, :password, :connect_timeout, VALID_CONN_PARAMS = [:host, :hostaddr, :port, :dbname, :user, :password, :connect_timeout,
:client_encoding, :options, :application_name, :fallback_application_name, :client_encoding, :options, :application_name, :fallback_application_name,
:keepalives, :keepalives_idle, :keepalives_interval, :keepalives_count, :keepalives, :keepalives_idle, :keepalives_interval, :keepalives_count,
@ -24,7 +24,7 @@ module ConnectionHandling
:requirepeer, :krbsrvname, :gsslib, :service] :requirepeer, :krbsrvname, :gsslib, :service]
# Establishes a connection to the database that's used by all Active Record objects # Establishes a connection to the database that's used by all Active Record objects
def postgresql_connection(config) # :nodoc: def postgresql_connection(config)
conn_params = config.symbolize_keys conn_params = config.symbolize_keys
conn_params.delete_if { |_, v| v.nil? } conn_params.delete_if { |_, v| v.nil? }

@ -6,9 +6,9 @@
require 'sqlite3' require 'sqlite3'
module ActiveRecord module ActiveRecord
module ConnectionHandling module ConnectionHandling # :nodoc:
# sqlite3 adapter reuses sqlite_connection. # sqlite3 adapter reuses sqlite_connection.
def sqlite3_connection(config) # :nodoc: def sqlite3_connection(config)
# Require database. # Require database.
unless config[:database] unless config[:database]
raise ArgumentError, "No database file specified. Missing argument: database" raise ArgumentError, "No database file specified. Missing argument: database"

@ -79,7 +79,7 @@ def retrieve_connection
connection_handler.retrieve_connection(self) connection_handler.retrieve_connection(self)
end end
# Returns true if Active Record is connected. # Returns +true+ if Active Record is connected.
def connected? def connected?
connection_handler.connected?(self) connection_handler.connected?(self)
end end

@ -90,8 +90,9 @@ class TooManyRecords < ActiveRecordError
# accepts_nested_attributes_for :posts # accepts_nested_attributes_for :posts
# end # end
# #
# You can now set or update attributes on an associated post model through # You can now set or update attributes on the associated posts through
# the attribute hash. # an attribute hash for a member: include the key +:posts_attributes+
# with an array of hashes of post attributes as a value.
# #
# For each hash that does _not_ have an <tt>id</tt> key a new record will # For each hash that does _not_ have an <tt>id</tt> key a new record will
# be instantiated, unless the hash also contains a <tt>_destroy</tt> key # be instantiated, unless the hash also contains a <tt>_destroy</tt> key
@ -183,6 +184,29 @@ class TooManyRecords < ActiveRecordError
# member.save # member.save
# member.reload.posts.length # => 1 # member.reload.posts.length # => 1
# #
# Nested attributes for an associated collection can also be passed in
# the form of a hash of hashes instead of an array of hashes:
#
# Member.create(name: 'joe',
# posts_attributes: { first: { title: 'Foo' },
# second: { title: 'Bar' } })
#
# has the same effect as
#
# Member.create(name: 'joe',
# posts_attributes: [ { title: 'Foo' },
# { title: 'Bar' } ])
#
# The keys of the hash which is the value for +:posts_attributes+ are
# ignored in this case.
# However, it is not allowed to use +'id'+ or +:id+ for one of
# such keys, otherwise the hash will be wrapped in an array and
# interpreted as an attribute hash for a single post.
#
# Passing attributes for an associated collection in the form of a hash
# of hashes can be used with hashes generated from HTTP/HTML parameters,
# where there maybe no natural way to submit an array of hashes.
#
# === Saving # === Saving
# #
# All changes to models, including the destruction of those marked for # All changes to models, including the destruction of those marked for

@ -135,7 +135,7 @@ def calculate(operation, column_name, options = {})
# # SELECT people.id, people.name FROM people # # SELECT people.id, people.name FROM people
# # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] # # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
# #
# Person.uniq.pluck(:role) # Person.pluck('DISTINCT role')
# # SELECT DISTINCT role FROM people # # SELECT DISTINCT role FROM people
# # => ['admin', 'member', 'guest'] # # => ['admin', 'member', 'guest']
# #

@ -85,7 +85,7 @@
* Improve `String#squish` to handle Unicode whitespace. *Antoine Lyset* * Improve `String#squish` to handle Unicode whitespace. *Antoine Lyset*
* Standardise on `to_time` returning an instance of `Time` in the local system timezone * Standardize on `to_time` returning an instance of `Time` in the local system timezone
across `String`, `Time`, `Date`, `DateTime` and `ActiveSupport::TimeWithZone`. across `String`, `Time`, `Date`, `DateTime` and `ActiveSupport::TimeWithZone`.
*Andrew White* *Andrew White*
@ -151,7 +151,7 @@
* Remove surrogate unicode character encoding from `ActiveSupport::JSON.encode` * Remove surrogate unicode character encoding from `ActiveSupport::JSON.encode`
The encoding scheme was broken for unicode characters outside the basic multilingual plane; The encoding scheme was broken for unicode characters outside the basic multilingual plane;
since json is assumed to be UTF-8, and we already force the encoding to UTF-8, since JSON is assumed to be UTF-8, and we already force the encoding to UTF-8,
simply pass through the un-encoded characters. simply pass through the un-encoded characters.
*Brett Carter* *Brett Carter*
@ -370,7 +370,7 @@
* An optional block can be passed to `HashWithIndifferentAccess#update` and `#merge`. * An optional block can be passed to `HashWithIndifferentAccess#update` and `#merge`.
The block will be invoked for each duplicated key, and used to resolve the conflict, The block will be invoked for each duplicated key, and used to resolve the conflict,
thus replicating the behaviour of the corresponding methods on the `Hash` class. thus replicating the behavior of the corresponding methods on the `Hash` class.
*Leo Cassarani* *Leo Cassarani*

@ -2,7 +2,7 @@
module ActiveSupport module ActiveSupport
module Notifications module Notifications
# Instrumentors are stored in a thread local. # Instrumenters are stored in a thread local.
class Instrumenter class Instrumenter
attr_reader :id attr_reader :id

@ -39,7 +39,7 @@ class ClientsController < ApplicationController
end end
``` ```
As an example, if a user goes to `/clients/new` in your application to add a new client, Rails will create an instance of `ClientsController` and run the `new` method. Note that the empty method from the example above could work just fine because Rails will by default render the `new.html.erb` view unless the action says otherwise. The `new` method could make available to the view a `@client` instance variable by creating a new `Client`: As an example, if a user goes to `/clients/new` in your application to add a new client, Rails will create an instance of `ClientsController` and run the `new` method. Note that the empty method from the example above would work just fine because Rails will by default render the `new.html.erb` view unless the action says otherwise. The `new` method could make available to the view a `@client` instance variable by creating a new `Client`:
```ruby ```ruby
def new def new
@ -115,19 +115,19 @@ To send a hash you include the key name inside the brackets:
When this form is submitted, the value of `params[:client]` will be `{ "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" } }`. Note the nested hash in `params[:client][:address]`. When this form is submitted, the value of `params[:client]` will be `{ "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" } }`. Note the nested hash in `params[:client][:address]`.
Note that the `params` hash is actually an instance of `ActiveSupport::HashWithIndifferentAccess`, which acts like a hash that lets you use symbols and strings interchangeably as keys. Note that the `params` hash is actually an instance of `ActiveSupport::HashWithIndifferentAccess`, which acts like a hash but lets you use symbols and strings interchangeably as keys.
### JSON parameters ### JSON parameters
If you're writing a web service application, you might find yourself more comfortable on accepting parameters in JSON format. Rails will automatically convert your parameters into `params` hash, which you'll be able to access like you would normally do with form data. If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. Rails will automatically convert your parameters into the `params` hash, which you can access as you would normally.
So for example, if you are sending this JSON parameter: So for example, if you are sending this JSON content:
```json ```json
{ "company": { "name": "acme", "address": "123 Carrot Street" } } { "company": { "name": "acme", "address": "123 Carrot Street" } }
``` ```
You'll get `params[:company]` as `{ :name => "acme", "address" => "123 Carrot Street" }`. You'll get `params[:company]` as `{ "name" => "acme", "address" => "123 Carrot Street" }`.
Also, if you've turned on `config.wrap_parameters` in your initializer or calling `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. The parameters will be cloned and wrapped in the key according to your controller's name by default. So the above parameter can be written as: Also, if you've turned on `config.wrap_parameters` in your initializer or calling `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. The parameters will be cloned and wrapped in the key according to your controller's name by default. So the above parameter can be written as:
@ -143,14 +143,14 @@ And assume that you're sending the data to `CompaniesController`, it would then
You can customize the name of the key or specific parameters you want to wrap by consulting the [API documentation](http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html) You can customize the name of the key or specific parameters you want to wrap by consulting the [API documentation](http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html)
NOTE: A support for parsing XML parameters has been extracted into a gem named `actionpack-xml_parser` NOTE: Support for parsing XML parameters has been extracted into a gem named `actionpack-xml_parser`
### Routing Parameters ### Routing Parameters
The `params` hash will always contain the `:controller` and `:action` keys, but you should use the methods `controller_name` and `action_name` instead to access these values. Any other parameters defined by the routing, such as `:id` will also be available. As an example, consider a listing of clients where the list can show either active or inactive clients. We can add a route which captures the `:status` parameter in a "pretty" URL: The `params` hash will always contain the `:controller` and `:action` keys, but you should use the methods `controller_name` and `action_name` instead to access these values. Any other parameters defined by the routing, such as `:id` will also be available. As an example, consider a listing of clients where the list can show either active or inactive clients. We can add a route which captures the `:status` parameter in a "pretty" URL:
```ruby ```ruby
match '/clients/:status' => 'clients#index', foo: "bar" match '/clients/:status' => 'clients#index', foo: 'bar'
``` ```
In this case, when a user opens the URL `/clients/active`, `params[:status]` will be set to "active". When this route is used, `params[:foo]` will also be set to "bar" just like it was passed in the query string. In the same way `params[:action]` will contain "index". In this case, when a user opens the URL `/clients/active`, `params[:status]` will be set to "active". When this route is used, `params[:foo]` will also be set to "bar" just like it was passed in the query string. In the same way `params[:action]` will contain "index".
@ -173,7 +173,7 @@ If you define `default_url_options` in `ApplicationController`, as in the exampl
### Strong Parameters ### Strong Parameters
With strong parameters Action Controller parameters are forbidden to With strong parameters, Action Controller parameters are forbidden to
be used in Active Model mass assignments until they have been be used in Active Model mass assignments until they have been
whitelisted. This means you'll have to make a conscious choice about whitelisted. This means you'll have to make a conscious choice about
which attributes to allow for mass updating and thus prevent which attributes to allow for mass updating and thus prevent
@ -232,15 +232,15 @@ The permitted scalar types are `String`, `Symbol`, `NilClass`,
`StringIO`, `IO`, `ActionDispatch::Http::UploadedFile` and `StringIO`, `IO`, `ActionDispatch::Http::UploadedFile` and
`Rack::Test::UploadedFile`. `Rack::Test::UploadedFile`.
To declare that the value in `params+ must be an array of permitted To declare that the value in `params` must be an array of permitted
scalar values map the key to an empty array: scalar values map the key to an empty array:
```ruby ```ruby
params.permit(:id => []) params.permit(:id => [])
``` ```
To whitelist an entire hash of parameters, the `permit!+ method can be To whitelist an entire hash of parameters, the `permit!` method can be
used used:
```ruby ```ruby
params.require(:log_entry).permit! params.require(:log_entry).permit!
@ -273,7 +273,7 @@ to having a `name` (any permitted scalar values allowed, too).
You want to also use the permitted attributes in the `new` You want to also use the permitted attributes in the `new`
action. This raises the problem that you can't use `require` on the action. This raises the problem that you can't use `require` on the
root-key because normally it does not exist when calling `new`: root key because normally it does not exist when calling `new`:
```ruby ```ruby
# using `fetch` you can supply a default and use # using `fetch` you can supply a default and use
@ -281,7 +281,7 @@ root-key because normally it does not exist when calling `new`:
params.fetch(:blog, {}).permit(:title, :author) params.fetch(:blog, {}).permit(:title, :author)
``` ```
`accepts_nested_attributes_for` allows you update and destroy the `accepts_nested_attributes_for` allows you to update and destroy
associated records. This is based on the `id` and `_destroy` associated records. This is based on the `id` and `_destroy`
parameters: parameters:
@ -291,7 +291,7 @@ params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy]
``` ```
Hashes with integer keys are treated differently and you can declare Hashes with integer keys are treated differently and you can declare
the attributes as if they were direct children. You get this kind of the attributes as if they were direct children. You get these kinds of
parameters when you use `accepts_nested_attributes_for` in combination parameters when you use `accepts_nested_attributes_for` in combination
with a `has_many` association: with a `has_many` association:
@ -311,7 +311,7 @@ in mind. It is not meant as a silver bullet to handle all your
whitelisting problems. However you can easily mix the API with your whitelisting problems. However you can easily mix the API with your
own code to adapt to your situation. own code to adapt to your situation.
Imagine a situation where you want to whitelist an attribute Imagine a scenario where you want to whitelist an attribute
containing a hash with any keys. Using strong parameters you can't containing a hash with any keys. Using strong parameters you can't
allow a hash with any keys but you can use a simple assignment to get allow a hash with any keys but you can use a simple assignment to get
the job done: the job done:

@ -492,7 +492,7 @@ image_path("edit.png") # => /assets/edit-2d1a2db63fc738690021fedb5a65b68e.png
#### image_url #### image_url
Computes the url to an image asset in the `app/asset/images` directory. This will call `image_path` internally and merge with your current host or your asset host. Computes the url to an image asset in the `app/assets/images` directory. This will call `image_path` internally and merge with your current host or your asset host.
```ruby ```ruby
image_url("edit.png") # => http://www.example.com/assets/edit.png image_url("edit.png") # => http://www.example.com/assets/edit.png

@ -506,19 +506,15 @@ This code will generate SQL like this:
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5)) SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
``` ```
### NOT, LIKE, and NOT LIKE Conditions ### NOT Conditions
`NOT`, `LIKE`, and `NOT LIKE` SQL queries can be built by `where.not`, `where.like`, and `where.not_like` respectively. `NOT` SQL queries can be built by `where.not`.
```ruby ```ruby
Post.where.not(author: author) Post.where.not(author: author)
Author.where.like(name: 'Nari%')
Developer.where.not_like(name: 'Tenderl%')
``` ```
In other words, these sort of queries can be generated by calling `where` with no argument, then immediately chain with `not`, `like`, or `not_like` passing `where` conditions. In other words, this query can be generated by calling `where` with no argument, then immediately chain with `not` passing `where` conditions.
Ordering Ordering
-------- --------
@ -971,7 +967,7 @@ SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id INNER JOIN posts ON posts.category_id = categories.id
``` ```
Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use `Category.joins(:posts).select("distinct(categories.id)")`. Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use `Category.joins(:posts).uniq`.
#### Joining Multiple Associations #### Joining Multiple Associations
@ -1298,7 +1294,7 @@ recommended that you use the block form of `unscoped`:
```ruby ```ruby
Client.unscoped { Client.unscoped {
Client.created_before(Time.zome.now) Client.created_before(Time.zone.now)
} }
``` ```

@ -530,6 +530,47 @@ field you should use `validates :field_name, inclusion: { in: [true, false] }`.
The default error message is _"can't be empty"_. The default error message is _"can't be empty"_.
### `absence`
This helper validates that the specified attributes are absent. It uses the
`present?` method to check if the value is not either nil or a blank string, that
is, a string that is either empty or consists of whitespace.
```ruby
class Person < ActiveRecord::Base
validates :name, :login, :email, absence: true
end
```
If you want to be sure that an association is absent, you'll need to test
whether the associated object itself is absent, and not the foreign key used
to map the association.
```ruby
class LineItem < ActiveRecord::Base
belongs_to :order
validates :order, absence: true
end
```
In order to validate associated records whose absence is required, you must
specify the `:inverse_of` option for the association:
```ruby
class Order < ActiveRecord::Base
has_many :line_items, inverse_of: :order
end
```
If you validate the absence of an object associated via a `has_one` or
`has_many` relationship, it will check that the object is neither `present?` nor
`marked_for_destruction?`.
Since `false.present?` is false, if you want to validate the absence of a boolean
field you should use `validates :field_name, exclusion: { in: [true, false] }`.
The default error message is _"must be blank"_.
### `uniqueness` ### `uniqueness`
This helper validates that the attribute's value is unique right before the This helper validates that the attribute's value is unique right before the

@ -1344,7 +1344,7 @@ The second argument, `indent_string`, specifies which indent string to use. The
"foo".indent(2, "\t") # => "\t\tfoo" "foo".indent(2, "\t") # => "\t\tfoo"
``` ```
While `indent_string` is tipically one space or tab, it may be any string. While `indent_string` is typically one space or tab, it may be any string.
The third argument, `indent_empty_lines`, is a flag that says whether empty lines should be indented. Default is false. The third argument, `indent_empty_lines`, is a flag that says whether empty lines should be indented. Default is false.
@ -2198,7 +2198,7 @@ This method accepts three options:
* `:words_connector`: What is used to join the elements of arrays with 3 or more elements, except for the last two. Default is ", ". * `:words_connector`: What is used to join the elements of arrays with 3 or more elements, except for the last two. Default is ", ".
* `:last_word_connector`: What is used to join the last items of an array with 3 or more elements. Default is ", and ". * `:last_word_connector`: What is used to join the last items of an array with 3 or more elements. Default is ", and ".
The defaults for these options can be localised, their keys are: The defaults for these options can be localized, their keys are:
| Option | I18n key | | Option | I18n key |
| ---------------------- | ----------------------------------- | | ---------------------- | ----------------------------------- |

@ -273,7 +273,7 @@ Action Mailer
to: ["users@rails.com", "ddh@rails.com"], to: ["users@rails.com", "ddh@rails.com"],
from: ["me@rails.com"], from: ["me@rails.com"],
date: Sat, 10 Mar 2012 14:18:09 +0100, date: Sat, 10 Mar 2012 14:18:09 +0100,
mail: "..." # ommitted for beverity mail: "..." # omitted for brevity
} }
``` ```
@ -299,7 +299,7 @@ Action Mailer
to: ["users@rails.com", "ddh@rails.com"], to: ["users@rails.com", "ddh@rails.com"],
from: ["me@rails.com"], from: ["me@rails.com"],
date: Sat, 10 Mar 2012 14:18:09 +0100, date: Sat, 10 Mar 2012 14:18:09 +0100,
mail: "..." # ommitted for beverity mail: "..." # omitted for brevity
} }
``` ```
@ -428,7 +428,7 @@ end
``` ```
Defining all those block arguments each time can be tedious. You can easily create an `ActiveSupport::Notifications::Event` Defining all those block arguments each time can be tedious. You can easily create an `ActiveSupport::Notifications::Event`
from block args like this: from block arguments like this:
```ruby ```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args| ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
@ -442,7 +442,7 @@ ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*a
end end
``` ```
Most times you only care about the data itself. Here is a shortuct to just get the data. Most times you only care about the data itself. Here is a shortcut to just get the data.
```ruby ```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args| ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
@ -465,7 +465,7 @@ Creating custom events
Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of
all the heavy lifting for you. Simply call `instrument` with a `name`, `payload` and a block. all the heavy lifting for you. Simply call `instrument` with a `name`, `payload` and a block.
The notification will be sent after the block returns. `ActiveSupport` will generate the start and end times The notification will be sent after the block returns. `ActiveSupport` will generate the start and end times
as well as the unique ID. All data passed into the `insturment` call will make it into the payload. as well as the unique ID. All data passed into the `instrument` call will make it into the payload.
Here's an example: Here's an example:

@ -547,7 +547,35 @@ This directive is available if the core module that provides this feature was co
If you're compiling nginx with Phusion Passenger you'll need to pass that option when prompted. If you're compiling nginx with Phusion Passenger you'll need to pass that option when prompted.
A robust configuration for Apache is possible but tricky; please Google around. (Or help update this Guide if you have a good example configuration for Apache.) Apache is also able to serve the [gzipped](http://en.wikipedia.org/wiki/Gzip) version of your assets; however, it requires a bit more work:
```apache
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Konqueror
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.+).(css|js)$ $1.$2.gz [QSA,L]
</LocationMatch>
<FilesMatch \.css\.gz>
ForceType text/css
</FilesMatch>
<FilesMatch \.js\.gz>
ForceType application/javascript
</FilesMatch>
AddEncoding gzip .gz
```
NOTE: You will need to make sure `mod_headers`, `mod_mime` and `mod_rewrite` are loaded; otherwise, the above configuration will fail.
### Local Precompilation ### Local Precompilation
@ -740,7 +768,7 @@ end
``` ```
Now that you have a `Template` class, it's time to associate it with an Now that you have a `Template` class, it's time to associate it with an
extenstion for template files: extension for template files:
```ruby ```ruby
Sprockets.register_engine '.bang', BangBang::Template Sprockets.register_engine '.bang', BangBang::Template

@ -572,7 +572,7 @@ end
These need to be backed up by a migration to create the `assemblies_parts` table. This table should be created without a primary key: These need to be backed up by a migration to create the `assemblies_parts` table. This table should be created without a primary key:
```ruby ```ruby
class CreateAssemblyPartJoinTable < ActiveRecord::Migration class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
def change def change
create_table :assemblies_parts, id: false do |t| create_table :assemblies_parts, id: false do |t|
t.integer :assembly_id t.integer :assembly_id

@ -82,7 +82,7 @@ The server can be run on a different port using the `-p` option. The default dev
$ rails server -e production -p 4000 $ rails server -e production -p 4000
``` ```
The `-b` option binds Rails to the specified ip, by default it is 0.0.0.0. You can run a server as a daemon by passing a `-d` option. The `-b` option binds Rails to the specified IP, by default it is 0.0.0.0. You can run a server as a daemon by passing a `-d` option.
### `rails generate` ### `rails generate`
@ -414,7 +414,7 @@ app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this? * [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy * [132] [FIXME] high priority for next deploy
app/model/school.rb: app/models/school.rb:
* [ 13] [OPTIMIZE] refactor this code to make it faster * [ 13] [OPTIMIZE] refactor this code to make it faster
* [ 17] [FIXME] * [ 17] [FIXME]
``` ```
@ -427,7 +427,7 @@ $ rake notes:fixme
app/controllers/admin/users_controller.rb: app/controllers/admin/users_controller.rb:
* [132] high priority for next deploy * [132] high priority for next deploy
app/model/school.rb: app/models/school.rb:
* [ 17] * [ 17]
``` ```
@ -436,7 +436,7 @@ You can also use custom annotations in your code and list them using `rake notes
```bash ```bash
$ rake notes:custom ANNOTATION=BUG $ rake notes:custom ANNOTATION=BUG
(in /home/foobar/commandsapp) (in /home/foobar/commandsapp)
app/model/post.rb: app/models/post.rb:
* [ 23] Have to fix this one before pushing! * [ 23] Have to fix this one before pushing!
``` ```
@ -448,7 +448,7 @@ By default, `rake notes` will look in the `app`, `config`, `lib`, `bin` and `tes
$ export SOURCE_ANNOTATION_DIRECTORIES='rspec,vendor' $ export SOURCE_ANNOTATION_DIRECTORIES='rspec,vendor'
$ rake notes $ rake notes
(in /home/foobar/commandsapp) (in /home/foobar/commandsapp)
app/model/user.rb: app/models/user.rb:
* [ 35] [FIXME] User should have a subscription at this point * [ 35] [FIXME] User should have a subscription at this point
rspec/model/user_spec.rb: rspec/model/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works * [122] [TODO] Verify the user that has a subscription works

@ -646,7 +646,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `active_support.initialize_time_zone` Sets the default time zone for the application based on the `config.time_zone` setting, which defaults to "UTC". * `active_support.initialize_time_zone` Sets the default time zone for the application based on the `config.time_zone` setting, which defaults to "UTC".
* `active_support.initialize_beginning_of_week` Sets the default beginnig of week for the application based on `config.beginning_of_week` setting, which defaults to `:monday`. * `active_support.initialize_beginning_of_week` Sets the default beginning of week for the application based on `config.beginning_of_week` setting, which defaults to `:monday`.
* `action_dispatch.configure` Configures the `ActionDispatch::Http::URL.tld_length` to be set to the value of `config.action_dispatch.tld_length`. * `action_dispatch.configure` Configures the `ActionDispatch::Http::URL.tld_length` to be set to the value of `config.action_dispatch.tld_length`.
@ -698,7 +698,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `engines_blank_point` Provides a point-in-initialization to hook into if you wish to do anything before engines are loaded. After this point, all railtie and engine initializers are run. * `engines_blank_point` Provides a point-in-initialization to hook into if you wish to do anything before engines are loaded. After this point, all railtie and engine initializers are run.
* `add_generator_templates` Finds templates for generators at `lib/templates` for the application, railities and engines and adds these to the `config.generators.templates` setting, which will make the templates available for all generators to reference. * `add_generator_templates` Finds templates for generators at `lib/templates` for the application, railties and engines and adds these to the `config.generators.templates` setting, which will make the templates available for all generators to reference.
* `ensure_autoload_once_paths_as_subset` Ensures that the `config.autoload_once_paths` only contains paths from `config.autoload_paths`. If it contains extra paths, then an exception will be raised. * `ensure_autoload_once_paths_as_subset` Ensures that the `config.autoload_once_paths` only contains paths from `config.autoload_paths`. If it contains extra paths, then an exception will be raised.

@ -206,7 +206,7 @@ $ cd rails
$ git checkout -b my_new_branch $ git checkout -b my_new_branch
``` ```
It doesnt matter much what name you use, because this branch will only exist on your local computer and your personal repository on Github. It won't be part of the Rails Git repository. It doesnt matter much what name you use, because this branch will only exist on your local computer and your personal repository on GitHub. It won't be part of the Rails Git repository.
### Write Your Code ### Write Your Code
@ -252,7 +252,7 @@ The above are guidelines — please use your best judgment in using them.
The CHANGELOG is an important part of every release. It keeps the list of changes for every Rails version. The CHANGELOG is an important part of every release. It keeps the list of changes for every Rails version.
You should add an entry to the CHANGELOG of the framework that you modified if you're adding or removing a feature, commiting a bug fix or adding deprecation notices. Refactorings and documentation changes generally should not go to the CHANGELOG. You should add an entry to the CHANGELOG of the framework that you modified if you're adding or removing a feature, committing a bug fix or adding deprecation notices. Refactorings and documentation changes generally should not go to the CHANGELOG.
A CHANGELOG entry should summarize what was changed and should end with author's name. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach issue's number. Here is an example CHANGELOG entry: A CHANGELOG entry should summarize what was changed and should end with author's name. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach issue's number. Here is an example CHANGELOG entry:

@ -23,7 +23,7 @@ One common task is to inspect the contents of a variable. In Rails, you can do t
### `debug` ### `debug`
The `debug` helper will return a \<pre>-tag that renders the object using the YAML format. This will generate human-readable data from any object. For example, if you have this code in a view: The `debug` helper will return a \<pre> tag that renders the object using the YAML format. This will generate human-readable data from any object. For example, if you have this code in a view:
```html+erb ```html+erb
<%= debug @post %> <%= debug @post %>
@ -174,7 +174,7 @@ class PostsController < ApplicationController
end end
``` ```
Here's an example of the log generated by this method: Here's an example of the log generated when this controller action is executed:
``` ```
Processing PostsController#create (for 127.0.0.1 at 2008-09-08 11:52:54) [POST] Processing PostsController#create (for 127.0.0.1 at 2008-09-08 11:52:54) [POST]
@ -194,7 +194,7 @@ Redirected to #<Post:0x20af760>
Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localhost/posts] Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localhost/posts]
``` ```
Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels, to avoid filling your production logs with useless trivia. Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels to avoid filling your production logs with useless trivia.
### Tagged Logging ### Tagged Logging
@ -216,7 +216,7 @@ The debugger can also help you if you want to learn about the Rails source code
### Setup ### Setup
Rails uses the `debugger` gem to set breakpoints and step through live code. To install it, just run: You can use the `debugger` gem to set breakpoints and step through live code in Rails. To install it, just run:
```bash ```bash
$ gem install debugger $ gem install debugger
@ -235,7 +235,7 @@ class PeopleController < ApplicationController
end end
``` ```
If you see the message in the console or logs: If you see this message in the console or logs:
``` ```
***** Debugger requested, but was not available: Start server with --debugger to enable ***** ***** Debugger requested, but was not available: Start server with --debugger to enable *****
@ -246,12 +246,12 @@ Make sure you have started your web server with the option `--debugger`:
```bash ```bash
$ rails server --debugger $ rails server --debugger
=> Booting WEBrick => Booting WEBrick
=> Rails 3.0.0 application starting on http://0.0.0.0:3000 => Rails 3.2.13 application starting on http://0.0.0.0:3000
=> Debugger enabled => Debugger enabled
... ...
``` ```
TIP: In development mode, you can dynamically `require \'debugger\'` instead of restarting the server, if it was started without `--debugger`. TIP: In development mode, you can dynamically `require \'debugger\'` instead of restarting the server, even if it was started without `--debugger`.
### The Shell ### The Shell
@ -266,7 +266,7 @@ For example:
(rdb:7) (rdb:7)
``` ```
Now it's time to explore and dig into your application. A good place to start is by asking the debugger for help... so type: `help` (You didn't see that coming, right?) Now it's time to explore and dig into your application. A good place to start is by asking the debugger for help. Type: `help`
``` ```
(rdb:7) help (rdb:7) help
@ -281,7 +281,7 @@ condition down finish list ps save thread var
continue edit frame method putl set tmate where continue edit frame method putl set tmate where
``` ```
TIP: To view the help menu for any command use `help <command-name>` in active debug mode. For example: _`help var`_ TIP: To view the help menu for any command use `help <command-name>` at the debugger prompt. For example: _`help var`_
The next command to learn is one of the most useful: `list`. You can abbreviate any debugging command by supplying just enough letters to distinguish them from other commands, so you can also use `l` for the `list` command. The next command to learn is one of the most useful: `list`. You can abbreviate any debugging command by supplying just enough letters to distinguish them from other commands, so you can also use `l` for the `list` command.
@ -289,7 +289,7 @@ This command shows you where you are in the code by printing 10 lines centered a
``` ```
(rdb:7) list (rdb:7) list
[1, 10] in /PathToProject/posts_controller.rb [1, 10] in /PathTo/project/app/controllers/posts_controller.rb
1 class PostsController < ApplicationController 1 class PostsController < ApplicationController
2 # GET /posts 2 # GET /posts
3 # GET /posts.json 3 # GET /posts.json
@ -325,7 +325,7 @@ On the other hand, to see the previous ten lines you should type `list-` (or `l-
``` ```
(rdb:7) l- (rdb:7) l-
[1, 10] in /PathToProject/posts_controller.rb [1, 10] in /PathTo/project/app/controllers/posts_controller.rb
1 class PostsController < ApplicationController 1 class PostsController < ApplicationController
2 # GET /posts 2 # GET /posts
3 # GET /posts.json 3 # GET /posts.json
@ -343,7 +343,7 @@ Finally, to see where you are in the code again you can type `list=`
``` ```
(rdb:7) list= (rdb:7) list=
[1, 10] in /PathToProject/posts_controller.rb [1, 10] in /PathTo/project/app/controllers/posts_controller.rb
1 class PostsController < ApplicationController 1 class PostsController < ApplicationController
2 # GET /posts 2 # GET /posts
3 # GET /posts.json 3 # GET /posts.json
@ -502,7 +502,7 @@ TIP: You can use the debugger while using `rails console`. Just remember to `req
``` ```
$ rails console $ rails console
Loading development environment (Rails 3.1.0) Loading development environment (Rails 3.2.13)
>> require "debugger" >> require "debugger"
=> [] => []
>> author = Author.first >> author = Author.first

@ -423,7 +423,7 @@ Whenever Rails sees that the internal value of an option being generated matches
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select` — you must pass 2. Be aware of values extracted from the `params` hash as they are all strings. TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer 2 you cannot pass "2" to `options_for_select` — you must pass 2. Be aware of values extracted from the `params` hash as they are all strings.
WARNING: when `:inlude_blank` or `:prompt:` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true. WARNING: when `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
You can add arbitrary attributes to the options using hashes: You can add arbitrary attributes to the options using hashes:

@ -589,11 +589,11 @@ Creates an initializer in the `config/initializers` directory of the application
initializer "begin.rb", "puts 'this is the beginning'" initializer "begin.rb", "puts 'this is the beginning'"
``` ```
This method also takes a block: This method also takes a block, expected to return a string:
```ruby ```ruby
initializer "begin.rb" do initializer "begin.rb" do
puts "Almost done!" "puts 'this is the beginning'"
end end
``` ```

@ -1761,7 +1761,7 @@ cannot be automatically detected by Rails and corrected.
Two very common sources of data that are not UTF-8: Two very common sources of data that are not UTF-8:
* Your text editor: Most text editors (such as Textmate), default to saving files as * Your text editor: Most text editors (such as TextMate), default to saving files as
UTF-8. If your text editor does not, this can result in special characters that you UTF-8. If your text editor does not, this can result in special characters that you
enter in your templates (such as é) to appear as a diamond with a question mark inside enter in your templates (such as é) to appear as a diamond with a question mark inside
in the browser. This also applies to your i18n translation files. in the browser. This also applies to your i18n translation files.

@ -363,7 +363,7 @@ You can use a symbol to defer the choice of layout until a request is processed:
```ruby ```ruby
class ProductsController < ApplicationController class ProductsController < ApplicationController
layout "products_layout" layout :products_layout
def show def show
@product = Product.find(params[:id]) @product = Product.find(params[:id])

@ -831,7 +831,7 @@ end
``` ```
```ruby ```ruby
# app/model/product.rb # app/models/product.rb
class Product < ActiveRecord::Base class Product < ActiveRecord::Base
validates :flag, presence: true validates :flag, presence: true
@ -856,7 +856,7 @@ end
``` ```
```ruby ```ruby
# app/model/product.rb # app/models/product.rb
class Product < ActiveRecord::Base class Product < ActiveRecord::Base
validates :flag, :fuzz, presence: true validates :flag, :fuzz, presence: true

@ -530,7 +530,7 @@ In particular, simple routing makes it very easy to map legacy URLs to new Rails
### Bound Parameters ### Bound Parameters
When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: `:controller` maps to the name of a controller in your application, and `:action` maps to the name of an action within that controller. For example, consider one of the default Rails routes: When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: `:controller` maps to the name of a controller in your application, and `:action` maps to the name of an action within that controller. For example, consider this route:
```ruby ```ruby
get ':controller(/:action(/:id))' get ':controller(/:action(/:id))'
@ -850,7 +850,7 @@ resources :user_permissions, controller: 'admin/user_permissions'
This will route to the `Admin::UserPermissions` controller. This will route to the `Admin::UserPermissions` controller.
NOTE: Only the directory notation is supported. specifying the NOTE: Only the directory notation is supported. Specifying the
controller with ruby constant notation (eg. `:controller => controller with ruby constant notation (eg. `:controller =>
'Admin::UserPermissions'`) can lead to routing problems and results in 'Admin::UserPermissions'`) can lead to routing problems and results in
a warning. a warning.

@ -65,7 +65,7 @@ HTML Guides
### Generation ### Generation
To generate all the guides, just `cd` into the **`guides`** directory, run `bundle install` and execute: To generate all the guides, just `cd` into the `guides` directory, run `bundle install` and execute:
``` ```
bundle exec rake guides:generate bundle exec rake guides:generate

@ -432,7 +432,7 @@ Depending on your web application, there may be more ways to hijack the user's a
INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._ INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._
But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](http://ambethia.com/recaptcha/) is also a Rails plug-in with the same name as the API. But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](https://github.com/ambethia/recaptcha/) is also a Rails plug-in with the same name as the API.
You will get two keys from the API, a public and a private key, which you have to put into your Rails environment. After that you can use the recaptcha_tags method in the view, and the verify_recaptcha method in the controller. Verify_recaptcha will return false if the validation fails. You will get two keys from the API, a public and a private key, which you have to put into your Rails environment. After that you can use the recaptcha_tags method in the view, and the verify_recaptcha method in the controller. Verify_recaptcha will return false if the validation fails.
The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that he is human, but reveal that a spam robot is a bot. The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that he is human, but reveal that a spam robot is a bot.

@ -128,12 +128,12 @@ When you use `rails generate scaffold`, for a resource among other things it cre
$ rails generate scaffold post title:string body:text $ rails generate scaffold post title:string body:text
... ...
create app/models/post.rb create app/models/post.rb
create test/models/post_test.rb create test/unit/post_test.rb
create test/fixtures/posts.yml create test/fixtures/posts.yml
... ...
``` ```
The default test stub in `test/models/post_test.rb` looks like this: The default test stub in `test/unit/post_test.rb` looks like this:
```ruby ```ruby
require 'test_helper' require 'test_helper'
@ -690,9 +690,9 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
get "/login" get "/login"
assert_response :success assert_response :success
post_via_redirect "/login", username: users(:avs).username, password: users(:avs).password post_via_redirect "/login", username: users(:david).username, password: users(:david).password
assert_equal '/welcome', path assert_equal '/welcome', path
assert_equal 'Welcome avs!', flash[:notice] assert_equal 'Welcome david!', flash[:notice]
https!(false) https!(false)
get "/posts/all" get "/posts/all"
@ -715,12 +715,12 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
test "login and browse site" do test "login and browse site" do
# User avs logs in # User avs logs in
avs = login(:avs) avs = login(:david)
# User guest logs in # User guest logs in
guest = login(:guest) guest = login(:guest)
# Both are now available in different sessions # Both are now available in different sessions
assert_equal 'Welcome avs!', avs.flash[:notice] assert_equal 'Welcome david!', avs.flash[:notice]
assert_equal 'Welcome guest!', guest.flash[:notice] assert_equal 'Welcome guest!', guest.flash[:notice]
# User avs can browse site # User avs can browse site
@ -997,5 +997,6 @@ The built-in `test/unit` based testing is not the only way to test Rails applica
* [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use. * [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use.
* [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures. * [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures.
* [Machinist](https://github.com/notahat/machinist/tree/master), another replacement for fixtures. * [Machinist](https://github.com/notahat/machinist/tree/master), another replacement for fixtures.
* [MiniTest::Spec Rails](https://github.com/metaskills/minitest-spec-rails), use the MiniTest::Spec DSL within your rails tests.
* [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions. * [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions.
* [RSpec](http://relishapp.com/rspec), a behavior-driven development framework * [RSpec](http://relishapp.com/rspec), a behavior-driven development framework

@ -31,6 +31,32 @@ If your application is currently on any version of Rails older than 3.2.x, you s
The following changes are meant for upgrading your application to Rails 4.0. The following changes are meant for upgrading your application to Rails 4.0.
### Gemfile
Rails 4.0 removed the *group :assets* from Gemfile (now you can use only :test, :development and/or :production groups). So change your Gemfile from:
```ruby
group :assets do
gem 'sass-rails', '~> 4.0.0.beta1'
gem 'coffee-rails', '~> 4.0.0.beta1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
gem 'uglifier', '>= 1.0.3'
end
```
to:
```ruby
gem 'sass-rails', '~> 4.0.0.beta1'
gem 'coffee-rails', '~> 4.0.0.beta1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
gem 'uglifier', '>= 1.0.3'
```
**note:** don't removing the *group assets* from the Gemfile will cause your assets stop compiling
### vendor/plugins ### vendor/plugins
Rails 4.0 no longer supports loading plugins from `vendor/plugins`. You must replace any plugins by extracting them to gems and adding them to your Gemfile. If you choose not to make them gems, you can move them into, say, `lib/my_plugin/*` and add an appropriate initializer in `config/initializers/my_plugin.rb`. Rails 4.0 no longer supports loading plugins from `vendor/plugins`. You must replace any plugins by extracting them to gems and adding them to your Gemfile. If you choose not to make them gems, you can move them into, say, `lib/my_plugin/*` and add an appropriate initializer in `config/initializers/my_plugin.rb`.
@ -67,7 +93,7 @@ Rails 4.0 extracted Active Resource to its own gem. If you still need the featur
* Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail, the error will be attached to `:#{attribute}_confirmation` instead of `attribute`. * Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail, the error will be attached to `:#{attribute}_confirmation` instead of `attribute`.
* Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default value to `false`. Now, Active Model Serializers and Active Record objects have the same default behaviour. This means that you can comment or remove the following option in the `config/initializers/wrap_parameters.rb` file: * Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default value to `false`. Now, Active Model Serializers and Active Record objects have the same default behavior. This means that you can comment or remove the following option in the `config/initializers/wrap_parameters.rb` file:
```ruby ```ruby
# Disable root element in JSON by default. # Disable root element in JSON by default.
@ -311,7 +337,7 @@ config.assets.debug = true
Again, most of the changes below are for the asset pipeline. You can read more about these in the [Asset Pipeline](asset_pipeline.html) guide. Again, most of the changes below are for the asset pipeline. You can read more about these in the [Asset Pipeline](asset_pipeline.html) guide.
```ruby ```ruby
# Compress JavaScripts and CSS # Compress JavaScript and CSS
config.assets.compress = true config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed # Don't fallback to assets pipeline if a precompiled asset is missed

@ -394,3 +394,4 @@ Here are some helpful links to help you learn even more:
* [jquery-ujs list of external articles](https://github.com/rails/jquery-ujs/wiki/External-articles) * [jquery-ujs list of external articles](https://github.com/rails/jquery-ujs/wiki/External-articles)
* [Rails 3 Remote Links and Forms: A Definitive Guide](http://www.alfajango.com/blog/rails-3-remote-links-and-forms/) * [Rails 3 Remote Links and Forms: A Definitive Guide](http://www.alfajango.com/blog/rails-3-remote-links-and-forms/)
* [Railscasts: Unobtrusive JavaScript](http://railscasts.com/episodes/205-unobtrusive-javascript) * [Railscasts: Unobtrusive JavaScript](http://railscasts.com/episodes/205-unobtrusive-javascript)
* [Railscasts: Turbolinks](http://railscasts.com/episodes/390-turbolinks)

@ -107,7 +107,7 @@ module Rails
# #
# The <tt>Application</tt> class adds a couple more paths to this set. And as in your # The <tt>Application</tt> class adds a couple more paths to this set. And as in your
# <tt>Application</tt>, all folders under +app+ are automatically added to the load path. # <tt>Application</tt>, all folders under +app+ are automatically added to the load path.
# If you have an <tt>app/services/tt> folder for example, it will be added by default. # If you have an <tt>app/services</tt> folder for example, it will be added by default.
# #
# == Endpoint # == Endpoint
# #