diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/action_view_overview.textile | 2 | ||||
-rw-r--r-- | guides/source/active_record_querying.textile | 9 | ||||
-rw-r--r-- | guides/source/ajax_on_rails.textile | 2 | ||||
-rw-r--r-- | guides/source/asset_pipeline.textile | 12 | ||||
-rw-r--r-- | guides/source/association_basics.textile | 577 | ||||
-rw-r--r-- | guides/source/command_line.textile | 49 | ||||
-rw-r--r-- | guides/source/configuring.textile | 4 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.textile | 2 | ||||
-rw-r--r-- | guides/source/engines.textile | 78 | ||||
-rw-r--r-- | guides/source/getting_started.textile | 18 | ||||
-rw-r--r-- | guides/source/i18n.textile | 4 | ||||
-rw-r--r-- | guides/source/performance_testing.textile | 230 | ||||
-rw-r--r-- | guides/source/security.textile | 2 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.textile | 2 |
14 files changed, 619 insertions, 372 deletions
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 b13932e8cb..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 *+. 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..42b5d102e7 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. @@ -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..2b8b1bd937 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,16 +965,6 @@ 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+. @@ -985,30 +984,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, -> { 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, :include => :representative + has_one :account end class Account < ActiveRecord::Base @@ -1021,51 +1064,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 +1278,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 +1305,124 @@ class Customer < ActiveRecord::Base end </ruby> -h6(#has_many-conditions). +:conditions+ +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. + +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. -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+ + +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. -If you need to evaluate conditions dynamically at runtime, use a proc: +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. - -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. +You can use any of the standard "querying methods":active_record_querying.html inside the scope block. The following ones are discussed below: -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 +1443,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 +1456,45 @@ class LineItem < ActiveRecord::Base end </ruby> -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 :orders, :inverse_of => :customer -end - -class Order < ActiveRecord::Base - belongs_to :customer, :inverse_of => :orders -end -</ruby> - -h6(#has_many-limit). +:limit+ +h6(#has_many-limit). +limit+ -The +:limit+ option lets you restrict the total number of objects that will be fetched through an association. +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 :recent_orders, :class_name => "Order", - :order => "order_date DESC", :limit => 100 + has_many :recent_orders, + -> { order('order_date desc').limit(100) }, + :class_name => "Order", end </ruby> -h6(#has_many-offset). +:offset+ +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. +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. -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+ - -If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association. - -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. - -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-readonly). +readonly+ -h6(#has_many-source_type). +:source_type+ +If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association. -The +:source_type+ option specifies the source association type for a +has_many :through+ association that proceeds through a polymorphic association. +h6(#has_many-select). +select+ -h6(#has_many-through). +:through+ +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. -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>. +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-uniq). +:uniq+ +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 +1512,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 +1530,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 +1715,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 +1747,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+ - -You can use the +:include+ option to specify second-order associations that should be eager-loaded when this association is used. +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". -h6(#has_and_belongs_to_many-join_table). +:join_table+ +h6(#has_and_belongs_to_many-extending). +extending+ -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. +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>. -h6(#has_and_belongs_to_many-limit). +:limit+ +h6(#has_and_belongs_to_many-group). +group+ -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+ -If you set the +:readonly+ option to +true+, then the associated objects will be read-only when retrieved via the association. +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. -h6(#has_and_belongs_to_many-select). +:select+ +h6(#has_and_belongs_to_many-order). +order+ -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 +order+ method dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause). -h6(#has_and_belongs_to_many-uniq). +:uniq+ +<ruby> +class Parts < ActiveRecord::Base + has_and_belongs_to_many :assemblies, + -> { order "assembly_name ASC" } +end +</ruby> -Specify the +:uniq => true+ option to remove duplicates from the collection. +h6(#has_and_belongs_to_many-readonly). +readonly+ -h6(#has_and_belongs_to_many-validate). +:validate+ +If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association. -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. +h6(#has_and_belongs_to_many-select). +select+ + +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 +1946,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..cc5c352df4 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+. diff --git a/guides/source/contributing_to_ruby_on_rails.textile b/guides/source/contributing_to_ruby_on_rails.textile index a8a097d156..dd43ef795f 100644 --- a/guides/source/contributing_to_ruby_on_rails.textile +++ b/guides/source/contributing_to_ruby_on_rails.textile @@ -215,7 +215,7 @@ 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. You can now run the tests as you did for +sqlite3+. The tasks are respectively 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 +<homedir>+ 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 +<homedir>+ 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/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>. |