From 56152d8f60963a3d862f335144a33782723ade83 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 18 Jan 2009 00:18:02 +0000 Subject: Regenerate guides --- railties/doc/guides/html/2_2_release_notes.html | 32 ++-- railties/doc/guides/html/action_mailer_basics.html | 197 +++++++++++++++++++ .../doc/guides/html/actioncontroller_basics.html | 62 +++--- .../doc/guides/html/active_record_querying.html | 136 ++++++------- .../html/activerecord_validations_callbacks.html | 96 +++++----- railties/doc/guides/html/association_basics.html | 210 ++++++++++----------- railties/doc/guides/html/caching_with_rails.html | 38 ++-- railties/doc/guides/html/command_line.html | 30 +-- railties/doc/guides/html/configuring.html | 6 +- railties/doc/guides/html/creating_plugins.html | 96 +++++----- .../guides/html/debugging_rails_applications.html | 30 +-- railties/doc/guides/html/form_helpers.html | 10 +- .../guides/html/getting_started_with_rails.html | 114 +++++------ railties/doc/guides/html/i18n.html | 82 ++++---- .../doc/guides/html/layouts_and_rendering.html | 164 ++++++++-------- railties/doc/guides/html/migrations.html | 46 ++--- railties/doc/guides/html/performance_testing.html | 58 +++--- railties/doc/guides/html/rails_on_rack.html | 24 +-- railties/doc/guides/html/routing_outside_in.html | 138 +++++++------- railties/doc/guides/html/security.html | 50 ++--- .../guides/html/testing_rails_applications.html | 72 +++---- 21 files changed, 944 insertions(+), 747 deletions(-) create mode 100644 railties/doc/guides/html/action_mailer_basics.html (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/2_2_release_notes.html b/railties/doc/guides/html/2_2_release_notes.html index 46d73fa96e..0dec014c3e 100644 --- a/railties/doc/guides/html/2_2_release_notes.html +++ b/railties/doc/guides/html/2_2_release_notes.html @@ -243,7 +243,7 @@ More information :

All told, the Guides provide tens of thousands of words of guidance for beginning and intermediate Rails developers.

If you want to generate these guides locally, inside your application:

-
@@ -283,7 +283,7 @@ More information:

Supporting the etag and last modified timestamp in HTTP headers means that Rails can now send back an empty response if it gets a request for a resource that hasn’t been modified lately. This allows you to check whether a response needs to be sent at all.

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

The work done to make Rails thread-safe is rolling out in Rails 2.2. Depending on your web server infrastructure, this means you can handle more requests with fewer copies of Rails in memory, leading to better server performance and higher utilization of multiple cores.

To enable multithreaded dispatching in production mode of your application, add the following line in your config/environments/production.rb:

-
@@ -384,7 +384,7 @@ More information:

5.2. Connection Pooling

Connection pooling lets Rails distribute database requests across a pool of database connections that will grow to a maximum size (by default 5, but you can add a pool key to your database.yml to adjust this). This helps remove bottlenecks in applications that support many concurrent users. There’s also a wait_timeout that defaults to 5 seconds before giving up. ActiveRecord::Base.connection_pool gives you direct access to the pool if you need it.

-
@@ -416,7 +416,7 @@ More information:

5.3. Hashes for Join Table Conditions

You can now specify conditions on join tables using a hash. This is a big help if you need to query across complex joins.

-
@@ -449,7 +449,7 @@ More information:

5.4.1. find_last_by_<attribute>

The find_last_by_<attribute> method is equivalent to Model.last(:conditions => {:attribute => value})

-
@@ -465,7 +465,7 @@ Lead Contributor: 5.4.2. find_by_<attribute>!

The new bang! version of find_by_<attribute>! is equivalent to Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFound Instead of returning nil if it can’t find a matching record, this method will raise an exception if it cannot find a match.

-
@@ -529,7 +529,7 @@ Counter cache columns (for associations declared with :counter_cache => t

6.1. Shallow Route Nesting

Shallow route nesting provides a solution to the well-known difficulty of using deeply-nested resources. With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with.

-
@@ -574,7 +574,7 @@ More information:

6.2. Method Arrays for Member or Collection Routes

You can now supply an array of methods for new member or collection routes. This removes the annoyance of having to define a route as accepting any verb as soon as you need it to handle more than one. With Rails 2.2, this is a legitimate route declaration:

-
@@ -589,7 +589,7 @@ Lead Contributor: Brennan Dunn

6.3. Resources With Specific Actions

By default, when you use map.resources to create a route, Rails generates routes for seven default actions (index, show, create, new, edit, update, and destroy). But each of these routes takes up memory in your application, and causes Rails to generate additional routing logic. Now you can use the :only and :except options to fine-tune the routes that Rails will generate for resources. You can supply a single action, an array of actions, or the special :all or :none options. These options are inherited by nested resources.

-
@@ -696,7 +696,7 @@ More information:

9.1. Memoization

Memoization is a pattern of initializing a method once and then stashing its value away for repeat use. You’ve probably used this pattern in your own applications:

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

Memoization lets you handle this task in a declarative fashion:

-
@@ -743,7 +743,7 @@ More information:

9.2. each_with_object

The each_with_object method provides an alternative to inject, using a method backported from Ruby 1.9. It iterates over a collection, passing the current element and the memo into the block.

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

9.3. Delegates With Prefixes

If you delegate behavior from one class to another, you can now specify a prefix that will be used to identify the delegated methods. For example:

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

This will produce delegated methods vendor#account_email and vendor#account_password. You can also specify a custom prefix:

-
@@ -953,7 +953,7 @@ Implicit local assignments when rendering partials has been deprecated.
-
diff --git a/railties/doc/guides/html/action_mailer_basics.html b/railties/doc/guides/html/action_mailer_basics.html new file mode 100644 index 0000000000..56451818eb --- /dev/null +++ b/railties/doc/guides/html/action_mailer_basics.html @@ -0,0 +1,197 @@ + + + + + Action Mailer Basics + + + + + + + + +
+ + + +
+

Action Mailer Basics

+
+
+

This guide should provide you with all you need to get started in sending emails from your application, and will also cover how to test your mailers.

+
+
+

1. What is Action Mailer?

+
+

Action Mailer allows you to send email from your application using a mailer model and views. +Yes, that is correct, in Rails, emails are used by creating Models that inherit from ActionMailer::Base. They live alongside other models in /app/models BUT they have views just like controllers that appear alongside other views in app/views.

+
+

2. Quick walkthrough to creating a Mailer

+
+

Let’s say you want to send a welcome email to a user after they signup. Here is how you would go about this:

+

2.1. 1. Create the mailer:

+
+
+
./script/generate mailer UserMailer
+exists  app/models/
+create  app/views/user_mailer
+exists  test/unit/
+create  test/fixtures/user_mailer
+create  app/models/user_mailer.rb
+create  test/unit/user_mailer_test.rb
+

So we got the model, the fixtures, and the tests all created for us

+

2.2. 2. Edit the model:

+
+
+
class UserMailer < ActionMailer::Base
+
+end
+

Lets add a method called welcome_email, that will send an email to the user’s registered email address:

+
+
+
class UserMailer < ActionMailer::Base
+
+  def welcome_email(user)
+    recipients    user.email
+    from          "My Awesome Site Notifications<notifications@example.com>"
+    subject       "Welcome to My Awesome Site"
+    sent_on       Time.now
+    body          {:user => user, :url => "http://example.com/login"}
+    content_type  "text/html"
+  end
+
+end
+

So what do we have here? +recipients: who the recipients are, put in an array for multiple, ie, @recipients = ["user1@example.com", "user2@example.com"] +from: Who the email will appear to come from in the recipients' mailbox +subject: The subject of the email +sent_on: Timestamp for the email +content_type: The content type, by default is text/plain

+

How about @body[:user]? Well anything you put in the @body hash will appear in the mailer view (more about mailer views below) as an instance variable ready for you to use, ie, in our example the mailer view will have a @user instance variable available for its consumption.

+

2.3. 3. Create the mailer view

+

+

The file can look like:

+
+
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+  <head>
+    <meta content='text/html; charset=iso-8859-1' http-equiv='Content-Type' />
+  </head>
+  <body>
+    <h1>Welcome to example.com, <%= @user.first_name %></h1>
+
+    <p>
+      You have successfully signed up to example.com, and your username is: <%= @user.login %>.<br/>
+      To login to the site, just follow this link: <%= @url %>.
+    </p>
+    <p>Thanks for joining and have a great day!</p>
+  </body>
+</html>
+

2.4. 4. Wire it up so that the system sends the email when a user signs up

+

There are 3 was to achieve this. One is to send the email from the controller that sends the email, another is to put it in a before_create block in the user model, and the last one is to use an observer on the user model. Whether you use the second or third methods is up to you, but staying away from the first is recommended. Not because it’s wrong, but because it keeps your controller clean, and keeps all logic related to the user model within the user model. This way, whichever way a user is created (from a web form, or from an API call, for example), we are guaranteed that the email will be sent.

+

+
+
+
# Code that already exists
+
+Rails::Initializer.run do |config|
+
+  # Code that already exists
+
+  config.active_record.observers = :user_observer
+
+end
+

+
+
+
# Code that already exists
+
+Rails::Initializer.run do |config|
+
+  # Code that already exists
+
+  config.load_paths += %W(#{RAILS_ROOT}/app/observers)
+
+  config.active_record.observers = :user_observer
+
+end
+

ALMOST THERE :) Now all we need is that danged observer, and we’re done:

+
+
+
class UserObserver < ActiveRecord::Observer
+  def after_create(user)
+    UserMailer.deliver_welcome_email(user)
+  end
+end
+

Notice how we call deliver_welcome_email? Where is that method? Well if you remember, we created a method called welcome_email in UserMailer, right? Well, as part of the "magic" of rails, we deliver the email identified by welcome_email by calling deliver_welcome_email.

+

That’s it! Now whenever your users signup, they will be greeted with a nice welcome email. Next up, we’ll talk about how to test a mailer model.

+
+

3. Mailer Testing

+
+
+ +
+
+ + diff --git a/railties/doc/guides/html/actioncontroller_basics.html b/railties/doc/guides/html/actioncontroller_basics.html index 76d7ee0588..f5b25a4d7a 100644 --- a/railties/doc/guides/html/actioncontroller_basics.html +++ b/railties/doc/guides/html/actioncontroller_basics.html @@ -181,7 +181,7 @@ Deal with exceptions that may be raised during request processing

A controller is a Ruby class which inherits from ApplicationController and has methods just like any other class. When your application receives a request, the routing will determine which controller and action to run, then Rails creates an instance of that controller and runs the public method with the same name as the action.

-
@@ -205,7 +205,7 @@ private

There’s no rule saying a method on a controller has to be an action; they may well be used for other purposes such as filters, which will be covered later in this guide.

As an example, if a user goes to /clients/new in your application to add a new client, Rails will create an instance of ClientsController and run the new method. Note that the empty method from the example above could work just fine because Rails will by default render the new.html.erb view unless the action says otherwise. The new method could make available to the view a @client instance variable by creating a new Client:

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

You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL, called query string parameters. The query string is everything after "?" in the URL. The second type of parameter is usually referred to as POST data. This information usually comes from a HTML form which has been filled in by the user. It’s called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the params hash in your controller:

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

3.2. Routing Parameters

The params hash will always contain the :controller and :action keys, but you should use the methods controller_name and action_name instead to access these values. Any other parameters defined by the routing, such as :id will also be available. As an example, consider a listing of clients where the list can show either active or inactive clients. We can add a route which captures the :status parameter in a "pretty" URL:

-
@@ -335,7 +335,7 @@ ActiveRecordStore - Stores the data in a database using Active Record.

Read more about session storage in the Security Guide.

If you need a different session storage mechanism, you can change it in the config/environment.rb file:

-
@@ -353,7 +353,7 @@ config.action_controller

Session values are stored using key/value pairs like a hash:

-
@@ -371,7 +371,7 @@ private end

To store something in the session, just assign it to the key like a hash:

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

To remove something from the session, assign that key to be nil:

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

4.2. The flash

The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages etc. It is accessed in much the same way as the session, like a hash. Let’s use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:

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

This way, if an action sets an error or a notice message, the layout will display it automatically.

If you want a flash value to be carried over to another request, use the keep method:

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

4.2.1. flash.now

By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use flash.now in the same way you use the normal flash:

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

Your application can store small amounts of data on the client - called cookies - that will be persisted across requests and even sessions. Rails provides easy access to cookies via the cookies method, which - much like the session - works like a hash:

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

Filters are methods that are run before, after or "around" a controller action. For example, one filter might check to see if the logged in user has the right credentials to access that particular controller or action. Filters are inherited, so if you set a filter on ApplicationController, it will be run on every controller in your application. A common, simple filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:

-
@@ -541,7 +541,7 @@ private end

The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a before filter (a filter which is run before the action) renders or redirects, the action will not run. If there are additional filters scheduled to run after the rendering or redirecting filter, they are also cancelled. To use this filter in a controller, use the before_filter method:

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

In this example, the filter is added to ApplicationController and thus all controllers in the application. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn’t be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with skip_before_filter:

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

6.1. After Filters and Around Filters

In addition to the before filters, you can run filters after an action has run or both before and after. The after filter is similar to the before filter, but because the action has already been run it has access to the response data that’s about to be sent to the client. Obviously, after filters can not stop the action from running. Around filters are responsible for running the action, but they can choose not to, which is the around filter’s way of stopping it.

-
@@ -589,7 +589,7 @@ private

While the most common way to use filters is by creating private methods and using *_filter to add them, there are two other ways to do the same thing.

The first is to use a block directly with the *_filter methods. The block receives the controller as an argument, and the require_login filter from above could be rewritten to use a block:

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

Note that the filter in this case uses send because the logged_in? method is private and the filter is not run in the scope of the controller. This is not the recommended way to implement this particular filter, but in more simple cases it might be useful.

The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex than can not be implemented in a readable and reusable way using the two other methods. As an example, you could rewrite the login filter again to use a class:

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

Verifications make sure certain criteria are met in order for a controller or action to run. They can specify that a certain key (or several keys in the form of an array) is present in the params, session or flash hashes or that a certain HTTP method was used or that the request was made using XMLHTTPRequest (Ajax). The default action taken when these criteria are not met is to render a 400 Bad Request response, but you can customize this by specifying a redirect URL or rendering something else and you can also add flash messages and HTTP headers to the response. It is described in the API documentation as "essentially a special kind of before_filter".

Here’s an example of using verification to make sure the user supplies a username and a password in order to log in:

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

Now the create action won’t run unless the "username" and "password" parameters are present, and if they’re not, an error message will be added to the flash and the new action will be rendered. But there’s something rather important missing from the verification above: It will be used for every action in LoginsController, which is not what we want. You can limit which actions it will be used for with the :only and :except options just like a filter:

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

Cross-site request forgery is a type of attack in which a site tricks a user into making requests on another site, possibly adding, modifying or deleting data on that site without the user’s knowledge or permission. The first step to avoid this is to make sure all "destructive" actions (create, update and destroy) can only be accessed with non-GET requests. If you’re following RESTful conventions you’re already doing this. However, a malicious site can still send a non-GET request to your site quite easily, and that’s where the request forgery protection comes in. As the name says, it protects from forged requests. The way this is done is to add a non-guessable token which is only known to your server to each request. This way, if a request comes in without the proper token, it will be denied access.

If you generate a form like this:

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

You will see how the token gets added as a hidden field:

-
@@ -797,7 +797,7 @@ headers - Headers used for the response.

9.2.1. Setting Custom Headers

If you want to set custom headers for a response then response.headers is the place to do it. The headers attribute is a hash which maps header names to their values, and Rails will set some of them - like "Content-Type" - automatically. If you want to add or change a header, just assign it to headers with the name and value:

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

Rails comes with built-in HTTP Basic authentication. This is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser’s HTTP Basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, authenticate_or_request_with_http_basic.

-
@@ -833,7 +833,7 @@ private

Sometimes you may want to send a file to the user instead of rendering an HTML page. All controllers in Rails have the send_data and the send_file methods, that will both stream data to the client. send_file is a convenience method which lets you provide the name of a file on the disk and it will stream the contents of that file for you.

To stream data to the client, use send_data:

-
@@ -862,7 +862,7 @@ private

11.1. Sending Files

If you want to send a file that already exists on disk, use the send_file method. This is usually not recommended, but can be useful if you want to perform some authentication before letting the user download the file.

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

11.2. RESTful Downloads

While send_data works just fine, if you are creating a RESTful application having separate actions for file downloads is usually not necessary. In REST terminology, the PDF file from the example above can be considered just another representation of the client resource. Rails provides an easy and quite sleek way of doing "RESTful downloads". Here’s how you can rewrite the example so that the PDF download is a part of the show action, without any streaming:

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

In order for this example to work, you have to add the PDF MIME type to Rails. This can be done by adding the following line to the file config/initializers/mime_types.rb:

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

Rails keeps a log file for each environment (development, test and production) in the log folder. These are extremely useful when debugging what’s actually going on in your application, but in a live application you may not want every bit of information to be stored in the log file. The filter_parameter_logging method can be used to filter out sensitive information from the log. It works by replacing certain values in the params hash with "[FILTERED]" as they are written to the log. As an example, let’s see how to filter all parameters with keys that include "password":

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

If you want to do something a bit more elaborate when catching errors, you can use rescue_from, which handles exceptions of a certain type (or multiple types) in an entire controller and its subclasses. When an exception occurs which is caught by a rescue_from directive, the exception object is passed to the handler. The handler can be a method or a Proc object passed to the :with option. You can also use a block directly instead of an explicit Proc object.

Here’s how you can use rescue_from to intercept all ActiveRecord::RecordNotFound errors and do something with them.

-
@@ -974,7 +974,7 @@ private end

Of course, this example is anything but elaborate and doesn’t improve on the default exception handling at all, but once you can catch all those exceptions you’re free to do whatever you want with them. For example, you could create custom exception classes that will be thrown when a user doesn’t have access to a certain section of your application:

-
diff --git a/railties/doc/guides/html/active_record_querying.html b/railties/doc/guides/html/active_record_querying.html index d5b0c42dca..e42bd80e2b 100644 --- a/railties/doc/guides/html/active_record_querying.html +++ b/railties/doc/guides/html/active_record_querying.html @@ -174,7 +174,7 @@ Perform various calculations on Active Record models

If you’re used to using raw SQL to find database records then, generally, you will find that there are better ways to carry out the same operations in Rails. Active Record insulates you from the need to use SQL in most cases.

Code examples throughout this guide will refer to one or more of the following models:

-
@@ -185,7 +185,7 @@ http://www.gnu.org/software/src-highlite --> has_and_belongs_to_many :roles end
-
@@ -193,14 +193,14 @@ http://www.gnu.org/software/src-highlite --> belongs_to :client end
-
class MailingAddress < Address
 end
-
@@ -208,7 +208,7 @@ http://www.gnu.org/software/src-highlite --> belongs_to :client, :counter_cache => true end
-
@@ -225,7 +225,7 @@ http://www.gnu.org/software/src-highlite -->

To retrieve objects from the database, Active Record provides a primary method called find. This method allows you to pass arguments into it to perform certain queries on your database without the need of SQL. If you wanted to find the record with the id of 1, you could type Client.find(1) which would execute this query on your database:

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

If you wanted to find clients with id 1 or 2, you call Client.find([1,2]) or Client.find(1,2) and then this will be executed as:

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

If you were reading your log file (the default is log/development.log) you may see something like this:

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

If you were reading your log file (the default is log/development.log) you may see something like this:

-
@@ -300,7 +300,7 @@ http://www.gnu.org/software/src-highlite -->
-
@@ -334,14 +334,14 @@ http://www.gnu.org/software/src-highlite -->

Now what if that number could vary, say as a argument from somewhere, or perhaps from the user’s level status somewhere? The find then becomes something like Client.first(:conditions => ["orders_count = ?", params[:orders]]). Active Record will go through the first element in the conditions value and any additional elements will replace the question marks (?) in the first element. If you want to specify two conditions, you can do it like Client.first(:conditions => ["orders_count = ? AND locked = ?", params[:orders], false]). In this example, the first question mark will be replaced with the value in params[:orders] and the second will be replaced with the SQL representation of false, which depends on the adapter.

The reason for doing code like:

-
Client.first(:conditions => ["orders_count = ?", params[:orders]])

instead of:

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

If you’re looking for a range inside of a table (for example, users created in a certain timeframe) you can use the conditions option coupled with the IN sql statement for this. If you had two dates coming in from a controller you could do something like this to look for a range:

-
@@ -365,7 +365,7 @@ http://www.gnu.org/software/src-highlite --> (params[:start_date].to_date)..(params[:end_date].to_date)])

This would generate the proper query which is great for small ranges but not so good for larger ranges. For example if you pass in a range of date objects spanning a year that’s 365 (or possibly 366, depending on the year) strings it will attempt to match your field against.

-
@@ -379,14 +379,14 @@ http://www.gnu.org/software/src-highlite --> '2008-12-27','2008-12-28','2008-12-29','2008-12-30','2008-12-31'))

Things can get really messy if you pass in Time objects as it will attempt to compare your field to every second in that range:

-
Client.all(:conditions => ["created_at IN (?)",
   (params[:start_date].to_date.to_time)..(params[:end_date].to_date.to_time)])
-
@@ -401,7 +401,7 @@ http://www.gnu.org/software/src-highlite -->

Where query is the actual query used to get that error.

In this example it would be better to use greater-than and less-than operators in SQL, like so:

-
@@ -409,7 +409,7 @@ http://www.gnu.org/software/src-highlite --> ["created_at > ? AND created_at < ?", params[:start_date], params[:end_date]])

You can also use the greater-than-or-equal-to and less-than-or-equal-to like this:

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

2.3. Placeholder Conditions

Similar to the array style of params you can also specify keys in your conditions:

-
@@ -429,28 +429,28 @@ http://www.gnu.org/software/src-highlite -->

2.4. Hash Conditions

Rails also allows you to pass in a hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:

-
Client.all(:conditions => { :locked => true })

The field name does not have to be a symbol it can also be a string:

-
Client.all(:conditions => { 'locked' => true })

The good thing about this is that we can pass in a range for our fields without it generating a large query as shown in the preamble of this section.

-
Client.all(:conditions => { :created_at => (Time.now.midnight - 1.day)..Time.now.midnight})

This will find all clients created yesterday by using a BETWEEN sql statement:

-
@@ -458,14 +458,14 @@ http://www.gnu.org/software/src-highlite -->

This demonstrates a shorter syntax for the examples in Array Conditions

You can also join in tables and specify their columns in the hash:

-
Client.all(:include => "orders", :conditions => { 'orders.created_at' => (Time.now.midnight - 1.day)..Time.now.midnight })

An alternative and cleaner syntax to this is:

-
@@ -473,14 +473,14 @@ http://www.gnu.org/software/src-highlite -->

This will find all clients who have orders that were created yesterday, again using a BETWEEN expression.

If you want to find records using the IN expression you can pass an array to the conditions hash:

-
Client.all(:include => "orders", :conditions => { :orders_count => [1,3,5] }

This code will generate SQL like this:

-
@@ -505,27 +505,27 @@ http://www.gnu.org/software/src-highlite -->

If you want to limit the amount of records to a certain subset of all the records retrieved you usually use limit for this, sometimes coupled with offset. Limit is the maximum number of records that will be retrieved from a query, and offset is the number of records it will start reading from from the first record of the set. Take this code for example:

-
Client.all(:limit => 5)

This code will return a maximum of 5 clients and because it specifies no offset it will return the first 5 clients in the table. The SQL it executes will look like this:

-
SELECT * FROM clients LIMIT 5
-
Client.all(:limit => 5, :offset => 5)

This code will return a maximum of 5 clients and because it specifies an offset this time, it will return these records starting from the 5th client in the clients table. The SQL looks like:

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

The group option for find is useful, for example, if you want to find a collection of the dates orders were created on. You could use the option in this context:

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

And this will give you a single Order object for each date where there are orders in the database.

The SQL that would be executed would be something like this:

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

The :having option allows you to specify SQL and acts as a kind of a filter on the group option. :having can only be specified when :group is specified.

An example of using it would be:

-
@@ -565,14 +565,14 @@ http://www.gnu.org/software/src-highlite -->

readonly is a find option that you can set in order to make that instance of the record read-only. Any attempt to alter or destroy the record will not succeed, raising an ActiveRecord::ReadOnlyRecord exception. To set this option, specify it like this:

-
Client.first(:readonly => true)

If you assign this record to a variable client, calling the following code will raise an ActiveRecord::ReadOnlyRecord exception:

-
@@ -584,7 +584,7 @@ client.save

If you’re wanting to stop race conditions for a specific record (for example, you’re incrementing a single field for a record, potentially from multiple simultaneous connections) you can use the lock option to ensure that the record is updated correctly. For safety, you should use this inside a transaction.

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

You can also pass SQL to this option to allow different types of locks. For example, MySQL has an expression called LOCK IN SHARE MODE where you can lock a record but still allow other queries to read it. To specify this expression just pass it in as the lock option:

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

Eager loading is loading associated records along with any number of records in as few queries as possible. For example, if you wanted to load all the addresses associated with all the clients in a single query you could use Client.all(:include => :address). If you wanted to include both the address and mailing address for the client you would use Client.find(:all, :include => [:address, :mailing_address]). Include will first find the client records and then load the associated address records. Running script/server in one window, and executing the code through script/console in another window, the output should look similar to this:

-
@@ -624,7 +624,7 @@ MailingAddress Load

If you wanted to get all the addresses for a client in the same query you would do Client.all(:joins => :address). If you wanted to find the address and mailing address for that client you would do Client.all(:joins => [:address, :mailing_address]). This is more efficient because it does all the SQL in one query, as shown by this example:

-
@@ -633,7 +633,7 @@ http://www.gnu.org/software/src-highlite --> mailing_addresses.client_id = client.id

This query is more efficent, but there’s a gotcha: if you have a client who does not have an address or a mailing address they will not be returned in this query at all. If you have any association as an optional association, you may want to use include rather than joins. Alternatively, you can use a SQL join clause to specify exactly the join you need (Rails always assumes an inner join):

-
@@ -642,7 +642,7 @@ http://www.gnu.org/software/src-highlite --> client.id = mailing_addresses.client_id”)

When using eager loading you can specify conditions for the columns of the tables inside the eager loading to get back a smaller subset. If, for example, you want to find a client and all their orders within the last two weeks you could use eager loading with conditions for this:

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

If you want to find both by name and locked, you can chain these finders together by simply typing and between the fields for example Client.find_by_name_and_locked("Ryan", true).

There’s another set of dynamic finders that let you find or create/initialize objects if they aren’t found. These work in a similar fashion to the other finders and can be used like find_or_create_by_name(params[:name]). Using this will firstly perform a find and then create if the find returns nil. The SQL looks like this for Client.find_or_create_by_name("Ryan"):

-
@@ -668,7 +668,7 @@ BEGIN COMMIT

find_or_create's sibling, find_or_initialize, will find an object and if it does not exist will act similar to calling new with the arguments you passed in. For example:

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

If you’d like to use your own SQL to find records in a table you can use find_by_sql. The find_by_sql method will return an array of objects even the underlying query returns just a single record. For example you could run this query:

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

find_by_sql has a close relative called connection#select_all. select_all will retrieve objects from the database using custom SQL just like find_by_sql but will not instantiate them. Instead, you will get an array of hashes where each hash indicates a record.

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

16.1. Simple Named Scopes

Suppose we want to find all clients who are male. You could use this code:

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

Then you could call Client.males.all to get all the clients who are male. Please note that if you do not specify the all on the end you will get a Scope object back, not a set of records which you do get back if you put the all on the end.

If you wanted to find all the clients who are active, you could use this:

-
@@ -727,14 +727,14 @@ http://www.gnu.org/software/src-highlite -->

16.2. Combining Named Scopes

If you wanted to find all the clients who are active and male you can stack the named scopes like this:

-
Client.males.active.all

If you would then like to do a all on that scope, you can. Just like an association, named scopes allow you to call all on them:

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

16.3. Runtime Evaluation of Named Scope Conditions

Consider the following code:

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

This looks like a standard named scope that defines a method called recent which gathers all records created any time between now and 2 weeks ago. That’s correct for the first time the model is loaded but for any time after that, 2.weeks.ago is set to that same value, so you will consistently get records from a certain date until your model is reloaded by something like your application restarting. The way to fix this is to put the code in a lambda block:

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

16.4. Named Scopes with Multiple Models

In a named scope you can use :include and :joins options just like in find.

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

16.5. Arguments to Named Scopes

If you want to pass to a named scope a required arugment, just specify it as a block argument like this:

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

This will work if you call Client.recent(2.weeks.ago).all but not if you call Client.recent. If you want to add an optional argument for this, you have to use prefix the arugment with an *.

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

16.6. Anonymous Scopes

All Active Record models come with a named scope named scoped, which allows you to create anonymous scopes. For example:

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

Anonymous scopes are most useful to create scopes "on the fly":

-
@@ -817,14 +817,14 @@ http://www.gnu.org/software/src-highlite -->

If you simply want to check for the existence of the object there’s a method called exists?. This method will query the database using the same query as find, but instead of returning an object or collection of objects it will return either true or false+.

-
Client.exists?(1)

The exists? method also takes multiple ids, but the catch is that it will return true if any one of those records exists.

-
@@ -833,7 +833,7 @@ http://www.gnu.org/software/src-highlite --> Client.exists?([1,2,3])

Further more, exists takes a conditions option much like find:

-
@@ -844,28 +844,28 @@ http://www.gnu.org/software/src-highlite -->

This section uses count as an example method in this preamble, but the options described apply to all sub-sections.

count takes conditions much in the same way exists? does:

-
Client.count(:conditions => "first_name = 'Ryan'")

Which will execute:

-
SELECT count(*) AS count_all FROM clients WHERE (first_name = 'Ryan')

You can also use :include or :joins for this to do something a little more complex:

-
Client.count(:conditions => "clients.first_name = 'Ryan' AND orders.status = 'received'", :include => "orders")

Which will execute:

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

18.2. Average

If you want to see the average of a certain number in one of your tables you can call the average method on the class that relates to the table. This method call will look something like this:

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

18.3. Minimum

If you want to find the minimum value of a field in your table you can call the minimum method on the class that relates to the table. This method call will look something like this:

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

18.4. Maximum

If you want to find the maximum value of a field in your table you can call the maximum method on the class that relates to the table. This method call will look something like this:

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

18.5. Sum

If you want to find the sum of a field for all records in your table you can call the sum method on the class that relates to the table. This method call will look something like this:

-
diff --git a/railties/doc/guides/html/activerecord_validations_callbacks.html b/railties/doc/guides/html/activerecord_validations_callbacks.html index 2153979d7b..be556283c1 100644 --- a/railties/doc/guides/html/activerecord_validations_callbacks.html +++ b/railties/doc/guides/html/activerecord_validations_callbacks.html @@ -236,7 +236,7 @@ Using validation directly in your Active Record classes ensures that only valid

1.2. When Does Validation Happen?

There are two kinds of Active Record objects: those that correspond to a row inside your database and those that do not. When you create a fresh object, using the new method, that object does not belong to the database yet. Once you call save upon that object it will be saved into the appropriate database table. Active Record uses the new_record? instance method to determine whether an object is already in the database or not. Consider the following simple Active Record class:

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

2.1. The validates_acceptance_of helper

Validates that a checkbox on the user interface was checked when a form was submitted. This is normally used when the user needs to agree to your application’s terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and actually this acceptance does not need to be recorded anywhere in your database (if you don’t have a field for it, the helper will just create a virtual attribute).

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

The default error message for validates_acceptance_of is "must be accepted"

validates_acceptance_of can receive an :accept option, which determines the value that will be considered acceptance. It defaults to "1", but you can change this.

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

2.2. The validates_associated helper

You should use this helper when your model has associations with other models and they also need to be validated. When you try to save your object, valid? will be called upon each one of the associated objects.

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

2.3. The validates_confirmation_of helper

You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute, using the name of the field that has to be confirmed with _confirmation appended.

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

In your view template you could use something like

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

2.4. The validates_exclusion_of helper

This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.

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

2.5. The validates_format_of helper

This helper validates the attributes' values by testing whether they match a given pattern. This pattern must be specified using a Ruby regular expression, which is specified using the :with option.

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

2.6. The validates_inclusion_of helper

This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.

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

2.7. The validates_length_of helper

This helper validates the length of your attribute’s value. It includes a variety of different options, so you can specify length constraints in different ways:

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

The default error messages depend on the type of length validation being performed. You can personalize these messages, using the :wrong_length, :too_long and :too_short options and the %d format mask as a placeholder for the number corresponding to the length constraint being used. You can still use the :message option to specify an error message.

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

This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by a integral or floating point number. Using the :integer_only option set to true, you can specify that only integral numbers are allowed.

If you set :integer_only to true, then it will use the $$/\A[\-]?\d+\Z/ regular expression to validate the attribute’s value. Otherwise, it will try to convert the value to a number using +Kernel.Float.

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

2.9. The validates_presence_of helper

This helper validates that the specified attributes are not empty. It uses the blank? method to check if the value is either nil or an empty string (if the string has only spaces, it will still be considered empty).

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

2.10. The validates_uniqueness_of helper

This helper validates that the attribute’s value is unique right before the object gets saved. It does not create a uniqueness constraint directly into your database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create an unique index in your database.

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

The validation happens by performing a SQL query into the model’s table, searching for a record where the attribute that must be validated is equal to the value in the object being validated.

There is a :scope option that you can use to specify other attributes that are used to limit the uniqueness check:

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

There is also a :case_sensitive option that you can use to define whether the uniqueness constraint will be case sensitive or not. This option defaults to true.

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

2.11. The validates_each helper

This helper validates attributes against a block. It doesn’t have a predefined validation function. You should create one using a block, and every attribute passed to validates_each will be tested against it. In the following example, we don’t want names and surnames to begin with lower case.

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

3.1. The :allow_nil option

The :allow_nil option skips the validation when the value being validated is nil. You may be asking yourself if it makes any sense to use :allow_nil and validates_presence_of together. Well, it does. Remember, the validation will be skipped only for nil attributes, but empty strings are not considered nil.

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

3.2. The :allow_blank option

The :allow_blank: option is similar to the +:allow_nil option. This option will let validation pass if the attribute’s value is nil or an empty string, i.e., any value that returns true for blank?.

-
@@ -596,7 +596,7 @@ Topic.create(3.4. The :on option

The :on option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be ran on save (both when you’re creating a new record and when you’re updating it). If you want to change it, you can use :on => :create to run the validation only when a new record is created or :on => :update to run the validation only when a record is updated.

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

4.1. Using a symbol with the :if and :unless options

You can associate the :if and :unless options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.

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

4.2. Using a string with the :if and :unless options

You can also use a string that will be evaluated using :eval and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.

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

4.3. Using a Proc object with the :if and :unless options

Finally, it’s possible to associate :if and :unless with a Ruby Proc object which will be called. Using a Proc object can give you the hability to write a condition that will be executed only when the validation happens and not when your code is loaded by the Ruby interpreter. This option is best suited when writing short validation methods, usually one-liners.

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

When the built-in validation helpers are not enough for your needs, you can write your own validation methods. You can do that by implementing methods that verify the state of your models and add messages to their errors collection when they are invalid. You must then register those methods by using one or more of the validate, validate_on_create or validate_on_update class methods, passing in the symbols for the validation methods' names. You can pass more than one symbol for each class method and the respective validations will be ran in the same order as they were registered.

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

You can even create your own validation helpers and reuse them in several different models. Here is an example where we create a custom validation helper to validate the format of fields that represent email addresses:

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

The recipe is simple: just create a new validation method inside the ActiveRecord::Validations::ClassMethods module. You can put this code in a file inside your application’s lib folder, and then requiring it from your environment.rb or any other file inside config/initializers. You can use this helper like this:

-
@@ -711,7 +711,7 @@ http://www.gnu.org/software/src-highlite -->
-
@@ -728,7 +728,7 @@ http://www.gnu.org/software/src-highlite -->
-
@@ -745,7 +745,7 @@ http://www.gnu.org/software/src-highlite -->
-
@@ -763,7 +763,7 @@ person.invalid?
-
@@ -793,7 +793,7 @@ person.errors.<
-
@@ -817,7 +817,7 @@ p.errors.

Rails provides built-in helpers to display the error messages of your models in your view templates. When creating a form with the form_for helper, you can use the error_messages method on the form builder to render all failed validation messages for the current model instance.

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

7.1. Changing the way form fields with errors are displayed

By default, form fields with errors are displayed enclosed by a div element with the fieldWithErrors CSS class. However, we can write some Ruby code to override the way Rails treats those fields by default. Here is a simple example where we change the Rails behaviour to always display the error messages in front of each of the form fields with errors. The error messages will be enclosed by a span element with a validation-error CSS class. There will be no div element enclosing the input element, so we get rid of that red border around the text field. You can use the validation-error CSS class to style it anyway you want.

-
@@ -937,7 +937,7 @@ An object of the ActionView::Helpers::InstanceTag class.

8.1. Callbacks registration

In order to use the available callbacks, you need to registrate them. You can do that by implementing them as an ordinary methods, and then using a macro-style class method to register then as callbacks.

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

The macro-style class methods can also receive a block. Rails best practices say that you should only use this style of registration if the code inside your block is so short that it fits in just one line.

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

9.1. Using a symbol with the :if and :unless options

You can associate the :if and :unless options with a symbol corresponding to the name of a method that will get called right before the callback. If this method returns false the callback won’t be executed. This is the most common option. Using this form of registration it’s also possible to register several different methods that should be called to check the if the callback should be executed.

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

9.2. Using a string with the :if and :unless options

You can also use a string that will be evaluated using :eval and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.

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

9.3. Using a Proc object with the :if and :unless options

Finally, it’s possible to associate :if and :unless with a Ruby Proc object. This option is best suited when writing short validation methods, usually one-liners.

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

9.4. Multiple Conditions for Callbacks

When writing conditional callbacks, it’s possible to mix both :if and :unless in the same callback declaration.

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

Sometimes the callback methods that you’ll write will be useful enough to be reused at other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.

Here’s an example where we create a class with a after_destroy callback for a PictureFile model.

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

When declared inside a class the callback method will receive the model object as a parameter. We can now use it this way:

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

Note that we needed to instantiate a new PictureFileCallbacks object, since we declared our callback as an instance method. Sometimes it will make more sense to have it as a class method.

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

If the callback method is declared this way, it won’t be necessary to instantiate a PictureFileCallbacks object.

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

Observer classes are subclasses of the ActiveRecord::Observer class. When this class is subclassed, Active Record will look at the name of the new class and then strip the Observer part to find the name of the Active Record class to observe.

Consider a Registration model, where we want to send an email every time a new registration is created. Since sending emails is not directly related to our model’s purpose, we could create an Observer to do just that:

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

Like in callback classes, the observer’s methods receive the observed model as a parameter.

Sometimes using the ModelName + Observer naming convention won’t be the best choice, mainly when you want to use the same observer for more than one model class. It’s possible to explicity specify the models that our observer should observe.

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

13.1. Registering observers

If you paid attention, you may be wondering where Active Record Observers are referenced in our applications, so they get instantiated and begin to interact with our models. For observers to work we need to register them somewhere. The usual place to do that is in our application’s config/environment.rb file. In this file there is a commented-out line where we can define the observers that our application should load at start-up.

-
diff --git a/railties/doc/guides/html/association_basics.html b/railties/doc/guides/html/association_basics.html index 8d03bdddba..bfe8f3f341 100644 --- a/railties/doc/guides/html/association_basics.html +++ b/railties/doc/guides/html/association_basics.html @@ -125,7 +125,7 @@ Use the methods added to your models by creating associations

Why do we need associations between models? Because they make common operations simpler and easier in your code. For example, consider a simple Rails application that includes a model for customers and a model for orders. Each customer can have many orders. Without associations, the model declarations would look like this:

-
@@ -136,14 +136,14 @@ http://www.gnu.org/software/src-highlite --> end

Now, suppose we wanted to add a new order for an existing customer. We’d need to do something like this:

-
@order = Order.create(:order_date => Time.now, :customer_id => @customer.id)

Or consider deleting a customer, and ensuring that all of its orders get deleted as well:

-
@@ -154,7 +154,7 @@ http://www.gnu.org/software/src-highlite --> @customer.destroy

With Active Record associations, we can streamline these - and other - operations by declaratively telling Rails that there is a connection between the two models. Here’s the revised code for setting up customers and orders:

-
@@ -167,14 +167,14 @@ http://www.gnu.org/software/src-highlite --> end

With this change, creating a new order for a particular customer is easier:

-
@order = @customer.orders.create(:order_date => Time.now)

Deleting a customer and all of its orders is much easier:

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

2.1. The belongs_to Association

A belongs_to association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model. For example, if your application includes customers and orders, and each order can be assigned to exactly one customer, you’d declare the order model this way:

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

2.2. The has_one Association

A has_one association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you’d declare the supplier model like this:

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

2.3. The has_many Association

A has_many association indicates a one-to-many connection with another model. You’ll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing customers and orders, the customer model could be declared like this:

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

2.4. The has_many :through Association

A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:

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

The has_many :through association is also useful for setting up "shortcuts" through nested :has_many associations. For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document. You could set that up this way:

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

2.5. The has_one :through Association

A has_one :through association sets up a one-to-one connection with another model. This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model. For example, if each supplier has one account, and each account is associated with one account history, then the customer model could look like this:

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

2.6. The has_and_belongs_to_many Association

A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model. For example, if your application includes assemblies and parts, with each assembly having many parts and each part appearing in many assemblies, you could declare the models this way:

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

If you want to set up a 1-1 relationship between two models, you’ll need to add belongs_to to one, and has_one to the other. How do you know which is which?

The distinction is in where you place the foreign key (it goes on the table for the class declaring the belongs_to association), but you should give some thought to the actual meaning of the data as well. The has_one relationship says that one of something is yours - that is, that something points back to you. For example, it makes more sense to say that a supplier owns an account than that an account owns a supplier. This suggests that the correct relationships are like this:

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

The corresponding migration might look like this:

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

2.8. Choosing Between has_many :through and has_and_belongs_to_many

Rails offers two different ways to declare a many-to-many relationship between models. The simpler way is to use has_and_belongs_to_many, which allows you to make the association directly:

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

The second way to declare a many-to-many relationship is to use has_many :through. This makes the association indirectly, through a join model:

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

2.9. Polymorphic Associations

A slightly more advanced twist on associations is the polymorphic association. With polymorphic associations, a model can belong to more than one other model, on a single association. For example, you might have a picture model that belongs to either an employee model or a product model. Here’s how this could be declared:

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

You can think of a polymorphic belongs_to declaration as setting up an interface that any other model can use. From an instance of the Employee model, you can retrieve a collection of pictures: @employee.pictures. Similarly, you can retrieve @product.pictures. If you have an instance of the Picture model, you can get to its parent via @picture.imageable. To make this work, you need to declare both a foreign key column and a type column in the model that declares the polymorphic interface:

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

This migration can be simplified by using the t.references form:

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

2.10. Self Joins

In designing a data model, you will sometimes find a model that should have a relation to itself. For example, you may want to store all employees in a single database model, but be able to trace relationships such as manager and subordinates. This situation can be modeled with self-joining associations:

-
@@ -532,7 +532,7 @@ Controlling association scope

3.1. Controlling Caching

All of the association methods are built around caching that keeps the result of the most recent query available for further operations. The cache is even shared across methods. For example:

-
@@ -541,7 +541,7 @@ customer.orders customer.orders.empty? # uses the cached copy of orders

But what if you want to reload the cache, because data might have been changed by some other part of the application? Just pass true to the association call:

-
@@ -555,7 +555,7 @@ customer.orders

3.3.1. Creating Foreign Keys for belongs_to Associations

When you declare a belongs_to association, you need to create foreign keys as appropriate. For example, consider this model:

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

This declaration needs to be backed up by the proper foreign key declaration on the orders table:

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

Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:

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

These need to be backed up by a migration to create the assemblies_parts table. This table should be created without a primary key:

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

3.4. Controlling Association Scope

By default, associations look for objects only within the current module’s scope. This can be important when you declare Active Record models within a module. For example:

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

This will work fine, because both the Supplier and the Account class are defined within the same scope. But this will not work, because Supplier and Account are defined in different scopes:

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

To associate a model with a model in a different scope, you must specify the complete class name in your association declaration:

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

In all of these methods, association is replaced with the symbol passed as the first argument to belongs_to. For example, given the declaration:

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

Each instance of the order model will have these methods:

-
@@ -737,7 +737,7 @@ create_customer
association(force_reload = false)

The association method returns the associated object, if any. If no associated object is found, it returns nil.

-
@@ -746,7 +746,7 @@ http://www.gnu.org/software/src-highlite -->
association=(associate)

The association= method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from the associate object and setting this object’s foreign key to the same value.

-
@@ -754,7 +754,7 @@ http://www.gnu.org/software/src-highlite -->
association.nil?

The association.nil? method returns true if there is no associated object.

-
@@ -764,7 +764,7 @@ http://www.gnu.org/software/src-highlite -->
build_association(attributes = {})

The build_association method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object’s foreign key will be set, but the associated object will not yet be saved.

-
@@ -772,7 +772,7 @@ http://www.gnu.org/software/src-highlite -->
create_association(attributes = {})

The create_association method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object’s foreign key will be set. In addition, the associated object will be saved (assuming that it passes any validations).

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

4.1.2. Options for belongs_to

In many situations, you can use the default behavior of belongs_to without any customization. But despite Rails' emphasis of convention over customization, you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a belongs_to association. For example, an association with several options might look like this:

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

If the name of the other model cannot be derived from the association name, you can use the :class_name option to supply the model name. For example, if an order belongs to a customer, but the actual name of the model containing customers is Patron, you’d set things up this way:

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

The :conditions option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL WHERE clause).

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

The :counter_cache option can be used to make finding the number of belonging objects more efficient. Consider these models:

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

With these declarations, asking for the value of @customer.orders.size requires making a call to the database to perform a COUNT(*) query. To avoid this call, you can add a counter cache to the belonging model:

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

With this declaration, Rails will keep the cache value up to date, and then return that value in response to the .size method.

Although the :counter_cache option is specified on the model that includes the belongs_to declaration, the actual column must be added to the associated model. In the case above, you would need to add a column named orders_count to the Customer model. You can override the default column name if you need to:

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

By convention, Rails guesses that the column used to hold the foreign key on this model is the name of the association with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly:

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

You can use the :include option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:

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

If you frequently retrieve customers directly from line items (@line_item.order.customer), then you can make your code somewhat more efficient by including customers in the association from line items to orders:

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

In all of these methods, association is replaced with the symbol passed as the first argument to has_one. For example, given the declaration:

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

Each instance of the Supplier model will have these methods:

-
@@ -1040,7 +1040,7 @@ create_account
association(force_reload = false)

The association method returns the associated object, if any. If no associated object is found, it returns nil.

-
@@ -1049,7 +1049,7 @@ http://www.gnu.org/software/src-highlite -->
association=(associate)

The association= method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from this object and setting the associate object’s foreign key to the same value.

-
@@ -1057,7 +1057,7 @@ http://www.gnu.org/software/src-highlite -->
association.nil?

The association.nil? method returns true if there is no associated object.

-
@@ -1067,7 +1067,7 @@ http://www.gnu.org/software/src-highlite -->
build_association(attributes = {})

The build_association method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through its foreign key will be set, but the associated object will not yet be saved.

-
@@ -1075,7 +1075,7 @@ http://www.gnu.org/software/src-highlite -->
create_association(attributes = {})

The create_association method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through its foreign key will be set. In addition, the associated object will be saved (assuming that it passes any validations).

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

4.2.2. Options for has_one

In many situations, you can use the default behavior of has_one without any customization. But despite Rails' emphasis of convention over customization, you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a has_one association. For example, an association with several options might look like this:

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

If the name of the other model cannot be derived from the association name, you can use the :class_name option to supply the model name. For example, if a supplier has an account, but the actual name of the model containing accounts is Billing, you’d set things up this way:

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

The :conditions option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL WHERE clause).

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

By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly:

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

You can use the :include option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:

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

If you frequently retrieve representatives directly from suppliers (@supplier.account.representative), then you can make your code somewhat more efficient by including representatives in the association from suppliers to accounts:

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

In all of these methods, collection is replaced with the symbol passed as the first argument to has_many, and collection\_singular is replaced with the singularized version of that symbol.. For example, given the declaration:

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

Each instance of the customer model will have these methods:

-
@@ -1361,7 +1361,7 @@ orders.create(<
collection(force_reload = false)

The collection method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.

-
@@ -1369,7 +1369,7 @@ http://www.gnu.org/software/src-highlite -->
collection<<(object, ...)

The collection<< method adds one or more objects to the collection by setting their foreign keys to the primary key of the calling model.

-
@@ -1377,7 +1377,7 @@ http://www.gnu.org/software/src-highlite -->
collection.delete(object, ...)

The collection.delete method removes one or more objects from the collection by setting their foreign keys to NULL.

-
@@ -1395,7 +1395,7 @@ http://www.gnu.org/software/src-highlite -->
collection\_singular\_ids

The collection\_singular\_ids method returns an array of the ids of the objects in the collection.

-
@@ -1407,7 +1407,7 @@ http://www.gnu.org/software/src-highlite -->
collection.empty?

The collection.empty? method returns true if the collection does not contain any associated objects.

-
@@ -1417,7 +1417,7 @@ http://www.gnu.org/software/src-highlite -->
collection.size

The collection.size method returns the number of objects in the collection.

-
@@ -1425,7 +1425,7 @@ http://www.gnu.org/software/src-highlite -->
collection.find(...)

The collection.find method finds objects within the collection. It uses the same syntax and options as ActiveRecord::Base.find.

-
@@ -1435,7 +1435,7 @@ http://www.gnu.org/software/src-highlite -->
collection.build(attributes = {}, ...)

The collection.build method returns one or more new objects of the associated type. These objects will be instantiated from the passed attributes, and the link through their foreign key will be created, but the associated objects will not yet be saved.

-
@@ -1443,7 +1443,7 @@ http://www.gnu.org/software/src-highlite -->
collection.create(attributes = {})

The collection.create method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and the associated object will be saved (assuming that it passes any validations).

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

4.3.2. Options for has_many

In many situations, you can use the default behavior for has_many without any customization. But you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a has_many association. For example, an association with several options might look like this:

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

If the name of the other model cannot be derived from the association name, you can use the :class_name option to supply the model name. For example, if a customer has many orders, but the actual name of the model containing orders is Transaction, you’d set things up this way:

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

The :conditions option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL WHERE clause).

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

You can also set conditions via a hash:

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

By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly:

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

The :group option supplies an attribute name to group the result set by, using a GROUP BY clause in the finder SQL.

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

You can use the :include option to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:

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

If you frequently retrieve line items directly from customers (@customer.orders.line_items), then you can make your code somewhat more efficient by including line items in the association from customers to orders:

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

The :limit option lets you restrict the total number of objects that will be fetched through an association.

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

The :order option dictates the order in which associated objects will be received (in the syntax used by a SQL ORDER BY clause).

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

In all of these methods, collection is replaced with the symbol passed as the first argument to has_many, and collection\_singular is replaced with the singularized version of that symbol.. For example, given the declaration:

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

Each instance of the part model will have these methods:

-
@@ -1846,7 +1846,7 @@ assemblies.createcollection(force_reload = false)

The collection method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.

-
@@ -1854,7 +1854,7 @@ http://www.gnu.org/software/src-highlite -->
collection<<(object, ...)

The collection<< method adds one or more objects to the collection by creating records in the join table.

-
@@ -1870,7 +1870,7 @@ http://www.gnu.org/software/src-highlite -->
collection.delete(object, ...)

The collection.delete method removes one or more objects from the collection by deleting records in the join table. This does not destroy the objects.

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

# Returns an array of the associated objects' ids

The collection\_singular\_ids method returns an array of the ids of the objects in the collection.

-
@@ -1893,7 +1893,7 @@ http://www.gnu.org/software/src-highlite -->
collection.empty?

The collection.empty? method returns true if the collection does not contain any associated objects.

-
@@ -1903,7 +1903,7 @@ http://www.gnu.org/software/src-highlite -->
collection.size

The collection.size method returns the number of objects in the collection.

-
@@ -1911,7 +1911,7 @@ http://www.gnu.org/software/src-highlite -->
collection.find(...)

The collection.find method finds objects within the collection. It uses the same syntax and options as ActiveRecord::Base.find. It also adds the additional condition that the object must be in the collection.

-
@@ -1921,7 +1921,7 @@ http://www.gnu.org/software/src-highlite -->
collection.build(attributes = {})

The collection.build method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through the join table will be created, but the associated object will not yet be saved.

-
@@ -1929,7 +1929,7 @@ http://www.gnu.org/software/src-highlite -->
collection.create(attributes = {})

The collection.create method returns a new object of the associated type. This objects will be instantiated from the passed attributes, the link through the join table will be created, and the associated object will be saved (assuming that it passes any validations).

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

4.4.2. Options for has_and_belongs_to_many

In many situations, you can use the default behavior for has_and_belongs_to_many without any customization. But you can alter that behavior in a number of ways. This section cover the options that you can pass when you create a has_and_belongs_to_many association. For example, an association with several options might look like this:

-
@@ -2053,7 +2053,7 @@ http://www.gnu.org/software/src-highlite -->
-
@@ -2064,7 +2064,7 @@ http://www.gnu.org/software/src-highlite -->
:class_name

If the name of the other model cannot be derived from the association name, you can use the :class_name option to supply the model name. For example, if a part has many assemblies, but the actual name of the model containing assemblies is Gadget, you’d set things up this way:

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

The :conditions option lets you specify the conditions that the associated object must meet (in the syntax used by a SQL WHERE clause).

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

You can also set conditions via a hash:

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

By convention, Rails guesses that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly:

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

The :group option supplies an attribute name to group the result set by, using a GROUP BY clause in the finder SQL.

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

The :limit option lets you restrict the total number of objects that will be fetched through an association.

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

The :order option dictates the order in which associated objects will be received (in the syntax used by a SQL ORDER BY clause).

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

You define association callbacks by adding options to the association declaration. For example:

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

Rails passes the object being added or removed to the callback.

You can stack callbacks on a single event by passing them as an array:

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

4.6. Association Extensions

You’re not limited to the functionality that Rails automatically builds into association proxy objects. You can also extend these objects through anonymous modules, adding new finders, creators, or other methods. For example:

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

If you have an extension that should be shared by many associations, you can use a named extension module. For example:

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

To include more than one extension module in a single association, specify an array of names:

-
diff --git a/railties/doc/guides/html/caching_with_rails.html b/railties/doc/guides/html/caching_with_rails.html index 04498f268f..02cc981b0e 100644 --- a/railties/doc/guides/html/caching_with_rails.html +++ b/railties/doc/guides/html/caching_with_rails.html @@ -75,7 +75,7 @@ to true for your environment. This flag is normally set in the corresponding config/environments/*.rb and caching is disabled by default there for development and test, and enabled for production.

-
@@ -91,7 +91,7 @@ expiration is an issue that needs to be dealt with.

have a controller called ProductsController and a list action that lists all the products

-
@@ -119,7 +119,7 @@ configuration setting config.action_controller.page_cache_extension.

In order to expire this page when a new product is added we could extend our example controler like this:

-
@@ -148,7 +148,7 @@ result of the output from a cached copy.

Let’s say you only wanted authenticated users to edit or create a Product object, but still cache those pages:

-
@@ -191,7 +191,7 @@ in real time and didn’t want to cache that part of the page, but did want to cache the part of the page which lists all products available, you could use this piece of code:

-
@@ -209,7 +209,7 @@ http://www.gnu.org/software/src-highlite --> written out to the same place as the Action Cache, which means that if you want to cache multiple fragments per action, you should provide an action_suffix to the cache call:

-
@@ -217,7 +217,7 @@ http://www.gnu.org/software/src-highlite --> All available products:

and you can expire it using the expire_fragment method, like so:

-
@@ -226,7 +226,7 @@ http://www.gnu.org/software/src-highlite --> also use globally keyed fragments by calling the cache method with a key, like so:

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

This fragment is then available to all actions in the ProductsController using the key and can be expired the same way:

-
@@ -250,7 +250,7 @@ an around or after filter.

Continuing with our Product controller example, we could rewrite it with a sweeper such as the following:

-
@@ -286,7 +286,7 @@ actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:

-
@@ -314,7 +314,7 @@ will used the cached result set as opposed to running the query against the database again.

For example:

-
@@ -360,7 +360,7 @@ caches. Page caches are always stored on disk.

take up a lot of memory since each process keeps all the caches in memory.

-
@@ -371,7 +371,7 @@ http://www.gnu.org/software/src-highlite --> running from the same application directory to access the cached content.

-
@@ -381,7 +381,7 @@ http://www.gnu.org/software/src-highlite --> only keeps one cache around for all processes, but requires that you run and manage a separate DRb process.

-
@@ -389,14 +389,14 @@ http://www.gnu.org/software/src-highlite -->

4) MemCached store: Works like DRbStore, but uses Danga’s MemCache instead. Rails uses the bundled memcached-client gem by default.

-
ActionController::Base.cache_store = :mem_cache_store, "localhost"

5) Custom store: You can define your own cache store (new in Rails 2.1)

-
@@ -421,7 +421,7 @@ timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in rails this is a pretty easy task:

-
@@ -447,7 +447,7 @@ http://www.gnu.org/software/src-highlite --> rendering mechanism (i.e. you’re not using respond_to or calling render yourself) then you’ve got an easy helper in fresh_when:

-
diff --git a/railties/doc/guides/html/command_line.html b/railties/doc/guides/html/command_line.html index 7f925bc10a..226a68e105 100644 --- a/railties/doc/guides/html/command_line.html +++ b/railties/doc/guides/html/command_line.html @@ -135,7 +135,7 @@ rails
-
@@ -171,7 +171,7 @@ http://www.gnu.org/software/src-highlite -->

Here we’ll flex our server command, which without any prodding of any kind will run our new shiny Rails app:

-
@@ -188,7 +188,7 @@ $ ./script/server

1.3. generate

The generate command uses templates to create a whole lot of things. You can always find out what’s available by running generate by itself. Let’s do that:

-
@@ -222,7 +222,7 @@ Installed Generators
-
@@ -251,7 +251,7 @@ Modules Example: Test: test/functional/admin/credit_card_controller_test.rb

Ah, the controller generator is expecting parameters in the form of generate controller ControllerName action1 action2. Let’s make a Greetings controller with an action of hello, which will say something nice to us.

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

Look there! Now what all did this generate? It looks like it made sure a bunch of directories were in our application, and created a controller file, a functional test file, a helper for the view, and a view file.

Let’s check out the controller and modify it a little (in app/controllers/greeting_controller.rb):

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

Then the view, to display our nice message (in app/views/greeting/hello.html.erb):

-
@@ -287,7 +287,7 @@ http://www.gnu.org/software/src-highlite --> <p><%= @message %></p>

Deal. Go check it out in your browser. Fire up your server. Remember? ./script/server at the root of your Rails application should do it.

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

"What about data, though?", you ask over a cup of coffee. Rails comes with a generator for data models too. Can you guess its generator name?

-
@@ -328,7 +328,7 @@ Examples:

But instead of generating a model directly (which we’ll be doing later), let’s set up a scaffold. A scaffold in Rails is a full set of model, database migration for that model, controller to manipulate it, views to view and manipulate the data, and a test suite for each of the above.

Let’s set up a simple resource called "HighScore" that will keep track of our highest score on video games we play.

-
@@ -371,7 +371,7 @@ dependency model
-
@@ -400,7 +400,7 @@ http://www.gnu.org/software/src-highlite -->

Let’s say you’re creating a website for a client who wants a small accounting system. Every event having to do with money must be logged, and must never be deleted. Wouldn’t it be great if we could override the behavior of a model to never actually take its record out of the database, but instead, just set a field?

There is such a thing! The plugin we’re installing is called "acts_as_paranoid", and it lets models implement a "deleted_at" column that gets set when you call destroy. Later, when calling find, the plugin will tack on a database check to filter out "deleted" things.

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

1.7. runner

runner runs Ruby code in the context of Rails non-interactively. For instance:

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

1.8. destroy

Think of destroy as the opposite of generate. It’ll figure out what generate did, and undo it. Believe you-me, the creation of this tutorial used this command many times!

-
@@ -449,7 +449,7 @@ $ ./script/destroy model Oops

1.9. about

Check it: Version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application’s folder, the current Rails environment name, your app’s database adapter, and schema version! about is useful when you need to ask help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.

-
diff --git a/railties/doc/guides/html/configuring.html b/railties/doc/guides/html/configuring.html index 7bbb849b90..3cd41f100e 100644 --- a/railties/doc/guides/html/configuring.html +++ b/railties/doc/guides/html/configuring.html @@ -137,14 +137,14 @@ After-Initializers

In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The environment.rb and environment-specific configuration files (such as config/environments/production.rb) allow you to specify the various settings that you want to pass down to all of the components. For example, the default Rails 2.3 environment.rb file includes one setting:

-
config.time_zone = 'UTC'

This is a setting for Rails itself. If you want to pass settings to individual Rails components, you can do so via the same config object:

-
@@ -304,7 +304,7 @@ and appear last in the mime encoded message.

After-initializers are run (as you might guess) after any initializers are loaded. You can supply an after_initialize block (or an array of such blocks) by setting up config.after_initialize in any of the Rails configuration files:

-
diff --git a/railties/doc/guides/html/creating_plugins.html b/railties/doc/guides/html/creating_plugins.html index c34bbef2f7..3347f77228 100644 --- a/railties/doc/guides/html/creating_plugins.html +++ b/railties/doc/guides/html/creating_plugins.html @@ -299,7 +299,7 @@ create vendor/plugins/yaffle/generators/yaffle/USAGE

vendor/plugins/yaffle/rails/init.rb

-
@@ -355,7 +355,7 @@ mysql:

For this guide you’ll need 2 tables/models, Hickwalls and Wickwalls, so add the following:

vendor/plugins/yaffle/test/schema.rb:

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

vendor/plugins/yaffle/test/test_helper.rb:

-
@@ -419,7 +419,7 @@ ENV['RAILS_ROOT

Once you have these files in place, you can write your first test to ensure that your plugin-testing setup is correct. By default rails generates a file in vendor/plugins/yaffle/test/yaffle_test.rb with a sample test. Replace the contents of that file with:

vendor/plugins/yaffle/test/yaffle_test.rb:

-
@@ -481,7 +481,7 @@ rake DB=postgresql

In this example you will add a method to String named to_squawk. To begin, create a new test file with a few assertions:

vendor/plugins/yaffle/test/core_ext_test.rb

-
@@ -510,7 +510,7 @@ NoMethodError: undefined method `to_squawk' for "Hello World":String

Then in lib/yaffle.rb require lib/core_ext.rb:

vendor/plugins/yaffle/lib/yaffle.rb

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

Finally, create the core_ext.rb file and add the to_squawk method:

vendor/plugins/yaffle/lib/yaffle/core_ext.rb

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

If you must reopen a class in init.rb you can use module_eval or class_eval to avoid any issues:

vendor/plugins/yaffle/rails/init.rb

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

Another way is to explicitly define the top-level module space for all modules and classes, like ::Hash:

vendor/plugins/yaffle/rails/init.rb

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

To begin, set up your files so that you have:

vendor/plugins/yaffle/test/acts_as_yaffle_test.rb

-
@@ -578,14 +578,14 @@ http://www.gnu.org/software/src-highlite --> end

vendor/plugins/yaffle/lib/yaffle.rb

-
require 'yaffle/acts_as_yaffle'

vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb

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

One of the most common plugin patterns for acts_as_yaffle plugins is to structure your file like so:

vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb

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

To start out, write a failing test that shows the behavior you’d like:

vendor/plugins/yaffle/test/acts_as_yaffle_test.rb

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

To make these tests pass, you could modify your acts_as_yaffle file like so:

vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb

-
@@ -673,7 +673,7 @@ ActiveRecord::Base

To start out, write a failing test that shows the behavior you’d like:

vendor/plugins/yaffle/test/acts_as_yaffle_test.rb

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

Run this test to make sure the last two tests fail, then update acts_as_yaffle.rb to look like this:

vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb

-
@@ -770,7 +770,7 @@ ActiveRecord::Base

As always, start with a test:

vendor/plugins/yaffle/yaffle/woodpecker_test.rb:

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

This is just a simple test to make sure the class is being loaded correctly. After watching it fail with rake, you can make it pass like so:

vendor/plugins/yaffle/lib/yaffle.rb:

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

Adding directories to the load path makes them appear just like files in the the main app directory - except that they are only loaded once, so you have to restart the web server to see the changes in the browser. Removing directories from the load_once_paths allow those changes to picked up as soon as you save the file - without having to restart the web server. This is particularly useful as you develop the plugin.

vendor/plugins/yaffle/lib/app/models/woodpecker.rb:

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

Finally, add the following to your plugin’s schema.rb:

vendor/plugins/yaffle/test/schema.rb:

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

You can test your plugin’s controller as you would test any other controller:

vendor/plugins/yaffle/test/woodpeckers_controller_test.rb:

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

This is just a simple test to make sure the controller is being loaded correctly. After watching it fail with rake, you can make it pass like so:

vendor/plugins/yaffle/lib/yaffle.rb:

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

vendor/plugins/yaffle/lib/app/controllers/woodpeckers_controller.rb:

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

You can test your plugin’s helper as you would test any other helper:

vendor/plugins/yaffle/test/woodpeckers_helper_test.rb

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

This is just a simple test to make sure the helper is being loaded correctly. After watching it fail with rake, you can make it pass like so:

vendor/plugins/yaffle/lib/yaffle.rb:

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

vendor/plugins/yaffle/lib/app/helpers/woodpeckers_helper.rb:

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

Testing routes from plugins is slightly different from testing routes in a standard rails app. To begin, add a test like this:

vendor/plugins/yaffle/test/routing_test.rb

-
@@ -957,14 +957,14 @@ http://www.gnu.org/software/src-highlite -->

Once you see the tests fail by running rake, you can make them pass with:

vendor/plugins/yaffle/lib/yaffle.rb

-
require "yaffle/routing"

vendor/plugins/yaffle/lib/yaffle/routing.rb

-
@@ -981,7 +981,7 @@ http://www.gnu.org/software/src-highlite --> ActionController::Routing::RouteSet::Mapper.send :include, Yaffle::Routing::MapperExtensions

config/routes.rb

-
@@ -1021,7 +1021,7 @@ Removes the fake rails root

This section will describe how to create a simple generator that adds a file. For the generator in this section, the test could look something like this:

vendor/plugins/yaffle/test/definition_generator_test.rb

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

To make it pass, create the generator:

vendor/plugins/yaffle/generators/yaffle_definition/yaffle_definition_generator.rb

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

To start, add the following test method:

vendor/plugins/yaffle/test/route_generator_test.rb

-
@@ -1161,14 +1161,14 @@ http://www.gnu.org/software/src-highlite -->

Run rake to watch the test fail, then make the test pass add the following:

vendor/plugins/yaffle/lib/yaffle.rb

-
require "yaffle/commands"

vendor/plugins/yaffle/lib/yaffle/commands.rb

-
@@ -1214,7 +1214,7 @@ Rails::Generator::Generator::Commands::Update.send :include, Yaffle::Generator::Commands::Update

vendor/plugins/yaffle/generators/yaffle/yaffle_route_generator.rb

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

Let’s say you have the following migration in your plugin:

vendor/plugins/yaffle/lib/db/migrate/20081116181115_create_birdhouses.rb:

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

11.1. Create a custom rake task

vendor/plugins/yaffle/lib/db/migrate/20081116181115_create_birdhouses.rb:

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

vendor/plugins/yaffle/tasks/yaffle.rake:

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

11.2. Call migrations directly

vendor/plugins/yaffle/lib/yaffle.rb:

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

db/migrate/20081116181115_create_birdhouses.rb:

-
@@ -1351,7 +1351,7 @@ examine the generated migration, adding/removing columns or other options as nec

This example will demonstrate how to use one of the built-in generator methods named migration_template to create a migration file. Extending the rails migration generator requires a somewhat intimate knowledge of the migration generator internals, so it’s best to write a test first:

vendor/plugins/yaffle/test/yaffle_migration_generator_test.rb

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

After running the test with rake you can make it pass with:

vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb

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

and you will see a new file:

db/migrate/20080529225649_add_yaffle_fields_to_birds.rb

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

Many plugin authors put all of their rake tasks into a common namespace that is the same as the plugin, like so:

vendor/plugins/yaffle/tasks/yaffle.rake

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

It’s common practice to put any developer-centric rake tasks (such as tests, rdoc and gem package tasks) in Rakefile. A rake task that packages the gem might look like this:

vendor/plugins/yaffle/Rakefile:

-
@@ -1604,7 +1604,7 @@ Warning, gotchas or tips that might help save users time

15.2. Contents of lib/yaffle.rb

vendor/plugins/yaffle/lib/yaffle.rb:

-
diff --git a/railties/doc/guides/html/debugging_rails_applications.html b/railties/doc/guides/html/debugging_rails_applications.html index 51db11eb4e..07557b9e99 100644 --- a/railties/doc/guides/html/debugging_rails_applications.html +++ b/railties/doc/guides/html/debugging_rails_applications.html @@ -160,7 +160,7 @@ Analyze the stack trace

1.1. debug

The debug helper will return a <pre>-tag that renders the object using the YAML format. This will generate human-readable data from any object. For example, if you have this code in a view:

-
@@ -188,7 +188,7 @@ Title: Rails debugging guide

1.2. to_yaml

Displaying an instance variable, or any other object or method, in yaml format can be achieved this way:

-
@@ -216,7 +216,7 @@ Title: Rails debugging guide

1.3. inspect

Another useful method for displaying object values is inspect, especially when working with arrays or hashes. This will print the object value as a string. For example:

-
@@ -236,14 +236,14 @@ Title: Rails debugging guide

Rails has built-in support to debug RJS, to active it, set ActionView::Base.debug_rjs to true, this will specify whether RJS responses should be wrapped in a try/catch block that alert()s the caught exception (and then re-raises it).

To enable it, add the following in the Rails::Initializer do |config| block inside environment.rb:

-
config.action_view[:debug_rjs] = true

Or, at any time, setting ActionView::Base.debug_rjs to true:

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

Rails makes use of Ruby’s standard logger to write log information. You can also substitute another logger such as Log4R if you wish.

You can specify an alternative logger in your environment.rb or any environment file:

-
@@ -272,7 +272,7 @@ http://www.gnu.org/software/src-highlite --> ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")

Or in the Initializer section, add any of the following

-
@@ -290,7 +290,7 @@ config.logger =

When something is logged it’s printed into the corresponding log if the log level of the message is equal or higher than the configured log level. If you want to know the current log level you can call the ActiveRecord::Base.logger.level method.

The available log levels are: :debug, :info, :warn, :error, and :fatal, corresponding to the log level numbers from 0 up to 4 respectively. To change the default log level, use

-
@@ -308,7 +308,7 @@ ActiveRecord::Base2.3. Sending Messages

To write in the current log use the logger.(debug|info|warn|error|fatal) method from within a controller, model or mailer:

-
@@ -317,7 +317,7 @@ logger.info "Pr logger.fatal "Terminating application, raised unrecoverable error!!!"

Here’s an example of a method instrumented with extra logging:

-
@@ -368,7 +368,7 @@ Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localh

3.1. Setup

The debugger used by Rails, ruby-debug, comes as a gem. To install it, just run:

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

Rails has had built-in support for ruby-debug since Rails 2.0. Inside any Rails application you can invoke the debugger by calling the debugger method.

Here’s an example:

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

Make sure you have started your web server with the option --debugger:

-
@@ -620,7 +620,7 @@ true

The difference between next and step is that step stops at the next line of code executed, doing just a single step, while next moves to the next line without descending inside methods.

For example, consider this block of code with an included debugger statement:

-
@@ -833,7 +833,7 @@ set listsize 25

Then setup you application for profiling. Then add the following at the bottom of config/environment.rb:

-
diff --git a/railties/doc/guides/html/form_helpers.html b/railties/doc/guides/html/form_helpers.html index 0834cdd15a..a43cbe584f 100644 --- a/railties/doc/guides/html/form_helpers.html +++ b/railties/doc/guides/html/form_helpers.html @@ -715,7 +715,7 @@ The model object helpers for dates and times submit parameters with special name

by defining a LabellingFormBuilder class similar to the following:

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

7.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).

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

the params hash will contain

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

will result in the params hash being

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

This will result in a params hash that looks like

-
diff --git a/railties/doc/guides/html/getting_started_with_rails.html b/railties/doc/guides/html/getting_started_with_rails.html index 56a7ff6b3e..a79d9903aa 100644 --- a/railties/doc/guides/html/getting_started_with_rails.html +++ b/railties/doc/guides/html/getting_started_with_rails.html @@ -347,7 +347,7 @@ Transferring representations of the state of that resource between system compon

3.1. Installing Rails

In most cases, the easiest way to install Rails is to take advantage of RubyGems:

-
@@ -375,28 +375,28 @@ If you want to keep up with cutting-edge changes to Rails, you’ll want to

3.2. Creating the Blog Application

Open a terminal, navigate to a folder where you have rights to create files, and type:

-
$ rails blog

This will create a Rails application that uses a SQLite database for data storage. If you prefer to use MySQL, run this command instead:

-
$ rails blog -d mysql

And if you’re using PostgreSQL for data storage, run this command:

-
$ rails blog -d postgresql

After you create the blog application, switch to its folder to continue work directly in that application:

-
@@ -495,7 +495,7 @@ The production environment is used when you deploy your application for

Rails comes with built-in support for SQLite, which is a lightweight serverless database application. While a busy production environment may overload SQLite, it works well for development and testing. Rails defaults to using a SQLite database when creating a new project, but you can always change it later.

Here’s the section of the default configuration file with connection information for the development environment:

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

If you don’t have any database set up, SQLite is the easiest to get installed. If you’re on OS X 10.5 or greater on a Mac, you already have it. Otherwise, you can install it using RubyGems:

If you’re not running OS X 10.5 or greater, you’ll need to install the SQLite gem. Similar to installing Rails you just need to run:

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

3.3.2. Configuring a MySQL Database

If you choose to use MySQL, your config/database.yml will look a little different. Here’s the development section:

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

3.3.3. Configuring a PostgreSQL Database

If you choose to use PostgreSQL, your config/database.yml will be customized to use PostgreSQL databases:

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

3.3.4. Creating the Database

Now that you have your database configured, it’s time to have Rails create an empty database for you. You can do this by running a rake command:

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

One of the traditional places to start with a new language is by getting some text up on screen quickly. To do that in Rails, you need to create at minimum a controller and a view. Fortunately, you can do that in a single command. Enter this command in your terminal:

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

Rails will create several files for you, including app/views/home/index.html.erb. This is the template that will be used to display the results of the index action (method) in the home controller. Open this file in your text editor and edit it to contain a single line of code:

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

4.1. Starting up the Web Server

You actually have a functional Rails application already - after running only two commands! To see it, you need to start a web server on your development machine. You can do this by running another command:

-
@@ -597,14 +597,14 @@ http://www.gnu.org/software/src-highlite -->

4.2. Setting the Application Home Page

You’d probably like to replace the "Welcome Aboard" page with your own application’s home page. The first step to doing this is to delete the default page from your application:

-
$ rm public/index.html

Now, you have to tell Rails where your actual home page is located. Open the file config/routes.rb in your editor. This is your application’s, routing file, which holds entries in a special DSL (domain-specific language) that tells Rails how to connect incoming requests to controllers and actions. At the bottom of the file you’ll see the default routes:

-
@@ -613,7 +613,7 @@ map.connect ':c

The default routes handle simple requests such as /home/index: Rails translates that into a call to the index action in the home controller. As another example, /posts/edit/1 would run the edit action in the posts controller with an id of 1.

To hook up your home page, you need to add another line to the routing file, above the default routes:

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

In the case of the blog application, you can start by generating a scaffolded Post resource: this will represent a single blog posting. To do this, enter this command in your terminal:

-
@@ -728,7 +728,7 @@ cellspacing="0" cellpadding="4">

One of the products of the script/generate scaffold command is a database migration. Migrations are Ruby classes that are designed to make it simple to create and modify database tables. Rails uses rake commands to run migrations, and it’s possible to undo a migration after it’s been applied to your database. Migration filenames include a timestamp to ensure that they’re processed in the order that they were created.

If you look in the db/migrate/20081013124235_create_posts.rb file (remember, yours will have a slightly different name), here’s what you’ll find:

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

If you were to translate that into words, it says something like: when this migration is run, create a table named posts with two string columns (name and title) and a text column (content), and generate timestamp fields to track record creation and updating. You can learn the detailed syntax for migrations in the Rails Database Migrations guide.

At this point, you can use a rake command to run the migration:

-
@@ -767,7 +767,7 @@ $ rake db:migrate

To hook the posts up to the home page you’ve already created, you can add a link to the home page. Open /app/views/home/index.html.erb and modify it as follows:

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

6.4. The Model

The model file, app/models/post.rb is about as simple as it can get:

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

6.5. Adding Some Validation

Rails includes methods to help you validate the data that you send to models. Open the app/models/post.rb file and edit it:

-
@@ -815,14 +815,14 @@ http://www.gnu.org/software/src-highlite -->

6.6. Using the Console

To see your validations in action, you can use the console. The console is a command-line tool that lets you execute Ruby code in the context of your application:

-
$ script/console

After the console loads, you can use it to work with your application’s models:

-
@@ -848,7 +848,7 @@ title: nil,6.7. Listing All Posts

The easiest place to start looking at functionality is with the code that lists all posts. Open the file app/controllers/posts_controller.rb + and look at the +index action:

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

The respond_to block handles both HTML and XML calls to this action. If you browse to http://localhost:3000/posts.xml, you’ll see all of the posts in XML format. The HTML format looks for a view in app/views/posts/ with a name that corresponds to the action name. Rails makes all of the instance variables from the action available to the view. Here’s app/view/posts/index.html.erb:

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

6.8. Customizing the Layout

The view is only part of the story of how HTML is displayed in your web browser. Rails also has the concept of layouts, which are containers for views. When Rails renders a view to the browser, it does so by putting the view’s HTML into a layout’s HTML. The script/generate scaffold command automatically created a default layout, app/views/layouts/posts.html.erb, for the posts. Open this layout in your editor and modify the body tag:

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

6.9. Creating New Posts

Creating a new post involves two actions. The first is the new action, which instantiates an empty Post object:

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

The new.html.erb view displays this empty Post to the user:

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

When the user clicks the Create button on this form, the browser will send information back to the create method of the controller (Rails knows to call the create method because the form is sent with an HTTP POST request; that’s one of the conventions that I mentioned earlier):

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

6.10. Showing an Individual Post

When you click the show link for a post on the index page, it will bring you to a URL like http://localhost:3000/posts/1. Rails interprets this as a call to the show action for the resource, and passes in 1 as the :id parameter. Here’s the show action:

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

The show action uses Post.find to search for a single record in the database by its id value. After finding the record, Rails displays it by using show.html.erb:

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

6.11. Editing Posts

Like creating a new post, editing a post is a two-part process. The first step is a request to edit_post_path(@post) with a particular post. This calls the edit action in the controller:

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

After finding the requested post, Rails uses the edit.html.erb view to display it:

-
@@ -1106,7 +1106,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', posts_path %>

Submitting the form created by this view will invoke the update action within the controller:

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

6.12. Destroying a Post

Finally, clicking one of the destroy links sends the associated id to the destroy action:

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

As you saw earlier, the scaffold-generated views for the new and edit actions are largely identical. You can pull the shared code out into a partial template. This requires editing the new and edit views, and adding a new template. The new _form.html.erb template should be saved in the same app/views/posts folder as the files from which it is being extracted:

new.html.erb:

-
@@ -1169,7 +1169,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', posts_path %>

edit.html.erb:

-
@@ -1181,7 +1181,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', posts_path %>

_form.html.erb:

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

7.2. Using Filters to Eliminate Controller Duplication

At this point, if you look at the controller for posts, you’ll see some duplication:

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

Four instances of the exact same line of code doesn’t seem very DRY. Rails provides filters as a way to address this sort of repeated code. In this case, you can DRY things up by using a before_filter:

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

8.1. Generating a Model

Models in Rails use a singular name, and their corresponding database tables use a plural name. For the model to hold comments, the convention is to use the name Comment. Even if you don’t want to use the entire apparatus set up by scaffolding, most Rails developers still use generators to make things like models and controllers. To create the new model, run this command in your terminal:

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

First, take a look at comment.rb:

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

This is very similar to the post.rb model that you saw earlier. The difference is the line belongs_to :post, which sets up an Active Record association. You’ll learn a little about associations in the next section of this guide.

In addition to the model, Rails has also made a migration to create the corresponding database table:

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

The t.references line sets up a foreign key column for the association between the two models. Go ahead and run the migration:

-
@@ -1350,7 +1350,7 @@ One post can have many comments

In fact, this is very close to the syntax that Rails uses to declare this association. You’ve already seen the line of code inside the Comment model that makes each comment belong to a Post:

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

You’ll need to edit the post.rb file to add the other side of the association:

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

8.3. Adding a Route

Routes are entries in the config/routes.rb file that tell Rails how to match incoming HTTP requests to controller actions. Open up that file and find the existing line referring to posts. Then edit it as follows:

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

8.4. Generating a Controller

With the model in hand, you can turn your attention to creating a matching controller. Again, there’s a generator for this:

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

The controller will be generated with empty methods for each action that you specified in the call to script/generate controller:

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

You’ll need to flesh this out with code to actually process requests appropriately in each method. Here’s a version that (for simplicity’s sake) only responds to requests that require HTML:

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

You’ll see a bit more complexity here than you did in the controller for posts. That’s a side-effect of the nesting that you’ve set up; each request for a comment has to keep track of the post to which the comment is attached.

In addition, the code takes advantage of some of the methods available for an association. For example, in the new method, it calls

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

Because you skipped scaffolding, you’ll need to build views for comments "by hand." Invoking script/generate controller will give you skeleton views, but they’ll be devoid of actual content. Here’s a first pass at fleshing out the comment views.

The index.html.erb view:

-
@@ -1552,7 +1552,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back to Post', @post %>

The new.html.erb view:

-
@@ -1577,7 +1577,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', post_comments_path(@post) %>

The show.html.erb view:

-
@@ -1597,7 +1597,7 @@ http://www.gnu.org/software/src-highlite --> <%= link_to 'Back', post_comments_path(@post) %>

The edit.html.erb view:

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

8.6. Hooking Comments to Posts

As a final step, I’ll modify the show.html.erb view for a post to show the comments on that post, and to allow managing those comments:

-
diff --git a/railties/doc/guides/html/i18n.html b/railties/doc/guides/html/i18n.html index 0297475d87..d4433451ba 100644 --- a/railties/doc/guides/html/i18n.html +++ b/railties/doc/guides/html/i18n.html @@ -168,7 +168,7 @@ A default backend (which is intentionally named Simple backend) that im

1.2. The public I18n API

The most important methods of the I18n API are:

-
@@ -176,7 +176,7 @@ http://www.gnu.org/software/src-highlite --> localize # Localize Date and Time objects to local formats

These have the aliases #t and #l so you can use them like this:

-
@@ -184,7 +184,7 @@ http://www.gnu.org/software/src-highlite --> I18n.l Time.now

There are also attribute readers and writers for the following attributes:

-
@@ -203,7 +203,7 @@ backend

Rails adds all .rb and .yml files from config/locales directory to your translations load path, automatically.

See the default en.yml locale in this directory, containing a sample pair of translation strings:

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

The default environment.rb files has instruction how to add locales from another directory and how to set different default locale. Just uncomment and edit the specific lines.

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

For the sake of completeness, let’s mention that if you do not want to use the environment.rb file for some reason, you can always wire up things manually, too.

To tell the I18n library where it can find your custom translation files you can specify the load path anywhere in your application - just make sure it gets run before any translations are actually looked up. You might also want to change the default locale. The simplest thing possible is to put the following into an initializer:

-
@@ -250,7 +250,7 @@ I18n.default_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:

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

The process of "internationalization" usually means to abstract all strings and other locale specific bits out of your application. The process of "localization" means to then provide translations and localized formats for these bits. [1]

So, let’s internationalize something. You most probably have something like this in one of your applications:

-
@@ -300,7 +300,7 @@ ActionController::Routing3.1. Adding Translations

Obviously there are two strings that are localized to English. In order to internationalize this code replace these strings with calls to Rails' #t helper with a key that makes sense for the translation:

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

So let’s add the missing translations (i.e. do the "localization" part):

-
@@ -353,7 +353,7 @@ pirate:

3.2. Adding Date/Time formats

Ok, let’s add a timestamp to the view so we can demo the date/time localization feature as well. To localize the time format you pass the Time object to I18n.l or (preferably) use Rails' #l helper. You can pick a format by passing the :format option, by default the :default format is used.

-
@@ -363,7 +363,7 @@ http://www.gnu.org/software/src-highlite --> <p><%= l Time.now, :format => :short %></p>

And in our pirate translations file let’s add a time format (it’s already there in Rails' defaults for English):

-
@@ -407,7 +407,7 @@ localize dates, numbers, currency etc.

4.1.1. Basic lookup, scopes and nested keys

Translations are looked up by keys which can be both Symbols or Strings, so these calls are equivalent:

-
@@ -415,7 +415,7 @@ http://www.gnu.org/software/src-highlite --> I18n.t 'message'

translate also takes a :scope option which can contain one or many additional keys that will be used to specify a “namespace” or scope for a translation key:

-
@@ -423,14 +423,14 @@ http://www.gnu.org/software/src-highlite -->

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

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

-
I18n.translate :"active_record.error_messages.invalid"

Thus the following calls are equivalent:

-
@@ -441,7 +441,7 @@ I18n.t :

4.1.2. Defaults

When a default option is given its value will be returned if the translation is missing:

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

If the default value is a Symbol it will be used as a key and translated. One can provide multiple values as default. The first one that results in a value will be returned.

E.g. the following first tries to translate the key :missing and then the key :also_missing. As both do not yield a result the string "Not here" will be returned:

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

4.1.3. Bulk and namespace lookup

To lookup multiple translations at once an array of keys can be passed:

-
@@ -467,7 +467,7 @@ http://www.gnu.org/software/src-highlite --> # => ["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:

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

In many cases you want to abstract your translations so that variables can be interpolated into the translation. For this reason the I18n API provides an interpolation feature.

All options besides :default and :scope that are passed to #translate will be interpolated to the translation:

-
@@ -489,7 +489,7 @@ I18n.translate

In English there’s only a singular and a plural form for a given string, e.g. "1 message" and "2 messages". Other languages (Arabic, Japanese, Russian and many more) have different grammars that have additional or less plural forms. Thus, the I18n API provides a flexible pluralization feature.

The :count interpolation variable has a special role in that it both is interpolated to the translation and used to pick a pluralization from the translations according to the pluralization rules defined by CLDR:

-
@@ -501,7 +501,7 @@ I18n.translate # => '2 messages'

The algorithm for pluralizations in :en is as simple as:

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

The locale can be either set pseudo-globally to I18n.locale (which uses Thread.current like, e.g., Time.zone) or can be passed as an option to #translate and #localize.

If no locale is passed I18n.locale is used:

-
@@ -521,7 +521,7 @@ I18n.t : I18n.l Time.now

Explicitely passing a locale:

-
@@ -529,7 +529,7 @@ http://www.gnu.org/software/src-highlite --> I18n.l Time.now, :locale => :de

I18n.locale defaults to I18n.default_locale which defaults to :en. The default locale can be set like this:

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

The shipped Simple backend allows you to store translations in both plain Ruby and YAML format. [2]

For example a Ruby Hash providing translations can look like this:

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

The equivalent YAML file would look like this:

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

As you see in both cases the toplevel key is the locale. :foo is a namespace key and :bar is the key for the translation "baz".

Here is a "real" example from the ActiveSupport en.yml translations YAML file:

-
@@ -575,7 +575,7 @@ http://www.gnu.org/software/src-highlite --> long: "%B %d, %Y"

So, all of the following equivalent lookups will return the :short date format "%B %d":

-
@@ -588,7 +588,7 @@ I18n.t :

You can use the methods Model.human_name and Model.human_attribute_name(attribute) to transparently lookup translations for your model and attribute names.

For example when you add the following translations:

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

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:

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

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

-
@@ -624,7 +624,7 @@ activerecord.errors.errors.messages

Thus, in our example it will try the following keys in this order and return the first result:

-
@@ -634,7 +634,7 @@ activerecord.errors

When your models are additionally using inheritance then the messages are looked up for the inherited model class names are looked up.

For example, you might have an Admin model inheriting from User:

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

Then ActiveRecord will look for messages in this order:

-
@@ -776,7 +776,7 @@ cellspacing="0" cellpadding="4">

If you are using the ActiveRecord error_messages_for helper you will want to add translations for it.

Rails ships with the following translations:

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

For several reasons the shipped Simple backend only does the "simplest thing that ever could work" for Ruby on Rails [3] ... which means that it is only guaranteed to work for English and, as a side effect, languages that are very similar to English. Also, the simple backend is only capable of reading translations but can not dynamically store them to any format.

That does not mean you’re stuck with these limitations though. The Ruby I18n gem makes it very easy to exchange the Simple backend implementation with something else that fits better for your needs. E.g. you could exchange it with Globalize’s Static backend:

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

6.2. Using different exception handlers

The I18n API defines the following exceptions that will be raised by backends when the corresponding unexpected conditions occur:

-
@@ -820,7 +820,7 @@ UnknownFileType

The reason for this is that during development you’d usually want your views to still render even though a translation is missing.

In other contexts you might want to change this behaviour though. E.g. the default exception handling does not allow to catch missing translations during automated tests easily. For this purpose a different exception handler can be specified. The specified exception handler must be a method on the I18n module:

-
@@ -835,7 +835,7 @@ I18n.exception_handler

Another example where the default behaviour is less desirable is the Rails TranslationHelper which provides the method #t (as well as #translate). When a MissingTranslationData exception occurs in this context the helper wraps the message into a span with the css class translation_missing.

To do so the helper forces I18n#translate to raise exceptions no matter what exception handler is defined by setting the :raise option:

-
diff --git a/railties/doc/guides/html/layouts_and_rendering.html b/railties/doc/guides/html/layouts_and_rendering.html index 8d9cbad381..037714db78 100644 --- a/railties/doc/guides/html/layouts_and_rendering.html +++ b/railties/doc/guides/html/layouts_and_rendering.html @@ -127,7 +127,7 @@ Call head to create a response consisting solely of HTTP headers to sen

2.1. Rendering by Default: Convention Over Configuration in Action

You’ve heard that Rails promotes "convention over configuration." Default rendering is an excellent example of this. By default, controllers in Rails automatically render views with names that correspond to actions. For example, if you have this code in your BooksController class:

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

2.2.1. Rendering Nothing

Perhaps the simplest thing you can do with render is to render nothing at all:

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

2.2.2. Rendering an Action’s View

If you want to render the view that corresponds to a different action within the same template, you can use render with the name of the view:

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

If the call to update_attributes fails, calling the update action in this controller will render the edit.html.erb template belonging to the same controller.

If you prefer, you can use a symbol instead of a string to specify the action to render:

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

To be explicit, you can use render with the :action option (though this is no longer necessary as of Rails 2.3):

-
@@ -228,14 +228,14 @@ http://www.gnu.org/software/src-highlite -->

2.2.3. Rendering an Action’s Template from Another Controller

What if you want to render a template from an entirely different controller from the one that contains the action code? You can also do that with render, which accepts the full path (relative to app/views) of the template to render. For example, if you’re running code in an AdminProductsController that lives in app/controllers/admin, you can render the results of an action to a template in app/views/products this way:

-
render 'products/show'

Rails knows that this view belongs to a different controller because of the embedded slash character in the string. If you want to be explicit, you can use the :template option (which was required on Rails 2.2 and earlier):

-
@@ -243,14 +243,14 @@ http://www.gnu.org/software/src-highlite -->

2.2.4. Rendering an Arbitrary File

The render method can also use a view that’s entirely outside of your application (perhaps you’re sharing views between two Rails applications):

-
render "/u/apps/warehouse_app/current/app/views/products/show"

Rails determines that this is a file render because of the leading slash character. To be explicit, you can use the :file option (which was required on Rails 2.2 and earlier):

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

2.2.5. Using render with :inline

The render method can do without a view completely, if you’re willing to use the :inline option to supply ERB as part of the method call. This is perfectly valid:

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

By default, inline rendering uses ERb. You can force it to use Builder instead with the :type option:

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

2.2.6. Using render with :update

You can also render javascript-based page updates inline using the :update option to render:

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

2.2.7. Rendering Text

You can send plain text - with no markup at all - back to the browser by using the :text option to render:

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

2.2.8. Rendering JSON

JSON is a javascript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:

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

2.2.9. Rendering XML

Rails also has built-in support for converting objects to XML and rendering that XML back to the caller:

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

2.2.10. Rendering Vanilla JavaScript

Rails can render vanilla JavaScript (as an alternative to using update with n .rjs file):

-
@@ -405,7 +405,7 @@ http://www.gnu.org/software/src-highlite -->
The :content_type Option

By default, Rails will serve the results of a rendering operation with the MIME content-type of text/html (or application/json if you use the :json option, or application/xml for the :xml option.). There are times when you might like to change this, and you can do so by setting the :content_type option:

-
@@ -414,14 +414,14 @@ http://www.gnu.org/software/src-highlite -->

With most of the options to render, the rendered content is displayed as part of the current layout. You’ll learn more about layouts and how to use them later in this guide.

You can use the :layout option to tell Rails to use a specific file as the layout for the current action:

-
render :layout => 'special_layout'

You can also tell Rails to render with no layout at all:

-
@@ -429,7 +429,7 @@ http://www.gnu.org/software/src-highlite -->
The :status Option

Rails will automatically generate a response with the correct HTML status code (in most cases, this is 200 OK). You can use the :status option to change this:

-
@@ -439,7 +439,7 @@ render :status
The :location Option

You can use the :location option to set the HTTP Location header:

-
@@ -449,7 +449,7 @@ http://www.gnu.org/software/src-highlite -->
Specifying Layouts on a per-Controller Basis

You can override the automatic layout conventions in your controllers by using the layout declaration in the controller. For example:

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

With this declaration, all methods within ProductsController will use app/views/layouts/inventory.html.erb for their layout.

To assign a specific layout for the entire application, use a declaration in your ApplicationController class:

-
@@ -472,7 +472,7 @@ http://www.gnu.org/software/src-highlite -->
Choosing Layouts at Runtime

You can use a symbol to defer the choice of layout until a request is processed:

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

Now, if the current user is a special user, they’ll get a special layout when viewing a product. You can even use an inline method to determine the layout:

-
@@ -514,7 +514,7 @@ end

Layouts are shared downwards in the hierarchy, and more specific layouts always override more general ones. For example:

application_controller.rb:

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

posts_controller.rb:

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

special_posts_controller.rb:

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

old_posts_controller.rb:

-
@@ -592,7 +592,7 @@ In general, views will be rendered in the main layout

Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it’s relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that render works.

For example, here’s some code that will trigger this error:

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

If @book.special? evaluates to true, Rails will start the rendering process to dump the @book variable into the special_show view. But this will not stop the rest of the code in the show action from running, and when Rails hits the end of the action, it will start to render the show view - and throw an error. The solution is simple: make sure that you only have one call to render or redirect in a single code path. One thing that can help is and return. Here’s a patched version of the method:

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

2.3. Using redirect_to

Another way to handle returning responses to a HTTP request is with redirect_to. As you’ve seen, render tells Rails which view (or other asset) to use in constructing a response. The redirect_to method does something completely different: it tells the browser to send a new request for a different URL. For example, you could redirect from wherever you are in your code to the index of photos in your application with this call:

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

Sometimes inexperienced developers conceive of redirect_to as a sort of goto command, moving execution from one place to another in your Rails code. This is not correct. Your code stops running and waits for a new request for the browser. It just happens that you’ve told the browser what request it should make next, by sending back a HTTP 302 status code.

Consider these actions to see the difference:

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

With the code in this form, there will be likely be a problem if the @book variable is nil. Remember, a render :action doesn’t run any code in the target action, so nothing will set up the @books variable that the index view is presumably depending on. One way to fix this is to redirect instead of rendering:

-
@@ -672,14 +672,14 @@ http://www.gnu.org/software/src-highlite -->

2.4. Using head To Build Header-Only Responses

The head method exists to let you send back responses to the browser that have only headers. It provides a more obvious alternative to calling render :nothing. The head method takes one response, which is interpreted as a hash of header names and values. For example, you can return only an error header:

-
head :bad_request

Or you can use other HTTP headers to convey additional information:

-
@@ -742,7 +742,7 @@ image_tag

The auto_discovery_link_tag helper builds HTML that most browsers and newsreaders can use to detect the presences of RSS or ATOM feeds. It takes the type of the link (:rss+ or :atom), a hash of options that are passed through to url_for, and a hash of options for the tag:

-
@@ -768,63 +768,63 @@ http://www.gnu.org/software/src-highlite -->

3.1.2. Linking to Javascript Files with javascript_include_tag

The javascript_include_tag helper returns an HTML <script> tag for each source provided. Rails looks in public/javascripts for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include public/javascripts/main.js:

-
<%= javascript_include_tag "main" %>

To include public/javascripts/main.js and public/javascripts/columns.js:

-
<%= javascript_include_tag "main", "columns" %>

To include public/javascripts/main.js and public/photos/columns.js:

-
<%= javascript_include_tag "main", "/photos/columns" %>

To include http://example.com/main.js:

-
<%= javascript_include_tag "http://example.com/main.js" %>

The defaults option loads the Prototype and Scriptaculous libraries:

-
<%= javascript_include_tag :defaults %>

The all option loads every javascript file in public/javascripts, starting with the Prototype and Scriptaculous libraries:

-
<%= javascript_include_tag :all %>

You can supply the :recursive option to load files in subfolders of public/javascripts as well:

-
<%= javascript_include_tag :all, :recursive => true %>

If you’re loading multiple javascript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify :cache => true in your javascript_include_tag:

-
<%= javascript_include_tag "main", "columns", :cache => true %>

By default, the combined file will be delivered as javascripts/all.js. You can specify a location for the cached asset file instead:

-
@@ -833,63 +833,63 @@ http://www.gnu.org/software/src-highlite -->

The stylesheet_link_tag helper returns an HTML <link> tag for each source provided. Rails looks in public/stylesheets for these files by default, but you can specify a full path relative to the document root, or a URL, if you prefer. For example, to include public/stylesheets/main.cs:

-
<%= stylesheet_link_tag "main" %>

To include public/stylesheets/main.css and public/stylesheets/columns.css:

-
<%= stylesheet_link_tag "main", "columns" %>

To include public/stylesheets/main.css and public/photos/columns.css:

-
<%= stylesheet_link_tag "main", "/photos/columns" %>

To include http://example.com/main.cs:

-
<%= stylesheet_link_tag "http://example.com/main.cs" %>

By default, stylesheet_link_tag creates links with media="screen" rel="stylesheet" type="text/css". You can override any of these defaults by specifying an appropriate option (:media, :rel, or :type):

-
<%= stylesheet_link_tag "main_print", media => "print" %>

The all option links every CSS file in public/stylesheets:

-
<%= stylesheet_link_tag :all %>

You can supply the :recursive option to link files in subfolders of public/stylesheets as well:

-
<%= stylesheet_link_tag :all, :recursive => true %>

If you’re loading multiple CSS files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify :cache => true in your stylesheet_link_tag:

-
<%= stylesheet_link_tag "main", "columns", :cache => true %>

By default, the combined file will be delivered as stylesheets/all.css. You can specify a location for the cached asset file instead:

-
@@ -898,21 +898,21 @@ http://www.gnu.org/software/src-highlite -->

3.1.4. Linking to Images with image_tag

The image_tag helper builds an HTML <image> tag to the specified file. By default, files are loaded from public/images. If you don’t specify an extension, .png is assumed by default:

-
<%= image_tag "header" %>

You can supply a path to the image if you like:

-
<%= image_tag "icons/delete.gif" %>

You can supply a hash of additional HTML options:

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

3.2. Understanding yield

Within the context of a layout, yield identifies a section where content from the view should be inserted. The simplest way to use this is to have a single yield, into which the entire contents of the view currently being rendered is inserted:

-
@@ -950,7 +950,7 @@ http://www.gnu.org/software/src-highlite --> </html>

You can also create a layout with multiple yielding regions:

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

3.3. Using content_for

The content_for method allows you to insert content into a yield block in your layout. You only use content_for to insert content in named yields. For example, this view would work with the layout that you just saw:

-
@@ -977,7 +977,7 @@ http://www.gnu.org/software/src-highlite --> <p>Hello, Rails!</p>

The result of rendering this page into the supplied layout would be this HTML:

-
@@ -995,14 +995,14 @@ http://www.gnu.org/software/src-highlite -->

3.4.1. Naming Partials

To render a partial as part of a view, you use the render method within the view, and include the :partial option:

-
<%= render :partial => "menu" %>

This will render a file named _menu.html.erb at that point within the view being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore. This holds true even when you’re pulling in a partial from another folder:

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

3.4.2. Using Partials to Simplify Views

One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what’s going on more easily. For example, you might have a view that looked like this:

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

3.4.3. Partial Layouts

A partial can use its own layout file, just as a view can use a layout. For example, you might call a partial like this:

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

You can also pass local variables into partials, making them even more powerful and flexible. For example, you can use this technique to reduce duplication between new and edit pages, while still keeping a bit of distinct content:

new.html.erb:

-
@@ -1054,7 +1054,7 @@ http://www.gnu.org/software/src-highlite --> <%= render :partial => "form", :locals => { :button_label => "Create zone", :zone => @zone } %>

edit.html.erb:

-
@@ -1063,7 +1063,7 @@ http://www.gnu.org/software/src-highlite --> <%= render :partial => "form", :locals => { :button_label => "Update zone", :zone => @zone } %>

_form.html.erb:

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

Although the same partial will be rendered into both views, the label on the submit button is controlled by a local variable passed into the partial.

Every partial also has a local variable with the same name as the partial (minus the underscore). You can pass an object in to this local variable via the :object option:

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

If you have an instance of a model to render into a partial, you can use a shorthand syntax:

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

Partials are very useful in rendering collections. When you pass a collection to a partial via the :collection option, the partial will be inserted once for each member in the collection:

index.html.erb:

-
@@ -1113,14 +1113,14 @@ http://www.gnu.org/software/src-highlite --> <%= render :partial => "product", :collection => @products %>

_product.html.erb:

-
<p>Product Name: <%= product.name %></p>

When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is _product, and within the +_product partial, you can refer to product to get the instance that is being rendered. To use a custom local variable name within the partial, specify the :as option in the call to the partial:

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

You can also specify a second partial to be rendered between instances of the main partial by using the :spacer_template option:

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

There’s also a shorthand syntax available for rendering collections. For example, if @products is a collection of products, you can render the collection this way:

index.html.erb:

-
@@ -1153,7 +1153,7 @@ http://www.gnu.org/software/src-highlite --> <%= render :partial => @products %>

_product.html.erb:

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

Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection:

index.html.erb:

-
@@ -1169,14 +1169,14 @@ http://www.gnu.org/software/src-highlite --> <%= render :partial => [customer1, employee1, customer2, employee2] %>

_customer.html.erb:

-
<p>Name: <%= customer.name %></p>

_employee.html.erb:

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

Suppose you have the follow ApplicationController layout:

app/views/layouts/application.erb

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

On pages generated by NewsController, you want to hide the top menu and add a right menu:

app/views/layouts/news.erb

-
diff --git a/railties/doc/guides/html/migrations.html b/railties/doc/guides/html/migrations.html index 47fddb4caf..0a8b85c77c 100644 --- a/railties/doc/guides/html/migrations.html +++ b/railties/doc/guides/html/migrations.html @@ -142,7 +142,7 @@ How they relate to schema.rb

Before I dive into the details of a migration, here are a few examples of the sorts of things you can do:

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

This migration adds a table called products with a string column called name and a text column called description. A primary key column called id will also be added, however since this is the default we do not need to ask for this. The timestamp columns created_at and updated_at which Active Record populates automatically will also be added. Reversing this migration is as simple as dropping the table.

Migrations are not limited to changing the schema. You can also use them to fix bad data in the database or populate new fields:

-
@@ -258,7 +258,7 @@ write code to set the value of that column for existing records (if necessary us

The model and scaffold generators will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want then statements for adding those will also be created. For example, running

ruby script/generate model Product name:string description:text will create a migration that looks like this

-
@@ -283,7 +283,7 @@ are automatically populated by Active Record) will be added for you.

ruby script/generate migration AddPartNumberToProducts

This will create an empty but appropriately named migration:

-
@@ -299,7 +299,7 @@ the appropriate add and remove column statements will be created.

ruby script/generate migration AddPartNumberToProducts part_number:string

will generate

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

ruby script/generate migration RemovePartNumberFromProducts part_number:string

generates

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

ruby script/generate migration AddDetailsToProducts part_number:string price:decimal

generates

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

3.1. Creating a table

create_table will be one of your workhorses. A typical use would be

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

which creates a products table with a column called name (and as discussed below, an implicit id column).

The object yielded to the block allows you create columns on the table. There are two ways of doing this. The first looks like

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

the second form, the so called "sexy" migrations, drops the somewhat redundant column method. Instead, the string, integer etc. methods create a column of that type. Subsequent parameters are identical.

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

By default create_table will create a primary key called id. You can change the name of the primary key with the :primary_key option (don’t forget to update the corresponding model) or if you don’t want a primary key at all (for example for a HABTM join table) you can pass :id => false. If you need to pass database specific options you can place an sql fragment in the :options option. For example

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

These will be mapped onto an appropriate underlying database type, for example with MySQL :string is mapped to VARCHAR(255). You can create columns of types not supported by Active Record when using the non sexy syntax, for example

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

3.2. Changing tables

create_table's close cousin is change_table. Used for changing existing tables, it is used in a similar fashion to create_table but the object yielded to the block knows more tricks. For example

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

removes the description column, creates a part_number column and adds an index on it. Finally it renames the upccode column. This is the same as doing

-
@@ -432,7 +432,7 @@ rename_column :products3.3. Special helpers

Active Record provides some shortcuts for common functionality. It is for example very common to add both the created_at and updated_at columns and so there is a method that does exactly that:

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

will create a new products table with those two columns whereas

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

adds those columns to an existing table.

The other helper is called references (also available as belongs_to). In its simplest form it just adds some readability

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

will create a category_id column of the appropriate type. Note that you pass the model name, not the column name. Active Record adds the _id for you. If you have polymorphic belongs_to associations then references will add both of the columns required:

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

3.4. Writing your down method

The down method of your migration should revert the transformations done by the up method. In other words the database should be unchanged if you do an up followed by a down. For example if you create a table in the up you should drop it in the down method. It is wise to do things in precisely the reverse order to in the up method. For example

-
@@ -586,7 +586,7 @@ A migration creating a table and adding an index might produce output like this<

For example, this migration

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

Consider for example a migration that uses the Product model to update a row in the corresponding table. Alice later updates the Product model, adding a new column and a validation on it. Bob comes back from holiday, updates the source and runs outstanding migrations with rake db:migrate, including the one that used the Product model. When the migration runs the source is up to date and so the Product model has the validation added by Alice. The database however is still old and so does not have that column and an error ensues because that validation is on a column that does not yet exist.

Frequently I just want to update rows in the database without writing out the SQL by hand: I’m not using anything specific to the model. One pattern for this is to define a copy of the model inside the migration itself, for example:

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

5.1. Dealing with changing models

For performance reasons information about the columns a model has is cached. For example if you add a column to a table and then try and use the corresponding model to insert a new row it may try and use the old column information. You can force Active Record to re-read the column information with the reset_column_information method, for example

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

There are two ways to dump the schema. This is set in config/environment.rb by the config.active_record.schema_format setting, which may be either :sql or :ruby.

If :ruby is selected then the schema is stored in db/schema.rb. If you look at this file you’ll find that it looks an awful lot like one very big migration:

-
diff --git a/railties/doc/guides/html/performance_testing.html b/railties/doc/guides/html/performance_testing.html index 95bfd5f980..858076008d 100644 --- a/railties/doc/guides/html/performance_testing.html +++ b/railties/doc/guides/html/performance_testing.html @@ -138,7 +138,7 @@ Learn about various tools facilitating benchmarking and profiling

Rails performance tests are a special type of integration tests, designed for benchmarking and profiling the test code. With performance tests, you can determine where your application’s memory or speed problems are coming from, and get a more in-depth picture of those problems.

In a freshly generated Rails application, test/performance/browsing_test.rb contains an example of a performance test:

-
@@ -155,14 +155,14 @@ http://www.gnu.org/software/src-highlite -->

1.1. Generating performance tests

Rails provides a generator called performance_test for creating new performance tests:

-
script/generate performance_test homepage

This generates homepage_test.rb in the test/performance directory:

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

1.2. Examples

Let’s assume your application has the following controller and model:

-
@@ -220,7 +220,7 @@ map.resources :

Because performance tests are a special kind of integration test, you can use the get and post methods in them.

Here’s the performance test for HomeController#dashboard and PostsController#create:

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

Even though the performance tests are integration tests and hence closer to the request/response cycle by nature, you can still performance test pure model code.

Performance test for Post model:

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

Benchmarking helps find out how fast each performance test runs. Each test case is run 4 times in benchmarking mode.

To run performance tests in benchmarking mode:

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

Profiling helps you see the details of a performance test and provide an in-depth picture of the slow and memory hungry parts. Each test case is run 1 time in profiling mode.

To run performance tests in profiling mode:

-
@@ -310,7 +310,7 @@ http://www.gnu.org/software/src-highlite -->
Command line

This is the primary form of output in benchmarking mode. Example :

-
@@ -352,7 +352,7 @@ BrowsingTest#test_homepage_wall_time.csv

As the results are appended to these files each time the performance tests are run in benchmarking mode, you can collect data over a period of time. This can be very helpful in analyzing the effects of code changes.

Sample output of BrowsingTest#test_homepage_wall_time.csv:

-
@@ -372,7 +372,7 @@ http://www.gnu.org/software/src-highlite -->
Command line

This is a very basic form of output in profiling mode:

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

1.7. Performance Test Environment

Performance tests are run in the development environment. But running performance tests will set the following configuration parameters:

-
@@ -414,7 +414,7 @@ Rails.logger.

Compile Ruby and apply this GC Patch:

1.8.2. Download and Extract

-
@@ -424,7 +424,7 @@ http://www.gnu.org/software/src-highlite --> [lifo@null ~]$ cd <ruby-version>

1.8.3. Apply the patch

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

1.8.4. Configure and Install

The following will install ruby in your home directory’s /rubygc directory. Make sure to replace <homedir> with a full patch to your actual home directory.

-
@@ -480,7 +480,7 @@ alias gcrails='~/rubygc/bin/rails'

If installing mysql fails, you can try to install it manually:

-
@@ -495,21 +495,21 @@ http://www.gnu.org/software/src-highlite -->

benchmarker is a wrapper around Ruby’s Benchmark module.

Usage:

-
$ script/performance/benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ...

Examples:

-
$ script/performance/benchmarker 10 'Item.all' 'CouchItem.all'

If the [times] argument is omitted, supplied methods are run just once:

-
@@ -518,21 +518,21 @@ http://www.gnu.org/software/src-highlite -->

profiler is a wrapper around ruby-prof gem.

Usage:

-
$ script/performance/profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]

Examples:

-
$ script/performance/profiler 'Item.all'

This will profile Item.all in RubyProf::WALL_TIME measure mode. By default, it prints flat output to the shell.

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

This will profile 10.times { Item.all } with RubyProf::WALL_TIME measure mode and print graph output to the shell.

If you want to store the output in a file:

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

Rails provides various helper methods inside Active Record, Action Controller and Action View to measure the time taken by a given piece of code. The method is called benchmark() in all the three components.

3.1. Model

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

This benchmarks the code enclosed in the Project.benchmark("Creating project") do..end block and prints the result to the log file:

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

3.3. View

And in views:

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

Rails log files contain very useful information about the time taken to serve each request. Here’s a typical log file entry:

-
@@ -614,7 +614,7 @@ Rendering items/index Completed in 5ms (View: 2, DB: 0) | 200 OK [http://0.0.0.0/items]

For this section, we’re only interested in the last line:

-
diff --git a/railties/doc/guides/html/rails_on_rack.html b/railties/doc/guides/html/rails_on_rack.html index 411411cb41..eb1ff6ef1b 100644 --- a/railties/doc/guides/html/rails_on_rack.html +++ b/railties/doc/guides/html/rails_on_rack.html @@ -165,7 +165,7 @@ Understand the best practices for developing a middleware aimed at Rails applica

script/server does the basic job of creating a Rack::Builder object and starting the webserver. This is Rails equivalent of Rack’s rackup script.

Here’s how script/server creates an instance of Rack::Builder

-
@@ -208,7 +208,7 @@ cellspacing="0" cellpadding="4">

2.3. rackup

To use rackup instead of Rails' script/server, you can put the following inside config.ru of your Rails application’s root directory:

-
@@ -220,14 +220,14 @@ use Rails::Rack run ActionController::Dispatcher.new

And start the server:

-
[lifo@null application]$ rackup

To find out more about different rackup options:

-
@@ -248,14 +248,14 @@ http://www.gnu.org/software/src-highlite -->

3.1. Inspecting Middleware Stack

Rails has a handy rake task for inspecting the middleware stack in use:

-
$ rake middleware

For a freshly generated Rails application, this will produce:

-
@@ -270,7 +270,7 @@ run ActionController::Dispatcher

Rails provides a very simple configuration interface for adding generic Rack middlewares to a Rails applications.

Here’s how you can add middlewares via environment.rb

-
@@ -279,7 +279,7 @@ http://www.gnu.org/software/src-highlite --> config.middleware.use Rack::BounceFavicon

3.3. Internal Middleware Stack

-
@@ -353,7 +353,7 @@ cellspacing="0" cellpadding="4">

VERIFY THIS WORKS. Just a code dump at the moment.

Put the following in an initializer.

-
@@ -380,14 +380,14 @@ or something like that

4.1. Generating a Metal Application

Rails provides a generator called performance_test for creating new performance tests:

-
script/generate metal poller

This generates poller.rb in the app/metal directory:

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

All Metal Applications are executed by Rails::Rack::Metal middleware, which is a part of the ActionController::MiddlewareStack chain.

Here’s the primary method responsible for running the Metal applications:

-
diff --git a/railties/doc/guides/html/routing_outside_in.html b/railties/doc/guides/html/routing_outside_in.html index 03ad1c1eca..22477e18e7 100644 --- a/railties/doc/guides/html/routing_outside_in.html +++ b/railties/doc/guides/html/routing_outside_in.html @@ -193,7 +193,7 @@ Identify how a route will map to a controller and action

1.2. Generating URLs from Code

Routing also works in reverse. If your application contains this code:

-
@@ -246,7 +246,7 @@ Default Routes

2.2. RESTful Routes

RESTful routes take advantage of the built-in REST orientation of Rails to wrap up a lot of routing information in a single declaration. A RESTful route looks like this:

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

2.3. Named Routes

Named routes give you very readable links in your code, as well as handling incoming requests. Here’s a typical named route:

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

2.4. Nested Routes

Nested routes let you declare that one resource is contained within another resource. You’ll see later on how this translates to URLs and paths in your code. For example, if your application includes parts, each of which belongs to an assembly, you might have this nested route declaration:

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

2.5. Regular Routes

In many applications, you’ll also see non-RESTful routing, which explicitly connects the parts of a URL to a particular action. For example,

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

2.6. Default Routes

The default routes are a safety net that catch otherwise-unrouted requests. Many Rails applications will contain this pair of default routes:

-
@@ -311,7 +311,7 @@ Transferring representations of the state of that resource between system compon

3.2. CRUD, Verbs, and Actions

In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as

-
@@ -432,7 +432,7 @@ cellspacing="0" cellpadding="4">

In each case, the _url helper generates a string containing the entire URL that the application will understand, while the _path helper generates a string containing the relative path from the root of the application. For example:

-
@@ -441,14 +441,14 @@ photos_path # =>

3.4. Defining Multiple Resources at the Same Time

If you need to create routes for more than one RESTful resource, you can save a bit of typing by defining them all with a single call to map.resources:

-
map.resources :photos, :books, :videos

This has exactly the same effect as

-
@@ -458,7 +458,7 @@ map.resources :

3.5. Singular Resources

You can also apply RESTful routing to singleton resources within your application. In this case, you use map.resource instead of map.resources and the route generation is slightly different. For example, a routing entry of

-
@@ -613,7 +613,7 @@ cellspacing="0" cellpadding="4">

3.6.1. Using :controller

The :controller option lets you use a controller name that is different from the public-facing resource name. For example, this routing entry:

-
@@ -702,7 +702,7 @@ cellspacing="0" cellpadding="4">

3.7. Controller Namespaces and Routing

Rails allows you to group your controllers into namespaces by saving them in folders underneath app/controllers. The :controller option provides a convenient way to use these routes. For example, you might have a resource whose controller is purely for admin users in the admin folder:

-
@@ -718,14 +718,14 @@ http://www.gnu.org/software/src-highlite -->

You can also specify a controller namespace with the :namespace option instead of a path:

-
map.resources :adminphotos, :namespace => "admin", :controller => "photos"

This can be especially useful when combined with with_options to map multiple namespaced routes together:

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

3.7.1. Using :singular

If for some reason Rails isn’t doing what you want in converting the plural resource name to a singular name in member routes, you can override its judgment with the :singular option:

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

3.7.2. Using :requirements

You an use the :requirements option in a RESTful route to impose a format on the implied :id parameter in the singular routes. For example:

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

3.7.4. Using :as

The :as option lets you override the normal naming for the actual generated paths. For example:

-
@@ -852,7 +852,7 @@ cellspacing="0" cellpadding="4">

3.7.5. Using :path_names

The :path_names option lets you override the automatically-generated "new" and "edit" segments in URLs:

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

3.7.6. Using :path_prefix

The :path_prefix option lets you add additional parameters that will be prefixed to the recognized paths. For example, suppose each photo in your application belongs to a particular photographer. In that case, you might declare this route:

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

3.7.7. Using :name_prefix

You can use the :name_prefix option to avoid collisions between routes. This is most useful when you have two resources with the same name that use :path_prefix to map differently. For example:

-
@@ -936,7 +936,7 @@ map.resources :

3.7.8. Using :only and :except

By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the :only and :except options to fine-tune this behavior. The :only option specifies that only certain routes should be generated:

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

With this declaration, a GET request to /photos would succeed, but a POST request to /photos (which would ordinarily be routed to the create action) will fail.

The :except option specifies a route or list of routes that should not be generated:

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

3.8. Nested Resources

It’s common to have resources that are logically children of other resources. For example, suppose your application includes these models:

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

Each ad is logically subservient to one magazine. Nested routes allow you to capture this relationship in your routing. In this case, you might include this route declaration:

-
@@ -1059,7 +1059,7 @@ cellspacing="0" cellpadding="4">

3.8.1. Using :name_prefix

The :name_prefix option overrides the automatically-generated prefix in nested route helpers. For example,

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

This will create routing helpers such as periodical_ads_url and periodical_edit_ad_path. You can even use :name_prefix to suppress the prefix entirely:

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

This will create routing helpers such as ads_url and edit_ad_path. Note that calling these will still require supplying an article id:

-
@@ -1086,14 +1086,14 @@ edit_ad_path(@m

3.8.2. Using :has_one and :has_many

The :has_one and :has_many options provide a succinct notation for simple nested routes. Use :has_one to nest a singleton resource, or :has_many to nest a plural resource:

-
map.resources :photos, :has_one => :photographer, :has_many => [:publications, :versions]

This has the same effect as this set of declarations:

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

3.8.3. Limits to Nesting

You can nest resources within other nested resources if you like. For example:

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

3.8.4. Shallow Nesting

The :shallow option provides an elegant solution to the difficulties of deeply-nested routes. If you specify this option at any level of routing, then paths for nested resources which reference a specific member (that is, those with an :id parameter) will not use the parent path prefix or name prefix. To see what this means, consider this set of routes:

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

With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with. If you like, you can combine shallow nesting with the :has_one and :has_many options:

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

3.9. Route Generation from Arrays

In addition to using the generated routing helpers, Rails can also generate RESTful routes from an array of parameters. For example, suppose you have a set of routes generated with these entries in routes.rb:

-
@@ -1161,14 +1161,14 @@ http://www.gnu.org/software/src-highlite --> end

Rails will generate helpers such as magazine_ad_path that you can use in building links:

-
<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %>

Another way to refer to the same route is with an array of objects:

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

3.10. Namespaced Resources

It’s possible to do some quite complex things by combining :path_prefix and :name_prefix. For example, you can use the combination of these two options to move administrative resources to their own folder in your application:

-
@@ -1186,7 +1186,7 @@ map.resources : map.resources :ratings, :name_prefix => 'admin_photo_', :path_prefix => 'admin/photos/:photo_id', :controller => 'admin/photo_ratings'

The good news is that if you find yourself using this level of complexity, you can stop. Rails supports namespaced resources to make placing resources in their own folder a snap. Here’s the namespaced version of those same three routes:

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

3.11.1. Adding Member Routes

To add a member route, use the :member option:

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

This will enable Rails to recognize URLs such as /photos/1/preview using the GET HTTP verb, and route them to the preview action of the Photos controller. It will also create a preview_photo route helper.

Within the hash of member routes, each route name specifies the HTTP verb that it will recognize. You can use :get, :put, :post, :delete, or :any here. You can also specify an array of methods, if you need more than one but you don’t want to allow just anything:

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

3.11.2. Adding Collection Routes

To add a collection route, use the :collection option:

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

This will enable Rails to recognize URLs such as /photos/search using the GET HTTP verb, and route them to the search action of the Photos controller. It will also create a search_photos route helper.

Just as with member routes, you can specify an array of methods for a collection route:

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

3.11.3. Adding New Routes

To add a new route (one that creates a new resource), use the :new option:

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

4.1. Bound Parameters

When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: :controller maps to the name of a controller in your application, and :action maps to the name of an action within that controller. For example, consider one of the default Rails routes:

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

4.2. Wildcard Components

You can set up as many wildcard symbols within a regular route as you like. Anything other than :controller or :action will be available to the matching action as part of the params hash. So, if you set up this route:

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

4.3. Static Text

You can specify static text when creating a route. In this case, the static text is used only for matching the incoming requests:

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

4.4. Querystring Parameters

Rails routing automatically picks up querystring parameters and makes them available in the params hash. For example, with this route:

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

4.5. Defining Defaults

You do not need to explicitly use the :controller and :action symbols within a route. You can supply defaults for these two parameters in a hash:

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

With this route, an incoming URL of /photos/12 would be dispatched to the show action within the Photos controller.

You an also define other defaults in a route by supplying a hash for the :defaults option. This even applies to parameters that are not explicitly defined elsewhere in the route. For example:

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

4.6. Named Routes

Regular routes need not use the connect method. You can use any other name here to create a named route. For example,

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

4.7. Route Requirements

You can use the :requirements option to enforce a format for any parameter in a route:

-
@@ -1333,7 +1333,7 @@ http://www.gnu.org/software/src-highlite --> :requirements => { :id => /[A-Z]\d{5}/ }

This route would respond to URLs such as /photo/A12345. You can more succinctly express the same route this way:

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

4.8. Route Conditions

Route conditions (introduced with the :conditions option) are designed to implement restrictions on routes. Currently, the only supported restriction is :method:

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

4.9. Route Globbing

Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example

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

4.10. Route Options

You can use :with_options to simplify defining groups of similar routes:

-
@@ -1377,14 +1377,14 @@ http://www.gnu.org/software/src-highlite -->

There’s one more way in which routing can do different things depending on differences in the incoming HTTP request: by issuing a response that corresponds to what the request specifies that it will accept. In Rails routing, you can control this with the special :format parameter in the route.

For instance, consider the second of the default routes in the boilerplate routes.rb file:

-
map.connect ':controller/:action/:id.:format'

This route matches requests such as /photo/edit/1.xml or /photo/show/2.rss. Within the appropriate action code, you can issue different responses depending on the requested format:

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

5.2. Recognized MIME types

By default, Rails recognizes html, text, json, csv, xml, rss, atom, and yaml as acceptable response types. If you need types beyond this, you can register them in your environment:

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

When you create a new Rails application, routes.rb is initialized with two default routes:

-
@@ -1429,7 +1429,7 @@ map.connect ':c

7.1. Using map.root

The preferred way to set up the empty route is with the map.root command:

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

The use of the root method tells Rails that this route applies to requests for the root of the site.

For better readability, you can specify an already-created route in your call to map.root:

-
@@ -1447,7 +1447,7 @@ map.root :7.2. Connecting the Empty String

You can also specify an empty route by explicitly connecting the empty string:

-
@@ -1526,7 +1526,7 @@ formatted_users GET /users.:format {:controller=>"users", :action=>"inde

8.2.1. The assert_generates Assertion

Use assert_generates to assert that a particular set of options generate a particular path. You can use this with default routes or custom routes

-
@@ -1535,21 +1535,21 @@ assert_generates "/about"8.2.2. The assert_recognizes Assertion

The assert_recognizes assertion is the inverse of assert_generates. It asserts that Rails recognizes the given path and routes it to a particular spot in your application.

-
assert_recognizes { :controller => "photos", :action => "show", :id => "1" }, "/photos/1"

You can supply a :method argument to specify the HTTP verb:

-
assert_recognizes { :controller => "photos", :action => "create" }, { :path => "photos", :method => :post }

You can also use the RESTful helpers to test recognition of a RESTful route:

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

8.2.3. The assert_routing Assertion

The assert_routing assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of assert_generates and assert_recognizes.

-
diff --git a/railties/doc/guides/html/security.html b/railties/doc/guides/html/security.html index 8ef01db21a..371decda64 100644 --- a/railties/doc/guides/html/security.html +++ b/railties/doc/guides/html/security.html @@ -210,7 +210,7 @@ And the most popular injection attack methods Rails will create a new session automatically if a new user accesses the application. It will load an existing session if the user has already used the application.

A session usually consists of a hash of values and a session id, usually a 32-character string, to identify the hash. Every cookie sent to the client’s browser includes the session id. And the other way round: the browser will send it to the server on every request from the client. In Rails you can save and retrieve values using the session method:

-
@@ -363,7 +363,7 @@ From now on, the victim and the attacker will co-use the web application with th

-- One line of code will protect you from session fixation.

The most effective countermeasure is to issue a new session identifier and declare the old one invalid after a successful login. That way, an attacker cannot use the fixed session identifier. This is a good countermeasure against session hijacking, as well. Here is how to create a new session in Rails:

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

-- Sessions that never expire extend the time-frame for attacks such as cross-site reference forgery (CSRF), session hijacking and session fixation.

One possibility is to set the expiry time-stamp of the cookie with the session id. However the client can edit cookies that are stored in the web browser so expiring sessions on the server is safer. Here is an example of how to expire sessions in a database table. Call Session.sweep("20m") to expire sessions that were used longer than 20 minutes ago.

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

The section about session fixation introduced the problem of maintained sessions. An attacker maintaining a session every five minutes can keep the session alive forever, although you are expiring sessions. A simple solution for this would be to add a created_at column to the sessions table. Now you can delete sessions that were created a long time ago. Use this line in the sweep method above:

-
@@ -478,7 +478,7 @@ The user is held accountable for the re

With this precaution, the attack from above will not work, because the browser sends a GET request for images, which will not be accepted by the web application.

But this was only the first step, because POST requests can be send automatically, too. Here is an example for a link which displays www.harmless.com as destination in the browser’s status bar. In fact it dynamically creates a new form that sends a POST request.

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

-- Redirection in a web application is an underestimated cracker tool: Not only can the attacker forward the user to a trap web site, he may also create a self-contained attack.

Whenever the user is allowed to pass (parts of) the URL for redirection, it is possibly vulnerable. The most obvious attack would be to redirect users to a fake web application which looks and feels exactly as the original one. This so-called phishing attack works by sending an unsuspicious link in an email to the users, injecting the link by XSS in the web application or putting the link into an external site. It is unsuspicious, because the link starts with the URL to the web application and the URL to the malicious site is hidden in the redirection parameter: http://www.example.com/site/redirect?to= www.attacker.com. Here is an example of a legacy action:

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

Many web applications allow users to upload files. File names, which the user may choose (partly), should always be filtered as an attacker could use a malicious file name to overwrite any file on the server. If you store file uploads at /var/www/uploads, and the user enters a file name like “../../../etc/passwd”, it may overwrite an important file. Of course, the Ruby interpreter would need the appropriate permissions to do so – one more reason to run web servers, database servers and other programs as a less privileged Unix user.

When filtering user input file names, don’t try to remove malicious parts. Think of a situation where the web application removes all “../” in a file name and an attacker uses a string such as “....//” - the result will be “../”. It is best to use a whitelist approach, which checks for the validity of a file name with a set of accepted characters. This is opposed to a blacklist approach which attempts to remove not allowed characters. In case it isn’t a valid file name, reject it (or replace not accepted characters), but don’t remove them. Here is the file name sanitizer from the attachment_fu plugin:

-
@@ -547,14 +547,14 @@ http://www.gnu.org/software/src-highlite -->

-- Make sure users cannot download arbitrary files.

Just as you have to filter file names for uploads, you have to do so for downloads. The send_file() method sends files from the server to the client. If you use a file name, that the user entered, without filtering, any file can be downloaded:

-
send_file('/var/www/uploads/' + params[:filename])

Simply pass a file name like “../../../etc/passwd” to download the server’s login information. A simple solution against this, is to check that the requested file is in the expected directory:

-
@@ -602,7 +602,7 @@ Does the admin really have to access the interface from everywhere in the world?

-- Without any precautions Model.new(params[:model]) allows attackers to set any database column’s value.

The mass-assignment feature may become a problem, as it allows an attacker to set any model’s attribute by manipulating the hash passed to a model’s new() method:

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

This will set the following parameters in the controller:

-
@@ -626,21 +626,21 @@ http://www.gnu.org/software/src-highlite -->

6.1. Countermeasures

To avoid this, Rails provides two class methods in your ActiveRecord class to control access to your attributes. The attr_protected method takes a list of attributes that will not be accessible for mass-assignment. For example:

-
attr_protected :admin

A much better way, because it follows the whitelist-principle, is the attr_accessible method. It is the exact opposite of attr_protected, because it takes a list of attributes that will be accessible. All other attributes will be protected. This way you won’t forget to protect attributes when adding new ones in the course of development. Here is an example:

-
attr_accessible :name

If you want to set a protected attribute, you will to have to assign it individually:

-
@@ -662,7 +662,7 @@ http://localhost:3006/user/activate?id=

This is possible because on some servers, this way the parameter id, as in params[:id], would be nil. However, here is the finder from the activation action:

-
@@ -735,7 +735,7 @@ Include more than one honeypot field of all types, including submission buttons

-- Tell Rails not to put passwords in the log files.

By default, Rails logs all requests being made to the web application. But log files can be a huge security issue, as they may contain login credentials, credit card numbers etcetera. When designing a web application security concept, you should also think about what will happen if an attacker got (full) access to the web server. Encrypting secrets and passwords in the database will be quite useless, if the log files list them in clear text. You can filter certain request parameters from your log files by the filter_parameter_logging method in a controller. These parameters will be marked [FILTERED] in the log.

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

-- A common pitfall in Ruby’s regular expressions is to match the string’s beginning and end by ^ and $, instead of \A and \z.

Ruby uses a slightly different approach than many other languages to match the end and the beginning of a string. That is why even many Ruby and Rails books make this wrong. So how is this a security threat? Imagine you have a File model and you validate the file name by a regular expression like this:

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

Whereas %0A is a line feed in URL encoding, so Rails automatically converts it to "file.txt\n<script>alert(hello)</script>". This file name passes the filter because the regular expression matches – up to the line end, the rest does not matter. The correct expression should read:

-
@@ -774,14 +774,14 @@ http://www.gnu.org/software/src-highlite -->

-- Changing a single parameter may give the user unauthorized access. Remember that every parameter may be changed, no matter how much you hide or obfuscate it.

The most common parameter that a user might tamper with, is the id parameter, as in http://www.domain.com/project/1, whereas 1 is the id. It will be available in params[:id] in the controller. There, you will most likely do something like this:

-
@project = Project.find(params[:id])

This is alright for some web applications, but certainly not if the user is not authorized to view all projects. If the user changes the id to 42, and he is not allowed to see that information, he will have access to it anyway. Instead, query the user’s access rights, too:

-
@@ -836,7 +836,7 @@ But reject malformed input

8.2.1. Introduction

SQL injection attacks aim at influencing database queries by manipulating web application parameters. A popular goal of SQL injection attacks is to bypass authorization. Another goal is to carry out data manipulation or reading arbitrary data. Here is an example of how not to use user input data in a query:

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

8.2.2. Bypassing authorization

Usually a web application includes access control. The user enters his login credentials, the web applications tries to find the matching record in the users table. The application grants access when it finds a record. However, an attacker may possibly bypass this check with SQL injection. The following shows a typical database query in Rails to find the first record in the users table which matches the login credentials parameters supplied by the user.

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

8.2.3. Unauthorized reading

The UNION statement connects two SQL queries and returns the data in one set. An attacker can use it to read arbitrary data from the database. Let’s take the example from above:

-
@@ -886,14 +886,14 @@ http://www.gnu.org/software/src-highlite -->

Ruby on Rails has a built in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. Using Model.find(id) or Model.find_by_some thing(something) automatically applies this countermeasure[,#fffcdb]. But in SQL fragments, especially in conditions fragments (:conditions => "..."), the connection.execute() or Model.find_by_sql() methods, it has to be applied manually.

Instead of passing a string to the conditions option, you can pass an array to sanitize tainted strings like this:

-
Model.find(:first, :conditions => ["login = ? AND password = ?", entered_user_name, entered_password])

As you can see, the first part of the array is an SQL fragment with question marks. The sanitized versions of the variables in the second part of the array replace the question marks. Or you can pass a hash for the same result:

-
diff --git a/railties/doc/guides/html/testing_rails_applications.html b/railties/doc/guides/html/testing_rails_applications.html index 7a46b889aa..16822904fc 100644 --- a/railties/doc/guides/html/testing_rails_applications.html +++ b/railties/doc/guides/html/testing_rails_applications.html @@ -196,7 +196,7 @@ test

2.2. Rails Sets up for Testing from the Word Go

Rails creates a test folder for you as soon as you create a Rails project using rails application_name. If you list the contents of this folder then you shall see:

-
@@ -213,7 +213,7 @@ fixtures/ functional

YAML-formatted fixtures are a very human-friendly way to describe your sample data. These types of fixtures have the .yml file extension (as in users.yml).

Here’s a sample YAML fixture file:

-
@@ -231,7 +231,7 @@ steve:

2.3.3. ERb’in It Up

ERb allows you embed ruby code within templates. Both the YAML and CSV fixture formats are pre-processed with ERb when you load fixtures. This allows you to use Ruby to help you generate some sample data.

-
@@ -249,7 +249,7 @@ mars: brightest_on: <%= 13.days.from_now.to_s(:db) %>

Anything encased within the

-
@@ -277,7 +277,7 @@ Dump the fixture data into a variable in case you want to access it directly

2.3.5. Hashes with Special Powers

Fixtures are basically Hash objects. As mentioned in point #3 above, you can access the hash object directly because it is automatically setup as a local variable of the test case. For example:

-
@@ -288,7 +288,7 @@ users(:david)(:david).id

Fixtures can also transform themselves into the form of the original class. Thus, you can get at the methods only available to that class.

-
@@ -322,7 +322,7 @@ create test/fixtures/posts.yml

The default test stub in test/unit/post_test.rb looks like this:

-
@@ -336,28 +336,28 @@ http://www.gnu.org/software/src-highlite --> end

A line by line examination of this file will help get you oriented to Rails testing code and terminology.

-
require 'test_helper'

As you know by now that test_helper.rb specifies the default configuration to run our tests. This is included with all the tests, so any methods added to this file are available to all your tests.

-
class PostTest < ActiveSupport::TestCase

The PostTest class defines a test case because it inherits from ActiveSupport::TestCase. PostTest thus has all the methods available from ActiveSupport::TestCase. You’ll see those methods a little later in this guide.

-
def test_truth

Any method defined within a test case that begins with test (case sensitive) is simply called a test. So, test_password, test_valid_password and testValidPassword all are legal test names and are run automatically when the test case is run.

-
@@ -389,7 +389,7 @@ is the user’s password greater than 5 characters?

3.1. Preparing you Application for Testing

Before you can run your tests you need to ensure that the test database structure is current. For this you can use the following rake commands:

-
@@ -454,7 +454,7 @@ cellspacing="0" cellpadding="4">

3.2. Running Tests

Running a test is as simple as invoking the file containing the test cases through Ruby:

-
@@ -483,7 +483,7 @@ Finished in 0.023513 seconds.

The . (dot) above indicates a passing test. When a test fails you see an F; when a test throws an error you see an E in its place. The last line of the output is the summary.

To see how a test failure is reported, you can add a failing test to the post_test.rb test case.

-
@@ -511,7 +511,7 @@ test_should_not_save_post_without_title(PostTest)

In the output, F denotes a failure. You can see the corresponding trace shown under 1) along with the name of the failing test. The next few lines contain the stack trace followed by a message which mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable every assertion provides an optional message parameter, as shown here:

-
@@ -540,7 +540,7 @@ Saved the post without a title.

Now to get this test to pass we can add a model level validation for the title field.

-
@@ -569,7 +569,7 @@ Finished in 0.193608 seconds.

To see how an error gets reported, here’s a test containing an error:

-
@@ -801,7 +801,7 @@ was the appropriate message displayed to the user in the view

Now that we have used Rails scaffold generator for our Post resource, it has already created the controller code and functional tests. You can take look at the file posts_controller_test.rb in the test/functional directory.

Let me take you through one such test, test_should_get_index from the file posts_controller_test.rb.

-
@@ -836,14 +836,14 @@ An optional hash of flash values.

Example: Calling the :show action, passing an id of 12 as the params and setting a user_id of 5 in the session:

-
get(:show, {'id' => "12"}, {'user_id' => 5})

Another example: Calling the :view action, passing an id of 12 as the params, this time with no session, but with a flash message.

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

Let us modify test_should_create_post test in posts_controller_test.rb so that all our test pass:

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

As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name, except for assigns. For example:

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

4.5. A Fuller Functional Test Example

Here’s another example that uses flash, assert_redirected_to, and assert_difference:

-
@@ -984,14 +984,14 @@ http://www.gnu.org/software/src-highlite -->

assert_select(element, selector, [equality], [message]) ensures that the equality condition is met on all the selected elements through the selector starting from the element (instance of HTML::Node) and its descendants.

For example, you could verify the contents on the title element in your response with:

-
assert_select 'title', "Welcome to Rails Testing Guide"

You can also use nested assert_select blocks. In this case the inner assert_select runs the assertion on the complete collection of elements selected by the outer assert_select block:

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

Alternatively the collection of elements selected by the outer assert_select may be iterated through so that assert_select may be called separately for each element. Suppose for example that the response contains two ordered lists, each with four list elements then the following tests will both pass.

-
@@ -1051,7 +1051,7 @@ cellspacing="0" cellpadding="4">

Here’s an example of using assert_select_email:

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

Integration tests are used to test the interaction among any number of controllers. They are generally used to test important work flows within your application.

Unlike Unit and Functional tests, integration tests have to be explicitly created under the test/integration folder within your application. Rails provides a generator to create an integration test skeleton for you.

-
@@ -1073,7 +1073,7 @@ http://www.gnu.org/software/src-highlite --> create test/integration/user_flows_test.rb

Here’s what a freshly-generated integration test looks like:

-
@@ -1154,7 +1154,7 @@ cellspacing="0" cellpadding="4">

5.2. Integration Testing Examples

A simple integration test that exercises multiple controllers:

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

As you can see the integration test involves multiple controllers and exercises the entire stack from database to dispatcher. In addition you can have multiple session instances open simultaneously in a test and extend those instances with assertion methods to create a very powerful testing DSL (domain-specific language) just for your application.

Here’s an example of multiple sessions and custom DSL in an integration test

-
@@ -1297,7 +1297,7 @@ cellspacing="0" cellpadding="4">

If you would like to run a block of code before the start of each test and another block of code after the end of each test you have two special callbacks for your rescue. Let’s take note of this by looking at an example for our functional test in Posts controller:

-
@@ -1357,7 +1357,7 @@ a lambda

Let’s see the earlier example by specifying setup callback by specifying a method name as a symbol:

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

Like everything else in you Rails application, it’s recommended to test you routes. An example test for a route in the default show action of Posts controller above should look like:

-
@@ -1444,7 +1444,7 @@ the right emails are being sent at the right times

10.2.2. The Basic Test case

Here’s a unit test to test a mailer named UserMailer whose action invite is used to send an invitation to a friend. It is an adapted version of the base test created by the generator for an invite action.

-
@@ -1478,7 +1478,7 @@ Cheers!

10.3. Functional Testing

Functional testing for mailers involves more than just checking that the email body, recipients and so forth are correct. In functional mail tests you call the mail deliver methods and check that the appropriate emails have been appended to the delivery list. It is fairly safe to assume that the deliver methods themselves do their job You are probably more interested in is whether your own business logic is sending emails when you expect them to got out. For example, you can check that the invite friend operation is sending an email appropriately:

-
-- cgit v1.2.3 From 69022dfd7bd401d4517aa641177db45a22549dc7 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 18 Jan 2009 00:31:42 +0000 Subject: Add links to lighthouse ticket for i18n guide --- railties/doc/guides/html/i18n.html | 12 +++--------- railties/doc/guides/html/index.html | 2 +- railties/doc/guides/source/i18n.txt | 7 ++----- railties/doc/guides/source/index.txt | 2 +- 4 files changed, 7 insertions(+), 16 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/html/i18n.html b/railties/doc/guides/html/i18n.html index d4433451ba..8a6e4cc990 100644 --- a/railties/doc/guides/html/i18n.html +++ b/railties/doc/guides/html/i18n.html @@ -103,10 +103,7 @@ Footnotes
  • - Credits -
  • -
  • - NOTES + Changelog
  • @@ -850,12 +847,9 @@ http://www.gnu.org/software/src-highlite -->

    [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. Credits

    -
    -
    -

    10. NOTES

    +

    9. Changelog

    -

    How to contribute?

    +
    diff --git a/railties/doc/guides/html/index.html b/railties/doc/guides/html/index.html index d1bea57d14..d7079c9393 100644 --- a/railties/doc/guides/html/index.html +++ b/railties/doc/guides/html/index.html @@ -196,7 +196,7 @@ of your code.

    Caution -still a basic draft +Lighthouse ticket

    This guide introduces you to the basic concepts and features of the Rails I18n API and shows you how to localize your application.

    diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index ebbbbee8a9..d624e7d9ed 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -644,9 +644,6 @@ 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. -== Credits - -== NOTES - -How to contribute? +== Changelog == +http://rails.lighthouseapp.com/projects/16213/tickets/23[Lighthouse ticket] diff --git a/railties/doc/guides/source/index.txt b/railties/doc/guides/source/index.txt index 9141a5292a..b32d8ef7b1 100644 --- a/railties/doc/guides/source/index.txt +++ b/railties/doc/guides/source/index.txt @@ -125,7 +125,7 @@ This guide covers how to build a plugin to extend the functionality of Rails. .link:i18n.html[The Rails Internationalization API] *********************************************************** -CAUTION: still a basic draft +CAUTION: link:http://rails.lighthouseapp.com/projects/16213/tickets/23[Lighthouse ticket] This guide introduces you to the basic concepts and features of the Rails I18n API and shows you how to localize your application. *********************************************************** -- cgit v1.2.3 From dad45fa21bc8188a54dbc1d59f62de96ec89598b Mon Sep 17 00:00:00 2001 From: George Ogata Date: Sun, 18 Jan 2009 17:50:56 +1100 Subject: Add missing validates_numericality_of message names to i18n guide. --- railties/doc/guides/source/i18n.txt | 43 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'railties/doc/guides') diff --git a/railties/doc/guides/source/i18n.txt b/railties/doc/guides/source/i18n.txt index d624e7d9ed..e80de7adc9 100644 --- a/railties/doc/guides/source/i18n.txt +++ b/railties/doc/guides/source/i18n.txt @@ -530,25 +530,30 @@ So, for example, instead of the default error message "can not be blank" you cou count and/or value are available where applicable. Count can be used for pluralization if present: -|================================================================================== -| validation | with option | message | interpolation -| validates_confirmation_of | - | :confirmation | - -| validates_acceptance_of | - | :accepted | - -| validates_presence_of | - | :blank | - -| validates_length_of | :within, :in | :too_short | count -| validates_length_of | :within, :in | :too_long | count -| validates_length_of | :is | :wrong_length | count -| validates_length_of | :minimum | :too_short | count -| validates_length_of | :maximum | :too_long | count -| validates_uniqueness_of | - | :taken | value -| validates_format_of | - | :invalid | value -| validates_inclusion_of | - | :inclusion | value -| validates_exclusion_of | - | :exclusion | value -| validates_associated | - | :invalid | value -| validates_numericality_of | - | :not_a_number | value -| validates_numericality_of | :odd | :odd | value -| validates_numericality_of | :even | :even | value -|================================================================================== +|===================================================================================================== +| validation | with option | message | interpolation +| validates_confirmation_of | - | :confirmation | - +| validates_acceptance_of | - | :accepted | - +| validates_presence_of | - | :blank | - +| validates_length_of | :within, :in | :too_short | count +| validates_length_of | :within, :in | :too_long | count +| validates_length_of | :is | :wrong_length | count +| validates_length_of | :minimum | :too_short | count +| validates_length_of | :maximum | :too_long | count +| validates_uniqueness_of | - | :taken | value +| validates_format_of | - | :invalid | value +| validates_inclusion_of | - | :inclusion | value +| validates_exclusion_of | - | :exclusion | value +| validates_associated | - | :invalid | value +| validates_numericality_of | - | :not_a_number | value +| 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 +| validates_numericality_of | :even | :even | value +|===================================================================================================== ==== Translations for the ActiveRecord error_messages_for helper -- cgit v1.2.3 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:

    +
      +
    • +

      +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:

    +
    +
    +
    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

    +
      +
    • +

      +distance_of_time_in_words translates and pluralizes its result and interpolates the number of seconds, minutes, hours and so on. See datetime.distance_in_words translations. +

      +
    • +
    • +

      +datetime_select and select_month use translated month names for populating the resulting select tag. See date.month_names for translations. datetime_select also looks up the order option from date.order (unless you pass the option explicitely). All date select helpers translate the prompt using the translations in the 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 number scope. +

      +
    • +
    +

    5.2.2. ActiveRecord methods

    +
      +
    • +

      +human_name and human_attribute_name use translations for model names and attribute names if available in the 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 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 activerecord.errors.format.separator (and defaults to ' '). +

      +
    • +
    +

    5.2.3. ActiveSupport methods

    +
      +
    • +

      +Array#to_sentence uses format settings as given in the support.array scope. +

      +
    • +

    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: