diff options
Diffstat (limited to 'railties/guides/source')
29 files changed, 949 insertions, 805 deletions
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index b064851312..7703d6c720 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -165,7 +165,7 @@ will produce <em>emphasized</em> <em><b>emph & bold</b></em> <a href="http://rubyonrails.org">A link</a> -<target option="fast" name="compile" \> +<target option="fast" name="compile" /> </html> Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following: @@ -211,7 +211,7 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do end </ruby> -h5. Template caching +h5. Template Caching By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode. @@ -235,7 +235,7 @@ This will render a file named +_menu.html.erb+ at that point within the view is That code will pull in the partial from +app/views/shared/_menu.html.erb+. -h5. Using Partials to Simplify Views +h5. Using Partials to simplify Views One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this: @@ -929,7 +929,7 @@ Creates a scope around a specific model object like form_for, but doesn‘t crea h5. file_field -Returns an file upload input tag tailored for accessing a specified attribute. +Returns a file upload input tag tailored for accessing a specified attribute. <ruby> file_field(:user, :avatar) @@ -1037,7 +1037,7 @@ Sample usage (selecting the associated Author for an instance of Post, +@post+): collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true}) </ruby> -If @post.author_id is already 1, this would return: +If <tt>@post.author_id</tt> is 1, this would return: <html> <select name="post[author_id]"> @@ -1080,8 +1080,6 @@ Sample usage: option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3) </ruby> -TODO check above textile output looks right - Possible output: <html> @@ -1132,13 +1130,13 @@ h5. select Create a select tag and a series of contained option tags for the provided object and method. -Example with @post.person_id => 1: +Example: <ruby> select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true }) </ruby> -could become: +If <tt>@post.person_id</tt> is 1, this would become: <html> <select name="post[person_id]"> @@ -1189,7 +1187,7 @@ h5. file_field_tag Creates a file upload field. -If you are using file uploads then you will also need to set the multipart option for the form tag: +Prior to Rails 3.1, if you are using file uploads, then you will need to set the multipart option for the form tag. Rails 3.1+ does this automatically. <ruby> <%= form_tag { :action => "post" }, { :multipart => true } do %> @@ -1400,102 +1398,6 @@ number_with_precision(111.2345) # => 111.235 number_with_precision(111.2345, 2) # => 111.23 </ruby> -h5. evaluate_remote_response - -Returns +eval(request.responseText)+ which is the JavaScript function that form_remote_tag can call in +:complete+ to evaluate a multiple update return document using +update_element_function+ calls. - -h5. form_remote_tag - -Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement. Even though it‘s using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side. - -For example, this: - -<ruby> -form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") } -</ruby> - -would generate the following: - -<html> -<form action="/some/place" method="post" onsubmit="new Ajax.Request('', - {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> -</html> - -h5. link_to_remote - -Returns a link to a remote action that's called in the background using XMLHttpRequest. You can generate a link that uses AJAX in the general case, while degrading gracefully to plain link behavior in the absence of JavaScript. For example: - -<ruby> -link_to_remote "Delete this post", - { :update => "posts", :url => { :action => "destroy", :id => post.id } }, - :href => url_for(:action => "destroy", :id => post.id) -</ruby> - -h5. observe_field - -Observes the field specified and calls a callback when its contents have changed. - -<ruby> -observe_field("my_field", :function => "alert('Field changed')") -</ruby> - -h5. observe_form - -Observes the form specified and calls a callback when its contents have changed. The options for observe_form are the same as the options for observe_field. - -<ruby> -observe_field("my_form", :function => "alert('Form changed')") -</ruby> - -h5. periodically_call_remote - -Periodically calls the specified url as often as specified. Usually used to update a specified div with the results of the remote call. The following example will call update every 20 seconds and update the news_block div: - -<ruby> -periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block') -# => PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20) -</ruby> - -h5. remote_form_for - -Creates a form that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement and a scope around a specific resource that is used as a base for questioning about values for the fields. - -<ruby> -<%= remote_form_for(@post) do |f| %> - ... -<% end %> -</ruby> - -h5. remote_function - -Returns the JavaScript needed for a remote function. Takes the same arguments as +link_to_remote+. - -<ruby> -<select id="options" onchange="<%= remote_function(:update => "options", :url => { :action => :update_options }) %>"> - <option value="0">Hello</option> - <option value="1">World</option> -</select> -# => <select id="options" onchange="new Ajax.Updater('options', '/testing/update_options', {asynchronous:true, evalScripts:true})"> -</ruby> - -h5. submit_to_remote - -Returns a button input tag that will submit form using XMLHttpRequest in the background instead of a regular POST request that reloads the page. - -For example, the following: - -<ruby> -submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } -</ruby> - -would generate: - -<html> -<input name="create_btn" onclick="new Ajax.Request('/testing/create', - {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); - return false;" type="button" value="Create" /> -</html> - h3. Localized Views Action View has the ability render different templates depending on the current locale. @@ -1520,6 +1422,7 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht 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_record_basics.textile b/railties/guides/source/active_record_basics.textile index b7926f3a3b..3e46e7df9f 100644 --- a/railties/guides/source/active_record_basics.textile +++ b/railties/guides/source/active_record_basics.textile @@ -64,8 +64,8 @@ There are also some optional column names that will create additional features t * *created_on* - Automatically gets set to the current date when the record is first created. * *updated_at* - Automatically gets set to the current date and time whenever the record is updated. * *updated_on* - Automatically gets set to the current date whenever the record is updated. -* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.com/classes/ActiveRecord/Locking.html to a model. -* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.com/classes/ActiveRecord/Base.html +* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.org/classes/ActiveRecord/Locking.html to a model. +* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.org/classes/ActiveRecord/Base.html * *(table_name)_count* - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post. NOTE: While these column names are optional they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling. diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index 579a323d57..e3871a3c34 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -57,6 +57,7 @@ The methods are: * +group+ * +order+ * +reorder+ +* +reverse_order+ * +limit+ * +offset+ * +joins+ @@ -483,16 +484,16 @@ SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You For example: <ruby> -Order.group("date(created_at)").having("created_at > ?", 1.month.ago) +Order.group("date(created_at)").having("created_at < ?", 1.month.ago) </ruby> The SQL that would be executed would be something like this: <sql> -SELECT * FROM orders GROUP BY date(created_at) HAVING created_at > '2009-01-15' +SELECT * FROM orders GROUP BY date(created_at) HAVING created_at < '2011-04-27' </sql> -This will return single order objects for each day, but only for the last month. +This will return single order objects for each day, but only those that are at least one month old. h3. Overriding Conditions @@ -550,6 +551,32 @@ In case the +reorder+ clause is not used, the SQL executed would be: SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC </sql> +h4. +reverse_order+ + +The +reverse_order+ method reverses the ordering clause if specified. + +<ruby> +Client.where("orders_count > 10").order(:name).reverse_order +</ruby> + +The SQL that would be executed: +<sql> +SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC +</sql> + +If no ordering clause is specified in the query, the +reverse_order+ orders by the primary key in reverse order. + +<ruby> +Client.where("orders_count > 10").reverse_order +</ruby> + +The SQL that would be executed: +<sql> +SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC +</sql> + +This method accepts *no* arguments. + h3. Readonly Objects Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception. @@ -675,7 +702,7 @@ class Post < ActiveRecord::Base has_many :tags end -class Comments < ActiveRecord::Base +class Comment < ActiveRecord::Base belongs_to :post has_one :guest end @@ -683,6 +710,10 @@ end class Guest < ActiveRecord::Base belongs_to :comment end + +class Tag < ActiveRecord::Base + belongs_to :post +end </ruby> Now all of the following will produce the expected join queries using +INNER JOIN+: @@ -700,6 +731,8 @@ SELECT categories.* FROM categories INNER JOIN posts ON posts.category_id = categories.id </sql> +Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)"). + h5. Joining Multiple Associations <ruby> @@ -714,18 +747,40 @@ SELECT posts.* FROM posts INNER JOIN comments ON comments.post_id = posts.id </sql> +Or, in English: "return all posts that have a category and at least one comment". Note again that posts with multiple comments will show up multiple times. + h5. Joining Nested Associations (Single Level) <ruby> Post.joins(:comments => :guest) </ruby> +This produces: + +<sql> +SELECT posts.* FROM posts + INNER JOIN comments ON comments.post_id = posts.id + INNER JOIN guests ON guests.comment_id = comments.id +</sql> + +Or, in English: "return all posts that have a comment made by a guest." + h5. Joining Nested Associations (Multiple Level) <ruby> Category.joins(:posts => [{:comments => :guest}, :tags]) </ruby> +This produces: + +<sql> +SELECT categories.* FROM categories + INNER JOIN posts ON posts.category_id = categories.id + INNER JOIN comments ON comments.post_id = posts.id + INNER JOIN guests ON guests.comment_id = comments.id + INNER JOIN tags ON tags.post_id = posts.id +</sql> + h4. Specifying Conditions on the Joined Tables You can specify conditions on the joined tables using the regular "Array":#array-conditions and "String":#pure-string-conditions conditions. "Hash conditions":#hash-conditions provides a special syntax for specifying conditions for the joined tables: diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile index 9f59397d7d..50ff1c9ff7 100644 --- a/railties/guides/source/active_record_validations_callbacks.textile +++ b/railties/guides/source/active_record_validations_callbacks.textile @@ -82,6 +82,7 @@ The following methods skip validations, and will save the object to the database * +increment!+ * +increment_counter+ * +toggle!+ +* +touch+ * +update_all+ * +update_attribute+ * +update_column+ @@ -181,7 +182,7 @@ It can receive an +:accept+ option, which determines the value that will be cons <ruby> class Person < ActiveRecord::Base - validates :terms_of_service, :acceptance => true, :accept => 'yes' + validates :terms_of_service, :acceptance => { :accept => 'yes' } end </ruby> @@ -337,7 +338,7 @@ WARNING. Note that the regular expression above allows a trailing newline charac <ruby> class Player < ActiveRecord::Base validates :points, :numericality => true - validates :games_played, :numericality => true, :only_integer => true + validates :games_played, :numericality => { :only_integer => true } end </ruby> @@ -392,8 +393,8 @@ There is a +:scope+ option that you can use to specify other attributes that are <ruby> class Holiday < ActiveRecord::Base - validates :name, :uniqueness => true, :scope => :year, - :message => "should happen once per year" + validates :name, :uniqueness => { :scope => :year, + :message => "should happen once per year" } end </ruby> @@ -401,7 +402,7 @@ There is also a +:case_sensitive+ option that you can use to define whether the <ruby> class Person < ActiveRecord::Base - validates :name, :uniqueness => true, :case_sensitive => false + validates :name, :uniqueness => { :case_sensitive => false } end </ruby> @@ -429,7 +430,7 @@ end The +validates_with+ helper takes a class, or a list of classes to use for validation. There is no default error message for +validates_with+. You must manually add errors to the record's errors collection in the validator class. -To implement the validate method, you must have an +record+ parameter defined, which is the record to be validated. +To implement the validate method, you must have a +record+ parameter defined, which is the record to be validated. Like all other validations, +validates_with+ takes the +:if+, +:unless+ and +:on+ options. If you pass any other options, it will send those options to the validator class as +options+: @@ -911,20 +912,20 @@ h4. Creating an Object * +before_validation+ * +after_validation+ * +before_save+ -* +after_save+ * +before_create+ * +around_create+ * +after_create+ +* +after_save+ h4. Updating an Object * +before_validation+ * +after_validation+ * +before_save+ -* +after_save+ * +before_update+ * +around_update+ * +after_update+ +* +after_save+ h4. Destroying an Object @@ -1007,6 +1008,7 @@ Just as with validations, it's also possible to skip callbacks. These methods sh * +increment+ * +increment_counter+ * +toggle+ +* +touch+ * +update_column+ * +update_all+ * +update_counters+ diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 43aa6dfbbb..bbf5af5dcc 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -868,7 +868,7 @@ The macro accepts several methods: delegate :name, :age, :address, :twitter, :to => :profile </ruby> -When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such a expression is evaluated in the context of the receiver: +When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such an expression is evaluated in the context of the receiver: <ruby> # delegates to the Rails constant @@ -947,7 +947,7 @@ h4. Class Attributes h5. +class_attribute+ -The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy: +The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy. <ruby> class A @@ -983,7 +983,7 @@ self.default_params = { }.freeze </ruby> -They can be also accessed and overridden at the instance level: +They can be also accessed and overridden at the instance level. <ruby> A.x = 1 @@ -996,7 +996,7 @@ a1.x # => 1, comes from A a2.x # => 2, overridden in a2 </ruby> -The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false, as in +The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to +false+. <ruby> module ActiveRecord @@ -1009,8 +1009,20 @@ end A model may find that option useful as a way to prevent mass-assignment from setting the attribute. +The generation of the reader instance method can be prevented by setting the option +:instance_reader+ to +false+. + +<ruby> +class A + class_attribute :x, :instance_reader => false +end + +A.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?+. +When +:instance_reader+ is +false+, the instance predicate returns a +NoMethodError+ just like the reader method. + NOTE: Defined in +active_support/core_ext/class/attribute.rb+ h5. +cattr_reader+, +cattr_writer+, and +cattr_accessor+ @@ -1036,18 +1048,24 @@ module ActionView end </ruby> -we can access +field_error_proc+ in views. The generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+ (not any false value, but exactly +false+): +we can access +field_error_proc+ in views. + +The generation of the reader instance method can be prevented by setting +:instance_reader+ to +false+ and the generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+. Generation of both methods can be prevented by setting +:instance_accessor+ to +false+. In all cases, the value must be exactly +false+ and not any false value. <ruby> -module ActiveRecord - class Base - # No pluralize_table_names= instance writer is generated. - cattr_accessor :pluralize_table_names, :instance_writer => false +module A + class B + # No first_name instance reader is generated. + cattr_accessor :first_name, :instance_reader => false + # No last_name= instance writer is generated. + cattr_accessor :last_name, :instance_writer => false + # No surname instance reader or surname= writer is generated. + cattr_accessor :surname, :instance_accessor => false end end </ruby> -A model may find that option useful as a way to prevent mass-assignment from setting the attribute. +A model may find it useful to set +:instance_accessor+ to +false+ as a way to prevent mass-assignment from setting the attribute. NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+. @@ -1146,8 +1164,12 @@ h3. Extensions to +String+ h4. Output Safety +h5. Motivation + Inserting data into HTML templates needs extra care. For example you can't just interpolate +@review.title+ verbatim into an HTML page. On one hand if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;". On the other hand, depending on the application that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks. +h5. Safe Strings + Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not. Strings are considered to be <i>unsafe</i> by default: @@ -1173,8 +1195,6 @@ s # => "<script>...</script>" It is your responsibility to ensure calling +html_safe+ on a particular string is fine. -NOTE: For performance reasons safe strings are implemented in a way that cannot offer an in-place +html_safe!+ variant. - If you append onto a safe string, either in-place with +concat+/<tt><<</tt>, or with <tt>+</tt>, the result is a safe string. Unsafe arguments are escaped: <ruby> @@ -1215,6 +1235,22 @@ end NOTE: Defined in +active_support/core_ext/string/output_safety.rb+. +h5. Transformation + +As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc. + +In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe. + +INFO: The safety bit is lost always, no matter whether the transformation actually changed something. + +h5. Conversion and Coercion + +Calling +to_s+ on a safe string returns a safe string, but coercion with +to_str+ returns an unsafe string. + +h5. Copying + +Calling +dup+ or +clone+ on safe strings yields safe strings. + h4. +squish+ The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each: @@ -1460,7 +1496,15 @@ end That may be handy to compute method names in a language that follows that convention, for example JavaScript. -INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. +INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. To support cases such as this, Active Support allows you to specify acronyms in +config/initializers/inflections.rb+: + +<ruby> +ActiveSupport::Inflector.inflections do |inflect| + inflect.acronym 'SSL' +end + +"SSLError".underscore.camelize #=> "SSLError" +</ruby> +camelize+ is aliased to +camelcase+. @@ -2282,7 +2326,7 @@ NOTE: Defined in +active_support/core_ext/array/grouping.rb+. h5. +in_groups(number, fill_with = nil)+ -The method +in_groups+ splits an array into a certain number of groups. The method returns and array with the groups: +The method +in_groups+ splits an array into a certain number of groups. The method returns an array with the groups: <ruby> %w(1 2 3 4 5 6 7).in_groups(3) @@ -2714,7 +2758,7 @@ Active Support extends the method +Range#step+ so that it can be invoked without (1..10).step(2) # => [1, 3, 5, 7, 9] </ruby> -As the example shows, in that case the method returns and array with the corresponding elements. +As the example shows, in that case the method returns an array with the corresponding elements. NOTE: Defined in +active_support/core_ext/range/blockless_step.rb+. @@ -3024,7 +3068,7 @@ Date.new(2010, 1, 31).change(:month => 2) h5(#date-durations). Durations -Durations can be added and substracted to dates: +Durations can be added to and subtracted from dates: <ruby> d = Date.current @@ -3232,7 +3276,7 @@ DateTime.current.change(:month => 2, :day => 30) h5(#datetime-durations). Durations -Durations can be added and substracted to datetimes: +Durations can be added to and subtracted from datetimes: <ruby> now = DateTime.current @@ -3316,6 +3360,32 @@ Active Support defines +Time.current+ to be today in the current time zone. That When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+. +h5. +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+ + +The method +all_day+ returns a range representing the whole day of the current time. + +<ruby> +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 +</ruby> + +Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges. + +<ruby> +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 +now.all_month +# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +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 +now.all_year +# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00 +</ruby> + h4. Time Constructors Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+: @@ -3353,7 +3423,7 @@ If the time to be constructed lies beyond the range supported by +Time+ in the r h5(#time-durations). Durations -Durations can be added and substracted to time objects: +Durations can be added to and subtracted from time objects: <ruby> now = Time.current diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index 1566c23414..8b72e20c33 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -72,7 +72,7 @@ link_to_remote "Add to cart", If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the DOM id +error+ is updated rather than the +cart+ element. -** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities: +** *position* By default (i.e. when not specifying this option, like in the examples before) the response is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities: *** +:before+ Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element. *** +:after+ Similar behavior to +:before+, but in this case the response is inserted after the target element. *** +:top+ Inserts the text into the target element, before it's original content. If the target element was empty, this is equivalent with not specifying +:position+ at all. diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile index e046bc5cbb..50e86e05a8 100644 --- a/railties/guides/source/api_documentation_guidelines.textile +++ b/railties/guides/source/api_documentation_guidelines.textile @@ -41,8 +41,8 @@ h3. Example Code Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas. -Use two spaces to indent chunks of code.—that is two spaces with respect to the left margin; the examples -themselves should use "Rails code conventions":http://rails.lighthouseapp.com/projects/8994/source-style. +Use two spaces to indent chunks of code--that is two spaces with respect to the left margin; the examples +themselves should use "Rails coding conventions":contributing_to_ruby_on_rails.html#follow-the-coding-conventions. Short docs do not need an explicit "Examples" label to introduce snippets, they just follow paragraphs: diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile index 9ea1aa9e01..78683b743c 100644 --- a/railties/guides/source/asset_pipeline.textile +++ b/railties/guides/source/asset_pipeline.textile @@ -3,27 +3,104 @@ h2. Asset Pipeline This guide will cover the ideology of the asset pipeline introduced in Rails 3.1. By referring to this guide you will be able to: +* Understand what the asset pipeline is and what it does * Properly organize your application assets -* Understand the benefits of the asset pipline -* Adding a preproccessor to the pipeline -* Package assets with your plugin +* Understand the benefits of the asset pipeline +* Adding a pre-processor to the pipeline +* Package assets with a gem endprologue. h3. What Is The Asset Pipeline? -h4. Why Should I Use it? +With Rails 3.1 comes a new feature known as the asset pipeline. The asset pipeline provides features that have usually been implemented by external gems, such as "Jammit":http://documentcloud.github.com/jammit and "Sprockets.":http://getsprockets.org These gems are popular for being able to serve concatenated or compressed versions of the assets of an application, such as Cascade Style Sheets (CSS) or JavaScript (JS) files so that the number of requests made to the server are reduced, making the page load faster. Rails 3.1 includes the Sprockets gem. h3. How to Use the Asset Pipeline +In previous versions of Rails, all assets lived under the +public+ directory in directories such as +images+, +javascripts+ and +stylesheets+. With the asset pipeline, the preferred location for these assets is now the +app/assets+ directory. Files in this directory will be served by the Sprockets middleware included in the sprockets gem. + +This is not to say that assets can (or should) no longer be placed in +public+. They still can be, they will just be served by the application or the web server which is running the application and served just like normal files. 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 will also generate a JavaScript file (or CoffeeScript if the +coffee-script+ gem is in the +Gemfile+) and a Cascade Style Sheet file (or SCSS if +sass-rails+ is in the +Gemfile+) file 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. + h4. Asset Organization -h4. Default Files Loaded +Assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+. + ++app/assets+ is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets. + ++lib/assets+ is for your own libraries' code that doesn't really fit into the scope of the application or those libraries which are shared across applications. + ++vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins. + +Any subdirectory that exists within these three locations will be 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 will be 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 then served up. + +h4. External Assets + +Assets can also come from external sources such as engines. A good example of this is the +jquery-rails+ gem which comes with Rails as the standard JavaScript library gem. This gem contains an engine class which inherits from +Rails::Engine+. By doing this, Rails is informed that the directory for this gem may contain assets and the +app/assets+, +lib/assets+ and +vendor/assets+ directories of this engine are added to the search path of Sprockets. + +h4. Serving Assets + +To serve assets, we can use the same tags that we are generally familiar with: + +<erb> + <%= image_tag "rails.png" %> +</erb> + +Providing that assets are enabled within our application (+config.assets.enabled+ in your environment is set to +true+), this file will be served by Sprockets unless a file at +public/assets/rails.png+ exists, in which case that file will be served. Otherwise, Sprockets will look through the available paths until it finds a file that matches the name and then will serve it, first looking in the application's assets directories and then falling back to the various engines of the application. + +Sprockets does not add any new methods to require your assets, we still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+. You can use it to include from the normal public directory or the assets directory. + +h4. Manifest Files and Directives + +Sprockets allows some assets to be manifest files. These manifest files require what's known as _directives_, which instruct Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets will load the files specified, process them if necessary, concatenate them into one single file and then compress them (if +Rails.application.config.assets.compress+ is set to +true+). By serving one file rather than many, a page's load time can be greatly reduced. + +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 . +</plain> + +In JavaScript files, directives begin with +//=+. In this case, the following file is using the +require+ directive and the +require_tree+ directive. The +require+ directive tells Sprockets that we would like to require a file called +jquery.js+ that is available somewhere in the search path for Sprockets. By default, this is located inside the +vendor/assets/javascripts+ directory contained within the +jquery-rails+ gem. An identical event takes place for the +jquery_ujs+ require specified here also. + +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's also a default +app/assets/stylesheets/application.css+ file which contains these lines: + +<plain> +/* ... +*= require_self +*= require_tree . +*/ +</plain> + +The directives that work in the JavaScript files will also work in stylesheets, obviously requiring stylesheets rather than JavaScript files. The +require_tree+ directive here works the same way as the JavaScript one, requiring all stylesheets from the current directory. + +In this example +require_self+ is used. This will put the CSS contained within the file (if any) at the top of any other CSS in this file unless +require_self+ is specified after another +require+ directive. + +h4. Preprocessing + +Based on the extensions of the assets, Sprockets will do preprocessing on the files. With the default gemset that comes with Rails, when a controller or a scaffold is generated, a CoffeeScript file and a SCSS file will be 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. + +When these files are requested, they will be 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. + +In addition to this single layer of pre-processing, we can also put on additional extensions to the end of the file in order for them to be processed using other languages first. For example, we could call our stylesheet +app/assets/stylesheets/projects.css.scss.erb+ it would first be processed as ERB, then SCSS and finally served as CSS. We could also do this with our JavaScript file, calling it +app/assets/javascripts/projects.js.coffee.erb+. + +Keep in mind that the order of these pre-processors is important. For example, if we called our 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 we would run into problems. + +h4. Compressing Assets + +The default Gemfile also includes the "uglifier":https://github.com/lautis/uglifier gem. This gem wraps "UglifierJS":https://github.com/mishoo/UglifyJS (written for NodeJS) in Ruby. It compress your code by removing white spaces and other magical things like changing your if and else statements to ternary operators when possible. + +Sprockets also turns on "Gzip":http://en.wikipedia.org/wiki/Gzip (.gz) when possible (by checking the user's headers). Gzip is a file compression technique, much like the ever so popular "zip" file, except it's more open source friendly. Gzip should not modify the contents of the file, but simply the size of the file. -h4. Directives +h4. Adding Assets to Your Gems -h4. Stacking Preproccessors +To include your assets inside of a gem, simple package it in +lib/assets+ as you would in +app/assets+. You should append or prepend the name of your gem though, this should help avoid name conflicts with other gems or the user's application. -h3. Packaging Assets with Your Plugin +h4. Making Your Library or Gem a Pre-Processor -h3. More on Sprockets +"You should be able to register [your gems] on Tilt and Sprockets will find them." - Josh +Tilt: https://github.com/rtomayko/tilt
\ No newline at end of file diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile index 458bfefad8..3c2497e83a 100644 --- a/railties/guides/source/association_basics.textile +++ b/railties/guides/source/association_basics.textile @@ -1120,11 +1120,9 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt> The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. <ruby> -@open_orders = @customer.orders.all(:conditions => "open = 1") +@open_orders = @customer.orders.where(:open => 1) </ruby> -NOTE: Starting Rails 3, supplying options to +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions. - h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt> The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed. diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 91827fd493..252003edd0 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -112,7 +112,7 @@ As an example, if you wanted to show all the orders placed on your website in re <ruby> <% Order.find_recent.each do |o| %> - <%= o.buyer.name %> bought <% o.product.name %> + <%= o.buyer.name %> bought <%= o.product.name %> <% end %> <% cache do %> @@ -162,17 +162,17 @@ class ProductSweeper < ActionController::Caching::Sweeper # If our sweeper detects that a Product was created call this def after_create(product) - expire_cache_for(product) + expire_cache_for(product) end # If our sweeper detects that a Product was updated call this def after_update(product) - expire_cache_for(product) + expire_cache_for(product) end # If our sweeper detects that a Product was deleted call this def after_destroy(product) - expire_cache_for(product) + expire_cache_for(product) end private @@ -345,7 +345,7 @@ ActionController::Base.cache_store = MyCacheStore.new h4. Cache Keys -The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. ActiveRecord will generate keys based on the class name and record id. +The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. Active Record will generate keys based on the class name and record id. You can use Hashes and Arrays of values as cache keys. @@ -382,6 +382,7 @@ class ProductsController < ApplicationController # anything. The default render checks for this using the parameters # used in the previous call to stale? and will automatically send a # :not_modified. So that's it, you're done. + end end </ruby> diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index ad36c6532e..b0edc1017d 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -5,7 +5,7 @@ Rails comes with every command line tool you'll need to * Create a Rails application * Generate models, controllers, database migrations, and unit tests * Start a development server -* Mess with objects through an interactive shell +* Experiment with objects through an interactive shell * Profile and benchmark your new creation endprologue. @@ -51,21 +51,19 @@ $ rails new commandsapp Rails will set you up with what seems like a huge amount of stuff for such a tiny command! You've got the entire Rails directory structure now with all the code you need to run our simple application right out of the box. -INFO: This output will seem very familiar when we get to the +generate+ command. Creepy foreshadowing! - h4. +rails server+ -Let's try it! The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to view your work through a web browser. +The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to access your application through a web browser. -INFO: WEBrick isn't your only option for serving Rails. We'll get to that in a later section. +INFO: WEBrick isn't your only option for serving Rails. We'll get to that "later":#different-servers. -Without any prodding of any kind, +rails server+ will run our new shiny Rails app: +With no further work, +rails server+ will run our new shiny Rails app: <shell> $ cd commandsapp $ rails server => Booting WEBrick -=> Rails 3.0.0 application starting in development on http://0.0.0.0:3000 +=> Rails 3.1.0 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2010-04-18 03:20:33] INFO WEBrick 1.3.1 @@ -75,13 +73,21 @@ $ rails server With just three commands we whipped up a Rails server listening on port 3000. Go to your browser and open "http://localhost:3000":http://localhost:3000, you will see a basic Rails app running. +You can also use the alias "s" to start the server: <tt>rails s</tt>. + +The server can be run on a different port using the +-p+ option. The default development environment can be changed using +-e+. + +<shell> +$ rails server -e production -p 4000 +</shell> + h4. +rails generate+ -The +rails generate+ command uses templates to create a whole lot of things. You can always find out what's available by running +rails generate+ by itself. Let's do that: +The +rails generate+ command uses templates to create a whole lot of things. Running +rails generate+ by itself gives a list of available generators: <shell> $ rails generate -Usage: rails generate generator [args] [options] +Usage: rails generate GENERATOR [args] [options] ... ... @@ -97,7 +103,7 @@ Rails: NOTE: You can install more generators through generator gems, portions of plugins you'll undoubtedly install, and you can even create your own! -Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work, but not necessary for you to spend time writing. That's what we have computers for. +Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work. Let's make our own controller with the controller generator. But what command should we use? Let's ask the generator: @@ -146,7 +152,8 @@ $ rails generate controller Greetings hello create test/unit/helpers/greetings_helper_test.rb invoke assets create app/assets/javascripts/greetings.js - create app/assets/stylesheets/greetings.css + invoke css + create app/assets/stylesheets/greetings.css </shell> @@ -169,7 +176,7 @@ Then the view, to display our message (in +app/views/greetings/hello.html.erb+): <p><%= @message %></p> </html> -Deal. Go check it out in your browser. Fire up your server using +rails server+. +Fire up your server using +rails server+. <shell> $ rails server @@ -182,7 +189,7 @@ The URL will be "http://localhost:3000/greetings/hello":http://localhost:3000/gr INFO: With a normal, plain-old Rails application, your URLs will generally follow the pattern of http://(host)/(controller)/(action), and a URL like http://(host)/(controller) will hit the *index* action of that controller. -Rails comes with a generator for data models too: +Rails comes with a generator for data models too. <shell> $ rails generate model @@ -237,7 +244,7 @@ dependency model create test/unit/high_score_test.rb create test/fixtures/high_scores.yml exists db/migrate - create db/migrate/20081217071914_create_high_scores.rb + create db/migrate/20100209025147_create_high_scores.rb </shell> The generator checks that there exist the directories for models, controllers, helpers, layouts, functional and unit tests, stylesheets, creates the views, controller, model and database migration for HighScore (creating the +high_scores+ table and fields), takes care of the route for the *resource*, and new tests for everything. @@ -267,11 +274,13 @@ h4. +rails console+ The +console+ command lets you interact with your Rails application from the command line. On the underside, +rails console+ uses IRB, so if you've ever used it, you'll be right at home. This is useful for testing out quick ideas with code and changing data server-side without touching the website. +You can also use the alias "c" to invoke the console: <tt>rails c</tt>. + If you wish to test out some code without changing any data, you can do that by invoking +rails console --sandbox+. <shell> $ rails console --sandbox -Loading development environment in sandbox (Rails 3.0.0) +Loading development environment in sandbox (Rails 3.1.0) Any modifications you make will be rolled back on exit irb(main):001:0> </shell> @@ -280,13 +289,11 @@ h4. +rails dbconsole+ +rails dbconsole+ figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3. -h4. +rails plugin+ +You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>. -The +rails plugin+ command simplifies plugin management; think a miniature version of the Gem utility. Let's walk through installing a plugin. You can call the sub-command +discover+, which sifts through repositories looking for plugins, or call +source+ to add a specific repository of plugins, or you can specify the plugin location directly. - -Let's say you're creating a website for a client who wants a small accounting system. Every event having to do with money must be logged, and must never be deleted. Wouldn't it be great if we could override the behavior of a model to never actually take its record out of the database, but instead, just set a field? +h4. +rails plugin+ -There is such a thing! The plugin we're installing is called +acts_as_paranoid+, and it lets models implement a +deleted_at+ column that gets set when you call destroy. Later, when calling find, the plugin will tack on a database check to filter out "deleted" things. +The +rails plugin+ command simplifies plugin management. Plugins can be installed by name or their repository URLs. You need to have Git installed if you want to install a plugin from a Git repo. The same holds for Subversion too. <shell> $ rails plugin install https://github.com/technoweenie/acts_as_paranoid.git @@ -304,9 +311,15 @@ h4. +rails runner+ $ rails runner "Model.long_running_method" </shell> +You can specify the environment in which the +runner+ command should operate using the +-e+ switch. + +<shell> +$ rails runner -e staging "Model.long_running_method" +</shell> + h4. +rails destroy+ -Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it. Believe you-me, the creation of this tutorial used this command many times! +Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it. <shell> $ rails generate model Oops @@ -333,9 +346,29 @@ $ rails destroy model Oops notempty app </shell> -h4. +rake about+ +h3. Rake + +Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other. -Check it: Version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version! +about+ is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation. +You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need. + +<shell> +$ rake --tasks +(in /home/foobar/commandsapp) +rake db:abort_if_pending_migrations # Raises an error if there are pending migrations +rake db:charset # Retrieves the charset for the current environment's database +rake db:collation # Retrieves the collation for the current environment's database +rake db:create # Create the database defined in config/database.yml for the current Rails.env +... +... +rake tmp:pids:clear # Clears all files in tmp/pids +rake tmp:sessions:clear # Clears all files in tmp/sessions +rake tmp:sockets:clear # Clears all files in tmp/sockets +</shell> + +h4. +about+ + +<tt>rake about</tt> gives information about version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version. It is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation. <shell> $ rake about @@ -343,17 +376,98 @@ About your application's environment Ruby version 1.8.7 (x86_64-linux) RubyGems version 1.3.6 Rack version 1.1 -Rails version 3.0.0 -Active Record version 3.0.0 -Action Pack version 3.0.0 -Active Resource version 3.0.0 -Action Mailer version 3.0.0 -Active Support version 3.0.0 +Rails version 3.1.0 +Active Record version 3.1.0 +Action Pack version 3.1.0 +Active Resource version 3.1.0 +Action Mailer version 3.1.0 +Active Support version 3.1.0 Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Callbacks, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::MethodOverride, ActionDispatch::Head Application root /home/foobar/commandsapp Environment development </shell> +h4. +assets+ + +You can precompile the assets in <tt>app/assets</tt> using <tt>rake assets:precompile</tt> and remove compiled assets using <tt>rake assets:clean</tt>. + +h4. +db+ + +The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database. + +More information about migrations can be found in the "Migrations":migrations.html guide. + +h4. +doc+ + +The +doc:+ namespace has the tools to generate documentation for your app, API documentation, guides. Documentation can also be stripped which is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform. + +* +rake doc:app+ generates documentation for your application in +doc/app+. +* +rake doc:guides+ generates Rails guides in +doc/guides+. +* +rake doc:rails+ generates API documentation for Rails in +doc/api+. +* +rake doc:plugins+ generates API documentation for all the plugins installed in the application in +doc/plugins+. +* +rake doc:clobber_plugins+ removes the generated documentation for all plugins. + +h4. +notes+ + ++rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is only done in files with extension +.builder+, +.rb+, +.rxml+, +.rhtml+ and +.erb+ for both default and custom annotations. + +<shell> +$ rake notes +(in /home/foobar/commandsapp) +app/controllers/admin/users_controller.rb: + * [ 20] [TODO] any other way to do this? + * [132] [FIXME] high priority for next deploy + +app/model/school.rb: + * [ 13] [OPTIMIZE] refactor this code to make it faster + * [ 17] [FIXME] +</shell> + +If you are looking for a specific annotation, say FIXME, you can use +rake notes:fixme+. Note that you have to lower case the annotation's name. + +<shell> +$ rake notes:fixme +(in /home/foobar/commandsapp) +app/controllers/admin/users_controller.rb: + * [132] high priority for next deploy + +app/model/school.rb: + * [ 17] +</shell> + +You can also use custom annotations in your code and list them using +rake notes:custom+ by specifying the annotation using an environment variable +ANNOTATION+. + +<shell> +$ rake notes:custom ANNOTATION=BUG +(in /home/foobar/commandsapp) +app/model/post.rb: + * [ 23] Have to fix this one before pushing! +</shell> + +NOTE. When using specific annotations and custom annotations, the annotation name (FIXME, BUG etc) is not displayed in the output lines. + +h4. +routes+ + ++rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with. + +h4. +test+ + +INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html + +Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should. + +The +test:+ namespace helps in running the different tests you will (hopefully!) write. + +h4. +tmp+ + +The <tt>Rails.root/tmp</tt> directory is, like the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry. + +h4. Miscellaneous + +* +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio. +* +rake secret+ will give you a pseudo-random key to use for your session secret. +* <tt>rake time:zones:all</tt> lists all the timezones Rails knows about. + h3. The Rails Advanced Command Line More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve. @@ -414,11 +528,13 @@ development: ... </shell> -It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app. +It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. + +NOTE. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app. -h4. +server+ with Different Backends +h4(#different-servers). +server+ with Different Backends -Many people have created a large number different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!). +Many people have created a large number of different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!). NOTE: For more details on the Rack integration, see "Rails on Rack":rails_on_rack.html. @@ -437,157 +553,6 @@ Successfully installed mongrel-1.1.5 Installing RDoc documentation for mongrel-1.1.5... $ rails server mongrel => Booting Mongrel (use 'rails server webrick' to force WEBrick) -=> Rails 3.0.0 application starting on http://0.0.0.0:3000 +=> Rails 3.1.0 application starting on http://0.0.0.0:3000 ... </shell> - -h4. The Rails Generation: Generators - -INFO: For a good rundown on generators, see "Understanding Generators":http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators. A lot of its material is presented here. - -Generators are code that generates code. Let's experiment by building one. Our generator will generate a text file. - -The Rails generator by default looks in these places for available generators, where Rails.root is the root of your Rails application, like /home/foobar/commandsapp: - -* Rails.root/lib/generators -* Rails.root/vendor/generators -* Inside any plugin with a directory like "generators" or "rails_generators" -* ~/.rails/generators -* Inside any Gem you have installed with a name ending in "_generator" -* Inside any Gem installed with a "rails_generators" path, and a file ending in "_generator.rb" -* Finally, the builtin Rails generators (controller, model, mailer, etc.) - -Let's try the fourth option (in our home directory), which will be easy to clean up later: - -<shell> -$ mkdir -p ~/.rails/generators/tutorial_test/templates -$ touch ~/.rails/generators/tutorial_test/templates/tutorial.erb -$ touch ~/.rails/generators/tutorial_test/tutorial_test_generator.rb -</shell> - -We'll fill +tutorial_test_generator.rb+ out with: - -<ruby> -class TutorialTestGenerator < Rails::Generator::Base - def initialize(*runtime_args) - super(*runtime_args) - @tut_args = runtime_args - end - - def manifest - record do |m| - m.directory "public" - m.template "tutorial.erb", File.join("public", "tutorial.txt"), - :assigns => { :args => @tut_args } - end - end -end -</ruby> - -We take whatever args are supplied, save them to an instance variable, and literally copying from the Rails source, implement a +manifest+ method, which calls +record+ with a block, and we: - -* Check there's a *public* directory. You bet there is. -* Run the ERB template called "tutorial.erb". -* Save it into "Rails.root/public/tutorial.txt". -* Pass in the arguments we saved through the +:assigns+ parameter. - -Next we'll build the template: - -<shell> -$ cat ~/.rails/generators/tutorial_test/templates/tutorial.erb -I'm a template! - -I got assigned some args: -<%= require 'pp'; PP.pp(args, "") %> -</shell> - -Then we'll make sure it got included in the list of available generators: - -<shell> -$ rails generate -... -... -Installed Generators - User: tutorial_test -</shell> - -SWEET! Now let's generate some text, yeah! - -<shell> -$ rails generate tutorial_test arg1 arg2 arg3 - exists public - create public/tutorial.txt -</shell> - -And the result: - -<shell> -$ cat public/tutorial.txt -I'm a template! - -I got assigned some args: -[["arg1", "arg2", "arg3"], - {:collision=>:ask, - :quiet=>false, - :generator=>"tutorial_test", - :command=>:create}] -</shell> - -Tada! - -h4. Rake is Ruby Make - -Rake is a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other. - -You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need. - -<shell> -$ rake --tasks -(in /home/foobar/commandsapp) -rake db:abort_if_pending_migrations # Raises an error if there are pending migrations -rake db:charset # Retrieves the charset for the current environment's database -rake db:collation # Retrieves the collation for the current environment's database -rake db:create # Create the database defined in config/database.yml for the current Rails.env -... -... -rake tmp:pids:clear # Clears all files in tmp/pids -rake tmp:sessions:clear # Clears all files in tmp/sessions -rake tmp:sockets:clear # Clears all files in tmp/sockets -</shell> - -h5. +db:+ Database - -The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database. - -h5. +doc:+ Documentation - -If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform. - -h5. +notes:+ Code note enumeration - -These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them. - -h5. +test:+ Rails tests - -INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html - -Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should. - -The +test:+ namespace helps in running the different tests you will (hopefully!) write. - -h5. +time:+ Timezones - -You can list all the timezones Rails knows about with +rake time:zones:all+, which is useful just in day-to-day life. - -h5. +tmp:+ Temporary files - -The tmp directory is, like in the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry. - -h5. Miscellaneous Tasks - - +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio. - - +rake secret+ will give you a pseudo-random key to use for your session secret. - - +rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with. - diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 135c849ec3..8e6010ff79 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -18,7 +18,7 @@ Rails offers four standard spots to place initialization code: h3. Running Code Before Rails -In the rare event that your application needs to run some code before Rails itself is loaded, put it above the call to +require 'rails/all'+ in your +config/application.rb+. +In the rare event that your application needs to run some code before Rails itself is loaded, put it above the call to +require 'rails/all'+ in +config/application.rb+. h3. Configuring Rails Components @@ -52,12 +52,14 @@ end * +config.asset_host+ sets the host for the assets. Useful when CDNs are used for hosting assets, or when you want to work around the concurrency constraints builtin in browsers using different domain aliases. Shorter version of +config.action_controller.asset_host+. -* +config.asset_path+ can take a callable, a string, or be +nil+. Default is +nil+. If set, this configuration parameter let's you decorate asset paths. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. *This option is ignored if the asset pipeline is enabled, which is by default*. Shorter version of +config.action_controller.asset_path+. +* +config.asset_path+ lets you decorate asset paths. This can be a callable, a string, or be +nil+ which is the default. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. Shorter version of +config.action_controller.asset_path+. <ruby> config.asset_path = proc { |path| "/blog/public#{path}" } </ruby> +NOTE. The +config.asset_path+ configuration is ignored if the asset pipeline is enabled, which is the default. + * +config.autoload_once_paths+ accepts an array of paths from which Rails will autoload constants that won't be wiped per request. Relevant if +config.cache_classes+ is false, which is the case in development mode by default. Otherwise, all autoloading happens only once. All elements of this array must also be in +autoload_paths+. Default is an empty array. * +config.autoload_paths+ accepts an array of paths from which Rails will autoload constants. Default is all directories under +app+. @@ -84,11 +86,11 @@ config.asset_path = proc { |path| "/blog/public#{path}" } * +config.log_level+ defines the verbosity of the Rails logger. This option defaults to +:debug+ for all modes except production, where it defaults to +:info+. -* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode. +* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode. -* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":configuring-middleware section below. +* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":#configuring-middleware section below. -* +config.plugins+ accepts the list of plugins to load. If this is set to +nil+, default, all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option let's you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them. +* +config.plugins+ accepts the list of plugins to load. The default is +nil+ in which case all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option lets you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them. * +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Enabled by +config.threadsafe!+. Defaults to +nil+, so is disabled. @@ -96,9 +98,9 @@ config.asset_path = proc { |path| "/blog/public#{path}" } * +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get +config.secret_token+ initialized to a random key in +config/initializers/secret_token.rb+. -* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to true, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead. +* +config.serve_static_assets+ configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. Nginx or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won´t be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app. -* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+, default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified like so: +* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+ which is the default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified: <ruby> config.session_store :my_custom_store @@ -114,52 +116,71 @@ WARNING: Threadsafe operation is incompatible with the normal workings of develo * +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments. +h4. Configuring Assets + +Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets within an application. This gem concatenates and compresses assets in order to make serving them much less painful. + +* +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.enabled+ a flag that controls whether the asset pipeline is enabled. It is explicitly initialized in +config/application.rb+. +* +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. + +* +config.assets.paths+ contains the paths which are used to look for assets. Appending paths to this configuration option will cause those paths to be used in the search for assets. + +* +config.assets.precompile+ allows you to specify additional assets (other than +application.css+ and +application.js+) which are to be precompiled when +rake assets:precompile+ is run. + +* +config.assets.prefix+ defines the prefix where assets are served from. Defaults to +/assets+. + + h4. Configuring Generators Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block: <ruby> - config.generators do |g| - g.orm :active_record - g.test_framework :test_unit - end +config.generators do |g| + g.orm :active_record + g.test_framework :test_unit +end </ruby> The full set of methods that can be used in this block are as follows: -* +force_plural+ allows pluralized model names. Defaults to _false_. -* +helper+ defines whether or not to generate helpers. Defaults to _true_. -* +orm+ defines which orm to use. Defaults to _nil_, so will use Active Record by default. -* +integration_tool+ defines which integration tool to use. Defaults to _nil_. -* +performance_tool+ defines which performance tool to use. Defaults to _nil_. +* +assets+ allows to create assets on generating a scaffold. Defaults to +true+. +* +force_plural+ allows pluralized model names. Defaults to +false+. +* +helper+ defines whether or not to generate helpers. Defaults to +true+. +* +integration_tool+ defines which integration tool to use. Defaults to +nil+. +* +javascripts+ turns on the hook for javascripts in generators. Used in Rails for when the +scaffold+ generator is ran. Defaults to +true+. +* +javascript_engine+ configures the engine to be used (for eg. coffee) when generating assets. Defaults to +nil+. +* +orm+ defines which orm to use. Defaults to +false+ and will use Active Record by default. +* +performance_tool+ defines which performance tool to use. Defaults to +nil+. * +resource_controller+ defines which generator to use for generating a controller when using +rails generate resource+. Defaults to +:controller+. * +scaffold_controller+ different from +resource_controller+, defines which generator to use for generating a _scaffolded_ controller when using +rails generate scaffold+. Defaults to +:scaffold_controller+. -* +stylesheets+ turns on the hook for stylesheets in generators. Used in Rails for when the +scaffold+ generator is ran, but this hook can be used in other generates as well. -* +test_framework+ defines which test framework to use. Defaults to _nil_, so will use Test::Unit by default. +* +stylesheets+ turns on the hook for stylesheets in generators. Used in Rails for when the +scaffold+ generator is ran, but this hook can be used in other generates as well. Defaults to +true+. +* +stylesheet_engine+ configures the stylesheet engine (for eg. sass) to be used when generating assets. Defaults to +:css+. +* +test_framework+ defines which test framework to use. Defaults to +false+ and will use Test::Unit by default. * +template_engine+ defines which template engine to use, such as ERB or Haml. Defaults to +:erb+. 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_. -* +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. +* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to +true+. +* +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. * +Rack::Runtime+ Sets an +X-Runtime+ header, containing the time (in seconds) taken to execute the request. -* +Rails::Rack::Logger+ Will notify the logs that the request has began. After request is complete, flushes all the logs. -* +ActionDispatch::ShowExceptions+ rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to _true_. If +config.action_dispatch.show_exceptions+ is set to _false_, exceptions will be raised regardless. -* +ActionDispatch::RemoteIp+ checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings. -* +Rack::Sendfile+ The Sendfile middleware intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with +config.action_dispatch.x_sendfile_header+ +* +Rails::Rack::Logger+ Notifies the logs that the request has began. After request is complete, flushes all the logs. +* +ActionDispatch::ShowExceptions+ Rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to +true+. If +config.action_dispatch.show_exceptions+ is set to +false+, exceptions will be raised regardless. +* +ActionDispatch::RemoteIp+ Checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings. +* +Rack::Sendfile+ Intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with +config.action_dispatch.x_sendfile_header+. * +ActionDispatch::Callbacks+ Runs the prepare callbacks before serving the request. -* +ActiveRecord::ConnectionAdapters::ConnectionManagement+ cleans active connections after each request, unless the +rack.test+ key in the request environment is set to _true_. -* +ActiveRecord::QueryCache+ caches all +SELECT+ queries generated in a request. If an +INSERT+ or +UPDATE+ takes place then the cache is cleaned. +* +ActiveRecord::ConnectionAdapters::ConnectionManagement+ cleans active connections after each request, unless the +rack.test+ key in the request environment is set to +true+. +* +ActiveRecord::QueryCache+ caches all SELECT queries generated in a request. If any INSERT or UPDATE takes place then the cache is cleaned. * +ActionDispatch::Cookies+ sets cookies for the request. * +ActionDispatch::Session::CookieStore+ is responsible for storing the session in cookies. An alternate middleware can be used for this by changing the +config.action_controller.session_store+ to an alternate value. Additionally, options passed to this can be configured by using +config.action_controller.session_options+. * +ActionDispatch::Flash+ sets up the +flash+ keys. Only available if +config.action_controller.session_store+ is set to a value. -* +ActionDispatch::ParamsParser+ parses out parameters from the request into +params+ +* +ActionDispatch::ParamsParser+ parses out parameters from the request into +params+. * +Rack::MethodOverride+ allows the method to be overridden if +params[:_method]+ is set. This is the middleware which supports the PUT and DELETE HTTP method types. * +ActionDispatch::Head+ converts HEAD requests to GET requests and serves them as so. * +ActionDispatch::BestStandardsSupport+ enables "best standards support" so that IE8 renders some elements correctly. @@ -167,44 +188,44 @@ Every Rails application comes with a standard set of middleware which it uses in Besides these usual middleware, you can add your own by using the +config.middleware.use+ method: <ruby> - config.middleware.use Magical::Unicorns +config.middleware.use Magical::Unicorns </ruby> -This will put the +Magical::Unicorns+ middleware on the end of the stack. If you wish to put this middleware before another use +insert_before+: +This will put the +Magical::Unicorns+ middleware on the end of the stack. You can use +insert_before+ if you wish to add a middleware before another. <ruby> - config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns +config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns </ruby> -There's also +insert_after+ which will insert a middleware _after_ another: +There's also +insert_after+ which will insert a middleware after another: <ruby> - config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns +config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns </ruby> Middlewares can also be completely swapped out and replaced with others: <ruby> - config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns +config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns </ruby> They can also be removed from the stack completely: <ruby> - config.middleware.delete ActionDispatch::BestStandardsSupport +config.middleware.delete ActionDispatch::BestStandardsSupport </ruby> h4. Configuring i18n * +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+. -* +config.i18n.load_path+ sets the path Rails uses to look for locale files. Defaults to +config/locales/*.{yml,rb}+ +* +config.i18n.load_path+ sets the path Rails uses to look for locale files. Defaults to +config/locales/*.{yml,rb}+. h4. Configuring Active Record <tt>config.active_record</tt> includes a variety of configuration options: -* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8.x Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to nil to disable logging. +* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to +nil+ to disable logging. * +config.active_record.primary_key_prefix_type+ lets you adjust the naming for primary key columns. By default, Rails assumes that primary key columns are named +id+ (and this configuration option doesn't need to be set.) There are two other choices: ** +:table_name+ would make the primary key for the Customer class +customerid+ @@ -214,21 +235,21 @@ h4. Configuring Active Record * +config.active_record.table_name_suffix+ lets you set a global string to be appended to table names. If you set this to +_northwest+, then the Customer class will look for +customers_northwest+ as its table. The default is an empty string. -* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to +true+ (the default), then the Customer class will use the +customers+ table. If set to +false+, then the Customers class will use the +customer+ table. +* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to true (the default), then the Customer class will use the +customers+ table. If set to false, then the Customer class will use the +customer+ table. -* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although ActiveRecord defaults to +:local+ when used outside of Rails. +* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although Active Record defaults to +:local+ when used outside of Rails. * +config.active_record.schema_format+ controls the format for dumping the database schema to a file. The options are +:ruby+ (the default) for a database-independent version that depends on migrations, or +:sql+ for a set of (potentially database-dependent) SQL statements. -* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is +true+, to use timestamps, which are preferred if there are multiple developers working on the same application. +* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is true, to use timestamps, which are preferred if there are multiple developers working on the same application. -* +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+. +* +config.active_record.lock_optimistically+ controls whether Active Record will use optimistic locking and is true by default. * +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app. The MySQL adapter adds one additional configuration option: -* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+. +* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans and is true by default. The schema dumper adds one additional configuration option: @@ -244,17 +265,17 @@ h4. Configuring Action Controller * +config.action_controller.page_cache_directory+ should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>. For Rails, this directory has already been set to +Rails.public_path+ (which is usually set to <tt>Rails.root + "/public"</tt>). Changing this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your web server to look in the new location for cached files. -* +config.action_controller.page_cache_extension+ configures the extension used for cached pages saved to +page_cache_directory+. Defaults to +.html+ +* +config.action_controller.page_cache_extension+ configures the extension used for cached pages saved to +page_cache_directory+. Defaults to +.html+. -* +config.action_controller.perform_caching+ configures whether the application should perform caching or not. Set to _false_ in development mode, _true_ in production. +* +config.action_controller.perform_caching+ configures whether the application should perform caching or not. Set to false in development mode, true in production. * +config.action_controller.default_charset+ specifies the default character set for all renders. The default is "utf-8". -* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging. +* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Controller. Set to +nil+ to disable logging. * +config.action_controller.request_forgery_protection_token+ sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ sets it to +:authenticity_token+ by default. -* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is +false+ in test mode and +true+ in all other modes. +* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is false in test mode and true in all other modes. * +config.action_controller.relative_url_root+ can be used to tell Rails that you are deploying to a subdirectory. The default is +ENV['RAILS_RELATIVE_URL_ROOT']+. @@ -288,45 +309,49 @@ h4. Configuring Action View There are only a few configuration options for Action View, starting with four on +ActionView::Base+: -* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%<div class="field_with_errors">#{html_tag}</div>).html_safe }</tt> +* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is + +<ruby> +Proc.new { |html_tag, instance| %Q(<div class="field_with_errors">#{html_tag}</div>).html_safe } +</ruby> * +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+. -* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging. +* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging. * +config.action_view.erb_trim_mode+ gives the trim mode to be used by ERB. It defaults to +'-'+. See the "ERB documentation":http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/ for more information. * +config.action_view.javascript_expansions+ is a hash containing expansions that can be used for the JavaScript include tag. By default, this is defined as: <ruby> - config.action_view.javascript_expansions = { :defaults => ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] } +config.action_view.javascript_expansions = { :defaults => %w(jquery jquery_ujs) } </ruby> However, you may add to this by defining others: <ruby> - config.action_view.javascript_expansions[:jquery] = ["jquery", "jquery-ui"] +config.action_view.javascript_expansions[:prototype] = ['prototype', 'effects', 'dragdrop', 'controls'] </ruby> And can reference in the view with the following code: <ruby> - <%= javascript_include_tag :jquery %> +<%= javascript_include_tag :prototype %> </ruby> * +config.action_view.stylesheet_expansions+ works in much the same way as +javascript_expansions+, but has no default key. Keys defined for this hash can be referenced in the view like such: <ruby> - <%= stylesheet_link_tag :special %> +<%= stylesheet_link_tag :special %> </ruby> -* +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running. +* +config.action_view.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running. h4. Configuring Action Mailer There are a number of settings available on +config.action_mailer+: -* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging. +* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging. * +config.action_mailer.smtp_settings+ allows detailed configuration for the +:smtp+ delivery method. It accepts a hash of options, which can include any of these options: ** +:address+ - Allows you to use a remote mail server. Just change it from its default "localhost" setting. @@ -340,25 +365,35 @@ There are a number of settings available on +config.action_mailer+: ** +:location+ - The location of the sendmail executable. Defaults to +/usr/sbin/sendmail+. ** +:arguments+ - The command line arguments. Defaults to +-i -t+. -* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to +true+. +* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to true. * +config.action_mailer.delivery_method+ defines the delivery method. The allowed values are +:smtp+ (default), +:sendmail+, and +:test+. -* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered. By default this is +true+; it can be convenient to set it to +false+ for testing. +* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered and is true by default. It can be convenient to set it to false for testing. * +config.action_mailer.default+ configures Action Mailer defaults. These default to: <ruby> - :mime_version => "1.0", - :charset => "UTF-8", - :content_type => "text/plain", - :parts_order => [ "text/plain", "text/enriched", "text/html" ] +:mime_version => "1.0", +:charset => "UTF-8", +:content_type => "text/plain", +:parts_order => [ "text/plain", "text/enriched", "text/html" ] +</ruby> + +* +config.action_mailer.observers+ registers observers which will be notified when mail is delivered. +<ruby> +config.action_mailer.observers = ["MailObserver"] +</ruby> + +* +config.action_mailer.interceptors+ registers interceptors which will be called before mail is sent. +<ruby> +config.action_mailer.interceptors = ["MailInterceptor"] </ruby> h4. Configuring Active Resource There is a single configuration setting available on +config.active_resource+: -* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Active Resource. Set to nil to disable logging. +* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Active Resource. Set to +nil+ to disable logging. h4. Configuring Active Support @@ -398,7 +433,7 @@ Some parts of Rails can also be configured externally by supplying environment v h3. Using Initializer Files -After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of Ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks, plugins and gems are loaded, such as options to configure settings for these parts. +After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any Ruby file stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks, plugins and gems are loaded, such as options to configure settings for these parts. NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the initializers folder on down. @@ -406,7 +441,7 @@ TIP: If you have any ordering dependency in your initializers, you can control t h3. Initialization events -Rails has 5 initialization events which can be hooked into (listed in order that they are ran): +Rails has 5 initialization events which can be hooked into (listed in the order that they are ran): * +before_configuration+: This is run as soon as the application constant inherits from +Rails::Application+. The +config+ calls are evaluated before this happens. @@ -437,7 +472,7 @@ Initializers defined using the +initializer+ method will be ran in the order the WARNING: You may put your initializer before or after any other initializer in the chain, as long as it is logical. Say you have 4 initializers called "one" through "four" (defined in that order) and you define "four" to go _before_ "four" but _after_ "three", that just isn't logical and Rails will not be able to determine your initializer order. -The block's argument of the +initialize+ is the instance of the application itself, and so we can access the configuration on it by using the +config+ method as this initializer does. +The block argument of the +initializer+ method is the instance of the application itself, and so we can access the configuration on it by using the +config+ method as done in the example. Because +Rails::Application+ inherits from +Rails::Railtie+ (indirectly), you can use the +initializer+ method in +config/application.rb+ to define initializers for the application. @@ -450,21 +485,21 @@ Serves as a placeholder so that +:load_environment_config+ can be defined to run *+load_active_support+* Requires +active_support/dependencies+ which sets up the basis for Active Support. Optionally requires +active_support/all+ if +config.active_support.bare+ is un-truthful, which is the default. -*+preload_frameworks+* Will load all autoload dependencies of Rails automatically if +config.preload_frameworks+ is +true+ or "truthful". By default this configuration option is disabled. In Rails, when internal classes are referenced for the first time they are autoloaded. +:preload_frameworks+ loads all of this at once on initialization. +*+preload_frameworks+* Loads all autoload dependencies of Rails automatically if +config.preload_frameworks+ is +true+ or "truthful". By default this configuration option is disabled. In Rails, when internal classes are referenced for the first time they are autoloaded. +:preload_frameworks+ loads all of this at once on initialization. -*+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, providing that there's no initializer inserted before this point that has defined +Rails.logger+. +*+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, provided that no initializer inserted before this point has defined +Rails.logger+. -*+initialize_cache+* If +RAILS_CACHE+ isn't yet set, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +RAILS_CACHE+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack. +*+initialize_cache+* If +RAILS_CACHE+ isn't set yet, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +RAILS_CACHE+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack. *+set_clear_dependencies_hook+* Provides a hook for +active_record.set_dispatch_hooks+ to use, which will run before this initializer. This initializer -- which runs only if +cache_classes+ is set to +false+ -- uses +ActionDispatch::Callbacks.after+ to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request. -*+initialize_dependency_mechanism+* If +config.cache_classes+ is set to +true+, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them. +*+initialize_dependency_mechanism+* If +config.cache_classes+ is true, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them. *+bootstrap_hook+* Runs all configured +before_initialize+ blocks. *+i18n.callbacks+* In the development environment, sets up a +to_prepare+ callback which will call +I18n.reload!+ if any of the locales have changed since the last request. In production mode this callback will only run on the first request. -*+active_support.initialize_whiny_nils+* Will require +active_support/whiny_nil+ if +config.whiny_nils+ is set to +true+. This file will output errors such as: +*+active_support.initialize_whiny_nils+* Requires +active_support/whiny_nil+ if +config.whiny_nils+ is true. This file will output errors such as: <plain> Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id @@ -480,19 +515,19 @@ The error occurred while evaluating nil.each *+active_support.deprecation_behavior+* Sets up deprecation reporting for environments, defaulting to +:log+ for development, +:notify+ for production and +:stderr+ for test. If a value isn't set for +config.active_support.deprecation+ then this initializer will prompt the user to configure this line in the current environment's +config/environments+ file. Can be set to an array of values. -*+active_support.initialize_time_zone+* Sets the default time zone for the application based off the +config.time_zone+ setting, which defaults to "UTC". +*+active_support.initialize_time_zone+* Sets the default time zone for the application based on the +config.time_zone+ setting, which defaults to "UTC". *+action_dispatch.configure+* Configures the +ActionDispatch::Http::URL.tld_length+ to be set to the value of +config.action_dispatch.tld_length+. -*+action_view.cache_asset_ids+* Will set +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ to +false+ when Active Support loads, but only if +config.cache_classes+ is too. +*+action_view.cache_asset_ids+* Sets +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ to +false+ when Active Support loads, but only if +config.cache_classes+ is too. *+action_view.javascript_expansions+* Registers the expansions set up by +config.action_view.javascript_expansions+ and +config.action_view.stylesheet_expansions+ to be recognised by Action View and therefore usable in the views. *+action_view.set_configs+* Sets up Action View by using the settings in +config.action_view+ by +send+'ing the method names as setters to +ActionView::Base+ and passing the values through. -*+action_controller.logger+* Sets +ActionController::Base.logger+ -- if it's not already set -- to +Rails.logger+. +*+action_controller.logger+* Sets +ActionController::Base.logger+ -- if it's not already set -- to +Rails.logger+. -*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +RAILS_CACHE+. +*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +RAILS_CACHE+. *+action_controller.set_configs+* Sets up Action Controller by using the settings in +config.action_controller+ by +send+'ing the method names as setters to +ActionController::Base+ and passing the values through. @@ -506,9 +541,9 @@ The error occurred while evaluating nil.each *+active_record.initialize_database+* Loads the database configuration (by default) from +config/database.yml+ and establishes a connection for the current environment. -*+active_record.log_runtime+* Includes +ActiveRecord::Railties::ControllerRuntime+ which is responsible for reporting the length of time Active Record calls took for the request back to the logger. +*+active_record.log_runtime+* Includes +ActiveRecord::Railties::ControllerRuntime+ which is responsible for reporting the time taken by Active Record calls for the request back to the logger. -*+active_record.set_dispatch_hooks+* If +config.cache_classes+ is set to false, all reloadable connections to the database will be reset. +*+active_record.set_dispatch_hooks+* Resets all reloadable connections to the database if +config.cache_classes+ is set to +false+. *+action_mailer.logger+* Sets +ActionMailer::Base.logger+ -- if it's not already set -- to +Rails.logger+. @@ -536,10 +571,6 @@ The error occurred while evaluating nil.each *+load_config_initializers+* Loads all Ruby files from +config/initializers+ in the application, railties and engines. The files in this directory can be used to hold configuration settings that should be made after all of the frameworks and plugins are loaded. -NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the +initializers+ folder on down. - -TIP: If you have any ordering dependency in your initializers, you can control the load order by naming. For example, +01_critical.rb+ will be loaded before +02_normal.rb+. - *+engines_blank_point+* Provides a point-in-initialization to hook into if you wish to do anything before engines are loaded. After this point, all railtie and engine initializers are ran. *+add_generator_templates+* Finds templates for generators at +lib/templates+ for the application, railities and engines and adds these to the +config.generators.templates+ setting, which will make the templates available for all generators to reference. @@ -552,13 +583,13 @@ TIP: If you have any ordering dependency in your initializers, you can control t *+build_middleware_stack+* Builds the middleware stack for the application, returning an object which has a +call+ method which takes a Rack environment object for the request. -*+eager_load!+* If +config.cache_classes+ is +true+, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+. +*+eager_load!+* If +config.cache_classes+ is true, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+. *+finisher_hook+* Provides a hook for after the initialization of process of the application is complete, as well as running all the +config.after_initialize+ blocks for the application, railties and engines. *+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+. +*+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 diff --git a/railties/guides/source/contribute.textile b/railties/guides/source/contribute.textile index 4bd527d4c7..f9bb80861c 100644 --- a/railties/guides/source/contribute.textile +++ b/railties/guides/source/contribute.textile @@ -14,7 +14,7 @@ h3. How to Contribute? * 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 commiting your changes by running +bundle exec rake validate_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? @@ -33,7 +33,7 @@ h3. What to Contribute? 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. In that case feedback can be given in its LH ticket. +* 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. @@ -53,7 +53,7 @@ h3. Rules * 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":https://wiki.github.com/lifo/docrails/rails-guides-conventions and the "Rails API Documentation Conventions":https://wiki.github.com/lifo/docrails/rails-api-documentation-conventions. +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 diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index 5eb925d7d2..e6ec061c9a 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -24,7 +24,7 @@ If you've found a problem in Ruby on Rails which is not a security risk do a sea At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need to at least post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix. -Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating a issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment. +Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment. h4. Special Treatment for Security Issues @@ -90,7 +90,7 @@ This command will install all dependencies except the MySQL and PostgreSQL Ruby $ rake test </shell> -You can also run tests for an specific framework, like Action Pack, by going into its directory and executing the same command: +You can also run tests for a specific framework, like Action Pack, by going into its directory and executing the same command: <shell> $ cd actionpack @@ -264,7 +264,7 @@ When working with documentation, please take into account the "API Documentation NOTE: As explained above, 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. +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. @@ -309,7 +309,7 @@ Rails follows a simple set of coding style conventions. * a = b and not a=b. * Follow the conventions you see used in the source already. -These are some guidelines and please use your best judgement in using them. +These are some guidelines and please use your best judgment in using them. h4. Sanity Check @@ -350,7 +350,7 @@ Navigate to the Rails "GitHub repository":https://github.com/rails/rails and pre Add the new remote to your local repository on your local machine: <shell> -$ git remote add mine https://<your user name>@github.com/<your user name>/rails.git +$ git remote add mine git@github.com:<your user name>/rails.git </shell> Push to your remote: @@ -361,7 +361,7 @@ $ git push mine my_new_branch h4. Issue a Pull Request -Navigate to the Rails repository you just pushed to (e.g. https://github.com/<your user name>/rails) and press "Pull Request" in the upper right hand corner. +Navigate to the Rails repository you just pushed to (e.g. https://github.com/your-user-name/rails) and press "Pull Request" in the upper right hand corner. Write your branch name in branch field (is filled with master by default) and press "Update Commit Range" diff --git a/railties/guides/source/credits.html.erb b/railties/guides/source/credits.html.erb index 65e396be95..da6bd6acdf 100644 --- a/railties/guides/source/credits.html.erb +++ b/railties/guides/source/credits.html.erb @@ -9,18 +9,14 @@ Ruby on Rails Guides: Credits <% end %> -<h3 class="section">Rails Documentation Team</h3> +<h3 class="section">Rails Guides Reviewers</h3> -<%= author('Mike Gunderloy', 'mgunderloy') do %> - Mike Gunderloy is a consultant with <a href="http://www.actionrails.com">ActionRails</a>. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at <a href="http://afreshcup.com">A Fresh Cup</a> and he <a href="http://twitter.com/MikeG1">twitters</a> too much. -<% end %> - -<%= author('Pratik Naik', 'lifo') do %> - Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through => :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>. +<%= author('Vijay Dev', 'vijaydev', 'vijaydev.jpg') do %> + Vijayakumar, found as Vijay Dev on the web, is a web applications developer and an open source enthusiast who lives in Chennai, India. He started using Rails in 2009 and began actively contributing to Rails documentation in late 2010. He <a href="https://twitter.com/vijay_dev">tweets</a> a lot and also <a href="http://vijaydev.wordpress.com">blogs</a>. <% end %> <%= author('Xavier Noria', 'fxn', 'fxn.png') do %> - Xavier Noria has been into Ruby on Rails since 2005. He is a Rails committer and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently a Ruby on Rails consultant. Oh, he also <a href="http://twitter.com/fxn">tweets</a> and can be found everywhere as "fxn". + Xavier Noria has been into Ruby on Rails since 2005. He is a Rails core team member and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently an independent Ruby on Rails consultant. Oh, he also <a href="http://twitter.com/fxn">tweets</a> and can be found everywhere as "fxn". <% end %> <h3 class="section">Rails Guides Designers</h3> @@ -31,6 +27,10 @@ Ruby on Rails Guides: Credits <h3 class="section">Rails Guides Authors</h3> +<%= author('Ryan Bigg', 'radar', 'radar.png') do %> +Ryan Bigg works as a consultant at <a href="http://rubyx.com">RubyX</a> and has been working with Rails since 2006. He's co-authoring a book called <a href="http://manning.com/katz">Rails 3 in Action</a> and he's written many gems which can be seen on <a href="http://github.com/radar">his GitHub page</a> and he also tweets prolifically as <a href="http://twitter.com/ryanbigg">@ryanbigg</a>. +<% end %> + <%= author('Frederick Cheung', 'fcheung') do %> Frederick Cheung is Chief Wizard at Texperts where he has been using Rails since 2006. He is based in Cambridge (UK) and when not consuming fine ales he blogs at <a href="http://www.spacevatican.org">spacevatican.org</a>. <% end %> @@ -43,6 +43,10 @@ Ruby on Rails Guides: Credits Jeff Dean is a software engineer with <a href="http://pivotallabs.com">Pivotal Labs</a>. <% end %> +<%= author('Mike Gunderloy', 'mgunderloy') do %> + Mike Gunderloy is a consultant with <a href="http://www.actionrails.com">ActionRails</a>. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at <a href="http://afreshcup.com">A Fresh Cup</a> and he <a href="http://twitter.com/MikeG1">twitters</a> too much. +<% end %> + <%= author('Mikel Lindsaar', 'raasdnil') do %> Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby <a href="https://github.com/mikel/mail">Mail gem</a> and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of <a href="http://rubyx.com/">RubyX</a>, has a <a href="http://lindsaar.net/">blog</a> and <a href="http://twitter.com/raasdnil">tweets</a>. <% end %> @@ -55,6 +59,10 @@ Ruby on Rails Guides: Credits James Miller is a software developer for <a href="http://www.jk-tech.com">JK Tech</a> in San Diego, CA. You can find James on GitHub, Gmail, Twitter, and Freenode as "bensie". <% end %> +<%= author('Pratik Naik', 'lifo') do %> + Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through => :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>. +<% end %> + <%= author('Emilio Tagua', 'miloops') do %> Emilio Tagua —a.k.a. miloops— is an Argentinian entrepreneur, developer, open source contributor and Rails evangelist. Cofounder of <a href="http://eventioz.com">Eventioz</a>. He has been using Rails since 2006 and contributing since early 2008. Can be found at gmail, twitter, freenode, everywhere as "miloops". <% end %> diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index 4134c9f8ed..4314d00f2e 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -545,7 +545,7 @@ NOTE: In many cases the built-in date pickers are clumsy as they do not aid the h4. Individual Components -Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overriden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value. +Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overridden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value. The first parameter specifies which value should be selected and can either be an instance of a Date, Time or DateTime, in which case the relevant component will be extracted, or a numerical value. For example @@ -777,7 +777,7 @@ If you need to post some data to an external resource it is still great to build Sometimes when you submit data to an external resource, like payment gateway, fields you can use in your form are limited by an external API. So you may want not to generate an +authenticity_token+ hidden field at all. For doing this just pass +false+ to the +:authenticity_token+ option: <erb> -<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %> +<%= form_tag 'http://farfar.away/form', :authenticity_token => false) do %> Form contents <% end %> </erb> diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile index a3181b9ac5..2fa1d6e21d 100644 --- a/railties/guides/source/generators.textile +++ b/railties/guides/source/generators.textile @@ -46,7 +46,7 @@ class InitializerGenerator < Rails::Generators::Base end </ruby> -NOTE: +create_file+ is a method provided by +Thor::Actions+ and the documentation for it and its brethren can be found at "rdoc.info":http://rdoc.info/github/wycats/thor/master/Thor/Actions. +NOTE: +create_file+ is a method provided by +Thor::Actions+. Documentation for +create_file+ and other Thor methods can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API. @@ -131,7 +131,7 @@ And let's execute our generator: $ rails generate initializer core_extensions </shell> -We can see that now a initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+. +We can see that now an initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+. The methods that are available for generators are covered in the "final section":#generator-methods of this guide. @@ -365,7 +365,7 @@ $ rails generate scaffold Comment body:text Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication. -h3. Application templates +h3. Application Templates Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template". diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 8a9086f416..6aca5d3420 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -5,7 +5,7 @@ This guide covers getting up and running with Ruby on Rails. After reading it, y * Installing Rails, creating a new Rails application, and connecting your application to a database * The general layout of a Rails application * The basic principles of MVC (Model, View Controller) and RESTful design -* How to quickly generate the starting pieces of a Rails application. +* How to quickly generate the starting pieces of a Rails application endprologue. @@ -177,14 +177,14 @@ In any case, Rails will create a folder in your working directory called <tt>blo |Gemfile|This file allows you to specify what gem dependencies are needed for your Rails application.| |README|This is a brief instruction manual for your application. Use it to tell others what your application does, how to set it up, and so on.| |Rakefile|This file contains batch jobs that can be run from the terminal.| -|app/|Contains the controllers, models, and views for your application. You'll focus on this folder for the remainder of this guide.| +|app/|Contains the controllers, models, views and assets for your application. You'll focus on this folder for the remainder of this guide.| |config/|Configure your application's runtime rules, routes, database, and more.| |config.ru|Rack configuration for Rack based servers used to start the application.| |db/|Shows your current database schema, as well as the database migrations. You'll learn about migrations shortly.| |doc/|In-depth documentation for your application.| |lib/|Extended modules for your application (not covered in this guide).| |log/|Application log files.| -|public/|The only folder seen to the world as-is. This is where your images, JavaScript files, stylesheets (CSS), and other static files go.| +|public/|The only folder seen to the world as-is. Contains the static files and compiled assets.| |script/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.| |test/|Unit tests, fixtures, and other test apparatus. These are covered in "Testing Rails Applications":testing.html| |tmp/|Temporary files| @@ -205,8 +205,8 @@ h4. Configuring a Database Just about every Rails application will interact with a database. The database to use is specified in a configuration file, +config/database.yml+. If you open this file in a new Rails application, you'll see a default database configuration using SQLite3. The file contains sections for three different environments in which Rails can run by default: -* The +development+ environment is used on your development computer as you interact manually with the application -* The +test+ environment is used to run automated tests +* The +development+ environment is used on your development computer as you interact manually with the application. +* The +test+ environment is used to run automated tests. * The +production+ environment is used when you deploy your application for the world to use. h5. Configuring an SQLite3 Database @@ -244,7 +244,7 @@ If your development computer's MySQL installation includes a root user with an e h5. Configuring a PostgreSQL Database -Finally if you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases: +If you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases: <yaml> development: @@ -256,6 +256,41 @@ development: password: </yaml> +h5. Configuring an SQLite3 Database for JRuby Platform + +If you choose to use SQLite3 and using JRuby, your +config/database.yml+ will look a little different. Here's the development section: + +<yaml> +development: + adapter: jdbcsqlite3 + database: db/development.sqlite3 +</yaml> + +h5. Configuring a MySQL Database for JRuby Platform + +If you choose to use MySQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section: + +<yaml> +development: + adapter: jdbcmysql + database: blog_development + username: root + password: +</yaml> + +h5. Configuring a PostgreSQL Database for JRuby Platform + +Finally if you choose to use PostgreSQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section: + +<yaml> +development: + adapter: jdbcpostgresql + encoding: unicode + database: blog_development + username: blog + password: +</yaml> + Change the username and password in the +development+ section as appropriate. TIP: You don't have to update the database configurations manually. If you had a look at the options of application generator, you have seen that one of them is named <tt>--database</tt>. It lets you choose an adapter for couple of most used relational databases. You can even run the generator repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting of the +config/database.yml+ file, your application will be configured for MySQL instead of SQLite. @@ -290,7 +325,7 @@ This will fire up an instance of the WEBrick web server by default (Rails can al TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server. -The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your Application's environment. +The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment. h4. Say "Hello", Rails @@ -364,11 +399,11 @@ The scaffold generator will build 15 files in your application, along with some |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| |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| |config/routes.rb |Edited to include routing information for posts| -|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better| h4. Running a Migration @@ -413,10 +448,10 @@ h4. Adding a Link To hook the posts up to the home page you've already created, you can add a link to the home page. Open +app/views/home/index.html.erb+ and modify it as follows: -<code lang="ruby"> +<ruby> <h1>Hello, Rails!</h1> <%= link_to "My Blog", posts_path %> -</code> +</ruby> The +link_to+ method is one of Rails' built-in view helpers. It creates a hyperlink based on text to display and where to go - in this case, to the path for posts. @@ -503,7 +538,7 @@ def index end </ruby> -+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in a instance variable called +@posts+. ++Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in an instance variable called +@posts+. TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html. diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 608643b3d3..0c8e4e974d 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -809,7 +809,7 @@ That does not mean you're stuck with these limitations, though. The Ruby I18n ge I18n.backend = Globalize::Backend::Static.new </ruby> -You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the ActiveRecord backend and fall back to the (default) Simple backend: +You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the Active Record backend and fall back to the (default) Simple backend: <ruby> I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend) diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 638830cd83..340699419b 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -20,15 +20,15 @@ h4. +bin/rails+ The actual +rails+ command is kept in _bin/rails_ at the and goes like this: <ruby> - #!/usr/bin/env ruby - - begin - require "rails/cli" - rescue LoadError - railties_path = File.expand_path('../../railties/lib', __FILE__) - $:.unshift(railties_path) - require "rails/cli" - end +#!/usr/bin/env ruby + +begin + require "rails/cli" +rescue LoadError + railties_path = File.expand_path('../../railties/lib', __FILE__) + $:.unshift(railties_path) + require "rails/cli" +end </ruby> This file will attempt to load +rails/cli+ and if it cannot find it then add the +railties/lib+ path to the load path (+$:+) and will then try to require it again. @@ -38,22 +38,22 @@ h4. +railites/lib/rails/cli.rb+ This file looks like this: <ruby> - require 'rbconfig' - require 'rails/script_rails_loader' +require 'rbconfig' +require 'rails/script_rails_loader' - # If we are inside a Rails application this method performs an exec and thus - # the rest of this script is not run. - Rails::ScriptRailsLoader.exec_script_rails! +# If we are inside a Rails application this method performs an exec and thus +# the rest of this script is not run. +Rails::ScriptRailsLoader.exec_script_rails! - require 'rails/ruby_version_check' - Signal.trap("INT") { puts; exit } +require 'rails/ruby_version_check' +Signal.trap("INT") { puts; exit } - if ARGV.first == 'plugin' - ARGV.shift - require 'rails/commands/plugin_new' - else - require 'rails/commands/application' - end +if ARGV.first == 'plugin' + ARGV.shift + require 'rails/commands/plugin_new' +else + require 'rails/commands/application' +end </ruby> The +rbconfig+ file here is out of Ruby's standard library and provides us with the +RbConfig+ class which contains useful information dependent on how Ruby was compiled. We'll see this in use in +railties/lib/rails/script_rails_loader+. @@ -76,46 +76,46 @@ The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +b Back in +rails/cli+, the next line is this: <ruby> - Rails::ScriptRailsLoader.exec_script_rails! +Rails::ScriptRailsLoader.exec_script_rails! </ruby> This method is defined in +rails/script_rails_loader+ like this: <ruby> - def self.exec_script_rails! - cwd = Dir.pwd - return unless in_rails_application? || in_rails_application_subdirectory? - exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? - Dir.chdir("..") do - # Recurse in a chdir block: if the search fails we want to be sure - # the application is generated in the original working directory. - exec_script_rails! unless cwd == Dir.pwd - end - rescue SystemCallError - # could not chdir, no problem just return +def self.exec_script_rails! + cwd = Dir.pwd + return unless in_rails_application? || in_rails_application_subdirectory? + exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? + Dir.chdir("..") do + # Recurse in a chdir block: if the search fails we want to be sure + # the application is generated in the original working directory. + exec_script_rails! unless cwd == Dir.pwd end +rescue SystemCallError + # could not chdir, no problem just return +end </ruby> This method will first check if the current working directory (+cwd+) is a Rails application or is a subdirectory of one. The way to determine this is defined in the +in_rails_application?+ method like this: <ruby> - def self.in_rails_application? - File.exists?(SCRIPT_RAILS) - end +def self.in_rails_application? + File.exists?(SCRIPT_RAILS) +end </ruby> The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+, then +in_rails_application_subdirectory?+ will be used: <ruby> - def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) - File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent) - end +def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) + File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent) +end </ruby> This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory is reached which contains this file then this line will run: <ruby> - exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? +exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? </ruby> This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server". @@ -125,9 +125,9 @@ h4. +script/rails+ This file looks like this: <ruby> - APP_PATH = File.expand_path('../../config/application', __FILE__) - require File.expand_path('../../config/boot', __FILE__) - require 'rails/commands' +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' </ruby> The +APP_PATH+ constant here will be used later in +rails/commands+. The +config/boot+ file that +script/rails+ references is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up. @@ -137,19 +137,19 @@ h4. +config/boot.rb+ +config/boot.rb+ contains this: <ruby> - require 'rubygems' +require 'rubygems' - # Set up gems listed in the Gemfile. - gemfile = File.expand_path('../../Gemfile', __FILE__) - begin - ENV['BUNDLE_GEMFILE'] = gemfile - require 'bundler' - Bundler.setup - rescue Bundler::GemNotFound => e - STDERR.puts e.message - STDERR.puts "Try running `bundle install`." - exit! - end if File.exist?(gemfile) +# Set up gems listed in the Gemfile. +gemfile = File.expand_path('../../Gemfile', __FILE__) +begin + ENV['BUNDLE_GEMFILE'] = gemfile + require 'bundler' + Bundler.setup +rescue Bundler::GemNotFound => e + STDERR.puts e.message + STDERR.puts "Try running `bundle install`." + exit! +end if File.exist?(gemfile) </ruby> In a standard Rails application, there's a +Gemfile+ which declares all dependencies of the application. +config/boot.rb+ sets +ENV["BUNDLE_GEMFILE"]+ to the location of this file, then requires Bundler and calls +Bundler.setup+ which adds the dependencies of the application (including all the Rails parts) to the load path, making them available for the application to load. The gems that a Rails 3.1 application depends on are as follows: @@ -186,34 +186,34 @@ h4. +rails/commands.rb+ Once +config/boot.rb+ has finished, the next file that is required is +rails/commands+ which will execute a command based on the arguments passed in. In this case, the +ARGV+ array simply contains +server+ which is extracted into the +command+ variable using these lines: <ruby> - aliases = { - "g" => "generate", - "c" => "console", - "s" => "server", - "db" => "dbconsole" - } +aliases = { + "g" => "generate", + "c" => "console", + "s" => "server", + "db" => "dbconsole" +} - command = ARGV.shift - command = aliases[command] || command +command = ARGV.shift +command = aliases[command] || command </ruby> If we used <tt>s</tt> rather than +server+, Rails will use the +aliases+ defined in the file and match them to their respective commands. With the +server+ command, Rails will run this code: <ruby> - when 'server' - # Change to the application's path if there is no config.ru file in current dir. - # This allows us to run script/rails server from other directories, but still get - # the main config.ru and properly set the tmp directory. - Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) - - require 'rails/commands/server' - Rails::Server.new.tap { |server| - # We need to require application after the server sets environment, - # otherwise the --environment option given to the server won't propagate. - require APP_PATH - Dir.chdir(Rails.application.root) - server.start - } +when 'server' + # Change to the application's path if there is no config.ru file in current dir. + # This allows us to run script/rails server from other directories, but still get + # the main config.ru and properly set the tmp directory. + Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) + + require 'rails/commands/server' + Rails::Server.new.tap { |server| + # We need to require application after the server sets environment, + # otherwise the --environment option given to the server won't propagate. + require APP_PATH + Dir.chdir(Rails.application.root) + server.start + } </ruby> This file will change into the root of the directory (a path two directories back from +APP_PATH+ which points at +config/application.rb+), but only if the +config.ru+ file isn't found. This then requires +rails/commands/server+ which requires +action_dispatch+ and sets up the +Rails::Server+ class. @@ -239,7 +239,7 @@ The +methods.rb+ file is responsible for defining methods such as +camelize+, +u In this file there are a lot of lines such as this inside the +ActiveSupport+ module: <ruby> - autoload :Inflector +autoload :Inflector </ruby> Due to the overriding of the +autoload+ method, Ruby will know to look for this file at +activesupport/lib/active_support/inflector.rb+ when the +Inflector+ class is first referenced. @@ -263,10 +263,10 @@ h4. +rails/commands/server.rb+ The +Rails::Server+ class is defined in this file as inheriting from +Rack::Server+. When +Rails::Server.new+ is called, this calls the +initialize+ method in +rails/commands/server.rb+: <ruby> - def initialize(*) - super - set_environment - end +def initialize(*) + super + set_environment +end </ruby> Firstly, +super+ is called which calls the +initialize+ method on +Rack::Server+. @@ -278,10 +278,10 @@ h4. Rack: +lib/rack/server.rb+ The +initialize+ method in +Rack::Server+ simply sets a couple of variables: <ruby> - def initialize(options = nil) - @options = options - @app = options[:app] if options && options[:app] - end +def initialize(options = nil) + @options = options + @app = options[:app] if options && options[:app] +end </ruby> In this case, +options+ will be +nil+ so nothing happens in this method. @@ -289,64 +289,64 @@ In this case, +options+ will be +nil+ so nothing happens in this method. After +super+ has finished in +Rack::Server+, we jump back to +rails/commands/server.rb+. At this point, +set_environment+ is called within the context of the +Rails::Server+ object and this method doesn't appear to do much at first glance: <ruby> - def set_environment - ENV["RAILS_ENV"] ||= options[:environment] - end +def set_environment + ENV["RAILS_ENV"] ||= options[:environment] +end </ruby> In fact, the +options+ method here does quite a lot. This method is defined in +Rack::Server+ like this: <ruby> - def options - @options ||= parse_options(ARGV) - end +def options + @options ||= parse_options(ARGV) +end </ruby> Then +parse_options+ is defined like this: <ruby> - def parse_options(args) - options = default_options +def parse_options(args) + options = default_options - # Don't evaluate CGI ISINDEX parameters. - # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html - args.clear if ENV.include?("REQUEST_METHOD") + # Don't evaluate CGI ISINDEX parameters. + # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html + args.clear if ENV.include?("REQUEST_METHOD") - options.merge! opt_parser.parse! args - options[:config] = ::File.expand_path(options[:config]) - ENV["RACK_ENV"] = options[:environment] - options - end + options.merge! opt_parser.parse! args + options[:config] = ::File.expand_path(options[:config]) + ENV["RACK_ENV"] = options[:environment] + options +end </ruby> With the +default_options+ set to this: <ruby> - def default_options - { - :environment => ENV['RACK_ENV'] || "development", - :pid => nil, - :Port => 9292, - :Host => "0.0.0.0", - :AccessLog => [], - :config => "config.ru" - } - end +def default_options + { + :environment => ENV['RACK_ENV'] || "development", + :pid => nil, + :Port => 9292, + :Host => "0.0.0.0", + :AccessLog => [], + :config => "config.ru" + } +end </ruby> There is no +REQUEST_METHOD+ key in +ENV+ so we can skip over that line. The next line merges in the options from +opt_parser+ which is defined plainly in +Rack::Server+ <ruby> - def opt_parser - Options.new - end +def opt_parser + Options.new +end </ruby> The class *is* defined in +Rack::Server+, but is overwritten in +Rails::Server+ to take different arguments. Its +parse!+ method begins like this: <ruby> - def parse!(args) - args, options = args.dup, {} +def parse!(args) + args, options = args.dup, {} opt_parser = OptionParser.new do |opts| opts.banner = "Usage: rails server [mongrel, thin, etc] [options]" @@ -362,100 +362,101 @@ h4. +Rails::Server#start+ This method is defined like this: <ruby> - def start - puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" - puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}" - puts "=> Call with -d to detach" unless options[:daemonize] - trap(:INT) { exit } - puts "=> Ctrl-C to shutdown server" unless options[:daemonize] - - #Create required tmp directories if not found - %w(cache pids sessions sockets).each do |dir_to_make| - FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make)) - end - - super - ensure - # The '-h' option calls exit before @options is set. - # If we call 'options' with it unset, we get double help banners. - puts 'Exiting' unless @options && options[:daemonize] +def start + puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" + puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}" + puts "=> Call with -d to detach" unless options[:daemonize] + trap(:INT) { exit } + puts "=> Ctrl-C to shutdown server" unless options[:daemonize] + + #Create required tmp directories if not found + %w(cache pids sessions sockets).each do |dir_to_make| + FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make)) end + + super +ensure + # The '-h' option calls exit before @options is set. + # If we call 'options' with it unset, we get double help banners. + puts 'Exiting' unless @options && options[:daemonize] +end </ruby> This is where the first output of the Rails initialization happens. This method creates a trap for +INT+ signals, so if you +CTRL+C+ the server, it will exit the process. As we can see from the code here, it will create the +tmp/cache+, +tmp/pids+, +tmp/sessions+ and +tmp/sockets+ directories if they don't already exist prior to calling +super+. The +super+ method will call +Rack::Server.start+ which begins its definition like this: <ruby> - def start - if options[:warn] - $-w = true - end +def start + if options[:warn] + $-w = true + end - if includes = options[:include] - $LOAD_PATH.unshift(*includes) - end + if includes = options[:include] + $LOAD_PATH.unshift(*includes) + end - if library = options[:require] - require library - end + if library = options[:require] + require library + end - if options[:debug] - $DEBUG = true - require 'pp' - p options[:server] - pp wrapped_app - pp app - end + if options[:debug] + $DEBUG = true + require 'pp' + p options[:server] + pp wrapped_app + pp app + end +end </ruby> In a Rails application, these options are not set at all and therefore aren't used at all. The first line of code that's executed in this method is a call to this method: <ruby> - wrapped_app +wrapped_app </ruby> This method calls another method: <ruby> - @wrapped_app ||= build_app app +@wrapped_app ||= build_app app </ruby> Then the +app+ method here is defined like so: <ruby> - def app - @app ||= begin - if !::File.exist? options[:config] - abort "configuration #{options[:config]} not found" - end - - app, options = Rack::Builder.parse_file(self.options[:config], opt_parser) - self.options.merge! options - app +def app + @app ||= begin + if !::File.exist? options[:config] + abort "configuration #{options[:config]} not found" end + + app, options = Rack::Builder.parse_file(self.options[:config], opt_parser) + self.options.merge! options + app end +end </ruby> The +options[:config]+ value defaults to +config.ru+ which contains this: <ruby> - # This file is used by Rack-based servers to start the application. +# This file is used by Rack-based servers to start the application. - require ::File.expand_path('../config/environment', __FILE__) - run YourApp::Application +require ::File.expand_path('../config/environment', __FILE__) +run YourApp::Application </ruby> 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 {( " + cfgfile + "\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: <ruby> - require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('../config/environment', __FILE__) </ruby> h4. +config/environment.rb+ @@ -475,7 +476,7 @@ h3. Loading Rails The next line in +config/application.rb+ is: <ruby> - require 'rails/all' +require 'rails/all' </ruby> h4. +railties/lib/rails/all.rb+ @@ -483,20 +484,20 @@ h4. +railties/lib/rails/all.rb+ This file is responsible for requiring all the individual parts of Rails like so: <ruby> - require "rails" +require "rails" - %w( +%w( active_record action_controller action_mailer active_resource rails/test_unit - ).each do |framework| - begin - require "#{framework}/railtie" - rescue LoadError - end +).each do |framework| + begin + require "#{framework}/railtie" + rescue LoadError end +end </ruby> First off the line is the +rails+ require itself. @@ -518,9 +519,9 @@ h4. +active_support/core_ext/kernel/reporting.rb+ This is the first of the many Active Support core extensions that come with Rails. This one in particular defines methods in the +Kernel+ module which is mixed in to the +Object+ class so the methods are available on +main+ and can therefore be called like this: <ruby> - silence_warnings do - # some code - end +silence_warnings do + # some code +end </ruby> These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide. @@ -635,14 +636,14 @@ h4. +railties/lib/rails/rack.rb+ The final file to be loaded by +railties/lib/rails/configuration.rb+ is +rails/rack+ which defines some simple autoloads: <ruby> - module Rails - module Rack - autoload :Debugger, "rails/rack/debugger" - autoload :Logger, "rails/rack/logger" - autoload :LogTailer, "rails/rack/log_tailer" - autoload :Static, "rails/rack/static" - end +module Rails + module Rack + autoload :Debugger, "rails/rack/debugger" + autoload :Logger, "rails/rack/logger" + autoload :LogTailer, "rails/rack/log_tailer" + autoload :Static, "rails/rack/static" end +end </ruby> Once this file is finished loading, then the +Rails::Configuration+ class is initialized. This completes the loading of +railties/lib/rails/configuration.rb+ and now we jump back to the loading of +railties/lib/rails/railtie.rb+, where the next file loaded is +active_support/inflector+. @@ -652,17 +653,17 @@ h4. +activesupport/lib/active_support/inflector.rb+ +active_support/inflector.rb+ requires a series of file which are responsible for setting up the basics for knowing how to pluralize and singularize words. These files are: <ruby> - require 'active_support/inflector/inflections' - require 'active_support/inflector/transliterate' - require 'active_support/inflector/methods' +require 'active_support/inflector/inflections' +require 'active_support/inflector/transliterate' +require 'active_support/inflector/methods' - require 'active_support/inflections' - require 'active_support/core_ext/string/inflections' +require 'active_support/inflections' +require 'active_support/core_ext/string/inflections' </ruby> -The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here. +The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here. The +activesupport/lib/active_support/inflector/inflections.rb+ is required by +active_support/inflector/methods+. -h4. +activesupport/lib/active_support/inflector/inflections.rb+ +h4. +active_support/inflections+ This file references the +ActiveSupport::Inflector+ constant which isn't loaded by this point. But there were autoloads set up in +activesupport/lib/active_support.rb+ which will load the file which loads this constant and so then it will be defined. Then this file defines pluralization and singularization rules for words in Rails. This is how Rails knows how to pluralize "tomato" to "tomatoes". @@ -721,22 +722,22 @@ h4. +activesupport/lib/active_support/i18n_railtie.rb+ This file is the first file that sets up configuration with these lines inside the class: <ruby> - class Railtie < Rails::Railtie - config.i18n = ActiveSupport::OrderedOptions.new - config.i18n.railties_load_path = [] - config.i18n.load_path = [] - config.i18n.fallbacks = ActiveSupport::OrderedOptions.new +class Railtie < Rails::Railtie + config.i18n = ActiveSupport::OrderedOptions.new + config.i18n.railties_load_path = [] + config.i18n.load_path = [] + config.i18n.fallbacks = ActiveSupport::OrderedOptions.new </ruby> By inheriting from +Rails::Railtie+ the +Rails::Railtie#inherited+ method is called: <ruby> - def inherited(base) - unless base.abstract_railtie? - base.send(:include, Railtie::Configurable) - subclasses << base - end +def inherited(base) + unless base.abstract_railtie? + base.send(:include, Railtie::Configurable) + subclasses << base end +end </ruby> This first checks if the Railtie that's inheriting it is a component of Rails itself: @@ -763,15 +764,15 @@ end The +config+ method used at the top of +I18n::Railtie+ is defined on +Rails::Railtie+ and is defined like this: <ruby> - def config - @config ||= Railtie::Configuration.new - end +def config + @config ||= Railtie::Configuration.new +end </ruby> At this point, that +Railtie::Configuration+ constant is automatically loaded which causes the +rails/railties/configuration+ file to be loaded. The line for this is this particular line in +railties/lib/rails/railtie.rb+: <ruby> - autoload :Configuration, "rails/railtie/configuration" +autoload :Configuration, "rails/railtie/configuration" </ruby> h4. +railties/lib/rails/railtie/configuration.rb+ @@ -781,15 +782,15 @@ This file begins with a require out to +rails/configuration+ which has already b This file defines the +Rails::Railtie::Configuration+ class which is responsible for providing a way to easily configure railties and it's the +initialize+ method here which is called by the +config+ method back in the +i18n_railtie.rb+ file. The methods on this object don't exist, and so are rescued by the +method_missing+ defined further down in +configuration.rb+: <ruby> - def method_missing(name, *args, &blk) - if name.to_s =~ /=$/ - @@options[$`.to_sym] = args.first - elsif @@options.key?(name) - @@options[name] - else - super - end +def method_missing(name, *args, &blk) + if name.to_s =~ /=$/ + @@options[$`.to_sym] = args.first + elsif @@options.key?(name) + @@options[name] + else + super end +end </ruby> So therefore when an option is referred to it simply stores the value as the key if it's used in a setter context, or retrieves it if used in a getter context. Nothing fancy going on there. @@ -799,21 +800,21 @@ h4. Back to +activesupport/lib/active_support/i18n_railtie.rb+ After the configuration method the +reloader+ method is defined, and then the first of of Railties' initializers is defined: +i18n.callbacks+. <ruby> - initializer "i18n.callbacks" do - ActionDispatch::Reloader.to_prepare do - I18n::Railtie.reloader.execute_if_updated - end +initializer "i18n.callbacks" do + ActionDispatch::Reloader.to_prepare do + I18n::Railtie.reloader.execute_if_updated end +end </ruby> The +initializer+ method (from the +Rails::Initializable+ module) here doesn't run the block, but rather stores it to be run later on: <ruby> - def initializer(name, opts = {}, &blk) - raise ArgumentError, "A block must be passed when defining an initializer" unless blk - opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] } - initializers << Initializer.new(name, nil, opts, &blk) - end +def initializer(name, opts = {}, &blk) + raise ArgumentError, "A block must be passed when defining an initializer" unless blk + opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] } + initializers << Initializer.new(name, nil, opts, &blk) +end </ruby> An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer]. @@ -821,25 +822,25 @@ An initializer can be configured to run before or after another initializer, whi The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables: <ruby> - def initialize(name, context, options, &block) - @name, @context, @options, @block = name, context, options, block - end +def initialize(name, context, options, &block) + @name, @context, @options, @block = name, context, options, block +end </ruby> Once this +initialize+ method is finished, the object is added to the object the +initializers+ method returns: <ruby> - def initializers - @initializers ||= self.class.initializers_for(self) - end +def initializers + @initializers ||= self.class.initializers_for(self) +end </ruby> If +@initializers+ isn't set (which it won't be at this point), the +intializers_for+ method will be called for this class. <ruby> - def initializers_for(binding) - Collection.new(initializers_chain.map { |i| i.bind(binding) }) - end +def initializers_for(binding) + Collection.new(initializers_chain.map { |i| i.bind(binding) }) +end </ruby> The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +Array+ and includes the +TSort+ module which is used to sort out the order of the initializers based on the order they are placed in. @@ -847,57 +848,57 @@ The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +A The +initializers_chain+ method referenced in the +initializers_for+ method is defined like this: <rub> - def initializers_chain - initializers = Collection.new - ancestors.reverse_each do | klass | - next unless klass.respond_to?(:initializers) - initializers = initializers + klass.initializers - end - initializers +def initializers_chain + initializers = Collection.new + ancestors.reverse_each do | klass | + next unless klass.respond_to?(:initializers) + initializers = initializers + klass.initializers end + initializers +end </ruby> This method collects the initializers from the ancestors of this class and adds them to a new +Collection+ object using the <tt>+</tt> method which is defined like this for the <tt>Collection</tt> class: <ruby> - def +(other) - Collection.new(to_a + other.to_a) - end +def +(other) + Collection.new(to_a + other.to_a) +end </ruby> -So this <tt>+</tt> method is overriden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer. +So this <tt>+</tt> method is overridden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer. The next method to be called after this +initializer+ method is the +after_initialize+ method on the +config+ object, which is defined like this: <ruby> - def after_initialize(&block) - ActiveSupport.on_load(:after_initialize, :yield => true, &block) - end +def after_initialize(&block) + ActiveSupport.on_load(:after_initialize, :yield => true, &block) +end </ruby> The +on_load+ method here is provided by the +active_support/lazy_load_hooks+ file which was required earlier and is defined like this: <ruby> - def self.on_load(name, options = {}, &block) - if base = @loaded[name] - execute_hook(base, options, block) - else - @load_hooks[name] << [block, options] - end +def self.on_load(name, options = {}, &block) + if base = @loaded[name] + execute_hook(base, options, block) + else + @load_hooks[name] << [block, options] end +end </ruby> The +@loaded+ variable here is a hash containing elements representing the different components of Rails that have been loaded at this stage. Currently, this hash is empty. So the +else+ is executed here, using the +@load_hooks+ variable defined in +active_support/lazy_load_hooks+: <ruby> - @load_hooks = Hash.new {|h,k| h[k] = [] } +@load_hooks = Hash.new {|h,k| h[k] = [] } </ruby> This defines a new hash which has keys that default to empty arrays. This saves Rails from having to do something like this instead: <ruby> - @load_hooks[name] = [] - @load_hooks[name] << [block, options] +@load_hooks[name] = [] +@load_hooks[name] << [block, options] </ruby> The value added to this array here consists of the block and options passed to +after_initialize+. @@ -929,11 +930,11 @@ h4. +activesupport/lib/action_dispatch.rb+ This file attempts to locate the +active_support+ and +active_model+ libraries by looking a couple of directories back from the current file and then adds the +active_support+ and +active_model+ +lib+ directories to the load path, but only if they aren't already, which they are. <ruby> - activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__) - $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path) +activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__) +$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path) - activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) - $:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path) +activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) +$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path) </ruby> In effect, these lines only define the +activesupport_path+ and +activemodel_path+ variables and nothing more. @@ -941,23 +942,23 @@ In effect, these lines only define the +activesupport_path+ and +activemodel_pat The next two requires in this file are already done, so they are not run: <ruby> - require 'active_support' - require 'active_support/dependencies/autoload' +require 'active_support' +require 'active_support/dependencies/autoload' </ruby> The following require is to +action_pack+ (+activesupport/lib/action_pack.rb+) which has a 22-line copyright notice at the top of it and ends in a simple require to +action_pack/version+. This file, like other +version.rb+ files before it, defines the +ActionPack::VERSION+ constant: <ruby> - module ActionPack - module VERSION #:nodoc: - MAJOR = 3 - MINOR = 1 - TINY = 0 - PRE = "beta" - - STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') - end +module ActionPack + module VERSION #:nodoc: + MAJOR = 3 + MINOR = 1 + TINY = 0 + PRE = "beta" + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end +end </ruby> Once +action_pack+ is finished, then +active_model+ is required. @@ -967,16 +968,16 @@ h4. +activemodel/lib/active_model.rb+ This file makes a require to +active_model/version+ which defines the version for Active Model: <ruby> - module ActiveModel - module VERSION #:nodoc: - MAJOR = 3 - MINOR = 1 - TINY = 0 - PRE = "beta" - - STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') - end +module ActiveModel + module VERSION #:nodoc: + MAJOR = 3 + MINOR = 1 + TINY = 0 + PRE = "beta" + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end +end </ruby> Once the +version.rb+ file is loaded, the +ActiveModel+ module has its autoloaded constants defined as well as a sub-module called +ActiveModel::Serializers+ which has autoloads of its own. When the +ActiveModel+ module is closed the +active_support/i18n+ file is required. @@ -986,15 +987,15 @@ h4. +activesupport/lib/active_support/i18n.rb+ This is where the +i18n+ gem is required and first configured: <ruby> - begin - require 'i18n' - require 'active_support/lazy_load_hooks' - rescue LoadError => e - $stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install" - raise e - end +begin + require 'i18n' + require 'active_support/lazy_load_hooks' +rescue LoadError => e + $stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end - I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml" +I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml" </ruby> In effect, the +I18n+ module first defined by +i18n_railtie+ is extended by the +i18n+ gem, rather than the other way around. This has no ill effect. They both work on the same way. @@ -1012,9 +1013,9 @@ h4. Back to +activesupport/lib/action_dispatch.rb+ The remainder of this file requires the +rack+ file from the Rack gem which defines the +Rack+ module. After +rack+, there's autoloads defined for the +Rack+, +ActionDispatch+, +ActionDispatch::Http+, +ActionDispatch::Session+. A new method called +autoload_under+ is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here: <ruby> - autoload_under 'testing' do - autoload :Assertions - ... +autoload_under 'testing' do + autoload :Assertions +... </ruby> The +Assertions+ module is in the +action_dispatch/testing+ folder rather than simply +action_dispatch+. @@ -1046,25 +1047,25 @@ This file begins by detecting if the +lib+ directories of +active_support+ and + The first three requires have already been done by other files and so aren't loaded here, but the 4th require, the one to +arel+ will require the file provided by the Arel gem, which defines the +Arel+ module. <ruby> - require 'active_support' - require 'active_support/i18n' - require 'active_model' - require 'arel' +require 'active_support' +require 'active_support/i18n' +require 'active_model' +require 'arel' </ruby> The 5th require in this file is one to +active_record/version+ which defines the +ActiveRecord::VERSION+ constant: <ruby> - module ActiveRecord - module VERSION #:nodoc: - MAJOR = 3 - MINOR = 1 - TINY = 0 - PRE = "beta" - - STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') - end +module ActiveRecord + module VERSION #:nodoc: + MAJOR = 3 + MINOR = 1 + TINY = 0 + PRE = "beta" + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end +end </ruby> Once these requires are finished, the base for the +ActiveRecord+ module is defined along with its autoloads. @@ -1072,9 +1073,9 @@ Once these requires are finished, the base for the +ActiveRecord+ module is defi Near the end of the file, we see this line: <ruby> - ActiveSupport.on_load(:active_record) do - Arel::Table.engine = self - end +ActiveSupport.on_load(:active_record) do + Arel::Table.engine = self +end </ruby> This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+. @@ -1082,7 +1083,7 @@ This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+. The file then finishes with this line: <ruby> - I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml' +I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml' </ruby> This will add the translations from +activerecord/lib/active_record/locale/en.yml+ to the load path for +I18n+, with this file being parsed when all the translations are loaded. @@ -1092,8 +1093,8 @@ h4. Back to +activerecord/lib/active_record/railtie.rb+ The next two <tt>require</tt>s in this file aren't run because their files are already required, with +rails+ being required by +rails/all+ and +active_model/railtie+ being required from +action_dispatch+. <ruby> - require "rails" - require "active_model/railtie" +require "rails" +require "active_model/railtie" </ruby> The next +require+ in this file is to +action_controller/railtie+. @@ -1103,9 +1104,9 @@ h4. +actionpack/lib/action_controller/railtie.rb+ This file begins with a couple more requires to files that have already been loaded: <ruby> - require "rails" - require "action_controller" - require "action_dispatch/railtie" +require "rails" +require "action_controller" +require "action_dispatch/railtie" </ruby> However the require after these is to a file that hasn't yet been loaded, +action_view/railtie+, which begins by requiring +action_view+. diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index d67668df91..ba45b84242 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -123,7 +123,7 @@ Cache-Control: no-cache $ </shell> -We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgement that the request was completed. +We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgment that the request was completed. TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers. diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile index d60b68ec7f..f17f686d47 100644 --- a/railties/guides/source/migrations.textile +++ b/railties/guides/source/migrations.textile @@ -55,6 +55,8 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration end </ruby> +NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations. + This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered to have already opted in, so we use the User model to set the flag to +true+ for existing users. @@ -73,11 +75,9 @@ class CreateProducts < ActiveRecord::Migration end </ruby> -NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations. - h4. Migrations are Classes -A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two class methods: +up+ (perform the required transformations) and +down+ (revert them). +A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two methods: +up+ (perform the required transformations) and +down+ (revert them). Active Record provides methods that perform common data definition tasks in a database independent way (you'll read about them in detail later): @@ -115,7 +115,7 @@ h4. Changing Migrations Occasionally you will make a mistake when writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version. -In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless. Just use some common sense. +In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless. h3. Creating a Migration diff --git a/railties/guides/source/nested_model_forms.textile b/railties/guides/source/nested_model_forms.textile index 55694c0eb4..4b1fd2e0ac 100644 --- a/railties/guides/source/nested_model_forms.textile +++ b/railties/guides/source/nested_model_forms.textile @@ -90,7 +90,7 @@ h3. Views h4. Controller code -A nested model form will _only_ be build if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first. +A nested model form will _only_ be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first. Consider the following typical RESTful controller which will prepare a new Person instance and its +address+ and +projects+ associations before rendering the +new+ template: @@ -144,7 +144,7 @@ Now add a nested form for the +address+ association: <%= f.text_field :name %> <%= f.fields_for :address do |af| %> - <%= f.text_field :street %> + <%= af.text_field :street %> <% end %> <% end %> </erb> @@ -159,7 +159,7 @@ This generates: </form> </html> -Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be build by the way it has namespaced the +name+ attribute. +Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be built by the way it has namespaced the +name+ attribute. When this form is posted the Rails parameter parser will construct a hash like the following: @@ -185,7 +185,7 @@ The form code for an association collection is pretty similar to that of a singl <%= f.text_field :name %> <%= f.fields_for :projects do |pf| %> - <%= f.text_field :name %> + <%= pf.text_field :name %> <% end %> <% end %> </erb> @@ -201,7 +201,7 @@ Which generates: </form> </html> -As you can see it has generated 2 +project name+ inputs, one for each new +project+ that’s build in the controllers +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as: +As you can see it has generated 2 +project name+ inputs, one for each new +project+ that was built in the controller's +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as: <ruby> { @@ -215,7 +215,7 @@ As you can see it has generated 2 +project name+ inputs, one for each new +proje } </ruby> -You can basically see the +projects_attributes+ hash as an array of attribute hashes. One for each model instance. +You can basically see the +projects_attributes+ hash as an array of attribute hashes, one for each model instance. NOTE: The reason that +fields_for+ constructed a form which would result in a hash instead of an array is that it won't work for any forms nested deeper than one level deep. diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile index 2b79237c59..dbe6f97f5c 100644 --- a/railties/guides/source/performance_testing.textile +++ b/railties/guides/source/performance_testing.textile @@ -66,7 +66,7 @@ resources :posts # home_controller.rb class HomeController < ApplicationController def dashboard - @users = User.last_ten(:include => :avatars) + @users = User.last_ten.includes(:avatars) @posts = Post.all_today end end @@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling. h5. Benchmarking -Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run +4 times+ in benchmarking mode. +Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run *4 times* in benchmarking mode. To run performance tests in benchmarking mode: @@ -161,7 +161,7 @@ $ rake test:benchmark h5. Profiling -Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run +1 time+ in profiling mode. +Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run *once* in profiling mode. To run performance tests in profiling mode: @@ -276,7 +276,7 @@ measurement,created_at,app,rails,ruby,platform h5(#output-profiling). Profiling -In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependant on the interpreter in use. A brief description of each type and their availability across interpreters is given below. +In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependent on the interpreter in use. A brief description of each type and their availability across interpreters is given below. h6. Command Line @@ -481,7 +481,7 @@ h4. +profiler+ Usage: <shell> -Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS] +Usage: rails profiler 'Ruby.code' 'Ruby.more_code' ... [OPTS] -r, --runs N Number of runs. Default: 1 -o, --output PATH Directory to use when writing the results. @@ -573,7 +573,7 @@ h3. Useful Links h4. Rails Plugins and Gems * "Rails Analyzer":http://rails-analyzer.rubyforge.org -* "Palmist":http://www.flyingmachinestudios.com/projects/ +* "Palmist":http://www.flyingmachinestudios.com/programming/announcing-palmist * "Rails Footnotes":https://github.com/josevalim/rails-footnotes/tree/master * "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile index 388d8eea3e..3db47a70e8 100644 --- a/railties/guides/source/rails_application_templates.textile +++ b/railties/guides/source/rails_application_templates.textile @@ -1,6 +1,6 @@ h2. Rails Application Templates -Application templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project. +Application templates are simple Ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project. By referring to this guide, you will be able to: @@ -58,14 +58,12 @@ gem "bj" gem "nokogiri" </ruby> -Please note that this will NOT install the gems for you. So you may want to run the +rake gems:install+ task too: +Please note that this will NOT install the gems for you and you will have to run +bundle install+ to do that. <ruby> -rake "gems:install" +bundle install </ruby> -And let Rails take care of installing the required gems if they’re not already installed. - h4. add_source(source, options = {}) Adds the given source to the generated application's +Gemfile+. @@ -229,7 +227,7 @@ rake("rails:freeze:gems") if yes?("Freeze rails gems ?") no?(question) acts just the opposite. </ruby> -h4. git(:must => "-a love") +h4. git(:command) Rails templates let you run any git command: diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile index aa53aa6db6..8d5985dba8 100644 --- a/railties/guides/source/rails_on_rack.textile +++ b/railties/guides/source/rails_on_rack.textile @@ -111,11 +111,11 @@ h5. Adding a Middleware You can add a new middleware to the middleware stack using any of the following methods: -* +config.middleware.use(new_middleware, args)+ - Adds the new middleware at the bottom of the middleware stack. +* <tt>config.middleware.use(new_middleware, args)</tt> - Adds the new middleware at the bottom of the middleware stack. -* +config.middleware.insert_before(existing_middleware, new_middleware, args)+ - Adds the new middleware before the specified existing middleware in the middleware stack. +* <tt>config.middleware.insert_before(existing_middleware, new_middleware, args)</tt> - Adds the new middleware before the specified existing middleware in the middleware stack. -* +config.middleware.insert_after(existing_middleware, new_middleware, args)+ - Adds the new middleware after the specified existing middleware in the middleware stack. +* <tt>config.middleware.insert_after(existing_middleware, new_middleware, args)</tt> - Adds the new middleware after the specified existing middleware in the middleware stack. <ruby> # config/environment.rb @@ -154,20 +154,20 @@ h4. Internal Middleware Stack Much of Action Controller's functionality is implemented as Middlewares. The following table explains the purpose of each of them: |_.Middleware|_.Purpose| -|+Rack::Lock+|Sets +env["rack.multithread"]+ flag to +true+ and wraps the application within a Mutex.| +|+Rack::Lock+|Sets <tt>env["rack.multithread"]</tt> flag to +true+ and wraps the application within a Mutex.| |+ActionController::Failsafe+|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.| |+ActiveRecord::QueryCache+|Enables the Active Record query cache.| |+ActionController::Session::CookieStore+|Uses the cookie based session store.| |+ActionController::Session::MemCacheStore+|Uses the memcached based session store.| |+ActiveRecord::SessionStore+|Uses the database based session store.| -|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or +env["HTTP_X_HTTP_METHOD_OVERRIDE"]+.| +|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or <tt>env["HTTP_X_HTTP_METHOD_OVERRIDE"]</tt>.| |+Rack::Head+|Discards the response body if the client sends a +HEAD+ request.| TIP: It's possible to use any of the above middlewares in your custom Rack stack. h4. Customizing Internal Middleware Stack -It's possible to replace the entire middleware stack with a custom stack using +ActionController::Dispatcher.middleware=+. +It's possible to replace the entire middleware stack with a custom stack using <tt>ActionController::Dispatcher.middleware=</tt>. Put the following in an initializer: diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index 08615bed4e..1cbc5c8f6e 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -288,7 +288,7 @@ When using +magazine_ad_path+, you can pass in instances of +Magazine+ and +Ad+ You can also use +url_for+ with a set of objects, and Rails will automatically determine which route you want: <erb> -<%= link_to "Ad details", url_for(@magazine, @ad) %> +<%= link_to "Ad details", url_for([@magazine, @ad]) %> </erb> In this case, Rails will see that +@magazine+ is a +Magazine+ and +@ad+ is an +Ad+ and will therefore use the +magazine_ad_path+ helper. In helpers like +link_to+, you can specify just the object in place of the full +url_for+ call: diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile index 9ae360a73b..5989191b5c 100644 --- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile +++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile @@ -65,7 +65,7 @@ It is also recommended that you work with +WARNINGS=1+. This detects duplicate I If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +GUIDES_LANGUAGE+ environment variable: <plain> -rake generate_guides GUIDES_LANGUAGE=es +bundle exec rake generate_guides GUIDES_LANGUAGE=es </plain> h3. HTML Validation @@ -73,7 +73,7 @@ h3. HTML Validation Please validate the generated HTML with: <plain> -rake validate_guides +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. diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index 7a93c3a1e6..cc55d1f756 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -929,8 +929,8 @@ class UserControllerTest < ActionController::TestCase end invite_email = ActionMailer::Base.deliveries.first - assert_equal invite_email.subject, "You have been invited by me@example.com" - assert_equal invite_email.to[0], 'friend@example.com' + 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 end end @@ -944,7 +944,7 @@ The built-in +test/unit+ based testing is not the only way to test Rails applica * "Factory Girl":https://github.com/thoughtbot/factory_girl/tree/master, a replacement for fixtures. * "Machinist":https://github.com/notahat/machinist/tree/master, another replacement for fixtures. * "Shoulda":http://www.thoughtbot.com/projects/shoulda, an extension to +test/unit+ with additional helpers, macros, and assertions. -* "RSpec":http://rspec.info/, a behavior-driven development framework +* "RSpec":http://relishapp.com/rspec, a behavior-driven development framework h3. Changelog |