From 72d2a64f63b2325e46318d2d9096954c6f391861 Mon Sep 17 00:00:00 2001 From: CassioMarques Date: Sun, 18 Jan 2009 21:56:10 -0200 Subject: Changed the 'guides' Rake task to ignore Vim swap files during the HTML generation, removed active_record_basics.txt from the ignore list and generated initial HTML of it with previous contents. --- railties/doc/guides/html/active_record_basics.html | 402 +++++++++++++++++++++ railties/doc/guides/html/form_helpers.html | 6 +- railties/doc/guides/html/i18n.html | 30 ++ railties/doc/guides/html/security.html | 2 +- 4 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 railties/doc/guides/html/active_record_basics.html (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/active_record_basics.html b/railties/doc/guides/html/active_record_basics.html new file mode 100644 index 0000000000..04f1e3e838 --- /dev/null +++ b/railties/doc/guides/html/active_record_basics.html @@ -0,0 +1,402 @@ + + + + + Active Record Basics + + + + + + + + +
+ + + +
+

Active Record Basics

+
+
+

Active Record is a design pattern that mitigates the mind-numbing mental gymnastics often needed to get your application to communicate with a database. This guide uses a mix of real-world examples, metaphors and detailed explanations of the actual Rails source code to help you make the most of ActiveRecord.

+

After reading this guide readers should have a strong grasp of the Active Record pattern and how it can be used with or without Rails. Hopefully, some of the philosophical and theoretical intentions discussed here will also make them a stronger and better developer.

+
+
+

1. ORM The Blueprint of Active Record

+
+

If Active Record is the engine of Rails then ORM is the blueprint of that engine. ORM is short for “Object Relational Mapping” and is a programming concept used to make structures within a system relational. As a thought experiment imagine the components that make up a typical car. There are doors, seats, windows, engines etc. Viewed independently they are simple parts, yet when bolted together through the aid of a blueprint, the parts become a more complex device. ORM is the blueprint that describes how the individual parts relate to one another and in some cases infers the part’s purpose through the way the associations are described.

+
+

2. Active Record The Engine of Rails

+
+

Active Record is a design pattern used to access data within a database. The name “Active Record” was coined by Martin Fowler in his book “Patterns of Enterprise Application Architecture”. Essentially, when a record is returned from the database instead of being just the data it is wrapped in a class, which gives you methods to control that data with. The rails framework is built around the MVC (Model View Controller) design patten and the Active Record is used as the default Model.

+

The Rails community added several useful concepts to their version of Active Record, including inheritance and associations, which are extremely useful for web applications. The associations are created by using a DSL (domain specific language) of macros, and inheritance is achieved through the use of STI (Single Table Inheritance) at the database level.

+

By following a few simple conventions the Rails Active Record will automatically map between:

+
    +
  • +

    +Classes & Database Tables +

    +
  • +
  • +

    +Class attributes & Database Table Columns +

    +
  • +
+

2.1. Rails Active Record Conventions

+

Here are the key conventions to consider when using Active Record.

+

2.1.1. Naming Conventions

+

Database Table - Plural with underscores separating words i.e. (book_clubs) +Model Class - Singular with the first letter of each word capitalized i.e. (BookClub) +Here are some additional Examples:

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Model / Class + + Table / Schema +
+ Post + + posts +
+ LineItem + + line_items +
+ Deer + + deer +
+ Mouse + + mice +
+ Person + + people +
+
+

2.1.2. Schema Conventions

+

To take advantage of some of the magic of Rails database tables must be modeled +to reflect the ORM decisions that Rails makes.

+
+ +++ + + + + + + + + + + + + + + + +
+ Convention + +
+ Foreign keys + + These fields are named table_id i.e. (item_id, order_id) +
+ Primary Key + + Rails automatically creates a primary key column named "id" unless told otherwise. +
+
+

2.1.3. Magic Field Names

+

When these optional fields are used in your database table definition they give the Active Record +instance additional features.

+
+ + + +
+Note +While these column names are optional they are in fact reserved by ActiveRecord. 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.
+
+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Attribute + + Purpose +
+ created_at / created_on + + Rails stores the current date & time to this field when creating the record. +
+ updated_at / updated_on + + Rails stores the current date & time to this field when updating the record. +
+ lock_version + + Adds optimistic locking to a model more about optimistic locking. +
+ type + + Specifies that the model uses Single Table Inheritance more about STI. +
+ id + + All models require an id. the default is name is "id" but can be changed using the "set_primary_key" or "primary_key" methods. +
+ table_name\_count + + Can be used to caches the number of belonging objects on the associated class. +
+
+

By default rails assumes all tables will use “id” as their primary key to identify each record. Though fortunately you won’t have explicitly declare this, Rails will automatically create that field unless you tell it not to.

+

For example suppose you created a database table called cars:

+
+
+
mysql> CREATE TABLE cars (
+         id INT,
+         color VARCHAR(100),
+         doors INT,
+         horses INT,
+         model VARCHAR(100)
+       );
+

Now you created a class named Car, which is to represent an instance of a record from your table.

+
+
+
class Car
+end
+

As you might expect without defining the explicit mappings between your class and the table it is impossible for Rails or any other program to correctly map those relationships.

+
+
+
>> c = Car.new
+=> #<Class:0x11e1e90>
+>> c.doors
+NoMethodError: undefined method `doors' for #<Class:0x11e1e90>
+        from (irb):2
+

Now you could define a door methods to write and read data to and from the database. In a nutshell this is what ActiveRecord does. According to the Rails API: +“Active Record objects don‘t specify their attributes directly, but rather infer them from the table definition with which they‘re linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.” +Lets try our Car class again, this time inheriting from ActiveRecord.

+
+
+
class Car < ActiveRecord::Base
+end
+

Now if we try to access an attribute of the table ActiveRecord automatically handles the mappings for us, as you can see in the following example.

+
+
+
>> c = Car.new
+=> #<Car id: nil, doors: nil, color: nil, horses: nil, model: nil>
+>> c.doors
+=> nil
+

Rails further extends this model by giving each ActiveRecord a way of describing the variety of ways records are associated with one another. We will touch on some of these associations later in the guide but I encourage readers who are interested to read the guide to ActiveRecord associations for an in-depth explanation of the variety of ways rails can model associations. +- Associations between objects controlled by meta-programming macros.

+
+

3. Philosophical Approaches & Common Conventions

+
+

Rails has a reputation of being a zero-config framework which means that it aims to get you off the ground with as little pre-flight checking as possible. This speed benefit is achieved by following “Convention over Configuration”, which is to say that if you agree to live with the defaults then you benefit from a the inherent speed-boost. As Courtneay Gasking put it to me once “You don’t want to off-road on Rails”. ActiveRecord is no different, while it’s possible to override or subvert any of the conventions of AR, unless you have a good reason for doing so you will probably be happy with the defaults. The following is a list of the common conventions of ActiveRecord

+
+

4. ActiveRecord Magic

+
+
    +
  • +

    +timestamps +

    +
  • +
  • +

    +updates +

    +
  • +
+
+

5. How ActiveRecord Maps your Database.

+
+
    +
  • +

    +sensible defaults +

    +
  • +
  • +

    +overriding conventions +

    +
  • +
+
+

6. Growing Your Database Relationships Naturally

+
+
+

7. Attributes

+
+
    +
  • +

    +attribute accessor method. How to override them? +

    +
  • +
  • +

    +attribute? +

    +
  • +
  • +

    +dirty records + - +== ActiveRecord handling the CRUD of your Rails application - Understanding the life-cycle of an ActiveRecord +

    +
  • +
+
+

8. Validations & Callbacks

+
+

see the Validations & Callbacks guide for more info.

+
+ +
+
+ + diff --git a/railties/doc/guides/html/form_helpers.html b/railties/doc/guides/html/form_helpers.html index a43cbe584f..1054aa8ff5 100644 --- a/railties/doc/guides/html/form_helpers.html +++ b/railties/doc/guides/html/form_helpers.html @@ -196,7 +196,7 @@ Learn what makes a file upload form different;

1.1. Generic search form

Probably the most minimal form often seen on the web is a search form with a single text input for search terms. This form consists of:

-
    +
    1. a form element with "GET" method, @@ -433,7 +433,7 @@ end <% end %>

There are a few things to note here:

-
    +
    1. :article is the name of the model and @article is the record. @@ -633,7 +633,7 @@ output:

      5. Date and time select boxes

      The date and time helpers differ from all the other form helpers in two important respects:

      -
        +
        1. Unlike other attributes you might typically have, dates and times are not representable by a single input element. Instead you have several, one for each component (year, month, day etc...). So in particular, there is no single value in your params hash with your date or time. diff --git a/railties/doc/guides/html/i18n.html b/railties/doc/guides/html/i18n.html index 8a6e4cc990..cc100e2171 100644 --- a/railties/doc/guides/html/i18n.html +++ b/railties/doc/guides/html/i18n.html @@ -756,6 +756,36 @@ cellspacing="0" cellpadding="4">

          validates_numericality_of

          +

          :greater_than

          +

          :greater_than

          +

          value

          + + +

          validates_numericality_of

          +

          :greater_than_or_equal_to

          +

          :greater_than_or_equal_to

          +

          value

          + + +

          validates_numericality_of

          +

          :equal_to

          +

          :equal_to

          +

          value

          + + +

          validates_numericality_of

          +

          :less_than

          +

          :less_than

          +

          value

          + + +

          validates_numericality_of

          +

          :less_than_or_equal_to

          +

          :less_than_or_equal_to

          +

          value

          + + +

          validates_numericality_of

          :odd

          :odd

          value

          diff --git a/railties/doc/guides/html/security.html b/railties/doc/guides/html/security.html index 371decda64..4751e9f92b 100644 --- a/railties/doc/guides/html/security.html +++ b/railties/doc/guides/html/security.html @@ -326,7 +326,7 @@ The user has his credit back.

      This attack focuses on fixing a user’s session id known to the attacker, and forcing the user’s browser into using this id. It is therefore not necessary for the attacker to steal the session id afterwards. Here is how this attack works:

      -
        +
        1. The attacker creates a valid session id: He loads the login page of the web application where he wants to fix the session, and takes the session id in the cookie from the response (see number 1 and 2 in the image). -- cgit v1.2.3 From e285ce828effbe44c4a6d88632f4b068e38c119f Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 00:18:51 +0000 Subject: move section on uploads up --- railties/doc/guides/source/form_helpers.txt | 76 ++++++++++++++--------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index d60ed10a39..a6a1540259 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -511,6 +511,44 @@ As a rule of thumb you should be using `date_select` when working with model obj NOTE: In many cases the built in date pickers are clumsy as they do not aid the user in working out the relationship between the date and the day of the week. +File Uploads +-------------- +A common task is uploading some sort of file, whether it's a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form's encoding *MUST* be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing `:multi_part => true` as an HTML option. This means that in the case of `form_tag` it must be passed in the second options hash and in the case of `form_for` inside the `:html` hash. + +The following two forms both upload a file. +----------- +<% form_tag({:action => :upload}, :multipart => true) do %> + <%= file_field_tag 'picture' %> +<% end %> + +<% form_for @person, :html => {:multipart => true} do |f| %> + <%= f.file_field :picture %> +<% end %> +----------- +Rails provides the usual pair of helpers: the barebones `file_field_tag` and the model oriented `file_field`. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in `params[:picture]` and in the second case in `params[:person][:picture]`. + +What gets uploaded +~~~~~~~~~~~~~~~~~~ +The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an `original_filename` attribute containing the name the file had on the user's computer and a `content_type` attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in `#\{RAILS_ROOT\}/public/uploads` under the same name as the original file (assuming the form was the one in the previous example). + +[source, ruby] +----------------- +def upload + uploaded_io = params[:person][:picture] + File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'w') do |file| + file.write(uploaded_io.read) + end +end +---------------- + +Once a file has been uploaded there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are http://github.com/technoweenie/attachment_fu[Attachment-Fu] and http://www.thoughtbot.com/projects/paperclip[Paperclip]. + +NOTE: If the user has not selected a file the corresponding parameter will be an empty string. + +Dealing with Ajax +~~~~~~~~~~~~~~~~~ +Unlike other forms making an asynchronous file upload form is not as simple as replacing `form_for` with `remote_form_for`. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission. + Form builders ------------- @@ -567,44 +605,6 @@ which produces the following output: ------------- -File Uploads --------------- -A common task is uploading some sort of file, whether it's a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form's encoding *MUST* be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing `:multi_part => true` as an HTML option. This means that in the case of `form_tag` it must be passed in the second options hash and in the case of `form_for` inside the `:html` hash. - -The following two forms both upload a file. ------------ -<% form_tag({:action => :upload}, :multipart => true) do %> - <%= file_field_tag 'picture' %> -<% end %> - -<% form_for @person, :html => {:multipart => true} do |f| %> - <%= f.file_field :picture %> -<% end %> ------------ -Rails provides the usual pair of helpers: the barebones `file_field_tag` and the model oriented `file_field`. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in `params[:picture]` and in the second case in `params[:person][:picture]`. - -What gets uploaded -~~~~~~~~~~~~~~~~~~ -The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an `original_filename` attribute containing the name the file had on the user's computer and a `content_type` attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in `#\{RAILS_ROOT\}/public/uploads` under the same name as the original file (assuming the form was the one in the previous example). - -[source, ruby] ------------------ -def upload - uploaded_io = params[:person][:picture] - File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'w') do |file| - file.write(uploaded_io.read) - end -end ----------------- - -Once a file has been uploaded there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are http://github.com/technoweenie/attachment_fu[Attachment-Fu] and http://www.thoughtbot.com/projects/paperclip[Paperclip]. - -NOTE: If the user has not selected a file the corresponding parameter will be an empty string. - -Dealing with Ajax -~~~~~~~~~~~~~~~~~ -Unlike other forms making an asynchronous file upload form is not as simple as replacing `form_for` with `remote_form_for`. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission. - Parameter Names --------------- [[parameter_names]] -- cgit v1.2.3 From 5ccc37e2d9f5702962ba49d7444655351e553498 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 00:23:21 +0000 Subject: tidy up some wording --- railties/doc/guides/source/form_helpers.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index a6a1540259..9cc434d938 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -315,9 +315,9 @@ For more information on Rails' routing system and the associated conventions, pl Making select boxes with ease ----------------------------- -Select boxes in HTML require a significant amount of markup (one `OPTION` element for each option to choose from), therefore it makes the most sense for them to be dynamically generated from data stored in arrays or hashes. +Select boxes in HTML require a significant amount of markup (one `OPTION` element for each option to choose from), therefore it makes the most sense for them to be dynamically generated. -Here is what our wanted markup might look like: +Here is what the markup might look like: ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -Here you have a list of cities where their names are presented to the user, but internally the application only wants to handle their IDs so they are used as the options' value attributes. Let's see how Rails can help out here. +Here you have a list of cities whose names are presented to the user. Internally the application only wants to handle their IDs so they are used as the options' value attribute. Let's see how Rails can help out here. The select tag and options ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -452,7 +452,7 @@ To leverage time zone support in Rails, you have to ask our users what time zone There is also `time_zone_options_for_select` helper for a more manual (therefore more customizable) way of doing this. Read the API documentation to learn about the possible arguments for these two methods. -Rails _used_ to have a `country_select` helper for choosing countries but this has been extracted to the http://github.com/rails/country_select/tree/master[country_select plugin]. When using this do be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from rails) +Rails _used_ to have a `country_select` helper for choosing countries but this has been extracted to the http://github.com/rails/country_select/tree/master[country_select plugin]. When using this do be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from rails). Date and time select boxes -------------------------- -- cgit v1.2.3 From e8c50fcd5e0ca2f0d8ff2c930e999373b9628e9b Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 01:48:52 +0000 Subject: Rearrange sections on basic form helpers/form_for --- railties/doc/guides/source/form_helpers.txt | 173 +++++++++++++++------------- 1 file changed, 92 insertions(+), 81 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index 9cc434d938..0fd7c23c96 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -14,8 +14,8 @@ In this guide you will: NOTE: This guide is not intended to be a complete documentation of available form helpers and their arguments. Please visit http://api.rubyonrails.org/[the Rails API documentation] for a complete reference. -Basic forms ------------ +Dealing With Basic Forms +------------------------ The most basic form helper is `form_tag`. @@ -113,9 +113,23 @@ This is a common pitfall when using form helpers, since many of them accept mult WARNING: Do not delimit the second hash without doing so with the first hash, otherwise your method invocation will result in an `expecting tASSOC` syntax error. -Checkboxes, radio buttons and other controls -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Helpers for generating form elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rails provides a series of helpers for generating form elements such as checkboxes, text fields, radio buttons and so. These basic helpers, with names ending in _tag such as `text_field_tag`, `check_box_tag` just generate a single `` element. The first parameter to these is always the name of the input. This is the name under which value will appear in the `params` hash in the controller. For example if the form contains + +--------------------------- +<%= text_field_tag(:query) %> +--------------------------- +then the controller code should use +--------------------------- +params[:query] +--------------------------- +to retrieve the value entered by the user. When naming inputs be aware that Rails uses certain conventions that control whether values appear at the top level of the params hash, inside an array or a nested hash and so on. You can read more about them in the <> section. For details on the precise usage of these helpers, please refer to the http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html[API documentation]. + +Checkboxes +^^^^^^^^^^ Checkboxes are form controls that give the user a set of options they can enable or disable: ---------------------------------------------------------------------------- @@ -132,6 +146,10 @@ output: ---------------------------------------------------------------------------- +The second parameter to `check_box_tag` is the value of the input. This is the value that will be submitted by the browser if the checkbox is ticked (i.e. the value that will be present in the params hash). With the above form you would check the value of `params[:pet_dog]` and `params[:pet_cat]` to see which pets the user owns. + +Radio buttons +^^^^^^^^^^^^^ Radio buttons, while similar to checkboxes, are controls that specify a set of options in which they are mutually exclusive (user can only pick one): ---------------------------------------------------------------------------- @@ -148,9 +166,13 @@ output: ---------------------------------------------------------------------------- +As with `check_box_tag` the second parameter to `radio_button_tag` is the value of the input. Because these two radio buttons share the same name (age) the user will only be able to select one and `params[:age]` will contain either `child` or `adult`. + IMPORTANT: Always use labels for each checkbox and radio button. They associate text with a specific option and provide a larger clickable region. -Other form controls worth mentioning are the text area, password input and hidden input: +Other helpers of interest +^^^^^^^^^^^^^^^^^^^^^^^^^ +Other form controls worth mentioning are the text area, password input and hidden input: ---------------------------------------------------------------------------- <%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %> @@ -164,55 +186,20 @@ output: ---------------------------------------------------------------------------- -Hidden inputs are not shown to the user, but they hold data same as any textual input. Values inside them can be changed with JavaScript. +Hidden inputs are not shown to the user, but they hold data like any textual input. Values inside them can be changed with JavaScript. TIP: If you're using password input fields (for any purpose), you might want to prevent their values showing up in application logs by activating `filter_parameter_logging(:password)` in your ApplicationController. -How do forms with PUT or DELETE methods work? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PUT" and "DELETE" requests (besides "GET" and "POST"). Still, most browsers _don't support_ methods other than "GET" and "POST" when it comes to submitting forms. How does this work, then? - -Rails works around this issue by emulating other methods over POST with a hidden input named `"_method"` that is set to reflect the desired method: - ----------------------------------------------------------------------------- -form_tag(search_path, :method => "put") - -output: -

          -
          - - -
          - ... ----------------------------------------------------------------------------- - -When parsing POSTed data, Rails will take into account the special `_method` parameter and act as if the HTTP method was the one specified inside it ("PUT" in this example). - -Different Families of helpers ------------------------------- - -Most of Rails' form helpers are available in two forms. - -Barebones helpers -~~~~~~~~~~~~~~~~~~ -These just generate the appropriate markup. These have names ending in _tag such as `text_field_tag`, `check_box_tag`. The first parameter to these is always the name of the input. This is the name under which value will appear in the `params` hash in the controller. For example if the form contains ---------------------------- -<%= text_field_tag(:query) %> ---------------------------- - -then the controller code should use ---------------------------- -params[:query] ---------------------------- -to retrieve the value entered by the user. When naming inputs be aware that Rails uses certain conventions that control whether values appear at the top level of the params hash, inside an array or a nested hash and so on. You can read more about them in the <> section. For details on the precise usage of these helpers, please refer to the http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html[API documentation]. +Dealing With Model Objects +-------------------------- Model object helpers -~~~~~~~~~~~~~~~~~~~~~ -These are designed to work with a model object (commonly an Active Record object but this need not be the case). These lack the _tag suffix, for example `text_field`, `text_area`. +~~~~~~~~~~~~~~~~~~~~~~ + +A particularly common task for a form is editing or creating a model object. While the `*_tag` helpers could certainly be used for this task they are somewhat verbose as for each tag you would have to ensure the correct parameter name is used and set the default value of the input appropriately. Rails provides helpers tailored to this task. These helpers lack the _tag suffix, for example `text_field`, `text_area`. -For these helpers the first arguement is the name of an instance variable and the second is the name a method (usually an attribute) to call on that object. Rails will set the value of the input control to the return value of that method for the object and set an appropriate input name. If your controller has defined `@person` and that person's name is Henry then a form containing: +For these helpers the first argument is the name of an instance variable and the second is the name of a method (usually an attribute) to call on that object. Rails will set the value of the input control to the return value of that method for the object and set an appropriate input name. If your controller has defined `@person` and that person's name is Henry then a form containing: --------------------------- <%= text_field(:person, :name) %> @@ -227,10 +214,13 @@ Upon form submission the value entered by the user will be stored in `params[:pe ============================================================================ You must pass the name of an instance variable, i.e. `:person` or `"person"`, not an actual instance of your model object. ============================================================================ -Forms that deal with model attributes -------------------------------------- -While the helpers seen so far are handy Rails can save you some work. For example typically a form is used to edit multiple attributes of a single object, so having to repeat the name of the object being edited is clumsy. The following examples will handle an Article model. First, have the controller create one: +Binding a form to an object +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While this is an increase in comfort it is far from perfect. If Person has many attributes to edit then we would be repeating the name of the edited object many times. What we want to do is somehow bind a form to a model object which is exactly what `form_for` does. + +Assume we have a controller for dealing with articles: .articles_controller.rb ---------------------------------------------------------------------------- @@ -239,7 +229,7 @@ def new end ---------------------------------------------------------------------------- -Now switch to the view. The first thing to remember is to use the `form_for` helper instead of `form_tag`, and that you should pass the model name and object as arguments: +The corresponding view using `form_for` looks like this .articles/new.html.erb ---------------------------------------------------------------------------- @@ -252,9 +242,9 @@ Now switch to the view. The first thing to remember is to use the `form_for` hel There are a few things to note here: -1. `:article` is the name of the model and `@article` is the record. +1. `:article` is the name of the model and `@article` is the actual object being edited. 2. There is a single hash of options. Routing options are passed inside `:url` hash, HTML options are passed in the `:html` hash. -3. The `form_for` method yields *a form builder* object (the `f` variable). +3. The `form_for` method yields a *form builder* object (the `f` variable). 4. Methods to create form controls are called *on* the form builder object `f` The resulting HTML is: @@ -270,10 +260,30 @@ The name passed to `form_for` controls where in the params hash the form values The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder. +You can create a similar binding without actually creating `` tags with the `fields_for` helper. This is useful for editing additional model objects with the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for editing both like so: +------------- +<% form_for @person do |person_form| %> + <%= person_form.text_field :name %> + <% fields_for @person.contact_detail do |contact_details_form| %> + <%= contact_details_form.text_field :phone_number %> + <% end %> +<% end %> +------------- + +which produces the following output: + +------------- + + + + +------------- +The object yielded by `fields_for` is a form builder like the one yielded by `form_for` (in fact `form_for` calls `fields_for` internally). + Relying on record identification ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In the previous chapter you handled the Article model. This model is directly available to users of our application, so -- following the best practices for developing with Rails -- you should declare it *a resource*. +The Article model is directly available to users of our application, so -- following the best practices for developing with Rails -- you should declare it *a resource*. When dealing with RESTful resources, calls to `form_for` can get significantly easier if you rely on *record identification*. In short, you can just pass the model instance and have Rails figure out model name and the rest: @@ -312,6 +322,28 @@ form_for [:admin, :management, @article] For more information on Rails' routing system and the associated conventions, please see the link:../routing_outside_in.html[routing guide]. +How do forms with PUT or DELETE methods work? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PUT" and "DELETE" requests (besides "GET" and "POST"). Still, most browsers _don't support_ methods other than "GET" and "POST" when it comes to submitting forms. How does this work, then? + +Rails works around this issue by emulating other methods over POST with a hidden input named `"_method"` that is set to reflect the desired method: + +---------------------------------------------------------------------------- +form_tag(search_path, :method => "put") + +output: + +
          +
          + + +
          + ... +---------------------------------------------------------------------------- +When parsing POSTed data, Rails will take into account the special `_method` parameter and act as if the HTTP method was the one specified inside it ("PUT" in this example). + + Making select boxes with ease ----------------------------- @@ -583,35 +615,14 @@ The form builder used also determines what happens when you do ------ If `f` is an instance of FormBuilder then this will render the 'form' partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the 'labelling_form' partial would be rendered instead. -Scoping out form controls with `fields_for` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -`fields_for` creates a form builder in exactly the same way as `form_for` but doesn't create the actual `` tags. It creates a scope around a specific model object like `form_for`, which is useful for specifying additional model objects in the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for editing both like so: -------------- -<% form_for @person do |person_form| %> - <%= person_form.text_field :name %> - <% fields_for @person.contact_detail do |contact_details_form| %> - <%= contact_details_form.text_field :phone_number %> - <% end %> -<% end %> -------------- - -which produces the following output: - -------------- - - - -
          -------------- +Understanding Parameter Naming Conventions +----------------------------------------- -Parameter Names ---------------- [[parameter_names]] -As you've seen in the previous sections values from forms can appear either at the top level of the params hash or may appear nested in another hash. For example in a standard create +As you've seen in the previous sections, values from forms can appear either at the top level of the params hash or may appear nested in another hash. For example in a standard create action for a Person model, `params[:model]` would usually be a hash of all the attributes for the person to create. The params hash can also contain arrays, arrays of hashes and so on. -Fundamentally HTML forms don't know about any sort of structured data. All they know about is name-value pairs. Rails tacks some conventions onto parameter names which it uses to express some structure. +Fundamentally HTML forms don't know about any sort of structured data, all they generate is name-value pairs. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses. [TIP] ======================== @@ -724,8 +735,8 @@ As a shortcut you can append [] to the name and omit the `:index` option. This i -------- produces exactly the same output as the previous example. -Complex forms -------------- +Building Complex forms +---------------------- Many apps grow beyond simple forms editing a single object. For example when creating a Person instance you might want to allow the user to (on the same form) create multiple address records (home, work etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include: -- cgit v1.2.3 From a0b2223740165bb95057f8dc07f3de352508701b Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 01:50:10 +0000 Subject: rename section --- railties/doc/guides/source/form_helpers.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index 0fd7c23c96..4f956b099c 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -543,7 +543,7 @@ As a rule of thumb you should be using `date_select` when working with model obj NOTE: In many cases the built in date pickers are clumsy as they do not aid the user in working out the relationship between the date and the day of the week. -File Uploads +Uploading Files -------------- A common task is uploading some sort of file, whether it's a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form's encoding *MUST* be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing `:multi_part => true` as an HTML option. This means that in the case of `form_tag` it must be passed in the second options hash and in the case of `form_for` inside the `:html` hash. -- cgit v1.2.3 From b9efc8a0ce7d864666d01c7099f263c70b170793 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 02:01:23 +0000 Subject: rename some sections --- railties/doc/guides/source/form_helpers.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index 4f956b099c..04c6f99349 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -486,8 +486,8 @@ There is also `time_zone_options_for_select` helper for a more manual (therefore Rails _used_ to have a `country_select` helper for choosing countries but this has been extracted to the http://github.com/rails/country_select/tree/master[country_select plugin]. When using this do be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from rails). -Date and time select boxes --------------------------- +Using Date and Time Form Helpers +-------------------------------- The date and time helpers differ from all the other form helpers in two important respects: @@ -581,7 +581,7 @@ Dealing with Ajax ~~~~~~~~~~~~~~~~~ Unlike other forms making an asynchronous file upload form is not as simple as replacing `form_for` with `remote_form_for`. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission. -Form builders +Customising Form Builders ------------- As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example -- cgit v1.2.3 From 0de89f815083886c8c98f91972cc717c6b42602f Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 02:04:45 +0000 Subject: link to the validations guide --- railties/doc/guides/source/form_helpers.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index 04c6f99349..804363aa3d 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -215,6 +215,8 @@ Upon form submission the value entered by the user will be stored in `params[:pe You must pass the name of an instance variable, i.e. `:person` or `"person"`, not an actual instance of your model object. ============================================================================ +Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the link:./activerecord_validations_callbacks.html#_using_the_tt_errors_tt_collection_in_your_view_templates[Active Record Validations and Callbacks] guide. + Binding a form to an object ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -319,7 +321,7 @@ will create a form that submits to the articles controller inside the admin name ------- form_for [:admin, :management, @article] ------- -For more information on Rails' routing system and the associated conventions, please see the link:../routing_outside_in.html[routing guide]. +For more information on Rails' routing system and the associated conventions, please see the link:./routing_outside_in.html[routing guide]. How do forms with PUT or DELETE methods work? -- cgit v1.2.3 From 1e550ccd0d5827bf7cf8de4c5b92938a9fabc96f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Mon, 19 Jan 2009 02:17:38 +0000 Subject: Regen guides --- railties/doc/guides/html/form_helpers.html | 308 ++++++++++++++--------------- railties/doc/guides/html/security.html | 2 +- 2 files changed, 147 insertions(+), 163 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/form_helpers.html b/railties/doc/guides/html/form_helpers.html index 1054aa8ff5..6169574d35 100644 --- a/railties/doc/guides/html/form_helpers.html +++ b/railties/doc/guides/html/form_helpers.html @@ -31,35 +31,29 @@

          Chapters

          1. - Basic forms + Dealing With Basic Forms
          2. - Different Families of helpers + Dealing With Model Objects -
          3. -
          4. - Forms that deal with model attributes -
          5. @@ -77,10 +71,10 @@
          6. - Date and time select boxes + Using Date and Time Form Helpers
          7. - Form builders - -
          8. -
          9. - File Uploads + Uploading Files -
          10. -
          11. - Parameter Names -
          12. - Complex forms + Building Complex forms
          13. Changelog @@ -165,7 +145,7 @@ Learn what makes a file upload form different;
      -

      1. Basic forms

      +

      1. Dealing With Basic Forms

      The most basic form helper is form_tag.

      @@ -196,7 +176,7 @@ Learn what makes a file upload form different;

      1.1. Generic search form

      Probably the most minimal form often seen on the web is a search form with a single text input for search terms. This form consists of:

      -
        +
        1. a form element with "GET" method, @@ -294,7 +274,19 @@ a submit element. Do not delimit the second hash without doing so with the first hash, otherwise your method invocation will result in an expecting tASSOC syntax error.

        -

        1.3. Checkboxes, radio buttons and other controls

        +

        1.3. Helpers for generating form elements

        +

        Rails provides a series of helpers for generating form elements such as checkboxes, text fields, radio buttons and so. These basic helpers, with names ending in _tag such as text_field_tag, check_box_tag just generate a single <input> element. The first parameter to these is always the name of the input. This is the name under which value will appear in the params hash in the controller. For example if the form contains

        +
        +
        +
        <%= text_field_tag(:query) %>
        +
        +

        then the controller code should use

        +
        +
        +
        params[:query]
        +
        +

        to retrieve the value entered by the user. When naming inputs be aware that Rails uses certain conventions that control whether values appear at the top level of the params hash, inside an array or a nested hash and so on. You can read more about them in the parameter names section. For details on the precise usage of these helpers, please refer to the API documentation.

        +

        1.3.1. Checkboxes

        Checkboxes are form controls that give the user a set of options they can enable or disable:

        @@ -310,6 +302,8 @@ output: <input id="pet_cat" name="pet_cat" type="checkbox" value="1" /> <label for="pet_cat">I own a cat</label>
        +

        The second parameter to check_box_tag is the value of the input. This is the value that will be submitted by the browser if the checkbox is ticked (i.e. the value that will be present in the params hash). With the above form you would check the value of params[:pet_dog] and params[:pet_cat] to see which pets the user owns.

        +

        1.3.2. Radio buttons

        Radio buttons, while similar to checkboxes, are controls that specify a set of options in which they are mutually exclusive (user can only pick one):

        @@ -325,6 +319,7 @@ output: <input id="age_adult" name="age" type="radio" value="adult" /> <label for="age_adult">I'm over 21</label>
        +

        As with check_box_tag the second parameter to radio_button_tag is the value of the input. Because these two radio buttons share the same name (age) the user will only be able to select one and params[:age] will contain either child or adult.

        @@ -333,7 +328,8 @@ output: Always use labels for each checkbox and radio button. They associate text with a specific option and provide a larger clickable region.
        -

        Other form controls worth mentioning are the text area, password input and hidden input:

        +

        1.3.3. Other helpers of interest

        +

        Other form controls worth mentioning are the text area, password input and hidden input:

        <%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
        @@ -346,7 +342,7 @@ output:
         <input id="password" name="password" type="password" />
         <input id="parent_id" name="parent_id" type="hidden" value="5" />
        -

        Hidden inputs are not shown to the user, but they hold data same as any textual input. Values inside them can be changed with JavaScript.

        +

        Hidden inputs are not shown to the user, but they hold data like any textual input. Values inside them can be changed with JavaScript.

        @@ -355,42 +351,12 @@ output: If you’re using password input fields (for any purpose), you might want to prevent their values showing up in application logs by activating filter_parameter_logging(:password) in your ApplicationController.
        -

        1.4. How do forms with PUT or DELETE methods work?

        -

        Rails framework encourages RESTful design of your applications, which means you’ll be making a lot of "PUT" and "DELETE" requests (besides "GET" and "POST"). Still, most browsers don’t support methods other than "GET" and "POST" when it comes to submitting forms. How does this work, then?

        -

        Rails works around this issue by emulating other methods over POST with a hidden input named "_method" that is set to reflect the desired method:

        -
        -
        -
        form_tag(search_path, :method => "put")
        -
        -output:
        -
        -<form action="/search" method="post">
        -  <div style="margin:0;padding:0">
        -    <input name="_method" type="hidden" value="put" />
        -    <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
        -  </div>
        -  ...
        -
        -

        When parsing POSTed data, Rails will take into account the special _method parameter and act as if the HTTP method was the one specified inside it ("PUT" in this example).

      -

      2. Different Families of helpers

      +

      2. Dealing With Model Objects

      -

      Most of Rails' form helpers are available in two forms.

      -

      2.1. Barebones helpers

      -

      These just generate the appropriate markup. These have names ending in _tag such as text_field_tag, check_box_tag. The first parameter to these is always the name of the input. This is the name under which value will appear in the params hash in the controller. For example if the form contains

      -
      -
      -
      <%= text_field_tag(:query) %>
      -
      -

      then the controller code should use

      -
      -
      -
      params[:query]
      -
      -

      to retrieve the value entered by the user. When naming inputs be aware that Rails uses certain conventions that control whether values appear at the top level of the params hash, inside an array or a nested hash and so on. You can read more about them in the parameter names section. For details on the precise usage of these helpers, please refer to the API documentation.

      -

      2.2. Model object helpers

      -

      These are designed to work with a model object (commonly an Active Record object but this need not be the case). These lack the _tag suffix, for example text_field, text_area.

      -

      For these helpers the first arguement is the name of an instance variable and the second is the name a method (usually an attribute) to call on that object. Rails will set the value of the input control to the return value of that method for the object and set an appropriate input name. If your controller has defined @person and that person’s name is Henry then a form containing:

      +

      2.1. Model object helpers

      +

      A particularly common task for a form is editing or creating a model object. While the *_tag helpers could certainly be used for this task they are somewhat verbose as for each tag you would have to ensure the correct parameter name is used and set the default value of the input appropriately. Rails provides helpers tailored to this task. These helpers lack the _tag suffix, for example text_field, text_area.

      +

      For these helpers the first argument is the name of an instance variable and the second is the name of a method (usually an attribute) to call on that object. Rails will set the value of the input control to the return value of that method for the object and set an appropriate input name. If your controller has defined @person and that person’s name is Henry then a form containing:

      <%= text_field(:person, :name) %>
      @@ -411,10 +377,10 @@ output:
      -
      -

      3. Forms that deal with model attributes

      -
      -

      While the helpers seen so far are handy Rails can save you some work. For example typically a form is used to edit multiple attributes of a single object, so having to repeat the name of the object being edited is clumsy. The following examples will handle an Article model. First, have the controller create one:

      +

      Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the Active Record Validations and Callbacks guide.

      +

      2.2. Binding a form to an object

      +

      While this is an increase in comfort it is far from perfect. If Person has many attributes to edit then we would be repeating the name of the edited object many times. What we want to do is somehow bind a form to a model object which is exactly what form_for does.

      +

      Assume we have a controller for dealing with articles:

      articles_controller.rb
      @@ -422,7 +388,7 @@ output: @article = Article.new end
      -

      Now switch to the view. The first thing to remember is to use the form_for helper instead of form_tag, and that you should pass the model name and object as arguments:

      +

      The corresponding view using form_for looks like this

      articles/new.html.erb
      @@ -433,10 +399,10 @@ end <% end %>

      There are a few things to note here:

      -
        +
        1. -:article is the name of the model and @article is the record. +:article is the name of the model and @article is the actual object being edited.

        2. @@ -446,7 +412,7 @@ There is a single hash of options. Routing options are passed inside :url
        3. -The form_for method yields a form builder object (the f variable). +The form_for method yields a form builder object (the f variable).

        4. @@ -466,8 +432,27 @@ Methods to create form controls are called on the form builder

      The name passed to form_for controls where in the params hash the form values will appear. Here the name is article and so all the inputs have names of the form article[attribute_name]. Accordingly, in the create action params[:article] will be a hash with keys :title and :body. You can read more about the significance of input names in the parameter names section.

      The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder.

      -

      3.1. Relying on record identification

      -

      In the previous chapter you handled the Article model. This model is directly available to users of our application, so — following the best practices for developing with Rails — you should declare it a resource.

      +

      You can create a similar binding without actually creating <form> tags with the fields_for helper. This is useful for editing additional model objects with the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for editing both like so:

      +
      +
      +
      <% form_for @person do |person_form| %>
      +  <%= person_form.text_field :name %>
      +  <% fields_for @person.contact_detail do |contact_details_form| %>
      +    <%= contact_details_form.text_field :phone_number %>
      +  <% end %>
      +<% end %>
      +
      +

      which produces the following output:

      +
      +
      +
      <form action="/people/1" class="edit_person" id="edit_person_1" method="post">
      +  <input id="person_name" name="person[name]" size="30" type="text" />
      +  <input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" />
      +</form>
      +
      +

      The object yielded by fields_for is a form builder like the one yielded by form_for (in fact form_for calls fields_for internally).

      +

      2.3. Relying on record identification

      +

      The Article model is directly available to users of our application, so — following the best practices for developing with Rails — you should declare it a resource.

      When dealing with RESTful resources, calls to form_for can get significantly easier if you rely on record identification. In short, you can just pass the model instance and have Rails figure out model name and the rest:

      @@ -493,7 +478,7 @@ form_for(@article) When you’re using STI (single-table inheritance) with your models, you can’t rely on record identification on a subclass if only their parent class is declared a resource. You will have to specify the model name, :url and :method explicitly.
      -

      3.1.1. Dealing with namespaces

      +

      2.3.1. Dealing with namespaces

      If you have created namespaced routes form_for has a nifty shorthand for that too. If your application has an admin namespace then

      @@ -504,12 +489,29 @@ form_for(@article)
      form_for [:admin, :management, @article]
      -

      For more information on Rails' routing system and the associated conventions, please see the routing guide.

      +

      For more information on Rails' routing system and the associated conventions, please see the routing guide.

      +

      2.4. How do forms with PUT or DELETE methods work?

      +

      Rails framework encourages RESTful design of your applications, which means you’ll be making a lot of "PUT" and "DELETE" requests (besides "GET" and "POST"). Still, most browsers don’t support methods other than "GET" and "POST" when it comes to submitting forms. How does this work, then?

      +

      Rails works around this issue by emulating other methods over POST with a hidden input named "_method" that is set to reflect the desired method:

      +
      +
      +
      form_tag(search_path, :method => "put")
      +
      +output:
      +
      +<form action="/search" method="post">
      +  <div style="margin:0;padding:0">
      +    <input name="_method" type="hidden" value="put" />
      +    <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
      +  </div>
      +  ...
      +
      +

      When parsing POSTed data, Rails will take into account the special _method parameter and act as if the HTTP method was the one specified inside it ("PUT" in this example).

      -

      4. Making select boxes with ease

      +

      3. Making select boxes with ease

      -

      Select boxes in HTML require a significant amount of markup (one OPTION element for each option to choose from), therefore it makes the most sense for them to be dynamically generated from data stored in arrays or hashes.

      -

      Here is what our wanted markup might look like:

      +

      Select boxes in HTML require a significant amount of markup (one OPTION element for each option to choose from), therefore it makes the most sense for them to be dynamically generated.

      +

      Here is what the markup might look like:

      <select name="city_id" id="city_id">
      @@ -519,8 +521,8 @@ form_for(@article)
      <option value="12">Berlin</option> </select>
      -

      Here you have a list of cities where their names are presented to the user, but internally the application only wants to handle their IDs so they are used as the options' value attributes. Let’s see how Rails can help out here.

      -

      4.1. The select tag and options

      +

      Here you have a list of cities whose names are presented to the user. Internally the application only wants to handle their IDs so they are used as the options' value attribute. Let’s see how Rails can help out here.

      +

      3.1. The select tag and options

      The most generic helper is select_tag, which — as the name implies — simply generates the SELECT tag that encapsulates an options string:

      @@ -565,7 +567,7 @@ output:
      -

      4.2. Select boxes for dealing with models

      +

      3.2. Select boxes for dealing with models

      Until now you’ve seen how to make generic select boxes, but in most cases our form controls will be tied to a specific database model. So, to continue from our previous examples, let’s assume that you have a "Person" model with a city_id attribute.

      Consistent with other form helpers, when dealing with models you drop the _tag suffix from select_tag.

      @@ -598,7 +600,7 @@ output:
      -

      4.3. Option tags from a collection of arbitrary objects

      +

      3.3. Option tags from a collection of arbitrary objects

      Until now you were generating option tags from nested arrays with the help of options_for_select method. Data in our array were raw values:

      @@ -621,19 +623,19 @@ output:
      <%= collection_select(:person, :city_id, City.all, :id, :name) %>

      To recap, options_from_collection_for_select is to collection_select what options_for_select is to select.

      -

      4.4. Time zone and country select

      +

      3.4. Time zone and country select

      To leverage time zone support in Rails, you have to ask our users what time zone they are in. Doing so would require generating select options from a list of pre-defined TimeZone objects using collection_select, but you can simply use the time_zone_select helper that already wraps this:

      <%= time_zone_select(:person, :city_id) %>

      There is also time_zone_options_for_select helper for a more manual (therefore more customizable) way of doing this. Read the API documentation to learn about the possible arguments for these two methods.

      -

      Rails used to have a country_select helper for choosing countries but this has been extracted to the country_select plugin. When using this do be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from rails)

      +

      Rails used to have a country_select helper for choosing countries but this has been extracted to the country_select plugin. When using this do be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from rails).

      -

      5. Date and time select boxes

      +

      4. Using Date and Time Form Helpers

      The date and time helpers differ from all the other form helpers in two important respects:

      -
        +
        1. Unlike other attributes you might typically have, dates and times are not representable by a single input element. Instead you have several, one for each component (year, month, day etc...). So in particular, there is no single value in your params hash with your date or time. @@ -646,7 +648,7 @@ Other helpers use the _tag suffix to indicate whether a helper is a barebones he

        Both of these families of helpers will create a series of select boxes for the different components (year, month, day etc...).

        -

        5.1. Barebones helpers

        +

        4.1. Barebones helpers

        The select_* family of helpers take as their first argument an instance of Date, Time or DateTime that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example

        @@ -665,7 +667,7 @@ Other helpers use the _tag suffix to indicate whether a helper is a barebones he
        Date::civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)

        The :prefix option controls where in the params hash the date components will be placed. Here it was set to start_date, if omitted it will default to date.

        -

        5.2. Model object helpers

        +

        4.2. Model object helpers

        select_date does not work well with forms that update or create Active Record objects as Active Record expects each element of the params hash to correspond to one attribute. The model object helpers for dates and times submit parameters with special names. When Active Record sees parameters with such names it knows they must be combined with the other parameters and given to a constructor appropriate to the column type. For example

        @@ -685,7 +687,7 @@ The model object helpers for dates and times submit parameters with special name
        {:person => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}

      When this is passed to Person.new, Active Record spots that these parameters should all be used to construct the birth_date attribute and uses the suffixed information to determine in which order it should pass these parameters to functions such as Date::civil.

      -

      5.3. Common options

      +

      4.3. Common options

      Both families of helpers use the same core set of functions to generate the individual select tags and so both accept largely the same options. In particular, by default Rails will generate year options 5 years either side of the current year. If this is not an appropriate range, the :start_year and :end_year options override this. For an exhaustive list of the available options, refer to the API documentation.

      As a rule of thumb you should be using date_select when working with model objects and select_date in others cases, such as a search form which filters results by date.

      @@ -697,61 +699,7 @@ The model object helpers for dates and times submit parameters with special name
      -

      6. Form builders

      -
      -

      As mentioned previously the object yielded by form_for and fields_for is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example

      -
      -
      -
      <% form_for @person  do |f| %>
      -  <%= text_field_with_label f, :first_name %>
      -<% end %>
      -
      -

      can be replaced with

      -
      -
      -
      <% form_for @person, :builder => LabellingFormBuilder do |f| %>
      -  <%= f.text_field :first_name %>
      -<% end %>
      -
      -

      by defining a LabellingFormBuilder class similar to the following:

      -
      -
      -
      class LabellingFormBuilder < FormBuilder
      -  def text_field attribute, options={}
      -    label(attribute) + text_field(attribute, options)
      -  end
      -end
      -

      If you reuse this frequently you could define a labeled_form_for helper that automatically applies the :builder => LabellingFormBuilder option.

      -

      The form builder used also determines what happens when you do

      -
      -
      -
      <%= render :partial => f %>
      -
      -

      If f is an instance of FormBuilder then this will render the form partial, setting the partial’s object to the form builder. If the form builder is of class LabellingFormBuilder then the labelling_form partial would be rendered instead.

      -

      6.1. Scoping out form controls with fields_for

      -

      fields_for creates a form builder in exactly the same way as form_for but doesn’t create the actual <form> tags. It creates a scope around a specific model object like form_for, which is useful for specifying additional model objects in the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for editing both like so:

      -
      -
      -
      <% form_for @person do |person_form| %>
      -  <%= person_form.text_field :name %>
      -  <% fields_for @person.contact_detail do |contact_details_form| %>
      -    <%= contact_details_form.text_field :phone_number %>
      -  <% end %>
      -<% end %>
      -
      -

      which produces the following output:

      -
      -
      -
      <form action="/people/1" class="edit_person" id="edit_person_1" method="post">
      -  <input id="person_name" name="person[name]" size="30" type="text" />
      -  <input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" />
      -</form>
      -
      -
      -

      7. File Uploads

      +

      5. Uploading Files

      A common task is uploading some sort of file, whether it’s a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form’s encoding MUST be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing :multi_part => true as an HTML option. This means that in the case of form_tag it must be passed in the second options hash and in the case of form_for inside the :html hash.

      The following two forms both upload a file.

      @@ -766,7 +714,7 @@ http://www.gnu.org/software/src-highlite --> <% end %>

      Rails provides the usual pair of helpers: the barebones file_field_tag and the model oriented file_field. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in params[:picture] and in the second case in params[:person][:picture].

      -

      7.1. What gets uploaded

      +

      5.1. What gets uploaded

      The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an original_filename attribute containing the name the file had on the user’s computer and a content_type attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in #{RAILS_ROOT}/public/uploads under the same name as the original file (assuming the form was the one in the previous example).

      If the user has not selected a file the corresponding parameter will be an empty string.
      -

      7.2. Dealing with Ajax

      +

      5.2. Dealing with Ajax

      Unlike other forms making an asynchronous file upload form is not as simple as replacing form_for with remote_form_for. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.

      -
      -

      8. Parameter Names

      -
      -

      As you’ve seen in the previous sections values from forms can appear either at the top level of the params hash or may appear nested in another hash. For example in a standard create +

      Customising Form Builders

      +
      +
      +
      As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example
      +
      +

      <% form_for @person do |f| %> + <%= text_field_with_label f, :first_name %> +<% end %>

      +
      +
      +
      can be replaced with
      +
      +

      <% form_for @person, :builder => LabellingFormBuilder do |f| %> + <%= f.text_field :first_name %> +<% end %>

      +
      +
      +
      by defining a LabellingFormBuilder class similar to the following:
      +
      +[source, ruby]
      +
      +

      class LabellingFormBuilder < FormBuilder + def text_field attribute, options={} + label(attribute) + text_field(attribute, options) + end +end

      +
      +
      +
      If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `:builder => LabellingFormBuilder` option.
      +
      +The form builder used also determines what happens when you do
      +
      +

      <%= render :partial => f %>

      +
      +
      +
      If `f` is an instance of FormBuilder then this will render the 'form' partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the 'labelling_form' partial would be rendered instead.
      +
      +Understanding Parameter Naming Conventions
      +
      +

      As you’ve seen in the previous sections, values from forms can appear either at the top level of the params hash or may appear nested in another hash. For example in a standard create action for a Person model, params[:model] would usually be a hash of all the attributes for the person to create. The params hash can also contain arrays, arrays of hashes and so on.

      -

      Fundamentally HTML forms don’t know about any sort of structured data. All they know about is name-value pairs. Rails tacks some conventions onto parameter names which it uses to express some structure.

      +

      Fundamentally HTML forms don’t know about any sort of structured data, all they generate is name-value pairs. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.

      @@ -811,7 +795,7 @@ action for a Person model, params[:model] would usually be a hash of al
      -

      8.1. Basic structures

      +

      5.3. Basic structures

      The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in the params. For example if a form contains

      @@ -845,7 +829,7 @@ http://www.gnu.org/software/src-highlite --> <input name="person[phone_number][]" type="text"/>

      This would result in params[:person][:phone_number] being an array.

      -

      8.2. Combining them

      +

      5.4. Combining them

      We can mix and match these two concepts. For example, one element of a hash might be an array as in the previous example, or you can have an array of hashes. For example a form might let you create any number of addresses by repeating the following form fragment

      @@ -863,7 +847,7 @@ http://www.gnu.org/software/src-highlite --> Array parameters do not play well with the check_box helper. According to the HTML specification unchecked checkboxes submit no value. However it is often convenient for a checkbox to always submit a value. The check_box helper fakes this by creating a second hidden input with the same name. If the checkbox is unchecked only the hidden input is submitted. If the checkbox is checked then both are submitted but the value submitted by the checkbox takes precedence. When working with array parameters this duplicate submission will confuse Rails since duplicate input names are how it decides when to start a new hash. It is preferable to either use check_box_tag or to use hashes instead of arrays.
      -

      8.3. Using form helpers

      +

      5.5. Using form helpers

      The previous sections did not use the Rails form helpers at all. While you can craft the input names yourself and pass them directly to helpers such as text_field_tag Rails also provides higher level support. The two tools at your disposal here are the name parameter to form_for/fields_for and the :index option.

      You might want to render a form with a set of edit fields for each of a person’s addresses. Something a little like this will do the trick

      @@ -916,7 +900,7 @@ http://www.gnu.org/software/src-highlite -->

      produces exactly the same output as the previous example.

      -

      9. Complex forms

      +

      6. Building Complex forms

      Many apps grow beyond simple forms editing a single object. For example when creating a Person instance you might want to allow the user to (on the same form) create multiple address records (home, work etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include:

        @@ -947,7 +931,7 @@ James Golick’s a
      -

      10. Changelog

      +

      7. Changelog

      Authors
        diff --git a/railties/doc/guides/html/security.html b/railties/doc/guides/html/security.html index 4751e9f92b..371decda64 100644 --- a/railties/doc/guides/html/security.html +++ b/railties/doc/guides/html/security.html @@ -326,7 +326,7 @@ The user has his credit back.

      This attack focuses on fixing a user’s session id known to the attacker, and forcing the user’s browser into using this id. It is therefore not necessary for the attacker to steal the session id afterwards. Here is how this attack works:

      -
        +
        1. The attacker creates a valid session id: He loads the login page of the web application where he wants to fix the session, and takes the session id in the cookie from the response (see number 1 and 2 in the image). -- cgit v1.2.3 From 41af666fb8537bf47d5f63d56ce41ddfcaace2fe Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Mon, 19 Jan 2009 11:46:52 +0000 Subject: Fix asciidoc formating --- railties/doc/guides/source/form_helpers.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/form_helpers.txt b/railties/doc/guides/source/form_helpers.txt index 804363aa3d..f4039070dd 100644 --- a/railties/doc/guides/source/form_helpers.txt +++ b/railties/doc/guides/source/form_helpers.txt @@ -584,7 +584,7 @@ Dealing with Ajax Unlike other forms making an asynchronous file upload form is not as simple as replacing `form_for` with `remote_form_for`. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission. Customising Form Builders -------------- +------------------------- As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example -- cgit v1.2.3 From b9a0c028209086a53022942c2a454d657edbf688 Mon Sep 17 00:00:00 2001 From: Karel Minarik Date: Wed, 21 Jan 2009 14:35:04 +0100 Subject: Basic draft of section "Setting and passing the locale" for i18n guide --- railties/doc/guides/source/i18n.txt | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index e80de7adc9..f0a7b93a58 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -112,22 +112,41 @@ I18n.default_locale = :pt === Setting and passing the locale -By default the I18n library will use :en (English) as a I18n.default_locale for looking up translations (if you do not specify a locale for a lookup). +If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +environment.rb+ or an initializer as shown above, and it will persist. -If you want to translate your Rails application to a single language other than English you can set I18n.default_locale to your locale. If you want to change the locale on a per-request basis though you can set it in a before_filter on the ApplicationController like this: +However, you would probably like to *provide support for more locales* in your applications. In such case, you need to set and pass the locale between requests. + +WARNING: You may be tempted to store choosed locale in a _session_ or a _cookie_. *Do not do so*. The locale should be transparent and a part of the URL. This way you don't break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you're being http://en.wikipedia.org/wiki/Representational_State_Transfer[_RESTful_]. There may be some exceptions to this rule, which are discussed below. + +You can simply set locale in a +before_filter+ in the ApplicationController like this: [source, ruby] ------------------------------------------------------- before_filter :set_locale def set_locale - # if this is nil then I18n.default_locale will be used + # if params[:locale] is nil then I18n.default_locale will be used I18n.locale = params[:locale] end ------------------------------------------------------- -This will already work for URLs where you pass the locale as a query parameter as in example.com?locale=pt (which is what Google also does). +This requires you to pass the locale as a URL query parameter as in +http://example.com/books?locale=pt+. (This is eg. Google's approach). So +http://localhost:3000?locale=pt+ will load the Portugese localization, whereas +http://localhost:3000?locale=de+ would load the German localization, and so on. + +Of course, you probably don't want to manually include locale in every URL all over your application, or want the URLs look differently, eg. the usual +http://example.com/pt/books+ versus +http://example.com/en/books+. Let's discuss the different options you have. + +=== Setting locale from the domain name + +* TODO : Based on http://github.com/karmi/rails_i18n_demo_app/blob/master/app/controllers/application.rb#L44-47 + +* TODO : Setting locale from subdomain -- similar to above + +=== Setting locale from the URL params + +* TODO : Based on *+default_url options+*, http://github.com/karmi/test_default_url_options/blob/master/app/controllers/application.rb#L22-26 + +* TODO : Discussion of plugins (translate_routes and routing_filter) + -TIP: For other URL designs, see http://rails-i18n.org/wiki/pages/how-to-encode-the-current-locale-in-the-url[How to encode the current locale in the URL]. +TIP: For setting locale from URL see http://rails-i18n.org/wiki/pages/how-to-encode-the-current-locale-in-the-url[How to encode the current locale in the URL] in the Rails i18n Wiki. Now you've initialized I18n support for your application and told it which locale should be used. With that in place you're now ready for the really interesting stuff. -- cgit v1.2.3 From 47b122468f45e51fff46560ccd66c878576265f6 Mon Sep 17 00:00:00 2001 From: Karel Minarik Date: Wed, 21 Jan 2009 18:17:42 +0100 Subject: Added section about Setting locale from URL to i18n guide --- railties/doc/guides/source/i18n.txt | 84 ++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 5 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index f0a7b93a58..6000ce8ec2 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -112,13 +112,13 @@ I18n.default_locale = :pt === Setting and passing the locale -If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +environment.rb+ or an initializer as shown above, and it will persist. +If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +environment.rb+ or an initializer as shown above, and it will persist through the requests. -However, you would probably like to *provide support for more locales* in your applications. In such case, you need to set and pass the locale between requests. +However, you would probably like to *provide support for more locales* in your application. In such case, you need to set and pass the locale between requests. WARNING: You may be tempted to store choosed locale in a _session_ or a _cookie_. *Do not do so*. The locale should be transparent and a part of the URL. This way you don't break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you're being http://en.wikipedia.org/wiki/Representational_State_Transfer[_RESTful_]. There may be some exceptions to this rule, which are discussed below. -You can simply set locale in a +before_filter+ in the ApplicationController like this: +The _setting part_ is easy. You can set locale in a +before_filter+ in the ApplicationController like this: [source, ruby] ------------------------------------------------------- @@ -133,11 +133,85 @@ This requires you to pass the locale as a URL query parameter as in +http://exam Of course, you probably don't want to manually include locale in every URL all over your application, or want the URLs look differently, eg. the usual +http://example.com/pt/books+ versus +http://example.com/en/books+. Let's discuss the different options you have. +IMPORTANT: Following examples rely on having locales loaded into your application available as an array of strings like +["en", "es", "gr"]+. This is not inclued in current version of Rails 2.2 -- forthcoming Rails version 2.3 will contain easy accesor +available_locales+. (See http://github.com/svenfuchs/i18n/commit/411f8fe7[this commit] and background at http://rails-i18n.org/wiki/pages/i18n-available_locales[Rails I18n Wiki].) + +We have to include support for getting available locales manually in an initializer like this: + +[source, ruby] +------------------------------------------------------- +# config/initializers/available_locales.rb +# +# Get loaded locales conveniently +# See http://rails-i18n.org/wiki/pages/i18n-available_locales +module I18n + class << self + def available_locales; backend.available_locales; end + end + module Backend + class Simple + def available_locales; translations.keys.collect { |l| l.to_s }.sort; end + end + end +end + +# You need to "force-initialize" loaded locales +I18n.backend.send(:init_translations) + +AVAILABLE_LOCALES = I18n.backend.available_locales +RAILS_DEFAULT_LOGGER.debug "* Loaded locales: #{AVAILABLE_LOCALES.inspect}" +------------------------------------------------------- + +You can then wrap the constant for easy access in ApplicationController: + +[source, ruby] +------------------------------------------------------- +class ApplicationController < ActionController::Base + def available_locales; AVAILABLE_LOCALES; end +end +------------------------------------------------------- + === Setting locale from the domain name -* TODO : Based on http://github.com/karmi/rails_i18n_demo_app/blob/master/app/controllers/application.rb#L44-47 +One option you have is to set the locale from the domain name, where your application runs. For example, we want +www.example.com+ to load English (or default) locale, and +www.example.es+ to load Spanish locale. Thus the _top-level domain name_ is used for locale setting. This has several advantages: + +* Locale is an _obvious_ part of the URL +* People intuitively grasp in which language the content will be displayed +* It is very trivial to implement in Rails +* Search engines seem to like that content in different languages lives at different, inter-linked domains + +You can implement it like this in your ApplicationController: + +[source, ruby] +------------------------------------------------------- +before_filter :set_locale +def set_locale + I18n.locale = extract_locale_from_uri +end +# Get locale from top-level domain or return nil if such locale is not available +# You have to put something like: +# 127.0.0.1 application.com +# 127.0.0.1 application.it +# 127.0.0.1 application.pl +# in your /etc/hosts file to try this out locally +def extract_locale_from_tld + parsed_locale = request.host.split('.').last + (available_locales.include? parsed_locale) ? parsed_locale : nil +end +------------------------------------------------------- + +We can also set the locale from the _subdomain_ in very similar way: -* TODO : Setting locale from subdomain -- similar to above +[source, ruby] +------------------------------------------------------- +# Get locale code from request subdomain (like http://it.application.local:3000) +# You have to put something like: +# 127.0.0.1 gr.application.local +# in your /etc/hosts file to try this out locally +def extract_locale_from_subdomain + parsed_locale = request.subdomains.first + (available_locales.include? parsed_locale) ? parsed_locale : nil +end +------------------------------------------------------- === Setting locale from the URL params -- cgit v1.2.3 From cc2243dee5cf0757410ad42ba0bf2f6b9a07f68b Mon Sep 17 00:00:00 2001 From: Karel Minarik Date: Wed, 21 Jan 2009 18:22:55 +0100 Subject: Fixed bad path to image (demo_translated_en.png) --- railties/doc/guides/source/i18n.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index 6000ce8ec2..d364f4bf46 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -292,7 +292,7 @@ pirate: There you go. Because you haven't changed the default_locale I18n will use English. Your application now shows: -image:images/i18n/demo_translated_english.png[rails i18n demo translated to english] +image:images/i18n/demo_translated_en.png[rails i18n demo translated to english] And when you change the URL to pass the pirate locale you get: -- cgit v1.2.3 From d9fd4c478cd526f5729ac9578bfc6e1dd4b9ae6e Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Wed, 21 Jan 2009 20:48:31 +0100 Subject: i18n guide: added sections: conclusion, contributing to rails-i18n, resources, authors --- railties/doc/guides/source/i18n.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index d364f4bf46..964dec823d 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -731,8 +731,39 @@ I18n.t :foo, :raise => true # always re-raises exceptions from the backend ------------------------------------------------------- +== Conclusion + +At this point you hopefully have a good overview about how I18n support in Ruby on Rails works and are ready to start translating your project. + +If you find anything missing or wrong in this guide please file a ticket on http://i18n.lighthouseapp.com/projects/14948-rails-i18n/overview[our issue tracker]. If you want to discuss certain portions or have questions please sign up to our http://groups.google.com/group/rails-i18n[mailinglist]. + + +== Contributing to Rails I18n + +I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first and then cherry-picking the best bread of most widely useful features second for inclusion to the core. + +Thus we encourage everybody to experiment with new ideas and features in plugins or other libraries and make them available to the community. (Don't forget to announce your work on our http://groups.google.com/group/rails-i18n[mailinglist]!) + +If you find your own locale (language) missing from our http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale[example translations data] repository for Ruby on Rails + + == Resources +* http://rails-i18n.org[rails-i18n.org] - Homepage of the rails-i18n project. You can find lots of useful resources on the http://rails-i18n.org/wiki[wiki]. +* http://groups.google.com/group/rails-i18n[rails-i18n Google group] - The project's mailinglist. +* http://github.com/svenfuchs/rails-i18n/tree/master[Github: rails-i18n] - Code repository for the rails-i18n project. Most importantly you can find lots of http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale[example translations] for Rails that should work for your application in most cases. +* http://i18n.lighthouseapp.com/projects/14948-rails-i18n/overview[Lighthouse: rails-i18n] - Issue tracker for the rails-i18n project. +* http://github.com/svenfuchs/i18n/tree/master[Github: i18n] - Code repository for the i18n gem. +* http://i18n.lighthouseapp.com/projects/14947-ruby-i18n/overview[Lighthouse: i18n] - Issue tracker for the i18n gem. + + +== Authors + +* Sven Fuchs[http://www.workingwithrails.com/person/9963-sven-fuchs] (initial author) +* Karel Minarik[http://www.workingwithrails.com/person/7476-karel-mina-k] + +If you found this guide useful please consider recommending its authors on http://www.workingwithrails.com[workingwithrails]. + == Footnotes @@ -742,6 +773,7 @@ I18n.t :foo, :raise => true # always re-raises exceptions from the backend [[[3]]] One of these reasons is that we don't want to any unnecessary load for applications that do not need any I18n capabilities, so we need to keep the I18n library as simple as possible for English. Another reason is that it is virtually impossible to implement a one-fits-all solution for all problems related to I18n for all existing languages. So a solution that allows us to exchange the entire implementation easily is appropriate anyway. This also makes it much easier to experiment with custom features and extensions. + == Changelog == http://rails.lighthouseapp.com/projects/16213/tickets/23[Lighthouse ticket] -- cgit v1.2.3 From 65ae0cc6229a4e0b977711d948cd10a7dcb342a3 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Wed, 21 Jan 2009 22:12:59 +0100 Subject: i18n guide: add section: overview of other built-in methods --- railties/doc/guides/source/i18n.txt | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index 964dec823d..f1c9e6ff6d 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -668,11 +668,29 @@ en: ------------------------------------------------------- -=== Other translations and localizations +=== Overview of other built-in methods that provide I18n support -Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. +Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here's a brief overview. -TODO list helpers and available keys +==== ActionView helper methods + +* distance_of_time_in_words translates and pluralizes its result and interpolates the number of seconds, minutes, hours and so on. See http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L51[datetime.distance_in_words] translations. + +* datetime_select and select_month use translated month names for populating the resulting select tag. See http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L15[date.month_names] for translations. datetime_select also looks up the order option from http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L18[date.order] (unless you pass the option explicitely). All date select helpers translate the prompt using the translations in the http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L83[datetime.prompts] scope if applicable. + +* The number_to_currency, number_with_precision, number_to_percentage, number_with_delimiter and humber_to_human_size helpers use the number format settings located in the http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2[number] scope. + +==== ActiveRecord methods + +* human_name and human_attribute_name use translations for model names and attribute names if available in the http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L43[activerecord.models] scope. They also support translations for inherited class names (e.g. for use with STI) as explained in (TODO:link). + +* ActiveRecord::Errors#generate_message (which is used by ActiveRecord validations but may also be used manually) uses human_name and human_attribute_name (see above). It also translates the error message and supports translations for inherited class names as explained in (TODO:link). + +* ActiveRecord::Errors#full_messages prepends the attribute name to the error message using a separator that will be looked up from http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L91[activerecord.errors.format.separator] (and defaults to ' '). + +==== ActiveSupport methods + +* Array#to_sentence uses format settings as given in the http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L30[support.array] scope. == Customize your I18n setup -- cgit v1.2.3 From 16909d3514454b14c0ab86347c57388ba2836f0d Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Wed, 21 Jan 2009 22:16:30 +0100 Subject: i18n guide: refer to section 'Error messages scopes' --- railties/doc/guides/source/i18n.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index f1c9e6ff6d..3418676ff5 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -682,9 +682,9 @@ Rails uses fixed strings and other localizations, such as format strings and oth ==== ActiveRecord methods -* human_name and human_attribute_name use translations for model names and attribute names if available in the http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L43[activerecord.models] scope. They also support translations for inherited class names (e.g. for use with STI) as explained in (TODO:link). +* human_name and human_attribute_name use translations for model names and attribute names if available in the http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L43[activerecord.models] scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes". -* ActiveRecord::Errors#generate_message (which is used by ActiveRecord validations but may also be used manually) uses human_name and human_attribute_name (see above). It also translates the error message and supports translations for inherited class names as explained in (TODO:link). +* ActiveRecord::Errors#generate_message (which is used by ActiveRecord validations but may also be used manually) uses human_name and human_attribute_name (see above). It also translates the error message and supports translations for inherited class names as explained above in "Error message scopes". * ActiveRecord::Errors#full_messages prepends the attribute name to the error message using a separator that will be looked up from http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L91[activerecord.errors.format.separator] (and defaults to ' '). -- cgit v1.2.3 From de23a0077635f46c8c03a44a81e3efe95e28f2ab Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 21 Jan 2009 21:30:37 +0000 Subject: Regenerate guides --- railties/doc/guides/html/form_helpers.html | 74 ++++---- railties/doc/guides/html/i18n.html | 265 +++++++++++++++++++++++++++-- 2 files changed, 293 insertions(+), 46 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/form_helpers.html b/railties/doc/guides/html/form_helpers.html index 6169574d35..54155cddb6 100644 --- a/railties/doc/guides/html/form_helpers.html +++ b/railties/doc/guides/html/form_helpers.html @@ -90,6 +90,15 @@

        2. Dealing with Ajax
        3. + + +
        4. + Customising Form Builders +
        5. +
        6. + Understanding Parameter Naming Conventions +

        5.2. Dealing with Ajax

        Unlike other forms making an asynchronous file upload form is not as simple as replacing form_for with remote_form_for. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.

        -

        Customising Form Builders

        +
      +

      6. Customising Form Builders

      +
      +

      As mentioned previously the object yielded by form_for and fields_for is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example

      -
      As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example
      -
      -

      <% form_for @person do |f| %> +

      <% form_for @person  do |f| %>
         <%= text_field_with_label f, :first_name %>
      -<% end %>

      -
      -
      -
      can be replaced with
      +<% end %>
      -

      <% form_for @person, :builder => LabellingFormBuilder do |f| %> - <%= f.text_field :first_name %> -<% end %>

      +

      can be replaced with

      -
      by defining a LabellingFormBuilder class similar to the following:
      -
      -[source, ruby]
      +
      <% form_for @person, :builder => LabellingFormBuilder do |f| %>
      +  <%= f.text_field :first_name %>
      +<% end %>
      -

      class LabellingFormBuilder < FormBuilder - def text_field attribute, options={} - label(attribute) + text_field(attribute, options) - end -end

      +

      by defining a LabellingFormBuilder class similar to the following:

      -
      -
      If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `:builder => LabellingFormBuilder` option.
      -
      -The form builder used also determines what happens when you do
      -
      -

      <%= render :partial => f %>

      +
      +
      class LabellingFormBuilder < FormBuilder
      +  def text_field attribute, options={}
      +    label(attribute) + text_field(attribute, options)
      +  end
      +end
      +

      If you reuse this frequently you could define a labeled_form_for helper that automatically applies the :builder => LabellingFormBuilder option.

      +

      The form builder used also determines what happens when you do

      -
      If `f` is an instance of FormBuilder then this will render the 'form' partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the 'labelling_form' partial would be rendered instead.
      -
      -Understanding Parameter Naming Conventions
      +
      <%= render :partial => f %>
      +

      If f is an instance of FormBuilder then this will render the form partial, setting the partial’s object to the form builder. If the form builder is of class LabellingFormBuilder then the labelling_form partial would be rendered instead.

      +
      +

      7. Understanding Parameter Naming Conventions

      +

      As you’ve seen in the previous sections, values from forms can appear either at the top level of the params hash or may appear nested in another hash. For example in a standard create action for a Person model, params[:model] would usually be a hash of all the attributes for the person to create. The params hash can also contain arrays, arrays of hashes and so on.

      Fundamentally HTML forms don’t know about any sort of structured data, all they generate is name-value pairs. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.

      @@ -795,7 +803,7 @@ action for a Person model, params[:model] would usually be a hash of al
      -

      5.3. Basic structures

      +

      7.1. Basic structures

      The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in the params. For example if a form contains

      @@ -829,7 +837,7 @@ http://www.gnu.org/software/src-highlite --> <input name="person[phone_number][]" type="text"/>

      This would result in params[:person][:phone_number] being an array.

      -

      5.4. Combining them

      +

      7.2. Combining them

      We can mix and match these two concepts. For example, one element of a hash might be an array as in the previous example, or you can have an array of hashes. For example a form might let you create any number of addresses by repeating the following form fragment

      @@ -847,7 +855,7 @@ http://www.gnu.org/software/src-highlite --> Array parameters do not play well with the check_box helper. According to the HTML specification unchecked checkboxes submit no value. However it is often convenient for a checkbox to always submit a value. The check_box helper fakes this by creating a second hidden input with the same name. If the checkbox is unchecked only the hidden input is submitted. If the checkbox is checked then both are submitted but the value submitted by the checkbox takes precedence. When working with array parameters this duplicate submission will confuse Rails since duplicate input names are how it decides when to start a new hash. It is preferable to either use check_box_tag or to use hashes instead of arrays.
      -

      5.5. Using form helpers

      +

      7.3. Using form helpers

      The previous sections did not use the Rails form helpers at all. While you can craft the input names yourself and pass them directly to helpers such as text_field_tag Rails also provides higher level support. The two tools at your disposal here are the name parameter to form_for/fields_for and the :index option.

      You might want to render a form with a set of edit fields for each of a person’s addresses. Something a little like this will do the trick

      @@ -900,7 +908,7 @@ http://www.gnu.org/software/src-highlite -->

      produces exactly the same output as the previous example.

      -

      6. Building Complex forms

      +

      8. Building Complex forms

      Many apps grow beyond simple forms editing a single object. For example when creating a Person instance you might want to allow the user to (on the same form) create multiple address records (home, work etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include:

        @@ -931,7 +939,7 @@ James Golick’s a
      -

      7. Changelog

      +

      9. Changelog

      Authors
    2. @@ -82,7 +86,7 @@
    3. Translations for ActiveRecord models
    4. -
    5. Other translations and localizations
    6. +
    7. Overview of other built-in methods that provide I18n support
    8. @@ -97,9 +101,18 @@
    9. + Conclusion +
    10. +
    11. + Contributing to Rails I18n +
    12. +
    13. Resources
    14. + Authors +
    15. +
    16. Footnotes
    17. @@ -244,8 +257,17 @@ I18n.load_path # set default locale to something else then :en I18n.default_locale = :pt

2.3. Setting and passing the locale

-

By default the I18n library will use :en (English) as a I18n.default_locale for looking up translations (if you do not specify a locale for a lookup).

-

If you want to translate your Rails application to a single language other than English you can set I18n.default_locale to your locale. If you want to change the locale on a per-request basis though you can set it in a before_filter on the ApplicationController like this:

+

If you want to translate your Rails application to a single language other than English (the default locale), you can set I18n.default_locale to your locale in environment.rb or an initializer as shown above, and it will persist through the requests.

+

However, you would probably like to provide support for more locales in your application. In such case, you need to set and pass the locale between requests.

+
+ + + +
+Warning +You may be tempted to store choosed locale in a session or a cookie. Do not do so. The locale should be transparent and a part of the URL. This way you don’t break people’s basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you’re being RESTful. There may be some exceptions to this rule, which are discussed below.
+
+

The setting part is easy. You can set locale in a before_filter in the ApplicationController like this:

before_filter :set_locale
 def set_locale
-  # if this is nil then I18n.default_locale will be used
+  # if params[:locale] is nil then I18n.default_locale will be used
   I18n.locale = params[:locale]
 end
-

This will already work for URLs where you pass the locale as a query parameter as in example.com?locale=pt (which is what Google also does).

+

This requires you to pass the locale as a URL query parameter as in http://example.com/books?locale=pt. (This is eg. Google’s approach). So http://localhost:3000?locale=pt will load the Portugese localization, whereas http://localhost:3000?locale=de would load the German localization, and so on.

+

Of course, you probably don’t want to manually include locale in every URL all over your application, or want the URLs look differently, eg. the usual http://example.com/pt/books versus http://example.com/en/books. Let’s discuss the different options you have.

+
+ + + +
+Important +Following examples rely on having locales loaded into your application available as an array of strings like ["en", "es", "gr"]. This is not inclued in current version of Rails 2.2 — forthcoming Rails version 2.3 will contain easy accesor available_locales. (See this commit and background at Rails I18n Wiki.)
+
+

We have to include support for getting available locales manually in an initializer like this:

+
+
+
# config/initializers/available_locales.rb
+#
+# Get loaded locales conveniently
+# See http://rails-i18n.org/wiki/pages/i18n-available_locales
+module I18n
+  class << self
+    def available_locales; backend.available_locales; end
+  end
+  module Backend
+    class Simple
+      def available_locales; translations.keys.collect { |l| l.to_s }.sort; end
+    end
+  end
+end
+
+# You need to "force-initialize" loaded locales
+I18n.backend.send(:init_translations)
+
+AVAILABLE_LOCALES = I18n.backend.available_locales
+RAILS_DEFAULT_LOGGER.debug "* Loaded locales: #{AVAILABLE_LOCALES.inspect}"
+

You can then wrap the constant for easy access in ApplicationController:

+
+
+
class ApplicationController < ActionController::Base
+  def available_locales; AVAILABLE_LOCALES; end
+end
+

2.4. Setting locale from the domain name

+

One option you have is to set the locale from the domain name, where your application runs. For example, we want www.example.com to load English (or default) locale, and www.example.es to load Spanish locale. Thus the top-level domain name is used for locale setting. This has several advantages:

+
+

You can implement it like this in your ApplicationController:

+
+
+
before_filter :set_locale
+def set_locale
+  I18n.locale = extract_locale_from_uri
+end
+# Get locale from top-level domain or return nil if such locale is not available
+# You have to put something like:
+#   127.0.0.1 application.com
+#   127.0.0.1 application.it
+#   127.0.0.1 application.pl
+# in your /etc/hosts file to try this out locally
+def extract_locale_from_tld
+  parsed_locale = request.host.split('.').last
+  (available_locales.include? parsed_locale) ? parsed_locale  : nil
+end
+

We can also set the locale from the subdomain in very similar way:

+
+
+
# Get locale code from request subdomain (like http://it.application.local:3000)
+# You have to put something like:
+#   127.0.0.1 gr.application.local
+# in your /etc/hosts file to try this out locally
+def extract_locale_from_subdomain
+  parsed_locale = request.subdomains.first
+  (available_locales.include? parsed_locale) ? parsed_locale  : nil
+end
+

2.5. Setting locale from the URL params

+
- +
Tip For other URL designs, see How to encode the current locale in the URL.For setting locale from URL see How to encode the current locale in the URL in the Rails i18n Wiki.

Now you’ve initialized I18n support for your application and told it which locale should be used. With that in place you’re now ready for the really interesting stuff.

@@ -340,7 +477,7 @@ pirate: hello_flash: Ahoy Flash

There you go. Because you haven’t changed the default_locale I18n will use English. Your application now shows:

-rails i18n demo translated to english +rails i18n demo translated to english

And when you change the URL to pass the pirate locale you get:

@@ -815,9 +952,52 @@ http://www.gnu.org/software/src-highlite --> one: "1 error prohibited this {{model}} from being saved" other: "{{count}} errors prohibited this {{model}} from being saved" body: "There were problems with the following fields:"

-

5.2. Other translations and localizations

-

Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers.

-

TODO list helpers and available keys

+

5.2. Overview of other built-in methods that provide I18n support

+

Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here’s a brief overview.

+

5.2.1. ActionView helper methods

+
+

5.2.2. ActiveRecord methods

+
+

5.2.3. ActiveSupport methods

+

6. Customize your I18n setup

@@ -868,16 +1048,75 @@ http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
I18n.t :foo, :raise => true # always re-raises exceptions from the backend
-

7. Resources

+

7. Conclusion

+
+

At this point you hopefully have a good overview about how I18n support in Ruby on Rails works and are ready to start translating your project.

+

If you find anything missing or wrong in this guide please file a ticket on our issue tracker. If you want to discuss certain portions or have questions please sign up to our mailinglist.

+
+

8. Contributing to Rails I18n

+
+

I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first and then cherry-picking the best bread of most widely useful features second for inclusion to the core.

+

Thus we encourage everybody to experiment with new ideas and features in plugins or other libraries and make them available to the community. (Don’t forget to announce your work on our mailinglist!)

+

If you find your own locale (language) missing from our example translations data repository for Ruby on Rails

+
+

9. Resources

+
+
+

10. Authors

+
+
    +
  • +

    +Sven Fuchs[http://www.workingwithrails.com/person/9963-sven-fuchs] (initial author) +

    +
  • +
  • +

    +Karel Minarik[http://www.workingwithrails.com/person/7476-karel-mina-k] +

    +
  • +
+

If you found this guide useful please consider recommending its authors on workingwithrails.

-

8. Footnotes

+

11. Footnotes

[1] Or, to quote Wikipedia: "Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting software for a specific region or language by adding locale-specific components and translating text."

[2] Other backends might allow or require to use other formats, e.g. a GetText backend might allow to read GetText files.

[3] One of these reasons is that we don’t want to any unnecessary load for applications that do not need any I18n capabilities, so we need to keep the I18n library as simple as possible for English. Another reason is that it is virtually impossible to implement a one-fits-all solution for all problems related to I18n for all existing languages. So a solution that allows us to exchange the entire implementation easily is appropriate anyway. This also makes it much easier to experiment with custom features and extensions.

-

9. Changelog

+

12. Changelog

-- cgit v1.2.3 From 8ad2f93a309e57e67286e0c4426b1ad003b9b33b Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 21 Jan 2009 21:35:53 +0000 Subject: ActiveRecord => Active Record --- railties/doc/guides/html/i18n.html | 26 +++++++++++++------------- railties/doc/guides/source/i18n.txt | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/i18n.html b/railties/doc/guides/html/i18n.html index 47a9abb93c..386b801d64 100644 --- a/railties/doc/guides/html/i18n.html +++ b/railties/doc/guides/html/i18n.html @@ -84,7 +84,7 @@ How to store your custom translations -

As part of this solution, every static string in the Rails framework — eg. ActiveRecord validation messages, time and date formats — has been internationalized, so localization of a Rails application means "over-riding" these defaults.

+

As part of this solution, every static string in the Rails framework — eg. Active Record validation messages, time and date formats — has been internationalized, so localization of a Rails application means "over-riding" these defaults.

1.1. The overall architecture of the library

Thus, the Ruby I18n gem is split into two parts:

    @@ -219,7 +219,7 @@ http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
    en:
       hello: "Hello world"
-

This means, that in the :en locale, the key hello will map to Hello world string. Every string inside Rails is internationalized in this way, see for instance ActiveRecord validation messages in the activerecord/lib/active_record/locale/en.yml file or time and date formats in the activesupport/lib/active_support/locale/en.yml file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.

+

This means, that in the :en locale, the key hello will map to Hello world string. Every string inside Rails is internationalized in this way, see for instance Active Record validation messages in the activerecord/lib/active_record/locale/en.yml file or time and date formats in the activesupport/lib/active_support/locale/en.yml file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.

The I18n library will use English as a default locale, ie. if you don’t set a different locale, :en will be used for looking up translations.

The translations load path (I18n.load_path) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.

@@ -554,7 +554,7 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
I18n.t :invalid, :scope => [:active_record, :error_messages]
-

This looks up the :invalid message in the ActiveRecord error messages.

+

This looks up the :invalid message in the Active Record error messages.

Additionally, both the key and scopes can be specified as dot separated keys as in:

I18n.t [:odd, :even], :scope => 'active_record.error_messages'
 # => ["must be odd", "must be even"]
-

Also, a key can translate to a (potentially nested) hash as grouped translations. E.g. one can receive all ActiveRecord error messages as a Hash with:

+

Also, a key can translate to a (potentially nested) hash as grouped translations. E.g. one can receive all Active Record error messages as a Hash with:

# will translate User attribute "login" as "Handle"

Then User.human_name will return "Dude" and User.human_attribute_name(:login) will return "Handle".

5.1.1. Error message scopes

-

ActiveRecord validation error messages can also be translated easily. ActiveRecord gives you a couple of namespaces where you can place your message translations in order to provide different messages and translation for certain models, attributes and/or validations. It also transparently takes single table inheritance into account.

+

Active Record validation error messages can also be translated easily. Active Record gives you a couple of namespaces where you can place your message translations in order to provide different messages and translation for certain models, attributes and/or validations. It also transparently takes single table inheritance into account.

This gives you quite powerful means to flexibly adjust your messages to your application’s needs.

Consider a User model with a validates_presence_of validation for the name attribute like this:

@@ -747,7 +747,7 @@ http://www.gnu.org/software/src-highlite -->
class User < ActiveRecord::Base
   validates_presence_of :name
 end
-

The key for the error message in this case is :blank. ActiveRecord will lookup this key in the namespaces:

+

The key for the error message in this case is :blank. Active Record will lookup this key in the namespaces:

class Admin < User
   validates_presence_of :name
 end
-

Then ActiveRecord will look for messages in this order:

+

Then Active Record will look for messages in this order: