aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides')
-rw-r--r--guides/rails_guides/textile_extensions.rb2
-rw-r--r--guides/source/4_0_release_notes.textile33
-rw-r--r--guides/source/action_view_overview.textile2
-rw-r--r--guides/source/active_record_querying.textile24
-rw-r--r--guides/source/active_record_validations_callbacks.textile4
-rw-r--r--guides/source/active_support_core_extensions.textile35
-rw-r--r--guides/source/ajax_on_rails.textile2
-rw-r--r--guides/source/asset_pipeline.textile14
-rw-r--r--guides/source/association_basics.textile589
-rw-r--r--guides/source/command_line.textile49
-rw-r--r--guides/source/configuring.textile12
-rw-r--r--guides/source/contributing_to_ruby_on_rails.textile87
-rw-r--r--guides/source/engines.textile78
-rw-r--r--guides/source/getting_started.textile18
-rw-r--r--guides/source/i18n.textile4
-rw-r--r--guides/source/performance_testing.textile230
-rw-r--r--guides/source/routing.textile30
-rw-r--r--guides/source/security.textile2
-rw-r--r--guides/source/upgrading_ruby_on_rails.textile2
19 files changed, 795 insertions, 422 deletions
diff --git a/guides/rails_guides/textile_extensions.rb b/guides/rails_guides/textile_extensions.rb
index 0a002a785f..1faddd4ca0 100644
--- a/guides/rails_guides/textile_extensions.rb
+++ b/guides/rails_guides/textile_extensions.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/object/inclusion'
-
module RedCloth::Formatters::HTML
def emdash(opts)
"--"
diff --git a/guides/source/4_0_release_notes.textile b/guides/source/4_0_release_notes.textile
index d545798f6f..0de8a0a4b7 100644
--- a/guides/source/4_0_release_notes.textile
+++ b/guides/source/4_0_release_notes.textile
@@ -196,6 +196,37 @@ h5(#actioncontroller_deprecations). Deprecations
h4. Action Dispatch
+* Add Routing Concerns to declare common routes that can be reused inside others resources and routes.
+
+Code before:
+
+<ruby>
+resources :messages do
+ resources :comments
+end
+
+resources :posts do
+ resources :comments
+ resources :images, only: :index
+end
+</ruby>
+
+Code after:
+
+<ruby>
+concern :commentable do
+ resources :comments
+end
+
+concern :image_attachable do
+ resources :images, only: :index
+end
+
+resources :messages, concerns: :commentable
+
+resources :posts, concerns: [:commentable, :image_attachable]
+</ruby>
+
* Show routes in exception page while debugging a <tt>RoutingError</tt> in development.
* Include <tt>mounted_helpers</tt> (helpers for accessing mounted engines) in <tt>ActionDispatch::IntegrationTest</tt> by default.
@@ -747,6 +778,8 @@ h3. Active Resource
h3. Active Support
+* Add default values to all <tt>ActiveSupport::NumberHelper</tt> methods, to avoid errors with empty locales or missing values.
+
* <tt>Time#change</tt> now works with time values with offsets other than UTC or the local time zone.
* Add <tt>Time#prev_quarter</tt> and <tt>Time#next_quarter</tt> short-hands for <tt>months_ago(3)</tt> and <tt>months_since(3)</tt>.
diff --git a/guides/source/action_view_overview.textile b/guides/source/action_view_overview.textile
index fdfa97effa..1fd98a5bbe 100644
--- a/guides/source/action_view_overview.textile
+++ b/guides/source/action_view_overview.textile
@@ -785,7 +785,7 @@ h5. content_for
Calling +content_for+ stores a block of markup in an identifier for later use. You can make subsequent calls to the stored content in other templates or the layout by passing the identifier as an argument to +yield+.
-For example, let's say we have a standard application layout, but also a special page that requires certain Javascript that the rest of the site doesn't need. We can use +content_for+ to include this Javascript on our special page without fattening up the rest of the site.
+For example, let's say we have a standard application layout, but also a special page that requires certain JavaScript that the rest of the site doesn't need. We can use +content_for+ to include this JavaScript on our special page without fattening up the rest of the site.
*app/views/layouts/application.html.erb*
diff --git a/guides/source/active_record_querying.textile b/guides/source/active_record_querying.textile
index f71a136b22..dff829a4c1 100644
--- a/guides/source/active_record_querying.textile
+++ b/guides/source/active_record_querying.textile
@@ -492,7 +492,7 @@ This code will generate SQL like this:
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
</sql>
-h3. Ordering
+h3(#ordering). Ordering
To retrieve records from the database in a specific order, you can use the +order+ method.
@@ -518,6 +518,13 @@ Client.order("orders_count ASC, created_at DESC")
Client.order("orders_count ASC", "created_at DESC")
</ruby>
+If you want to call +order+ multiple times e.g. in different context, new order will prepend previous one
+
+<ruby>
+Client.order("orders_count ASC").order("created_at DESC")
+# SELECT * FROM clients ORDER BY created_at DESC, orders_count ASC
+</ruby>
+
h3. Selecting Specific Fields
By default, <tt>Model.find</tt> selects all the fields from the result set using +select *+.
@@ -1132,21 +1139,6 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.created_before(time)
</ruby>
-h4. Working with scopes
-
-Where a relational object is required, the +scoped+ method may come in handy. This will return an +ActiveRecord::Relation+ object which can have further scoping applied to it afterwards. A place where this may come in handy is on associations
-
-<ruby>
-client = Client.find_by_first_name("Ryan")
-orders = client.orders.scoped
-</ruby>
-
-With this new +orders+ object, we are able to ascertain that this object can have more scopes applied to it. For instance, if we wanted to return orders only in the last 30 days at a later point.
-
-<ruby>
-orders.where("created_at > ?", 30.days.ago)
-</ruby>
-
h4. Applying a default scope
If we wish for a scope to be applied across all queries to the model we can use the +default_scope+ method within the model itself.
diff --git a/guides/source/active_record_validations_callbacks.textile b/guides/source/active_record_validations_callbacks.textile
index f49d91fd3c..cf7293bd9e 100644
--- a/guides/source/active_record_validations_callbacks.textile
+++ b/guides/source/active_record_validations_callbacks.textile
@@ -86,6 +86,7 @@ The following methods skip validations, and will save the object to the database
* +update_all+
* +update_attribute+
* +update_column+
+* +update_columns+
* +update_counters+
Note that +save+ also has the ability to skip validations if passed +:validate => false+ as argument. This technique should be used with caution.
@@ -373,6 +374,8 @@ class LineItem < ActiveRecord::Base
end
</ruby>
+If you validate the presence of an object associated via a +has_one+ or +has_many+ relationship, it will check that the object is neither +blank?+ nor +marked_for_destruction?+.
+
Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use <tt>validates :field_name, :inclusion => { :in => [true, false] }</tt>.
The default error message is "_can't be empty_".
@@ -1082,6 +1085,7 @@ Just as with validations, it is also possible to skip callbacks. These methods s
* +toggle+
* +touch+
* +update_column+
+* +update_columns+
* +update_all+
* +update_counters+
diff --git a/guides/source/active_support_core_extensions.textile b/guides/source/active_support_core_extensions.textile
index 66de6fd310..109228f8c7 100644
--- a/guides/source/active_support_core_extensions.textile
+++ b/guides/source/active_support_core_extensions.textile
@@ -1325,6 +1325,41 @@ that amount of leading whitespace.
NOTE: Defined in +active_support/core_ext/string/strip.rb+.
+h4. +indent+
+
+Indents the lines in the receiver:
+
+<ruby>
+<<EOS.indent(2)
+def some_method
+ some_code
+end
+EOS
+# =>
+ def some_method
+ some_code
+ end
+</ruby>
+
+The second argument, +indent_string+, specifies which indent string to use. The default is +nil+, which tells the method to make an educated guess peeking at the first indented line, and fallback to a space if there is none.
+
+<ruby>
+" foo".indent(2) # => " foo"
+"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
+"foo".indent(2, "\t") # => "\t\tfoo"
+</ruby>
+
+While +indent_string+ is tipically 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.
+
+<ruby>
+"foo\n\nbar".indent(2) # => " foo\n\n bar"
+"foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
+</ruby>
+
+The +indent!+ method performs indentation in-place.
+
h4. Access
h5. +at(position)+
diff --git a/guides/source/ajax_on_rails.textile b/guides/source/ajax_on_rails.textile
index 26e0270a31..67b0c9f0d3 100644
--- a/guides/source/ajax_on_rails.textile
+++ b/guides/source/ajax_on_rails.textile
@@ -28,7 +28,7 @@ the +ul+ node.
h4. Asynchronous JavaScript + XML
AJAX means Asynchronous JavaScript + XML. Asynchronous means that the page is not
-reloaded, the request made is separate from the regular page request. Javascript
+reloaded, the request made is separate from the regular page request. JavaScript
is used to evaluate the response and the XML part is a bit misleading as XML is
not required, you respond to the HTTP request with JSON or regular HTML as well.
diff --git a/guides/source/asset_pipeline.textile b/guides/source/asset_pipeline.textile
index d0952fcf29..8fec109951 100644
--- a/guides/source/asset_pipeline.textile
+++ b/guides/source/asset_pipeline.textile
@@ -121,7 +121,7 @@ h5. Search paths
When a file is referenced from a manifest or a helper, Sprockets searches the three default asset locations for it.
-The default locations are: +app/assets/images+ and the subdirectories +javascripts+ and +stylesheets+ in all three asset locations.
+The default locations are: +app/assets/images+ and the subdirectories +javascripts+ and +stylesheets+ in all three asset locations, but these subdirectories are not special. Any path under +assets/*+ will be searched.
For example, these files:
@@ -129,6 +129,7 @@ For example, these files:
app/assets/javascripts/home.js
lib/assets/javascripts/moovinator.js
vendor/assets/javascripts/slider.js
+vendor/assets/somepackage/phonebox.js
</plain>
would be referenced in a manifest like this:
@@ -137,6 +138,7 @@ would be referenced in a manifest like this:
//= require home
//= require moovinator
//= require slider
+//= require phonebox
</plain>
Assets inside subdirectories can also be accessed.
@@ -153,13 +155,13 @@ is referenced as:
You can view the search path by inspecting +Rails.application.config.assets.paths+ in the Rails console.
-Additional (fully qualified) paths can be added to the pipeline in +config/application.rb+. For example:
+Besides the standard +assets/*+ paths, additional (fully qualified) paths can be added to the pipeline in +config/application.rb+. For example:
<ruby>
-config.assets.paths << Rails.root.join("app", "assets", "flash")
+config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
</ruby>
-Paths are traversed in the order that they occur in the search path.
+Paths are traversed in the order that they occur in the search path. By default, this means the files in +app/assets+ take precedence, and will mask corresponding paths in +lib+ and +vendor+.
It is important to note that files you want to reference outside a manifest must be added to the precompile array or they will not be available in the production environment.
@@ -430,7 +432,7 @@ NOTE. If you are precompiling your assets locally, you can use +bundle install -
The default matcher for compiling files includes +application.js+, +application.css+ and all non-JS/CSS files (this will include all image assets automatically):
<ruby>
-[ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) }, /application.(css|js)$/ ]
+[ Proc.new{ |path| !%w(.js .css).include?(File.extname(path)) }, /application.(css|js)$/ ]
</ruby>
NOTE. The matcher (and other members of the precompile array; see below) is applied to final compiled file names. This means that anything that compiles to JS/CSS is excluded, as well as raw JS/CSS files; for example, +.coffee+ and +.scss+ files are *not* automatically included as they compile to JS/CSS.
@@ -651,7 +653,7 @@ WARNING: If you are upgrading an existing application and intend to use this opt
h3. Assets Cache Store
-Sprockets uses the default Rails cache store will be used to cache assets in development and production. This can be changed by setting +config.assets.cache_store+.
+The default Rails cache store will be used by Sprockets to cache assets in development and production. This can be changed by setting +config.assets.cache_store+.
<ruby>
config.assets.cache_store = :memory_store
diff --git a/guides/source/association_basics.textile b/guides/source/association_basics.textile
index 4dca7a508c..d4c0a1ba74 100644
--- a/guides/source/association_basics.textile
+++ b/guides/source/association_basics.textile
@@ -630,12 +630,12 @@ The <tt>create_<em>association</em></tt> method returns a new object of the asso
h5. Options for +belongs_to+
-While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +belongs_to+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
+While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +belongs_to+ association reference. Such customizations can easily be accomplished by passing options and scope blocks when you create the association. For example, this assocation uses two such options:
<ruby>
class Order < ActiveRecord::Base
- belongs_to :customer, :counter_cache => true,
- :conditions => "active = 1"
+ belongs_to :customer, :dependent => :destroy,
+ :counter_cache => true
end
</ruby>
@@ -643,15 +643,11 @@ The +belongs_to+ association supports these options:
* +:autosave+
* +:class_name+
-* +:conditions+
* +:counter_cache+
* +:dependent+
* +:foreign_key+
-* +:include+
* +:inverse_of+
* +:polymorphic+
-* +:readonly+
-* +:select+
* +:touch+
* +:validate+
@@ -669,16 +665,6 @@ class Order < ActiveRecord::Base
end
</ruby>
-h6(#belongs_to-conditions). +:conditions+
-
-The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by an SQL +WHERE+ clause).
-
-<ruby>
-class Order < ActiveRecord::Base
- belongs_to :customer, :conditions => "active = 1"
-end
-</ruby>
-
h6(#belongs_to-counter_cache). +:counter_cache+
The +:counter_cache+ option can be used to make finding the number of belonging objects more efficient. Consider these models:
@@ -737,35 +723,31 @@ end
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
-h6(#belongs_to-includes). +:include+
+h6(#belongs_to-inverse_of). +:inverse_of+
-You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
+The +:inverse_of+ option specifies the name of the +has_many+ or +has_one+ association that is the inverse of this association. Does not work in combination with the +:polymorphic+ options.
<ruby>
-class LineItem < ActiveRecord::Base
- belongs_to :order
+class Customer < ActiveRecord::Base
+ has_many :orders, :inverse_of => :customer
end
class Order < ActiveRecord::Base
- belongs_to :customer
- has_many :line_items
-end
-
-class Customer < ActiveRecord::Base
- has_many :orders
+ belongs_to :customer, :inverse_of => :orders
end
</ruby>
-If you frequently retrieve customers directly from line items (+@line_item.order.customer+), then you can make your code somewhat more efficient by including customers in the association from line items to orders:
+h6(#belongs_to-polymorphic). +:polymorphic+
-<ruby>
-class LineItem < ActiveRecord::Base
- belongs_to :order, :include => :customer
-end
+Passing +true+ to the +:polymorphic+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
+
+h6(#belongs_to-touch). +:touch+
+
+If you set the +:touch+ option to +:true+, then the +updated_at+ or +updated_on+ timestamp on the associated object will be set to the current time whenever this object is saved or destroyed:
+<ruby>
class Order < ActiveRecord::Base
- belongs_to :customer
- has_many :line_items
+ belongs_to :customer, :touch => true
end
class Customer < ActiveRecord::Base
@@ -773,43 +755,58 @@ class Customer < ActiveRecord::Base
end
</ruby>
-NOTE: There's no need to use +:include+ for immediate associations - that is, if you have +Order belongs_to :customer+, then the customer is eager-loaded automatically when it's needed.
-
-h6(#belongs_to-inverse_of). +:inverse_of+
-
-The +:inverse_of+ option specifies the name of the +has_many+ or +has_one+ association that is the inverse of this association. Does not work in combination with the +:polymorphic+ options.
+In this case, saving or destroying an order will update the timestamp on the associated customer. You can also specify a particular timestamp attribute to update:
<ruby>
-class Customer < ActiveRecord::Base
- has_many :orders, :inverse_of => :customer
-end
-
class Order < ActiveRecord::Base
- belongs_to :customer, :inverse_of => :orders
+ belongs_to :customer, :touch => :orders_updated_at
end
</ruby>
-h6(#belongs_to-polymorphic). +:polymorphic+
+h6(#belongs_to-validate). +:validate+
-Passing +true+ to the +:polymorphic+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
+If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
-h6(#belongs_to-readonly). +:readonly+
+h5(#belongs_to-scopes_for_belongs_to). Scopes for +belongs_to+
-If you set the +:readonly+ option to +true+, then the associated object will be read-only when retrieved via the association.
+There may be times when you wish to customize the query used by +belongs_to+. Such customizations can be achieved via a scope block. For example:
-h6(#belongs_to-select). +:select+
+<ruby>
+class Order < ActiveRecord::Base
+ belongs_to :customer, -> { where :active => true },
+ :dependent => :destroy
+end
+</ruby>
-The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
+You can use any of the standard "querying methods":active_record_querying.html inside the scope block. The following ones are discussed below:
-TIP: If you set the +:select+ option on a +belongs_to+ association, you should also set the +foreign_key+ option to guarantee the correct results.
+* +where+
+* +includes+
+* +readonly+
+* +select+
-h6(#belongs_to-touch). +:touch+
+h6(#belongs_to-where). +where+
-If you set the +:touch+ option to +:true+, then the +updated_at+ or +updated_on+ timestamp on the associated object will be set to the current time whenever this object is saved or destroyed:
+The +where+ method lets you specify the conditions that the associated object must meet.
<ruby>
class Order < ActiveRecord::Base
- belongs_to :customer, :touch => true
+ belongs_to :customer, -> { where :active => true }
+end
+</ruby>
+
+h6(#belongs_to-includes). +includes+
+
+You can use the +includes+ method let you specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
+
+<ruby>
+class LineItem < ActiveRecord::Base
+ belongs_to :order
+end
+
+class Order < ActiveRecord::Base
+ belongs_to :customer
+ has_many :line_items
end
class Customer < ActiveRecord::Base
@@ -817,17 +814,34 @@ class Customer < ActiveRecord::Base
end
</ruby>
-In this case, saving or destroying an order will update the timestamp on the associated customer. You can also specify a particular timestamp attribute to update:
+If you frequently retrieve customers directly from line items (+@line_item.order.customer+), then you can make your code somewhat more efficient by including customers in the association from line items to orders:
<ruby>
+class LineItem < ActiveRecord::Base
+ belongs_to :order, -> { includes :customer }
+end
+
class Order < ActiveRecord::Base
- belongs_to :customer, :touch => :orders_updated_at
+ belongs_to :customer
+ has_many :line_items
+end
+
+class Customer < ActiveRecord::Base
+ has_many :orders
end
</ruby>
-h6(#belongs_to-validate). +:validate+
+NOTE: There's no need to use +includes+ for immediate associations - that is, if you have +Order belongs_to :customer+, then the customer is eager-loaded automatically when it's needed.
-If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
+h6(#belongs_to-readonly). +readonly+
+
+If you use +readonly+, then the associated object will be read-only when retrieved via the association.
+
+h6(#belongs_to-select). +select+
+
+The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
+
+TIP: If you use the +select+ method on a +belongs_to+ association, you should also set the +:foreign_key+ option to guarantee the correct results.
h5(#belongs_to-do_any_associated_objects_exist). Do Any Associated Objects Exist?
@@ -924,15 +938,10 @@ The +has_one+ association supports these options:
* +:as+
* +:autosave+
* +:class_name+
-* +:conditions+
* +:dependent+
* +:foreign_key+
-* +:include+
* +:inverse_of+
-* +:order+
* +:primary_key+
-* +:readonly+
-* +:select+
* +:source+
* +:source_type+
* +:through+
@@ -956,22 +965,15 @@ class Supplier < ActiveRecord::Base
end
</ruby>
-h6(#has_one-conditions). +:conditions+
-
-The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by an SQL +WHERE+ clause).
-
-<ruby>
-class Supplier < ActiveRecord::Base
- has_one :account, :conditions => "confirmed = 1"
-end
-</ruby>
-
h6(#has_one-dependent). +:dependent+
-If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated object to delete that object. If you set the +:dependent+ option to +:delete+, then deleting this object will delete the associated object _without_ calling its +destroy+ method. If you set the +:dependent+ option to +:nullify+, then deleting this object will set the foreign key in the association object to +NULL+.
-If you set the +:dependent+ option to +:restrict+, then the deletion of the object is restricted if a dependent associated object exist and a +DeleteRestrictionError+ exception is raised.
+Controls what happens to the associated object when its owner is destroyed:
-NOTE: The default behavior for +:dependent => :restrict+ is to raise a +DeleteRestrictionError+ when associated objects exist. Since Rails 4.0 this behavior is being deprecated in favor of adding an error to the base model. To silence the warning in Rails 4.0, you should fix your code to not expect this Exception and add +config.active_record.dependent_restrict_raises = false+ to your application config.
+* +:destroy+ causes the associated object to also be destroyed
+* +:delete+ causes the asssociated object to be deleted directly from the database (so callbacks will not execute)
+* +:nullify+ causes the foreign key to be set to +NULL+. Callbacks are not executed.
+* +:restrict_with_exception+ causes an exception to be raised if there is an associated record
+* +:restrict_with_error+ causes an error to be added to the owner if there is an associated object
h6(#has_one-foreign_key). +:foreign_key+
@@ -985,30 +987,74 @@ end
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
-h6(#has_one-include). +:include+
+h6(#has_one-inverse_of). +:inverse_of+
-You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
+The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
<ruby>
class Supplier < ActiveRecord::Base
- has_one :account
+ has_one :account, :inverse_of => :supplier
end
class Account < ActiveRecord::Base
- belongs_to :supplier
- belongs_to :representative
+ belongs_to :supplier, :inverse_of => :account
end
+</ruby>
-class Representative < ActiveRecord::Base
- has_many :accounts
+h6(#has_one-primary_key). +:primary_key+
+
+By convention, Rails assumes that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
+
+h6(#has_one-source). +:source+
+
+The +:source+ option specifies the source association name for a +has_one :through+ association.
+
+h6(#has_one-source_type). +:source_type+
+
+The +:source_type+ option specifies the source association type for a +has_one :through+ association that proceeds through a polymorphic association.
+
+h6(#has_one-through). +:through+
+
+The +:through+ option specifies a join model through which to perform the query. +has_one :through+ associations were discussed in detail <a href="#the-has_one-through-association">earlier in this guide</a>.
+
+h6(#has_one-validate). +:validate+
+
+If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
+
+h5(#belongs_to-scopes_for_has_one). Scopes for +has_one+
+
+There may be times when you wish to customize the query used by +has_one+. Such customizations can be achieved via a scope block. For example:
+
+<ruby>
+class Supplier < ActiveRecord::Base
+ has_one :account, -> { where :active => true }
end
</ruby>
-If you frequently retrieve representatives directly from suppliers (+@supplier.account.representative+), then you can make your code somewhat more efficient by including representatives in the association from suppliers to accounts:
+You can use any of the standard "querying methods":active_record_querying.html inside the scope block. The following ones are discussed below:
+
+* +where+
+* +includes+
+* +readonly+
+* +select+
+
+h6(#has_one-where). +where+
+
+The +where+ method lets you specify the conditions that the associated object must meet.
<ruby>
class Supplier < ActiveRecord::Base
- has_one :account, :include => :representative
+ has_one :account, -> { where "confirmed = 1" }
+end
+</ruby>
+
+h6(#has_one-includes). +includes+
+
+You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
+
+<ruby>
+class Supplier < ActiveRecord::Base
+ has_one :account
end
class Account < ActiveRecord::Base
@@ -1021,51 +1067,30 @@ class Representative < ActiveRecord::Base
end
</ruby>
-h6(#has_one-inverse_of). +:inverse_of+
-
-The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
+If you frequently retrieve representatives directly from suppliers (+@supplier.account.representative+), then you can make your code somewhat more efficient by including representatives in the association from suppliers to accounts:
<ruby>
class Supplier < ActiveRecord::Base
- has_one :account, :inverse_of => :supplier
+ has_one :account, -> { includes :representative }
end
class Account < ActiveRecord::Base
- belongs_to :supplier, :inverse_of => :account
+ belongs_to :supplier
+ belongs_to :representative
end
-</ruby>
-
-h6(#has_one-order). +:order+
-
-The +:order+ option dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause). Because a +has_one+ association will only retrieve a single associated object, this option should not be needed.
-
-h6(#has_one-primary_key). +:primary_key+
-
-By convention, Rails assumes that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
-
-h6(#has_one-readonly). +:readonly+
-
-If you set the +:readonly+ option to +true+, then the associated object will be read-only when retrieved via the association.
-
-h6(#has_one-select). +:select+
-The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
-
-h6(#has_one-source). +:source+
-
-The +:source+ option specifies the source association name for a +has_one :through+ association.
-
-h6(#has_one-source_type). +:source_type+
-
-The +:source_type+ option specifies the source association type for a +has_one :through+ association that proceeds through a polymorphic association.
+class Representative < ActiveRecord::Base
+ has_many :accounts
+end
+</ruby>
-h6(#has_one-through). +:through+
+h6(#has_one-readonly). +readonly+
-The +:through+ option specifies a join model through which to perform the query. +has_one :through+ associations were discussed in detail <a href="#the-has_one-through-association">earlier in this guide</a>.
+If you use the +readonly+ method, then the associated object will be read-only when retrieved via the association.
-h6(#has_one-validate). +:validate+
+h6(#has_one-select). +select+
-If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
+The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
h5(#has_one-do_any_associated_objects_exist). Do Any Associated Objects Exist?
@@ -1256,23 +1281,13 @@ The +has_many+ association supports these options:
* +:as+
* +:autosave+
* +:class_name+
-* +:conditions+
* +:dependent+
-* +:extend+
* +:foreign_key+
-* +:group+
-* +:include+
* +:inverse_of+
-* +:limit+
-* +:offset+
-* +:order+
* +:primary_key+
-* +:readonly+
-* +:select+
* +:source+
* +:source_type+
* +:through+
-* +:uniq+
* +:validate+
h6(#has_many-as). +:as+
@@ -1293,75 +1308,127 @@ class Customer < ActiveRecord::Base
end
</ruby>
-h6(#has_many-conditions). +:conditions+
+h6(#has_many-dependent). +:dependent+
+
+Controls what happens to the associated objects when their owner is destroyed:
+
+* +:destroy+ causes all the associated objects to also be destroyed
+* +:delete_all+ causes all the asssociated objects to be deleted directly from the database (so callbacks will not execute)
+* +:nullify+ causes the foreign keys to be set to +NULL+. Callbacks are not executed.
+* +:restrict_with_exception+ causes an exception to be raised if there are any associated records
+* +:restrict_with_error+ causes an error to be added to the owner if there are any associated objects
+
+NOTE: This option is ignored when you use the +:through+ option on the association.
-The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by an SQL +WHERE+ clause).
+h6(#has_many-foreign_key). +:foreign_key+
+
+By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
<ruby>
class Customer < ActiveRecord::Base
- has_many :confirmed_orders, :class_name => "Order",
- :conditions => "confirmed = 1"
+ has_many :orders, :foreign_key => "cust_id"
end
</ruby>
-You can also set conditions via a hash:
+TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
+
+h6(#has_many-inverse_of). +:inverse_of+
+
+The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
<ruby>
class Customer < ActiveRecord::Base
- has_many :confirmed_orders, :class_name => "Order",
- :conditions => { :confirmed => true }
+ has_many :orders, :inverse_of => :customer
+end
+
+class Order < ActiveRecord::Base
+ belongs_to :customer, :inverse_of => :orders
end
</ruby>
-If you use a hash-style +:conditions+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@customer.confirmed_orders.create+ or +@customer.confirmed_orders.build+ will create orders where the confirmed column has the value +true+.
+h6(#has_many-primary_key). +:primary_key+
-If you need to evaluate conditions dynamically at runtime, use a proc:
+By convention, Rails assumes that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
+
+h6(#has_many-source). +:source+
+
+The +:source+ option specifies the source association name for a +has_many :through+ association. You only need to use this option if the name of the source association cannot be automatically inferred from the association name.
+
+h6(#has_many-source_type). +:source_type+
+
+The +:source_type+ option specifies the source association type for a +has_many :through+ association that proceeds through a polymorphic association.
+
+h6(#has_many-through). +:through+
+
+The +:through+ option specifies a join model through which to perform the query. +has_many :through+ associations provide a way to implement many-to-many relationships, as discussed <a href="#the-has_many-through-association">earlier in this guide</a>.
+
+h6(#has_many-validate). +:validate+
+
+If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
+
+h5(#has_many-scopes_for_has_many). Scopes for +has_many+
+
+There may be times when you wish to customize the query used by +has_many+. Such customizations can be achieved via a scope block. For example:
<ruby>
class Customer < ActiveRecord::Base
- has_many :latest_orders, :class_name => "Order",
- :conditions => proc { ["orders.created_at > ?", 10.hours.ago] }
+ has_many :orders, -> { where :processed => true }
end
</ruby>
-h6(#has_many-dependent). +:dependent+
-
-If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated objects to delete those objects. If you set the +:dependent+ option to +:delete_all+, then deleting this object will delete the associated objects _without_ calling their +destroy+ method. If you set the +:dependent+ option to +:nullify+, then deleting this object will set the foreign key in the associated objects to +NULL+.
-If you set the +:dependent+ option to +:restrict+, then the deletion of the object is restricted if a dependent associated object exist and a +DeleteRestrictionError+ exception is raised.
+You can use any of the standard "querying methods":active_record_querying.html inside the scope block. The following ones are discussed below:
-NOTE: The default behavior for +:dependent => :restrict+ is to raise a +DeleteRestrictionError+ when associated objects exist. Since Rails 4.0 this behavior is being deprecated in favor of adding an error to the base model. To silence the warning in Rails 4.0, you should fix your code to not expect this Exception and add +config.active_record.dependent_restrict_raises = false+ to your application config.
-
-NOTE: This option is ignored when you use the +:through+ option on the association.
+* +where+
+* +extending+
+* +group+
+* +includes+
+* +limit+
+* +offset+
+* +order+
+* +readonly+
+* +select+
+* +uniq+
-h6(#has_many-extend). +:extend+
+h6(#has_many-where). +where+
-The +:extend+ option specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
+The +where+ method lets you specify the conditions that the associated object must meet.
-h6(#has_many-foreign_key). +:foreign_key+
+<ruby>
+class Customer < ActiveRecord::Base
+ has_many :confirmed_orders, -> { where "confirmed = 1" },
+ :class_name => "Order"
+end
+</ruby>
-By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
+You can also set conditions via a hash:
<ruby>
class Customer < ActiveRecord::Base
- has_many :orders, :foreign_key => "cust_id"
+ has_many :confirmed_orders, -> { where :confirmed => true },
+ :class_name => "Order"
end
</ruby>
-TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
+If you use a hash-style +where+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@customer.confirmed_orders.create+ or +@customer.confirmed_orders.build+ will create orders where the confirmed column has the value +true+.
+
+h6(#has_many-extending). +extending+
-h6(#has_many-group). +:group+
+The +extending+ method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
-The +:group+ option supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
+h6(#has_many-group). +group+
+
+The +group+ method supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
<ruby>
class Customer < ActiveRecord::Base
- has_many :line_items, :through => :orders, :group => "orders.id"
+ has_many :line_items, -> { group 'orders.id' },
+ :through => :orders
end
</ruby>
-h6(#has_many-include). +:include+
+h6(#has_many-includes). +includes+
-You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
+You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
<ruby>
class Customer < ActiveRecord::Base
@@ -1382,7 +1449,7 @@ If you frequently retrieve line items directly from customers (+@customer.orders
<ruby>
class Customer < ActiveRecord::Base
- has_many :orders, :include => :line_items
+ has_many :orders, -> { includes :line_items }
end
class Order < ActiveRecord::Base
@@ -1395,74 +1462,45 @@ class LineItem < ActiveRecord::Base
end
</ruby>
-h6(#has_many-inverse_of). +:inverse_of+
+h6(#has_many-limit). +limit+
-The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
+The +limit+ method lets you restrict the total number of objects that will be fetched through an association.
<ruby>
class Customer < ActiveRecord::Base
- has_many :orders, :inverse_of => :customer
-end
-
-class Order < ActiveRecord::Base
- belongs_to :customer, :inverse_of => :orders
+ has_many :recent_orders,
+ -> { order('order_date desc').limit(100) },
+ :class_name => "Order",
end
</ruby>
-h6(#has_many-limit). +:limit+
+h6(#has_many-offset). +offset+
-The +:limit+ option lets you restrict the total number of objects that will be fetched through an association.
+The +offset+ method lets you specify the starting offset for fetching objects via an association. For example, +-> { offset(11) }+ will skip the first 11 records.
-<ruby>
-class Customer < ActiveRecord::Base
- has_many :recent_orders, :class_name => "Order",
- :order => "order_date DESC", :limit => 100
-end
-</ruby>
-
-h6(#has_many-offset). +:offset+
-
-The +:offset+ option lets you specify the starting offset for fetching objects via an association. For example, if you set +:offset => 11+, it will skip the first 11 records.
+h6(#has_many-order). +order+
-h6(#has_many-order). +:order+
-
-The +:order+ option dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
+The +order+ method dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
<ruby>
class Customer < ActiveRecord::Base
- has_many :orders, :order => "date_confirmed DESC"
+ has_many :orders, -> { order "date_confirmed DESC" }
end
</ruby>
-h6(#has_many-primary_key). +:primary_key+
-
-By convention, Rails assumes that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
-
-h6(#has_many-readonly). +:readonly+
+h6(#has_many-readonly). +readonly+
-If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association.
+If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association.
-h6(#has_many-select). +:select+
+h6(#has_many-select). +select+
-The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
+The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
-WARNING: If you specify your own +:select+, be sure to include the primary key and foreign key columns of the associated model. If you do not, Rails will throw an error.
+WARNING: If you specify your own +select+, be sure to include the primary key and foreign key columns of the associated model. If you do not, Rails will throw an error.
-h6(#has_many-source). +:source+
-
-The +:source+ option specifies the source association name for a +has_many :through+ association. You only need to use this option if the name of the source association cannot be automatically inferred from the association name.
-
-h6(#has_many-source_type). +:source_type+
+h6(#has_many-uniq). +uniq+
-The +:source_type+ option specifies the source association type for a +has_many :through+ association that proceeds through a polymorphic association.
-
-h6(#has_many-through). +:through+
-
-The +:through+ option specifies a join model through which to perform the query. +has_many :through+ associations provide a way to implement many-to-many relationships, as discussed <a href="#the-has_many-through-association">earlier in this guide</a>.
-
-h6(#has_many-uniq). +:uniq+
-
-Set the +:uniq+ option to true to keep the collection free of duplicates. This is mostly useful together with the +:through+ option.
+Use the +uniq+ method to keep the collection free of duplicates. This is mostly useful together with the +:through+ option.
<ruby>
class Person < ActiveRecord::Base
@@ -1480,12 +1518,12 @@ Reading.all.inspect # => [#<Reading id: 12, person_id: 5, post_id: 5>, #<Readin
In the above case there are two readings and +person.posts+ brings out both of them even though these records are pointing to the same post.
-Now let's set +:uniq+ to true:
+Now let's set +uniq+:
<ruby>
class Person
has_many :readings
- has_many :posts, :through => :readings, :uniq => true
+ has_many :posts, -> { uniq }, :through => :readings
end
person = Person.create(:name => 'honda')
@@ -1498,10 +1536,6 @@ Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Readin
In the above case there are still two readings. However +person.posts+ shows only one post because the collection loads only unique records.
-h6(#has_many-validate). +:validate+
-
-If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
-
h5(#has_many-when_are_objects_saved). When are Objects Saved?
When you assign an object to a +has_many+ association, that object is automatically saved (in order to update its foreign key). If you assign multiple objects in one statement, then they are all saved.
@@ -1687,18 +1721,8 @@ The +has_and_belongs_to_many+ association supports these options:
* +:association_foreign_key+
* +:autosave+
* +:class_name+
-* +:conditions+
-* +:extend+
* +:foreign_key+
-* +:group+
-* +:include+
* +:join_table+
-* +:limit+
-* +:offset+
-* +:order+
-* +:readonly+
-* +:select+
-* +:uniq+
* +:validate+
h6(#has_and_belongs_to_many-association_foreign_key). +:association_foreign_key+
@@ -1729,102 +1753,126 @@ class Parts < ActiveRecord::Base
end
</ruby>
-h6(#has_and_belongs_to_many-conditions). +:conditions+
+h6(#has_and_belongs_to_many-foreign_key). +:foreign_key+
-The +:conditions+ option lets you specify the conditions that the associated object must meet (in the syntax used by an SQL +WHERE+ clause).
+By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
<ruby>
-class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies,
- :conditions => "factory = 'Seattle'"
+class User < ActiveRecord::Base
+ has_and_belongs_to_many :friends, :class_name => "User",
+ :foreign_key => "this_user_id",
+ :association_foreign_key => "other_user_id"
end
</ruby>
-You can also set conditions via a hash:
+h6(#has_and_belongs_to_many-join_table). +:join_table+
+
+If the default name of the join table, based on lexical ordering, is not what you want, you can use the +:join_table+ option to override the default.
+
+h6(#has_and_belongs_to_many-validate). +:validate+
+
+If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
+
+h5(#has_and_belongs_to_many-scopes_for_has_and_belongs_to_many). Scopes for +has_and_belongs_to_many+
+
+There may be times when you wish to customize the query used by +has_and_belongs_to_many+. Such customizations can be achieved via a scope block. For example:
<ruby>
class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies,
- :conditions => { :factory => 'Seattle' }
+ has_and_belongs_to_many :assemblies, -> { where :active => true }
end
</ruby>
-If you use a hash-style +:conditions+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@parts.assemblies.create+ or +@parts.assemblies.build+ will create orders where the +factory+ column has the value "Seattle".
+You can use any of the standard "querying methods":active_record_querying.html inside the scope block. The following ones are discussed below:
-h6(#has_and_belongs_to_many-extend). +:extend+
+* +where+
+* +extending+
+* +group+
+* +includes+
+* +limit+
+* +offset+
+* +order+
+* +readonly+
+* +select+
+* +uniq+
-The +:extend+ option specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
+h6(#has_and_belongs_to_many-where). +where+
-h6(#has_and_belongs_to_many-foreign_key). +:foreign_key+
-
-By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
+The +where+ method lets you specify the conditions that the associated object must meet.
<ruby>
-class User < ActiveRecord::Base
- has_and_belongs_to_many :friends, :class_name => "User",
- :foreign_key => "this_user_id",
- :association_foreign_key => "other_user_id"
+class Parts < ActiveRecord::Base
+ has_and_belongs_to_many :assemblies,
+ -> { where "factory = 'Seattle'" }
end
</ruby>
-h6(#has_and_belongs_to_many-group). +:group+
-
-The +:group+ option supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
+You can also set conditions via a hash:
<ruby>
class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies, :group => "factory"
+ has_and_belongs_to_many :assemblies,
+ -> { where :factory => 'Seattle' }
end
</ruby>
-h6(#has_and_belongs_to_many-include). +:include+
+If you use a hash-style +where+, then record creation via this association will be automatically scoped using the hash. In this case, using +@parts.assemblies.create+ or +@parts.assemblies.build+ will create orders where the +factory+ column has the value "Seattle".
-You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used.
+h6(#has_and_belongs_to_many-extending). +extending+
-h6(#has_and_belongs_to_many-join_table). +:join_table+
+The +extending+ method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
-If the default name of the join table, based on lexical ordering, is not what you want, you can use the +:join_table+ option to override the default.
+h6(#has_and_belongs_to_many-group). +group+
-h6(#has_and_belongs_to_many-limit). +:limit+
-
-The +:limit+ option lets you restrict the total number of objects that will be fetched through an association.
+The +group+ method supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
<ruby>
class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies, :order => "created_at DESC",
- :limit => 50
+ has_and_belongs_to_many :assemblies, -> { group "factory" }
end
</ruby>
-h6(#has_and_belongs_to_many-offset). +:offset+
+h6(#has_and_belongs_to_many-includes). +includes+
-The +:offset+ option lets you specify the starting offset for fetching objects via an association. For example, if you set +:offset => 11+, it will skip the first 11 records.
+You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used.
-h6(#has_and_belongs_to_many-order). +:order+
+h6(#has_and_belongs_to_many-limit). +limit+
-The +:order+ option dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
+The +limit+ method lets you restrict the total number of objects that will be fetched through an association.
<ruby>
class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies, :order => "assembly_name ASC"
+ has_and_belongs_to_many :assemblies,
+ -> { order("created_at DESC").limit(50) }
end
</ruby>
-h6(#has_and_belongs_to_many-readonly). +:readonly+
+h6(#has_and_belongs_to_many-offset). +offset+
+
+The +offset+ method lets you specify the starting offset for fetching objects via an association. For example, if you set +offset(11)+, it will skip the first 11 records.
-If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association.
+h6(#has_and_belongs_to_many-order). +order+
-h6(#has_and_belongs_to_many-select). +:select+
+The +order+ method dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
-The +:select+ option lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
+<ruby>
+class Parts < ActiveRecord::Base
+ has_and_belongs_to_many :assemblies,
+ -> { order "assembly_name ASC" }
+end
+</ruby>
-h6(#has_and_belongs_to_many-uniq). +:uniq+
+h6(#has_and_belongs_to_many-readonly). +readonly+
-Specify the +:uniq => true+ option to remove duplicates from the collection.
+If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association.
-h6(#has_and_belongs_to_many-validate). +:validate+
+h6(#has_and_belongs_to_many-select). +select+
-If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
+The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
+
+h6(#has_and_belongs_to_many-uniq). +uniq+
+
+Use the +uniq+ method to remove duplicates from the collection.
h5(#has_and_belongs_to_many-when_are_objects_saved). When are Objects Saved?
@@ -1904,20 +1952,11 @@ module FindRecentExtension
end
class Customer < ActiveRecord::Base
- has_many :orders, :extend => FindRecentExtension
+ has_many :orders, -> { extending FindRecentExtension }
end
class Supplier < ActiveRecord::Base
- has_many :deliveries, :extend => FindRecentExtension
-end
-</ruby>
-
-To include more than one extension module in a single association, specify an array of modules:
-
-<ruby>
-class Customer < ActiveRecord::Base
- has_many :orders,
- :extend => [FindRecentExtension, FindActiveExtension]
+ has_many :deliveries, -> { extending FindRecentExtension }
end
</ruby>
diff --git a/guides/source/command_line.textile b/guides/source/command_line.textile
index 19e42cea93..39b75c2781 100644
--- a/guides/source/command_line.textile
+++ b/guides/source/command_line.textile
@@ -160,7 +160,7 @@ $ rails generate controller Greetings hello
create app/assets/stylesheets/greetings.css.scss
</shell>
-What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a view file, a functional test file, a helper for the view, a javascript file and a stylesheet file.
+What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a view file, a functional test file, a helper for the view, a JavaScript file and a stylesheet file.
Check out the controller and modify it a little (in +app/controllers/greetings_controller.rb+):
@@ -477,6 +477,53 @@ h4. Miscellaneous
* +rake secret+ will give you a pseudo-random key to use for your session secret.
* <tt>rake time:zones:all</tt> lists all the timezones Rails knows about.
+h4. Writing Rake Tasks
+
+If you have (or want to write) any automation scripts outside your app (data import, checks, etc), you can make them as rake tasks. It's easy.
+
+INFO: "Complete guide about how to write tasks":http://rake.rubyforge.org/files/doc/rakefile_rdoc.html is available in the official documentation.
+
+Tasks should be placed in <tt>Rails.root/lib/tasks</tt> and should have a +.rake+ extension.
+
+Each task should be defined in next format (dependencies are optional):
+
+<ruby>
+desc "I am short, but comprehensive description for my cool task"
+task :task_name => [:prerequisite_task, :another_task_we_depend_on] do
+ # All your magick here
+ # Any valid Ruby code is allowed
+end
+</ruby>
+
+If you need to pass parameters, you can use next format (both arguments and dependencies are optional):
+
+<ruby>
+task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
+ # You can use args from here
+end
+</ruby>
+
+You can group tasks by placing them in namespaces:
+
+<ruby>
+namespace :do
+ desc "This task does nothing"
+ task :nothing do
+ # Seriously, nothing
+ end
+end
+</ruby>
+
+You can see your tasks to be listed by <tt>rake -T</tt> command. And, according to the examples above, you can invoke them as follows:
+
+<shell>
+rake task_name
+rake "task_name[value 1]" # entire argument string should be quoted
+rake do:nothing
+</shell>
+
+NOTE: If your need to interact with your application models, perform database queries and so on, your task should depend on the +environment+ task, which will load your application code.
+
h3. The Rails Advanced Command Line
More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
diff --git a/guides/source/configuring.textile b/guides/source/configuring.textile
index cd9aab4892..5ed3ad4a6b 100644
--- a/guides/source/configuring.textile
+++ b/guides/source/configuring.textile
@@ -157,7 +157,7 @@ Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets wit
* +config.assets.digest+ enables the use of MD5 fingerprints in asset names. Set to +true+ by default in +production.rb+.
-* +config.assets.debug+ disables the concatenation and compression of assets. Set to +false+ by default in +development.rb+.
+* +config.assets.debug+ disables the concatenation and compression of assets. Set to +true+ by default in +development.rb+.
* +config.assets.manifest+ defines the full path to be used for the asset precompiler's manifest file. Defaults to using +config.assets.prefix+.
@@ -186,7 +186,7 @@ The full set of methods that can be used in this block are as follows:
* +force_plural+ allows pluralized model names. Defaults to +false+.
* +helper+ defines whether or not to generate helpers. Defaults to +true+.
* +integration_tool+ defines which integration tool to use. Defaults to +nil+.
-* +javascripts+ turns on the hook for javascripts in generators. Used in Rails for when the +scaffold+ generator is run. Defaults to +true+.
+* +javascripts+ turns on the hook for JavaScript files in generators. Used in Rails for when the +scaffold+ generator is run. Defaults to +true+.
* +javascript_engine+ configures the engine to be used (for eg. coffee) when generating assets. Defaults to +nil+.
* +orm+ defines which orm to use. Defaults to +false+ and will use Active Record by default.
* +performance_tool+ defines which performance tool to use. Defaults to +nil+.
@@ -286,8 +286,6 @@ h4. Configuring Active Record
* +config.active_record.auto_explain_threshold_in_seconds+ configures the threshold for automatic EXPLAINs (+nil+ disables this feature). Queries exceeding the threshold get their query plan logged. Default is 0.5 in development mode.
-* +config.active_record.dependent_restrict_raises+ will control the behavior when an object with a <tt>:dependent => :restrict</tt> association is deleted. Setting this to false will prevent +DeleteRestrictionError+ from being raised and instead will add an error on the model object. Defaults to false in the development mode.
-
* +config.active_record.mass_assignment_sanitizer+ will determine the strictness of the mass assignment sanitization within Rails. Defaults to +:strict+. In this mode, mass assigning any non-+attr_accessible+ attribute in a +create+ or +update_attributes+ call will raise an exception. Setting this option to +:logger+ will only print to the log file when an attribute is being assigned and will not raise an exception.
The MySQL adapter adds one additional configuration option:
@@ -340,6 +338,12 @@ h4. Configuring Action Dispatch
* +config.action_dispatch.session_store+ sets the name of the store for session data. The default is +:cookie_store+; other valid options include +:active_record_store+, +:mem_cache_store+ or the name of your own custom class.
+* +config.action_dispatch.default_headers+ is a hash with HTTP headers that are set by default in each response. By default, this is defined as:
+
+<ruby>
+config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block' }
+</ruby>
+
* +config.action_dispatch.tld_length+ sets the TLD (top-level domain) length for the application. Defaults to +1+.
* +ActionDispatch::Callbacks.before+ takes a block of code to run before the request.
diff --git a/guides/source/contributing_to_ruby_on_rails.textile b/guides/source/contributing_to_ruby_on_rails.textile
index a8a097d156..65db40e77d 100644
--- a/guides/source/contributing_to_ruby_on_rails.textile
+++ b/guides/source/contributing_to_ruby_on_rails.textile
@@ -36,11 +36,17 @@ Please don't put "feature request" items into GitHub Issues. If there's a new fe
If you'd like feedback on an idea for a feature before doing the work for make a patch, please send an email to the "rails-core mailing list":https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core. You might get no response, which means that everyone is indifferent. You might find someone who's also interested in building that feature. You might get a "This won't be accepted." But it's the proper place to discuss new ideas. GitHub Issues are not a particularly good venue for the sometimes long and involved discussions new features require.
-h3. Running the Test Suite
+h3. Setting Up a Development Environment
To move on from submitting bugs to helping resolve existing issues or contributing your own code to Ruby on Rails, you _must_ be able to run its test suite. In this section of the guide you'll learn how to set up the tests on your own computer.
-h4. Install Git
+h4. The Easy Way
+
+The easiest way to get a development environment ready to hack is to use the "Rails development box":https://github.com/rails/rails-dev-box.
+
+h4. The Hard Way
+
+h5. Install Git
Ruby on Rails uses git for source code control. The "git homepage":http://git-scm.com/ has installation instructions. There are a variety of resources on the net that will help you get familiar with git:
@@ -49,7 +55,7 @@ Ruby on Rails uses git for source code control. The "git homepage":http://git-sc
* "GitHub":http://help.github.com offers links to a variety of git resources.
* "Pro Git":http://progit.org/book/ is an entire book about git with a Creative Commons license.
-h4. Clone the Ruby on Rails Repository
+h5. Clone the Ruby on Rails Repository
Navigate to the folder where you want the Ruby on Rails source code (it will create its own +rails+ subdirectory) and run:
@@ -58,7 +64,7 @@ $ git clone git://github.com/rails/rails.git
$ cd rails
</shell>
-h4. Set up and Run the Tests
+h5. Set up and Run the Tests
The test suite must pass with any submitted code. No matter whether you are writing a new patch, or evaluating someone else's, you need to be able to run the tests.
@@ -128,36 +134,17 @@ $ cd actionpack
$ bundle exec ruby -Itest test/template/form_helper_test.rb
</shell>
-h4. Warnings
-
-The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings.
-
-As of this writing (December, 2010) they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag:
-
-<shell>
-$ RUBYOPT=-W0 bundle exec rake test
-</shell>
-
-h4. Testing Active Record
+h5. Active Record Setup
The test suite of Active Record attempts to run four times: once for SQLite3, once for each of the two MySQL gems (+mysql+ and +mysql2+), and once for PostgreSQL. We are going to see now how to set up the environment for them.
WARNING: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
-h5. Database Configuration
+h6. Database Configuration
The Active Record test suite requires a custom config file: +activerecord/test/config.yml+. An example is provided in +activerecord/test/config.example.yml+ which can be copied and used as needed for your environment.
-h5. SQLite3
-
-The gem +sqlite3-ruby+ does not belong to the "db" group. Indeed, if you followed the instructions above you're ready. This is how you run the Active Record test suite only for SQLite3:
-
-<shell>
-$ cd activerecord
-$ bundle exec rake test_sqlite3
-</shell>
-
-h5. MySQL and PostgreSQL
+h6. MySQL and PostgreSQL
To be able to run the suite for MySQL and PostgreSQL we need their gems. Install first the servers, their client libraries, and their development files. In Ubuntu just run
@@ -215,7 +202,16 @@ NOTE: Using the rake task to create the test databases ensures they have the cor
NOTE: You'll see the following warning (or localized warning) during activating HStore extension in PostgreSQL 9.1.x or earlier: "WARNING: => is deprecated as an operator".
-If you’re using another database, check the files under +activerecord/test/connections+ for default connection information. You can edit these files to provide different credentials on your machine if you must, but obviously you should not push any such changes back to Rails.
+If you’re using another database, check the file +activerecord/test/config.yml+ or +activerecord/test/config.example.yml+ for default connection information. You can edit +activerecord/test/config.yml+ to provide different credentials on your machine if you must, but obviously you should not push any such changes back to Rails.
+
+h3. Testing Active Record
+
+This is how you run the Active Record test suite only for SQLite3:
+
+<shell>
+$ cd activerecord
+$ bundle exec rake test_sqlite3
+</shell>
You can now run the tests as you did for +sqlite3+. The tasks are respectively
@@ -225,7 +221,7 @@ test_mysql2
test_postgresql
</shell>
-As we mentioned before
+Finally,
<shell>
$ bundle exec rake test
@@ -241,6 +237,16 @@ $ ARCONN=sqlite3 ruby -Itest test/cases/associations/has_many_associations_test.
You can invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql+ also. See the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/travis.rb+ for the test suite run by the continuous integration server.
+h4. Warnings
+
+The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings.
+
+As of this writing (December, 2010) they are specially noisy with Ruby 1.9. If you are sure about what you are doing and would like to have a more clear output, there's a way to override the flag:
+
+<shell>
+$ RUBYOPT=-W0 bundle exec rake test
+</shell>
+
h4. Older Versions of Ruby on Rails
If you want to add a fix to older versions of Ruby on Rails, you'll need to set up and switch to your own local tracking branch. Here is an example to switch to the 3-0-stable branch:
@@ -359,6 +365,31 @@ Rails follows a simple set of coding style conventions.
The above are guidelines -- please use your best judgment in using them.
+h4. Updating the CHANGELOG
+
+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.
+
+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:
+
+<plain>
+* Summary of a change that briefly describes what was changed. You can use multiple
+ lines and wrap them at around 80 characters. Code examples are ok, too, if needed:
+
+ class Foo
+ def bar
+ puts 'baz'
+ end
+ end
+
+ You can continue after the code example and you can attach issue number. GH#1234
+
+ * Your Name *
+</plain>
+
+Your name can be added directly after the last word if you don't provide any code examples or don't need multiple paragraphs. Otherwise, it's best to make as a new paragraph.
+
h4. Sanity Check
You should not be the only person who looks at the code before you submit it. You know at least one other Rails developer, right? Show them what you’re doing and ask for feedback. Doing this in private before you push a patch out publicly is the “smoke test” for a patch: if you can’t convince one other developer of the beauty of your code, you’re unlikely to convince the core team either.
diff --git a/guides/source/engines.textile b/guides/source/engines.textile
index 53c2845731..11c837be32 100644
--- a/guides/source/engines.textile
+++ b/guides/source/engines.textile
@@ -657,6 +657,84 @@ h3. Improving engine functionality
This section looks at overriding or adding functionality to the views, controllers and models provided by an engine.
+h4. Overriding Models
+
+Engine Models can be extended by (1) implementing decorators, or (2) including modules.
+
+h5. Decorators
+
+Decorators extends Engine's model classes in the main application by open classing Engine models at run time execution.
+
+<ruby>
+# MyApp/app/decorators/models/blorgh/post_decorator.rb
+
+Blorgh::Post.class_eval do
+ def time_since_created
+ Time.current - created_at
+ end
+end
+</ruby>
+
+h5. Modules
+
+The other strategy is to create modules within the Engine holding all the models' code and include these in the respective Engine's model classes. Thus the Engine's model classes contain a mere include line referencing the respective module.
+
+Engine models can be overriden in the main application by creating a file with the Engine's same namespace and including the module originally referenced in the Engine's model class. ["**ActiveSupport::Concern**":http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html] helps manage the correct ordering of module dependencies at run time (it's worth it to reach the linked documentation).
+
+<ruby>
+# MyApp/app/models/blorgh/post.rb
+# overrides Blorgh's original Post model
+
+class Blorgh::Post < ActiveRecord::Base
+ include Blorgh::Concerns::Models::Post
+
+ def time_since_created
+ Time.current - created_at
+ end
+end
+
+
+# Blorgh/app/models/post.rb
+# this class is overriden by the MyApp Post model
+
+class Post < ActiveRecord::Base
+ include Blorgh::Concerns::Models::Post
+end
+
+
+# Blorgh/app/concerns/models/post
+
+module Blorg::Concerns::Models::Post
+ extend ActiveSupport::Concern
+
+ # 'included do' causes the code within to be evaluated in the conext
+ # where it is included, rather be executed in the module's context.
+ included do
+ attr_accessor :author_name
+ belongs_to :author, :class_name => "User"
+
+ before_save :set_author
+
+ private
+
+ def set_author
+ self.author = User.find_or_create_by_name(author_name)
+ end
+ end
+
+ # methods defined here will be instance methods by default
+ def some_method
+ 'some method string'
+ end
+
+ module ClassMethods
+ def some_class_method
+ 'some class method string'
+ end
+ end
+end
+</ruby>
+
h4. Overriding views
When Rails looks for a view to render, it will first look in the +app/views+ directory of the application. If it cannot find the view there, then it will check in the +app/views+ directories of all engines which have this directory.
diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile
index 8d7c0d4bea..22da369a2a 100644
--- a/guides/source/getting_started.textile
+++ b/guides/source/getting_started.textile
@@ -373,7 +373,7 @@ Edit the +form_for+ line inside +app/views/posts/new.html.erb+ to look like this
In this example, a +Hash+ object is passed to the +:url+ option. What Rails will do with this is that it will point the form to the +create+ action of the current controller, the +PostsController+, and will send a +POST+ request to that route. For this to work, you will need to add a route to +config/routes.rb+, right underneath the one for "posts/new":
<ruby>
-post "posts/create"
+post "posts" => "posts#create"
</ruby>
By using the +post+ method rather than the +get+ method, Rails will define a route that will only respond to POST methods. The POST method is the typical method used by forms all over the web.
@@ -1064,13 +1064,13 @@ received an error before.
<shell>
# rake routes
- posts GET /posts(.:format) posts#index
- posts_new GET /posts/new(.:format) posts#new
-posts_create POST /posts/create(.:format) posts#create
- GET /posts/:id(.:format) posts#show
- GET /posts/:id/edit(.:format) posts#edit
- PUT /posts/:id(.:format) posts#update
- root / welcome#index
+ posts GET /posts(.:format) posts#index
+posts_new GET /posts/new(.:format) posts#new
+ POST /posts(.:format) posts#create
+ GET /posts/:id(.:format) posts#show
+ GET /posts/:id/edit(.:format) posts#edit
+ PUT /posts/:id(.:format) posts#update
+ root / welcome#index
</shell>
To fix this, open +config/routes.rb+ and modify the +get "posts/:id"+
@@ -1175,7 +1175,7 @@ declaring separate routes with the appropriate verbs into
<ruby>
get "posts" => "posts#index"
get "posts/new"
-post "posts/create"
+post "posts" => "posts#create"
get "posts/:id" => "posts#show", :as => :post
get "posts/:id/edit" => "posts#edit"
put "posts/:id" => "posts#update"
diff --git a/guides/source/i18n.textile b/guides/source/i18n.textile
index 8ad6ee4b73..c782539399 100644
--- a/guides/source/i18n.textile
+++ b/guides/source/i18n.textile
@@ -405,6 +405,10 @@ So that would give you:
TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails' defaults for your locale*. See the "rails-i18n repository at Github":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use.
+h4. Inflection Rules For Other Locales
+
+Rails 4.0 allows you to define inflection rules (such as rules for singularization and pluralization) for locales other than English. In +config/initializers/inflections.rb+, you can define these rules for multiple locales. The initializer contains a default example for specifying additional rules for English; follow that format for other locales as you see fit.
+
h4. Localized Views
Rails 2.3 introduces another convenient localization feature: localized views (templates). Let's say you have a _BooksController_ in your application. Your _index_ action renders content in +app/views/books/index.html.erb+ template. When you put a _localized variant_ of this template: *+index.es.html.erb+* in the same directory, Rails will render content in this template, when the locale is set to +:es+. When the locale is set to the default locale, the generic +index.html.erb+ view will be used. (Future Rails versions may well bring this _automagic_ localization to assets in +public+, etc.)
diff --git a/guides/source/performance_testing.textile b/guides/source/performance_testing.textile
index 982fd1b070..b7d4f1ef33 100644
--- a/guides/source/performance_testing.textile
+++ b/guides/source/performance_testing.textile
@@ -1,40 +1,55 @@
h2. Performance Testing Rails Applications
-This guide covers the various ways of performance testing a Ruby on Rails application. By referring to this guide, you will be able to:
-
-* Understand the various types of benchmarking and profiling metrics
-* Generate performance and benchmarking tests
-* Install and use a GC-patched Ruby binary to measure memory usage and object allocation
-* Understand the benchmarking information provided by Rails inside the log files
-* Learn about various tools facilitating benchmarking and profiling
-
-Performance testing is an integral part of the development cycle. It is very important that you don't make your end users wait for too long before the page is completely loaded. Ensuring a pleasant browsing experience for end users and cutting the cost of unnecessary hardware is important for any non-trivial web application.
+This guide covers the various ways of performance testing a Ruby on Rails
+application. By referring to this guide, you will be able to:
+
+* Understand the various types of benchmarking and profiling metrics.
+* Generate performance and benchmarking tests.
+* Install and use a GC-patched Ruby binary to measure memory usage and object
+ allocation.
+* Understand the benchmarking information provided by Rails inside the log files.
+* Learn about various tools facilitating benchmarking and profiling.
+
+Performance testing is an integral part of the development cycle. It is very
+important that you don't make your end users wait for too long before the page
+is completely loaded. Ensuring a pleasant browsing experience for end users and
+cutting the cost of unnecessary hardware is important for any non-trivial web
+application.
endprologue.
h3. Performance Test Cases
-Rails performance tests are a special type of integration tests, designed for benchmarking and profiling the test code. With performance tests, you can determine where your application's memory or speed problems are coming from, and get a more in-depth picture of those problems.
+Rails performance tests are a special type of integration tests, designed for
+benchmarking and profiling the test code. With performance tests, you can
+determine where your application's memory or speed problems are coming from,
+and get a more in-depth picture of those problems.
-In a freshly generated Rails application, +test/performance/browsing_test.rb+ contains an example of a performance test:
+In a freshly generated Rails application, +test/performance/browsing_test.rb+
+contains an example of a performance test:
<ruby>
require 'test_helper'
require 'rails/performance_test_help'
-# Profiling results for each test method are written to tmp/performance.
class BrowsingTest < ActionDispatch::PerformanceTest
- def test_homepage
+ # Refer to the documentation for all available options
+ # self.profile_options = { runs: 5, metrics: [:wall_time, :memory],
+ # output: 'tmp/performance', formats: [:flat] }
+
+ test "homepage" do
get '/'
end
end
</ruby>
-This example is a simple performance test case for profiling a GET request to the application's homepage.
+This example is a simple performance test case for profiling a GET request to
+the application's homepage.
h4. Generating Performance Tests
-Rails provides a generator called +performance_test+ for creating new performance tests:
+Rails provides a generator called +performance_test+ for creating new
+performance tests:
<shell>
$ rails generate performance_test homepage
@@ -47,8 +62,11 @@ require 'test_helper'
require 'rails/performance_test_help'
class HomepageTest < ActionDispatch::PerformanceTest
- # Replace this with your real tests.
- def test_homepage
+ # Refer to the documentation for all available options
+ # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory],
+ # :output => 'tmp/performance', :formats => [:flat] }
+
+ test "homepage" do
get '/'
end
end
@@ -60,7 +78,7 @@ Let's assume your application has the following controller and model:
<ruby>
# routes.rb
-root :to => 'home#index'
+root to: 'home#dashboard'
resources :posts
# home_controller.rb
@@ -97,9 +115,11 @@ end
h5. Controller Example
-Because performance tests are a special kind of integration test, you can use the +get+ and +post+ methods in them.
+Because performance tests are a special kind of integration test, you can use
+the +get+ and +post+ methods in them.
-Here's the performance test for +HomeController#dashboard+ and +PostsController#create+:
+Here's the performance test for +HomeController#dashboard+ and
++PostsController#create+:
<ruby>
require 'test_helper'
@@ -111,21 +131,24 @@ class PostPerformanceTest < ActionDispatch::PerformanceTest
login_as(:lifo)
end
- def test_homepage
+ test "homepage" do
get '/dashboard'
end
- def test_creating_new_post
- post '/posts', :post => { :body => 'lifo is fooling you' }
+ test "creating new post" do
+ post '/posts', post: { body: 'lifo is fooling you' }
end
end
</ruby>
-You can find more details about the +get+ and +post+ methods in the "Testing Rails Applications":testing.html guide.
+You can find more details about the +get+ and +post+ methods in the
+"Testing Rails Applications":testing.html guide.
h5. Model Example
-Even though the performance tests are integration tests and hence closer to the request/response cycle by nature, you can still performance test pure model code.
+Even though the performance tests are integration tests and hence closer to
+the request/response cycle by nature, you can still performance test pure model
+code.
Performance test for +Post+ model:
@@ -134,11 +157,11 @@ require 'test_helper'
require 'rails/performance_test_help'
class PostModelTest < ActionDispatch::PerformanceTest
- def test_creation
- Post.create :body => 'still fooling you', :cost => '100'
+ test "creation" do
+ Post.create body: 'still fooling you', cost: '100'
end
- def test_slow_method
+ test "slow method" do
# Using posts(:awesome) fixture
posts(:awesome).slow_method
end
@@ -151,7 +174,8 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
h5. Benchmarking
-Benchmarking makes it easy to quickly gather a few metrics about each test run. By default, each test case is run *4 times* in benchmarking mode.
+Benchmarking makes it easy to quickly gather a few metrics about each test run.
+By default, each test case is run *4 times* in benchmarking mode.
To run performance tests in benchmarking mode:
@@ -161,7 +185,10 @@ $ rake test:benchmark
h5. Profiling
-Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run *once* in profiling mode.
+Profiling allows you to make an in-depth analysis of each of your tests by using
+an external profiler. Depending on your Ruby interpreter, this profiler can be
+native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each
+test case is run *once* in profiling mode.
To run performance tests in profiling mode:
@@ -171,23 +198,33 @@ $ rake test:profile
h4. Metrics
-Benchmarking and profiling run performance tests and give you multiple metrics. The availability of each metric is determined by the interpreter being used—none of them support all metrics—and by the mode in use. A brief description of each metric and their availability across interpreters/modes is given below.
+Benchmarking and profiling run performance tests and give you multiple metrics.
+The availability of each metric is determined by the interpreter being used—none
+of them support all metrics—and by the mode in use. A brief description of each
+metric and their availability across interpreters/modes is given below.
h5. Wall Time
-Wall time measures the real world time elapsed during the test run. It is affected by any other processes concurrently running on the system.
+Wall time measures the real world time elapsed during the test run. It is
+affected by any other processes concurrently running on the system.
h5. Process Time
-Process time measures the time taken by the process. It is unaffected by any other processes running concurrently on the same system. Hence, process time is likely to be constant for any given performance test, irrespective of the machine load.
+Process time measures the time taken by the process. It is unaffected by any
+other processes running concurrently on the same system. Hence, process time
+is likely to be constant for any given performance test, irrespective of the
+machine load.
h5. CPU Time
-Similar to process time, but leverages the more accurate CPU clock counter available on the Pentium and PowerPC platforms.
+Similar to process time, but leverages the more accurate CPU clock counter
+available on the Pentium and PowerPC platforms.
h5. User Time
-User time measures the amount of time the CPU spent in user-mode, i.e. within the process. This is not affected by other processes and by the time it possibly spends blocked.
+User time measures the amount of time the CPU spent in user-mode, i.e. within
+the process. This is not affected by other processes and by the time it possibly
+spends blocked.
h5. Memory
@@ -223,11 +260,13 @@ h6(#profiling_1). Profiling
|_.Rubinius | yes | no | no | no | no | no | no | no |
|_.JRuby | yes | no | no | no | no | no | no | no |
-NOTE: To profile under JRuby you'll need to run +export JRUBY_OPTS="-Xlaunch.inproc=false --profile.api"+ *before* the performance tests.
+NOTE: To profile under JRuby you'll need to run +export JRUBY_OPTS="-Xlaunch.inproc=false --profile.api"+
+*before* the performance tests.
h4. Understanding the Output
-Performance tests generate different outputs inside +tmp/performance+ directory depending on their mode and metric.
+Performance tests generate different outputs inside +tmp/performance+ directory
+depending on their mode and metric.
h5(#output-benchmarking). Benchmarking
@@ -248,7 +287,9 @@ BrowsingTest#test_homepage (31 ms warmup)
h6. CSV Files
-Performance test results are also appended to +.csv+ files inside +tmp/performance+. For example, running the default +BrowsingTest#test_homepage+ will generate following five files:
+Performance test results are also appended to +.csv+ files inside +tmp/performance+.
+For example, running the default +BrowsingTest#test_homepage+ will generate
+following five files:
* BrowsingTest#test_homepage_gc_runs.csv
* BrowsingTest#test_homepage_gc_time.csv
@@ -256,7 +297,9 @@ Performance test results are also appended to +.csv+ files inside +tmp/performan
* BrowsingTest#test_homepage_objects.csv
* BrowsingTest#test_homepage_wall_time.csv
-As the results are appended to these files each time the performance tests are run in benchmarking mode, you can collect data over a period of time. This can be very helpful in analyzing the effects of code changes.
+As the results are appended to these files each time the performance tests are
+run in benchmarking mode, you can collect data over a period of time. This can
+be very helpful in analyzing the effects of code changes.
Sample output of +BrowsingTest#test_homepage_wall_time.csv+:
@@ -276,7 +319,10 @@ measurement,created_at,app,rails,ruby,platform
h5(#output-profiling). Profiling
-In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependent on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
+In profiling mode, performance tests can generate multiple types of outputs.
+The command line output is always presented but support for the others is
+dependent on the interpreter in use. A brief description of each type and
+their availability across interpreters is given below.
h6. Command Line
@@ -291,15 +337,18 @@ BrowsingTest#test_homepage (58 ms warmup)
h6. Flat
-Flat output shows the metric—time, memory, etc—measure in each method. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/flat_txt.html.
+Flat output shows the metric—time, memory, etc—measure in each method.
+"Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/flat_txt.html.
h6. Graph
-Graph output shows the metric measure in each method, which methods call it and which methods it calls. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/graph_txt.html.
+Graph output shows the metric measure in each method, which methods call it and
+which methods it calls. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/graph_txt.html.
h6. Tree
-Tree output is profiling information in calltree format for use by "kcachegrind":http://kcachegrind.sourceforge.net/html/Home.html and similar tools.
+Tree output is profiling information in calltree format for use by "kcachegrind":http://kcachegrind.sourceforge.net/html/Home.html
+and similar tools.
h6. Output Availability
@@ -311,24 +360,24 @@ h6. Output Availability
h4. Tuning Test Runs
-Test runs can be tuned by setting the +profile_options+ class variable on your test class.
+Test runs can be tuned by setting the +profile_options+ class variable on your
+test class.
<ruby>
require 'test_helper'
require 'rails/performance_test_help'
-# Profiling results for each test method are written to tmp/performance.
class BrowsingTest < ActionDispatch::PerformanceTest
- self.profile_options = { :runs => 5,
- :metrics => [:wall_time, :memory] }
+ self.profile_options = { runs: 5, metrics: [:wall_time, :memory] }
- def test_homepage
+ test "homepage"
get '/'
end
end
</ruby>
-In this example, the test would run 5 times and measure wall time and memory. There are a few configurable options:
+In this example, the test would run 5 times and measure wall time and memory.
+There are a few configurable options:
|_.Option |_.Description|_.Default|_.Mode|
|+:runs+ |Number of runs.|Benchmarking: 4, Profiling: 1|Both|
@@ -346,11 +395,13 @@ Metrics and formats have different defaults depending on the interpreter in use.
|/2.JRuby |Benchmarking|+[:wall_time, :user_time, :memory, :gc_runs, :gc_time]+|N/A|
|Profiling |+[:wall_time]+|+[:flat, :graph]+|
-As you've probably noticed by now, metrics and formats are specified using a symbol array with each name "underscored.":http://api.rubyonrails.org/classes/String.html#method-i-underscore
+As you've probably noticed by now, metrics and formats are specified using a
+symbol array with each name "underscored.":http://api.rubyonrails.org/classes/String.html#method-i-underscore
h4. Performance Test Environment
-Performance tests are run in the +test+ environment. But running performance tests will set the following configuration parameters:
+Performance tests are run in the +test+ environment. But running performance
+tests will set the following configuration parameters:
<shell>
ActionController::Base.perform_caching = true
@@ -358,11 +409,13 @@ ActiveSupport::Dependencies.mechanism = :require
Rails.logger.level = ActiveSupport::BufferedLogger::INFO
</shell>
-As +ActionController::Base.perform_caching+ is set to +true+, performance tests will behave much as they do in the +production+ environment.
+As +ActionController::Base.perform_caching+ is set to +true+, performance tests
+will behave much as they do in the +production+ environment.
h4. Installing GC-Patched MRI
-To get the best from Rails' performance tests under MRI, you'll need to build a special Ruby binary with some super powers.
+To get the best from Rails' performance tests under MRI, you'll need to build
+a special Ruby binary with some super powers.
The recommended patches for each MRI version are:
@@ -371,13 +424,18 @@ The recommended patches for each MRI version are:
|1.8.7|ruby187gc|
|1.9.2 and above|gcdata|
-All of these can be found on "RVM's _patches_ directory":https://github.com/wayneeseguin/rvm/tree/master/patches/ruby under each specific interpreter version.
+All of these can be found on "RVM's _patches_ directory":https://github.com/wayneeseguin/rvm/tree/master/patches/ruby
+under each specific interpreter version.
-Concerning the installation itself, you can either do this easily by using "RVM":http://rvm.beginrescueend.com or you can build everything from source, which is a little bit harder.
+Concerning the installation itself, you can either do this easily by using
+"RVM":http://rvm.beginrescueend.com or you can build everything from source,
+which is a little bit harder.
h5. Install Using RVM
-The process of installing a patched Ruby interpreter is very easy if you let RVM do the hard work. All of the following RVM commands will provide you with a patched Ruby interpreter:
+The process of installing a patched Ruby interpreter is very easy if you let RVM
+do the hard work. All of the following RVM commands will provide you with a
+patched Ruby interpreter:
<shell>
$ rvm install 1.9.2-p180 --patch gcdata
@@ -385,7 +443,8 @@ $ rvm install 1.8.7 --patch ruby187gc
$ rvm install 1.9.2-p180 --patch ~/Downloads/downloaded_gcdata_patch.patch
</shell>
-You can even keep your regular interpreter by assigning a name to the patched one:
+You can even keep your regular interpreter by assigning a name to the patched
+one:
<shell>
$ rvm install 1.9.2-p180 --patch gcdata --name gcdata
@@ -397,7 +456,9 @@ And it's done! You have installed a patched Ruby interpreter.
h5. Install From Source
-This process is a bit more complicated, but straightforward nonetheless. If you've never compiled a Ruby binary before, follow these steps to build a Ruby binary inside your home directory.
+This process is a bit more complicated, but straightforward nonetheless. If
+you've never compiled a Ruby binary before, follow these steps to build a
+Ruby binary inside your home directory.
h6. Download and Extract
@@ -417,7 +478,9 @@ $ curl http://github.com/wayneeseguin/rvm/raw/master/patches/ruby/1.8.7/ruby187g
h6. Configure and Install
-The following will install Ruby in your home directory's +/rubygc+ directory. Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home directory.
+The following will install Ruby in your home directory's +/rubygc+ directory.
+Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home
+directory.
<shell>
$ ./configure --prefix=/<homedir>/rubygc
@@ -438,23 +501,22 @@ alias gcrails='~/rubygc/bin/rails'
Don't forget to use your aliases from now on.
-h6. Install RubyGems (1.8 only!)
-
-Download "RubyGems":http://rubyforge.org/projects/rubygems and install it from source. Rubygem's README file should have necessary installation instructions. Please note that this step isn't necessary if you've installed Ruby 1.9 and above.
-
h4. Using Ruby-Prof on MRI and REE
-Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile under MRI or REE:
+Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile
+under MRI or REE:
<ruby>
-gem 'ruby-prof', :git => 'git://github.com/wycats/ruby-prof.git'
+gem 'ruby-prof', git: 'git://github.com/wycats/ruby-prof.git'
</ruby>
Now run +bundle install+ and you're ready to go.
h3. Command Line Tools
-Writing performance test cases could be an overkill when you are looking for one time tests. Rails ships with two command line tools that enable quick and dirty performance testing:
+Writing performance test cases could be an overkill when you are looking for one
+time tests. Rails ships with two command line tools that enable quick and dirty
+performance testing:
h4. +benchmarker+
@@ -498,11 +560,14 @@ Example:
$ rails profiler 'Item.all' 'CouchItem.all' --runs 2 --metrics process_time --formats flat
</shell>
-NOTE: Metrics and formats vary from interpreter to interpreter. Pass +--help+ to each tool to see the defaults for your interpreter.
+NOTE: Metrics and formats vary from interpreter to interpreter. Pass +--help+ to
+each tool to see the defaults for your interpreter.
h3. Helper Methods
-Rails provides various helper methods inside Active Record, Action Controller and Action View to measure the time taken by a given piece of code. The method is called +benchmark()+ in all the three components.
+Rails provides various helper methods inside Active Record, Action Controller
+and Action View to measure the time taken by a given piece of code. The method
+is called +benchmark()+ in all the three components.
h4. Model
@@ -514,17 +579,19 @@ Project.benchmark("Creating project") do
end
</ruby>
-This benchmarks the code enclosed in the +Project.benchmark("Creating project") do...end+ block and prints the result to the log file:
+This benchmarks the code enclosed in the +Project.benchmark("Creating project") do...end+
+block and prints the result to the log file:
<ruby>
Creating project (185.3ms)
</ruby>
-Please refer to the "API docs":http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001336 for additional options to +benchmark()+
+Please refer to the "API docs":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html#method-i-benchmark
+for additional options to +benchmark()+.
h4. Controller
-Similarly, you could use this helper method inside "controllers":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html
+Similarly, you could use this helper method inside "controllers.":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html
<ruby>
def process_projects
@@ -535,7 +602,7 @@ def process_projects
end
</ruby>
-NOTE: +benchmark+ is a class method inside controllers
+NOTE: +benchmark+ is a class method inside controllers.
h4. View
@@ -549,7 +616,8 @@ And in "views":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.ht
h3. Request Logging
-Rails log files contain very useful information about the time taken to serve each request. Here's a typical log file entry:
+Rails log files contain very useful information about the time taken to serve
+each request. Here's a typical log file entry:
<shell>
Processing ItemsController#index (for 127.0.0.1 at 2009-01-08 03:06:39) [GET]
@@ -564,9 +632,14 @@ For this section, we're only interested in the last line:
Completed in 5ms (View: 2, DB: 0) | 200 OK [http://0.0.0.0/items]
</shell>
-This data is fairly straightforward to understand. Rails uses millisecond(ms) as the metric to measure the time taken. The complete request spent 5 ms inside Rails, out of which 2 ms were spent rendering views and none was spent communication with the database. It's safe to assume that the remaining 3 ms were spent inside the controller.
+This data is fairly straightforward to understand. Rails uses millisecond(ms) as
+the metric to measure the time taken. The complete request spent 5 ms inside
+Rails, out of which 2 ms were spent rendering views and none was spent
+communication with the database. It's safe to assume that the remaining 3 ms
+were spent inside the controller.
-Michael Koziarski has an "interesting blog post":http://www.therailsway.com/2009/1/6/requests-per-second explaining the importance of using milliseconds as the metric.
+Michael Koziarski has an "interesting blog post":http://www.therailsway.com/2009/1/6/requests-per-second
+explaining the importance of using milliseconds as the metric.
h3. Useful Links
@@ -587,11 +660,12 @@ h4. Generic Tools
h4. Tutorials and Documentation
* "ruby-prof API Documentation":http://ruby-prof.rubyforge.org
-* "Request Profiling Railscast":http://railscasts.com/episodes/98-request-profiling - Outdated, but useful for understanding call graphs
+* "Request Profiling Railscast":http://railscasts.com/episodes/98-request-profiling - Outdated, but useful for understanding call graphs.
h3. Commercial Products
-Rails has been lucky to have a few companies dedicated to Rails-specific performance tools. A couple of those are:
+Rails has been lucky to have a few companies dedicated to Rails-specific
+performance tools. A couple of those are:
* "New Relic":http://www.newrelic.com
-* "Scout":http://scoutapp.com
+* "Scout":http://scoutapp.com \ No newline at end of file
diff --git a/guides/source/routing.textile b/guides/source/routing.textile
index cffbf9bec4..bed7d03e06 100644
--- a/guides/source/routing.textile
+++ b/guides/source/routing.textile
@@ -273,6 +273,36 @@ The corresponding route helper would be +publisher_magazine_photo_url+, requirin
TIP: _Resources should never be nested more than 1 level deep._
+h4. Routing concerns
+
+Routing Concerns allows you to declare common routes that can be reused inside others resources and routes.
+
+<ruby>
+concern :commentable do
+ resources :comments
+end
+
+concern :image_attachable do
+ resources :images, only: :index
+end
+</ruby>
+
+These concerns can be used in resources to avoid code duplication and share behavior across routes.
+
+<ruby>
+resources :messages, concerns: :commentable
+
+resources :posts, concerns: [:commentable, :image_attachable]
+</ruby>
+
+Also you can use them in any place that you want inside the routes, for example in a scope or namespace call:
+
+<ruby>
+namespace :posts do
+ concerns :commentable
+end
+</ruby>
+
h4. Creating Paths and URLs From Objects
In addition to using the routing helpers, Rails can also create paths and URLs from an array of parameters. For example, suppose you have this set of routes:
diff --git a/guides/source/security.textile b/guides/source/security.textile
index 8879122b66..49e5da6bb7 100644
--- a/guides/source/security.textile
+++ b/guides/source/security.textile
@@ -608,7 +608,7 @@ This URL passes the filter because the regular expression matches – the second
link_to "Homepage", @user.homepage
</ruby>
-The link looks innocent to visitors, but when it's clicked, it will execute the javascript function "exploit_code" or any other javascript the attacker provides.
+The link looks innocent to visitors, but when it's clicked, it will execute the JavaScript function "exploit_code" or any other JavaScript the attacker provides.
To fix the regular expression, \A and \z should be used instead of ^ and $, like so:
diff --git a/guides/source/upgrading_ruby_on_rails.textile b/guides/source/upgrading_ruby_on_rails.textile
index 4bf4751127..5024bc4c37 100644
--- a/guides/source/upgrading_ruby_on_rails.textile
+++ b/guides/source/upgrading_ruby_on_rails.textile
@@ -42,6 +42,8 @@ h4(#active_record4_0). Active Record
The <tt>delete</tt> method in collection associations can now receive <tt>Fixnum</tt> or <tt>String</tt> arguments as record ids, besides records, pretty much like the <tt>destroy</tt> method does. Previously it raised <tt>ActiveRecord::AssociationTypeMismatch</tt> for such arguments. From Rails 4.0 on <tt>delete</tt> automatically tries to find the records matching the given ids before deleting them.
+Rails 4.0 has changed how orders get stacked in +ActiveRecord::Relation+. In previous versions of rails new order was applied after previous defined order. But this is no long true. Check "ActiveRecord Query guide":active_record_querying.html#ordering for more information.
+
h4(#active_model4_0). Active Model
Rails 4.0 has changed how errors attach with the <tt>ActiveModel::Validations::ConfirmationValidator</tt>. Now when confirmation validations fail the error will be attached to <tt>:#{attribute}_confirmation</tt> instead of <tt>attribute</tt>.