File: README

README

Path: | README
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Welcome to Rails

Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Control pattern.

This pattern splits the view (also called the presentation) into "dumb" templates that are primarily responsible for inserting pre-built data in between HTML tags. The model contains the "smart" domain objects (such as Account, Product, Person, Post) that holds all the business logic and knows how to persist themselves to a database. The controller handles the incoming requests (such as Save New Account, Update Product, Show Post) by manipulating the model and directing data to the view.

In Rails, the model is handled by what‘s called an object-relational mapping layer entitled Active Record. This layer allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in files/vendor/rails/activerecord/README.html.

The controller and view are handled by the Action Pack, which handles both layers by its two parts: Action View and Action Controller. These two layers are bundled in a single package due to their heavy interdependence. This is unlike the relationship between the Active Record and Action Pack that is much more separate. Each of these packages can be used independently outside of Rails. You can read more about Action Pack in files/vendor/rails/actionpack/README.html.

Getting Started

  1. At the command prompt, start a new Rails application using the rails command and your application name. Ex: rails myapp
  2. Change directory into myapp and start the web server: script/server (run with —help for options)
  3. Go to localhost:3000/ and get "Welcome aboard: You‘re riding the Rails!"
  4. Follow the guidelines to start developing your application

Web Servers

By default, Rails will try to use Mongrel if it‘s are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails with a variety of other web servers.

Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is suitable for development and deployment of Rails applications. If you have Ruby Gems installed, getting up and running with mongrel is as easy as: gem install mongrel. More info at: mongrel.rubyforge.org

Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.

Apache .htaccess example for FCGI/CGI

# General Apache options AddHandler fastcgi-script .fcgi AddHandler cgi-script .cgi Options +FollowSymLinks +ExecCGI

# If you don‘t want Rails to look in certain directories, # use the following rewrite rules so that Apache won‘t rewrite certain requests # # Example: # RewriteCond %{REQUEST_URI} ^/notrails.* # RewriteRule .* - [L]

# Redirect all requests not available on the filesystem to Rails # By default the cgi dispatcher is used which is very slow # # For better performance replace the dispatcher with the fastcgi one # # Example: # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] RewriteEngine On

# If your Rails application is accessed via an Alias directive, # then you MUST also set the RewriteBase in this htaccess file. # # Example: # Alias /myrailsapp /path/to/myrailsapp/public # RewriteBase /myrailsapp

RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

# In case Rails experiences terminal errors # Instead of displaying this message you can supply a file here which will be rendered instead # # Example: # ErrorDocument 500 /500.html

ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"

Debugging Rails

Sometimes your application goes wrong. Fortunately there are a lot of tools that will help you debug it and get it back on the rails.

First area to check is the application log files. Have "tail -f" commands running on the server.log and development.log. Rails will automatically display debugging and runtime information to these files. Debugging info will also be shown in the browser on requests from 127.0.0.1.

You can also log your own messages directly into the log file from your code using the Ruby logger class from inside your controllers. Example:

  class WeblogController < ActionController::Base
    def destroy
      @weblog = Weblog.find(params[:id])
      @weblog.destroy
      logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
    end
  end

The result will be a message in your log file along the lines of:

  Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1

More information on how to use the logger is at www.ruby-doc.org/core/

Also, Ruby documentation can be found at www.ruby-lang.org/ including:

  • The Learning Ruby (Pickaxe) Book: www.ruby-doc.org/docs/ProgrammingRuby/
  • Learn to Program: pine.fm/LearnToProgram/ (a beginners guide)

These two online (and free) books will bring you up to speed on the Ruby language and also on programming in general.

Debugger

Debugger support is available through the debugger command when you start your Mongrel or Webrick server with —debugger. This means that you can break out of execution at any point in the code, investigate and change the model, AND then resume execution! You need to install ruby-debug to run the server in debugging mode. With gems, use ‘gem install ruby-debug’ Example:

  class WeblogController < ActionController::Base
    def index
      @posts = Post.find(:all)
      debugger
    end
  end

So the controller will accept the action, run the first line, then present you with a IRB prompt in the server window. Here you can do things like:

  >> @posts.inspect
  => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
       #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
  >> @posts.first.title = "hello from a debugger"
  => "hello from a debugger"

…and even better is that you can examine how your runtime objects actually work:

  >> f = @posts.first
  => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
  >> f.
  Display all 152 possibilities? (y or n)

Finally, when you‘re ready to resume execution, you enter "cont"

Console

You can interact with the domain model by starting the console through script/console. Here you‘ll have all parts of the application configured, just like it is when the application is running. You can inspect domain models, change values, and save to the database. Starting the script without arguments will launch it in the development environment. Passing an argument will specify a different environment, like script/console production.

To reload your controllers and models after launching the console run reload!

dbconsole

You can go to the command line of your database directly through script/dbconsole. You would be connected to the database with the credentials defined in database.yml. Starting the script without arguments will connect you to the development database. Passing an argument will connect you to a different database, like script/dbconsole production. Currently works for mysql, postgresql and sqlite.

Description of Contents

app

  Holds all the code that's specific to this particular application.

app/controllers

  Holds controllers that should be named like weblogs_controller.rb for
  automated URL mapping. All controllers should descend from ApplicationController
  which itself descends from ActionController::Base.

app/models

  Holds models that should be named like post.rb.
  Most models will descend from ActiveRecord::Base.

app/views

  Holds the template files for the view that should be named like
  weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
  syntax.

app/views/layouts

  Holds the template files for layouts to be used with views. This models the common
  header/footer method of wrapping views. In your views, define a layout using the
  <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
  call <% yield %> to render the view using this layout.

app/helpers

  Holds view helpers that should be named like weblogs_helper.rb. These are generated
  for you automatically when using script/generate for controllers. Helpers can be used to
  wrap functionality for your views into methods.

config

  Configuration files for the Rails environment, the routing map, the database, and other dependencies.

db

  Contains the database schema in schema.rb.  db/migrate contains all
  the sequence of Migrations for your schema.

doc

  This directory is where your application documentation will be stored when generated
  using <tt>rake doc:app</tt>

lib

  Application specific libraries. Basically, any kind of custom code that doesn't
  belong under controllers, models, or helpers. This directory is in the load path.

public

  The directory available for the web server. Contains subdirectories for images, stylesheets,
  and javascripts. Also contains the dispatchers and the default HTML files. This should be
  set as the DOCUMENT_ROOT of your web server.

script

  Helper scripts for automation and generation.

test

  Unit and functional tests along with fixtures. When using the script/generate scripts, template
  test files will be generated for you and placed in this directory.

vendor

  External libraries that the application depends on. Also includes the plugins subdirectory.
  If the app has frozen rails, those gems also go here, under vendor/rails/.
  This directory is in the load path.


File: MIT-LICENSE

MIT-LICENSE

Path: | vendor/rails/railties/MIT-LICENSE
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Copyright (c) 2004-2009 David Heinemeier Hansson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


File: README

README

Path: | vendor/rails/activerecord/README
Last Update: | Sun Mar 15 23:31:35 -0500 2009

Active Record — Object-relation mapping put on rails

Active Record connects business objects and database tables to create a persistable domain model where logic and data are presented in one wrapping. It‘s an implementation of the object-relational mapping (ORM) pattern by the same name as described by Martin Fowler:

  "An object that wraps a row in a database table or view, encapsulates
       the database access, and adds domain logic on that data."

Active Record‘s main contribution to the pattern is to relieve the original of two stunting problems: lack of associations and inheritance. By adding a simple domain language-like set of macros to describe the former and integrating the Single Table Inheritance pattern for the latter, Active Record narrows the gap of functionality between the data mapper and active record approach.

A short rundown of the major features:

  • Automated mapping between classes and tables, attributes and columns.
     class Product < ActiveRecord::Base; end

 ...is automatically mapped to the table named "products", such as:

 CREATE TABLE products (
   id int(11) NOT NULL auto_increment,
   name varchar(255),
   PRIMARY KEY  (id)
 );

 ...which again gives Product#name and Product#name=(new_name)

    Learn more

  • Associations between objects controlled by simple meta-programming macros.
     class Firm < ActiveRecord::Base
   has_many   :clients
   has_one    :account
   belongs_to :conglomorate
 end

    Learn more

  • Aggregations of value objects controlled by simple meta-programming macros.
     class Account < ActiveRecord::Base
   composed_of :balance, :class_name => "Money",
               :mapping => %w(balance amount)
   composed_of :address,
               :mapping => [%w(address_street street), %w(address_city city)]
 end

    Learn more

  • Validation rules that can differ for new or existing objects.
      class Account < ActiveRecord::Base
    validates_presence_of     :subdomain, :name, :email_address, :password
    validates_uniqueness_of   :subdomain
    validates_acceptance_of   :terms_of_service, :on => :create
    validates_confirmation_of :password, :email_address, :on => :create
  end

    Learn more

  • Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
     class Person < ActiveRecord::Base
   def before_destroy # is called just before Person#destroy
     CreditCard.find(credit_card_id).destroy
   end
 end

 class Account < ActiveRecord::Base
   after_find :eager_load, 'self.class.announce(#{id})'
 end

    Learn more

  • Observers for the entire lifecycle
     class CommentObserver < ActiveRecord::Observer
   def after_create(comment) # is called just after Comment#save
     Notifications.deliver_new_comment("david@loudthinking.com", comment)
   end
 end

    Learn more

  • Inheritance hierarchies
     class Company < ActiveRecord::Base; end
 class Firm < Company; end
 class Client < Company; end
 class PriorityClient < Client; end

    Learn more

  • Transactions
      # Database transaction
  Account.transaction do
    david.withdrawal(100)
    mary.deposit(100)
  end

    Learn more

  • Reflections on columns, associations, and aggregations
      reflection = Firm.reflect_on_association(:clients)
  reflection.klass # => Client (class)
  Firm.columns # Returns an array of column descriptors for the firms table

    Learn more

  • Direct manipulation (instead of service invocation)

    So instead of (Hibernate example):

       long pkId = 1234;
   DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId) );
   // something interesting involving a cat...
   sess.save(cat);
   sess.flush(); // force the SQL INSERT

    Active Record lets you:

       pkId = 1234
   cat = Cat.find(pkId)
   # something even more interesting involving the same cat...
   cat.save

    Learn more

  • Database abstraction through simple adapters (~100 lines) with a shared connector
     ActiveRecord::Base.establish_connection(:adapter => "sqlite", :database => "dbfile")

 ActiveRecord::Base.establish_connection(
   :adapter  => "mysql",
   :host     => "localhost",
   :username => "me",
   :password => "secret",
   :database => "activerecord"
 )

    Learn more and read about the built-in support for MySQL, PostgreSQL, SQLite, Oracle, SQLServer, and DB2.

  • Logging support for Log4r and Logger
      ActiveRecord::Base.logger = Logger.new(STDOUT)
  ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")
  • Database agnostic schema management with Migrations
      class AddSystemSettings < ActiveRecord::Migration
    def self.up
      create_table :system_settings do |t|
        t.string :name
        t.string :label
        t.text :value
        t.string :type
        t.integer  :position
      end

      SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
    end

    def self.down
      drop_table :system_settings
    end
  end

    Learn more

Simple example (1/2): Defining tables and classes (using MySQL)

Data definitions are specified only in the database. Active Record queries the database for the column names (that then serves to determine which attributes are valid) on regular object instantiation through the new constructor and relies on the column names in the rows with the finders.

   # CREATE TABLE companies (
   #   id int(11) unsigned NOT NULL auto_increment,
   #   client_of int(11),
   #   name varchar(255),
   #   type varchar(100),
   #   PRIMARY KEY  (id)
   # )

Active Record automatically links the "Company" object to the "companies" table

   class Company < ActiveRecord::Base
     has_many :people, :class_name => "Person"
   end

   class Firm < Company
     has_many :clients

     def people_with_all_clients
      clients.inject([]) { |people, client| people + client.people }
     end
   end

The foreign_key is only necessary because we didn‘t use "firm_id" in the data definition

   class Client < Company
     belongs_to :firm, :foreign_key => "client_of"
   end

   # CREATE TABLE people (
   #   id int(11) unsigned NOT NULL auto_increment,
   #   name text,
   #   company_id text,
   #   PRIMARY KEY  (id)
   # )

Active Record will also automatically link the "Person" object to the "people" table

   class Person < ActiveRecord::Base
     belongs_to :company
   end

Simple example (2/2): Using the domain

Picking a database connection for all the Active Records

   ActiveRecord::Base.establish_connection(
     :adapter  => "mysql",
     :host     => "localhost",
     :username => "me",
     :password => "secret",
     :database => "activerecord"
   )

Create some fixtures

   firm = Firm.new("name" => "Next Angle")
   # SQL: INSERT INTO companies (name, type) VALUES("Next Angle", "Firm")
   firm.save

   client = Client.new("name" => "37signals", "client_of" => firm.id)
   # SQL: INSERT INTO companies (name, client_of, type) VALUES("37signals", 1, "Firm")
   client.save

Lots of different finders

   # SQL: SELECT * FROM companies WHERE id = 1
   next_angle = Company.find(1)

   # SQL: SELECT * FROM companies WHERE id = 1 AND type = 'Firm'
   next_angle = Firm.find(1)

   # SQL: SELECT * FROM companies WHERE id = 1 AND name = 'Next Angle'
   next_angle = Company.find(:first, :conditions => "name = 'Next Angle'")

   next_angle = Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first

The supertype, Company, will return subtype instances

   Firm === next_angle

All the dynamic methods added by the has_many macro

  next_angle.clients.empty?  # true
  next_angle.clients.size    # total number of clients
  all_clients = next_angle.clients

Constrained finds makes access security easier when ID comes from a web-app

   # SQL: SELECT * FROM companies WHERE client_of = 1 AND type = 'Client' AND id = 2
   thirty_seven_signals = next_angle.clients.find(2)

Bi-directional associations thanks to the "belongs_to" macro

   thirty_seven_signals.firm.nil? # true

Philosophy

Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is object-relational mapping. The prime directive for this mapping has been to minimize the amount of code needed to build a real-world domain model. This is made possible by relying on a number of conventions that make it easy for Active Record to infer complex relations and structures from a minimal amount of explicit direction.

Convention over Configuration:

  • No XML-files!
  • Lots of reflection and run-time extension
  • Magic is not inherently a bad word

Admit the Database:

  • Lets you drop down to SQL for odd cases and performance
  • Doesn‘t attempt to duplicate or replace data definitions

Download

The latest version of Active Record can be found at

  • rubyforge.org/project/showfiles.php?group_id=182

Documentation can be found at

  • ar.rubyonrails.com

Installation

The prefered method of installing Active Record is through its GEM file. You‘ll need to have RubyGems installed for that, though. If you have, then use:

  % [sudo] gem install activerecord-1.10.0.gem

You can also install Active Record the old-fashioned way with the following command:

  % [sudo] ruby install.rb

from its distribution directory.

License

Active Record is released under the MIT license.

Support

The Active Record homepage is www.rubyonrails.com. You can find the Active Record RubyForge page at rubyforge.org/projects/activerecord. And as Jim from Rake says:

   Feel free to submit commits or feature requests.  If you send a patch,
   remember to update the corresponding unit tests.  If fact, I prefer
   new feature to be submitted in the form of new unit tests.

For other information, feel free to ask on the rubyonrails-talk (groups.google.com/group/rubyonrails-talk) mailing list.


Class: ActiveRecord::ActiveRecordError

Class | ActiveRecord::ActiveRecordError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | StandardError

Generic Active Record exception class.


Class: ActiveRecord::AdapterNotFound

Class | ActiveRecord::AdapterNotFound
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when Active Record cannot find database adapter specified in config/database.yml or programmatically.


Class: ActiveRecord::AdapterNotSpecified

Class | ActiveRecord::AdapterNotSpecified
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when adapter not specified on connection (or configuration file config/database.yml misses adapter field).


Module: ActiveRecord::Aggregations::ClassMethods

Module | ActiveRecord::Aggregations::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/aggregations.rb

Active Record implements aggregation through a macro-like class method called composed_of for representing attributes as value objects. It expresses relationships like "Account [is] composed of Money [among other things]" or "Person [is] composed of [an] address". Each call to the macro adds a description of how the value objects are created from the attributes of the entity object (when the entity is initialized either as a new object or from finding an existing object) and how it can be turned back into attributes (when the entity is saved to the database). Example:

  class Customer < ActiveRecord::Base
    composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
    composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ]
  end

The customer class now has the following methods to manipulate the value objects:

  • Customer#balance, Customer#balance=(money)
  • Customer#address, Customer#address=(address)

These methods will operate with value objects like the ones described below:

 class Money
   include Comparable
   attr_reader :amount, :currency
   EXCHANGE_RATES = { "USD_TO_DKK" => 6 }

   def initialize(amount, currency = "USD")
     @amount, @currency = amount, currency
   end

   def exchange_to(other_currency)
     exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor
     Money.new(exchanged_amount, other_currency)
   end

   def ==(other_money)
     amount == other_money.amount && currency == other_money.currency
   end

   def <=>(other_money)
     if currency == other_money.currency
       amount <=> amount
     else
       amount <=> other_money.exchange_to(currency).amount
     end
   end
 end

 class Address
   attr_reader :street, :city
   def initialize(street, city)
     @street, @city = street, city
   end

   def close_to?(other_address)
     city == other_address.city
   end

   def ==(other_address)
     city == other_address.city && street == other_address.street
   end
 end

Now it‘s possible to access attributes from the database through the value objects instead. If you choose to name the composition the same as the attribute‘s name, it will be the only way to access that attribute. That‘s the case with our balance attribute. You interact with the value objects just like you would any other attribute, though:

  customer.balance = Money.new(20)     # sets the Money value object and the attribute
  customer.balance                     # => Money value object
  customer.balance.exchange_to("DKK")  # => Money.new(120, "DKK")
  customer.balance > Money.new(10)     # => true
  customer.balance == Money.new(20)    # => true
  customer.balance < Money.new(5)      # => false

Value objects can also be composed of multiple attributes, such as the case of Address. The order of the mappings will determine the order of the parameters. Example:

  customer.address_street = "Hyancintvej"
  customer.address_city   = "Copenhagen"
  customer.address        # => Address.new("Hyancintvej", "Copenhagen")
  customer.address = Address.new("May Street", "Chicago")
  customer.address_street # => "May Street"
  customer.address_city   # => "Chicago"

Writing value objects

Value objects are immutable and interchangeable objects that represent a given value, such as a Money object representing $5. Two Money objects both representing $5 should be equal (through methods such as == and <=> from Comparable if ranking makes sense). This is unlike entity objects where equality is determined by identity. An entity class such as Customer can easily have two different objects that both have an address on Hyancintvej. Entity identity is determined by object or relational unique identifiers (such as primary keys). Normal ActiveRecord::Base classes are entity objects.

It‘s also important to treat the value objects as immutable. Don‘t allow the Money object to have its amount changed after creation. Create a new Money object with the new value instead. This is exemplified by the Money#exchange_to method that returns a new value object instead of changing its own values. Active Record won‘t persist value objects that have been changed through means other than the writer method.

The immutable requirement is enforced by Active Record by freezing any object assigned as a value object. Attempting to change it afterwards will result in a ActiveSupport::FrozenObjectError.

Read more about value objects on c2.com/cgi/wiki?ValueObject and on the dangers of not keeping value objects immutable on c2.com/cgi/wiki?ValueObjectsShouldBeImmutable

Custom constructors and converters

By default value objects are initialized by calling the new constructor of the value class passing each of the mapped attributes, in the order specified by the :mapping option, as arguments. If the value class doesn‘t support this convention then composed_of allows a custom constructor to be specified.

When a new value is assigned to the value object the default assumption is that the new value is an instance of the value class. Specifying a custom converter allows the new value to be automatically converted to an instance of value class if necessary.

For example, the NetworkResource model has network_address and cidr_range attributes that should be aggregated using the NetAddr::CIDR value class (netaddr.rubyforge.org). The constructor for the value class is called create and it expects a CIDR address string as a parameter. New values can be assigned to the value object using either another NetAddr::CIDR object, a string or an array. The :constructor and :converter options can be used to meet these requirements:

  class NetworkResource < ActiveRecord::Base
    composed_of :cidr,
                :class_name => 'NetAddr::CIDR',
                :mapping => [ %w(network_address network), %w(cidr_range bits) ],
                :allow_nil => true,
                :constructor => Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
                :converter => Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
  end

  # This calls the :constructor
  network_resource = NetworkResource.new(:network_address => '192.168.0.1', :cidr_range => 24)

  # These assignments will both use the :converter
  network_resource.cidr = [ '192.168.2.1', 8 ]
  network_resource.cidr = '192.168.0.1/24'

  # This assignment won't use the :converter as the value is already an instance of the value class
  network_resource.cidr = NetAddr::CIDR.create('192.168.2.1/8')

  # Saving and then reloading will use the :constructor on reload
  network_resource.save
  network_resource.reload

Finding records by a value object

Once a composed_of relationship is specified for a model, records can be loaded from the database by specifying an instance of the value object in the conditions hash. The following example finds all customers with balance_amount equal to 20 and balance_currency equal to "USD":

  Customer.find(:all, :conditions => {:balance => Money.new(20, "USD")})

Methods

composed_of

Public Instance methods

composed_of(part_id, options = {}, &block)

Adds reader and writer methods for manipulating a value object: composed_of :address adds address and address=(new_address) methods.

Options are:

  • :class_name - Specifies the class name of the association. Use it only if that name can‘t be inferred from the part id. So composed_of :address will by default be linked to the Address class, but if the real class name is CompanyAddress, you‘ll have to specify it with this option.
  • :mapping - Specifies the mapping of entity attributes to attributes of the value object. Each mapping is represented as an array where the first item is the name of the entity attribute and the second item is the name the attribute in the value object. The order in which mappings are defined determine the order in which attributes are sent to the value class constructor.
  • :allow_nil - Specifies that the value object will not be instantiated when all mapped attributes are nil. Setting the value object to nil has the effect of writing nil to all mapped attributes. This defaults to false.
  • :constructor - A symbol specifying the name of the constructor method or a Proc that is called to initialize the value object. The constructor is passed all of the mapped attributes, in the order that they are defined in the :mapping option, as arguments and uses them to instantiate a :class_name object. The default is :new.
  • :converter - A symbol specifying the name of a class method of :class_name or a Proc that is called when a new value is assigned to the value object. The converter is passed the single value that is used in the assignment and is only called if the new value is not an instance of :class_name.

Option examples:

  composed_of :temperature, :mapping => %w(reading celsius)
  composed_of :balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new { |balance| balance.to_money }
  composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ]
  composed_of :gps_location
  composed_of :gps_location, :allow_nil => true
  composed_of :ip_address,
              :class_name => 'IPAddr',
              :mapping => %w(ip to_i),
              :constructor => Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
              :converter => Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }

[Source]

     # File vendor/rails/activerecord/lib/active_record/aggregations.rb, line 194
194:       def composed_of(part_id, options = {}, &block)
195:         options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)
196:
197:         name        = part_id.id2name
198:         class_name  = options[:class_name]  || name.camelize
199:         mapping     = options[:mapping]     || [ name, name ]
200:         mapping     = [ mapping ] unless mapping.first.is_a?(Array)
201:         allow_nil   = options[:allow_nil]   || false
202:         constructor = options[:constructor] || :new
203:         converter   = options[:converter]   || block
204:
205:         ActiveSupport::Deprecation.warn('The conversion block has been deprecated, use the :converter option instead.', caller) if block_given?
206:
207:         reader_method(name, class_name, mapping, allow_nil, constructor)
208:         writer_method(name, class_name, mapping, allow_nil, converter)
209:
210:         create_reflection(:composed_of, part_id, options, self)
211:       end


Module: ActiveRecord::AssociationPreload::ClassMethods

Module | ActiveRecord::AssociationPreload::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/association_preload.rb

Implements the details of eager loading of ActiveRecord associations. Application developers should not use this module directly.

ActiveRecord::Base is extended with this module. The source code in ActiveRecord::Base references methods defined in this module.

Note that ‘eager loading’ and ‘preloading’ are actually the same thing. However, there are two different eager loading strategies.

The first one is by using table joins. This was only strategy available prior to Rails 2.1. Suppose that you have an Author model with columns ‘name’ and ‘age’, and a Book model with columns ‘name’ and ‘sales’. Using this strategy, ActiveRecord would try to retrieve all data for an author and all of its books via a single query:

  SELECT * FROM authors
  LEFT OUTER JOIN books ON authors.id = books.id
  WHERE authors.name = 'Ken Akamatsu'

However, this could result in many rows that contain redundant data. After having received the first row, we already have enough data to instantiate the Author object. In all subsequent rows, only the data for the joined ‘books’ table is useful; the joined ‘authors’ data is just redundant, and processing this redundant data takes memory and CPU time. The problem quickly becomes worse and worse as the level of eager loading increases (i.e. if ActiveRecord is to eager load the associations’ assocations as well).

The second strategy is to use multiple database queries, one for each level of association. Since Rails 2.1, this is the default strategy. In situations where a table join is necessary (e.g. when the +:conditions+ option references an association‘s column), it will fallback to the table join strategy.

See also ActiveRecord::Associations::ClassMethods, which explains eager loading in a more high-level (application developer-friendly) manner.

Methods

preload_associations

Protected Instance methods

preload_associations(records, associations, preload_options={})

Eager loads the named associations for the given ActiveRecord record(s).

In this description, ‘association name’ shall refer to the name passed to an association creation method. For example, a model that specifies belongs_to :author, has_many :buyers has association names +:author+ and +:buyers+.

Parameters

records is an array of ActiveRecord::Base. This array needs not be flat, i.e. records itself may also contain arrays of records. In any case, preload_associations will preload the associations all records by flattening records.

associations specifies one or more associations that you want to preload. It may be:

  • a Symbol or a String which specifies a single association name. For example, specifiying +:books+ allows this method to preload all books for an Author.
  • an Array which specifies multiple association names. This array is processed recursively. For example, specifying [:avatar, :books] allows this method to preload an author‘s avatar as well as all of his books.
  • a Hash which specifies multiple association names, as well as association names for the to-be-preloaded association objects. For example, specifying { :author => :avatar } will preload a book‘s author, as well as that author‘s avatar.

+:associations+ has the same format as the +:include+ option for ActiveRecord::Base.find. So associations could look like this:

  :books
  [ :books, :author ]
  { :author => :avatar }
  [ :books, { :author => :avatar } ]

preload_options contains options that will be passed to ActiveRecord#find (which is called under the hood for preloading records). But it is passed only one level deep in the associations argument, i.e. it‘s not passed to the child associations when associations is a Hash.

[Source]

     # File vendor/rails/activerecord/lib/active_record/association_preload.rb, line 86
 86:       def preload_associations(records, associations, preload_options={})
 87:         records = [records].flatten.compact.uniq
 88:         return if records.empty?
 89:         case associations
 90:         when Array then associations.each {|association| preload_associations(records, association, preload_options)}
 91:         when Symbol, String then preload_one_association(records, associations.to_sym, preload_options)
 92:         when Hash then
 93:           associations.each do |parent, child|
 94:             raise "parent must be an association name" unless parent.is_a?(String) || parent.is_a?(Symbol)
 95:             preload_associations(records, parent, preload_options)
 96:             reflection = reflections[parent]
 97:             parents = records.map {|record| record.send(reflection.name)}.flatten.compact
 98:             unless parents.empty?
 99:               parents.first.class.preload_associations(parents, child)
100:             end
101:           end
102:         end
103:       end


Class: ActiveRecord::AssociationTypeMismatch

Class | ActiveRecord::AssociationTypeMismatch
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when an object assigned to an association has an incorrect type.

  class Ticket < ActiveRecord::Base
    has_many :patches
  end

  class Patch < ActiveRecord::Base
    belongs_to :ticket
  end

  # Comments are not patches, this assignment raises AssociationTypeMismatch.
  @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")


Module: ActiveRecord::Associations::ClassMethods

Module | ActiveRecord::Associations::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/associations.rb

Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby‘s own attr* methods. Example:

  class Project < ActiveRecord::Base
    belongs_to              :portfolio
    has_one                 :project_manager
    has_many                :milestones
    has_and_belongs_to_many :categories
  end

The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships:

  • Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?
  • Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,
  • Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone), Project#milestones.delete(milestone), Project#milestones.find(milestone_id), Project#milestones.find(:all, options), Project#milestones.build, Project#milestones.create
  • Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1), Project#categories.delete(category1)

A word of warning

Don‘t create associations that have the same name as instance methods of ActiveRecord::Base. Since the association adds a method with that name to its model, it will override the inherited method and break things. For instance, attributes and connection would be bad choices for association names.

Auto-generated methods

Singular associations (one-to-one)

                                    |            |  belongs_to  |
  generated methods                 | belongs_to | :polymorphic | has_one
  ----------------------------------+------------+--------------+---------
  other                             |     X      |      X       |    X
  other=(other)                     |     X      |      X       |    X
  build_other(attributes={})        |     X      |              |    X
  create_other(attributes={})       |     X      |              |    X
  other.create!(attributes={})      |            |              |    X

Collection associations (one-to-many / many-to-many)

                                    |       |          | has_many
  generated methods                 | habtm | has_many | :through
  ----------------------------------+-------+----------+----------
  others                            |   X   |    X     |    X
  others=(other,other,...)          |   X   |    X     |    X
  other_ids                         |   X   |    X     |    X
  other_ids=(id,id,...)             |   X   |    X     |    X
  others<<                          |   X   |    X     |    X
  others.push                       |   X   |    X     |    X
  others.concat                     |   X   |    X     |    X
  others.build(attributes={})       |   X   |    X     |    X
  others.create(attributes={})      |   X   |    X     |    X
  others.create!(attributes={})     |   X   |    X     |    X
  others.size                       |   X   |    X     |    X
  others.length                     |   X   |    X     |    X
  others.count                      |   X   |    X     |    X
  others.sum(args*,&block)          |   X   |    X     |    X
  others.empty?                     |   X   |    X     |    X
  others.clear                      |   X   |    X     |    X
  others.delete(other,other,...)    |   X   |    X     |    X
  others.delete_all                 |   X   |    X     |
  others.destroy_all                |   X   |    X     |    X
  others.find(*args)                |   X   |    X     |    X
  others.find_first                 |   X   |          |
  others.exists?                    |   X   |    X     |    X
  others.uniq                       |   X   |    X     |    X
  others.reset                      |   X   |    X     |    X

Cardinality and associations

Active Record associations can be used to describe one-to-one, one-to-many and many-to-many relationships between models. Each model uses an association to describe its role in the relation. The belongs_to association is always used in the model that has the foreign key.

One-to-one

Use has_one in the base, and belongs_to in the associated model.

  class Employee < ActiveRecord::Base
    has_one :office
  end
  class Office < ActiveRecord::Base
    belongs_to :employee    # foreign key - employee_id
  end

One-to-many

Use has_many in the base, and belongs_to in the associated model.

  class Manager < ActiveRecord::Base
    has_many :employees
  end
  class Employee < ActiveRecord::Base
    belongs_to :manager     # foreign key - manager_id
  end

Many-to-many

There are two ways to build a many-to-many relationship.

The first way uses a has_many association with the :through option and a join model, so there are two stages of associations.

  class Assignment < ActiveRecord::Base
    belongs_to :programmer  # foreign key - programmer_id
    belongs_to :project     # foreign key - project_id
  end
  class Programmer < ActiveRecord::Base
    has_many :assignments
    has_many :projects, :through => :assignments
  end
  class Project < ActiveRecord::Base
    has_many :assignments
    has_many :programmers, :through => :assignments
  end

For the second way, use has_and_belongs_to_many in both models. This requires a join table that has no corresponding model or primary key.

  class Programmer < ActiveRecord::Base
    has_and_belongs_to_many :projects       # foreign keys in the join table
  end
  class Project < ActiveRecord::Base
    has_and_belongs_to_many :programmers    # foreign keys in the join table
  end

Choosing which way to build a many-to-many relationship is not always simple. If you need to work with the relationship model as its own entity, use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.

Is it a belongs_to or has_one association?

Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class declaring the belongs_to relationship. Example:

  class User < ActiveRecord::Base
    # I reference an account.
    belongs_to :account
  end

  class Account < ActiveRecord::Base
    # One user references me.
    has_one :user
  end

The tables for these classes could look something like:

  CREATE TABLE users (
    id int(11) NOT NULL auto_increment,
    account_id int(11) default NULL,
    name varchar default NULL,
    PRIMARY KEY  (id)
  )

  CREATE TABLE accounts (
    id int(11) NOT NULL auto_increment,
    name varchar default NULL,
    PRIMARY KEY  (id)
  )

Unsaved objects and associations

You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be aware of, mostly involving the saving of associated objects.

Unless you enable the :autosave option on a has_one, belongs_to, has_many, or has_and_belongs_to_many association, in which case the members are always saved.

One-to-one associations

  • Assigning an object to a has_one association automatically saves that object and the object being replaced (if there is one), in order to update their primary keys - except if the parent object is unsaved (new_record? == true).
  • If either of these saves fail (due to one of the objects being invalid) the assignment statement returns false and the assignment is cancelled.
  • If you wish to assign an object to a has_one association without saving it, use the association.build method (documented below).
  • Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does not save the parent either.

Collections

  • Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object (the owner of the collection) is not yet stored in the database.
  • If saving any of the objects being added to a collection (via push or similar) fails, then push returns false.
  • You can add an object to a collection without automatically saving it by using the collection.build method (documented below).
  • All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved.

Association callbacks

Similar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get triggered when you add an object to or remove an object from an association collection. Example:

  class Project
    has_and_belongs_to_many :developers, :after_add => :evaluate_velocity

    def evaluate_velocity(developer)
      ...
    end
  end

It‘s possible to stack callbacks by passing them as an array. Example:

  class Project
    has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
  end

Possible callbacks are: before_add, after_add, before_remove and after_remove.

Should any of the before_add callbacks throw an exception, the object does not get added to the collection. Same with the before_remove callbacks; if an exception is thrown the object doesn‘t get removed.

Association extensions

The proxy objects that control the access to associations can be extended through anonymous modules. This is especially beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this association. Example:

  class Account < ActiveRecord::Base
    has_many :people do
      def find_or_create_by_name(name)
        first_name, last_name = name.split(" ", 2)
        find_or_create_by_first_name_and_last_name(first_name, last_name)
      end
    end
  end

  person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson")
  person.first_name # => "David"
  person.last_name  # => "Heinemeier Hansson"

If you need to share the same extensions between many associations, you can use a named extension module. Example:

  module FindOrCreateByNameExtension
    def find_or_create_by_name(name)
      first_name, last_name = name.split(" ", 2)
      find_or_create_by_first_name_and_last_name(first_name, last_name)
    end
  end

  class Account < ActiveRecord::Base
    has_many :people, :extend => FindOrCreateByNameExtension
  end

  class Company < ActiveRecord::Base
    has_many :people, :extend => FindOrCreateByNameExtension
  end

If you need to use multiple named extension modules, you can specify an array of modules with the :extend option. In the case of name conflicts between methods in the modules, methods in modules later in the array supercede those earlier in the array. Example:

  class Account < ActiveRecord::Base
    has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
  end

Some extensions can only be made to work with knowledge of the association proxy‘s internals. Extensions can access relevant state using accessors on the association proxy:

  • proxy_owner - Returns the object the association is part of.
  • proxy_reflection - Returns the reflection object that describes the association.
  • proxy_target - Returns the associated object for belongs_to and has_one, or the collection of associated objects for has_many and has_and_belongs_to_many.

Association Join Models

Has Many associations can be configured with the :through option to use an explicit join model to retrieve the data. This operates similarly to a has_and_belongs_to_many association. The advantage is that you‘re able to add validations, callbacks, and extra attributes on the join model. Consider the following schema:

  class Author < ActiveRecord::Base
    has_many :authorships
    has_many :books, :through => :authorships
  end

  class Authorship < ActiveRecord::Base
    belongs_to :author
    belongs_to :book
  end

  @author = Author.find :first
  @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to.
  @author.books                              # selects all books by using the Authorship join model

You can also go through a has_many association on the join model:

  class Firm < ActiveRecord::Base
    has_many   :clients
    has_many   :invoices, :through => :clients
  end

  class Client < ActiveRecord::Base
    belongs_to :firm
    has_many   :invoices
  end

  class Invoice < ActiveRecord::Base
    belongs_to :client
  end

  @firm = Firm.find :first
  @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm
  @firm.invoices                                   # selects all invoices by going through the Client join model.

Polymorphic Associations

Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they specify an interface that a has_many association must adhere to.

  class Asset < ActiveRecord::Base
    belongs_to :attachable, :polymorphic => true
  end

  class Post < ActiveRecord::Base
    has_many :assets, :as => :attachable         # The :as option specifies the polymorphic interface to use.
  end

  @asset.attachable = @post

This works by using a type column in addition to a foreign key to specify the associated record. In the Asset example, you‘d need an attachable_id integer column and an attachable_type string column.

Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts and member posts that use the posts table for STI. In this case, there must be a type column in the posts table.

  class Asset < ActiveRecord::Base
    belongs_to :attachable, :polymorphic => true

    def attachable_type=(sType)
       super(sType.to_s.classify.constantize.base_class.to_s)
    end
  end

  class Post < ActiveRecord::Base
    # because we store "Post" in attachable_type now :dependent => :destroy will work
    has_many :assets, :as => :attachable, :dependent => :destroy
  end

  class GuestPost < Post
  end

  class MemberPost < Post
  end

Caching

All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without worrying too much about performance at the first go. Example:

  project.milestones             # fetches milestones from the database
  project.milestones.size        # uses the milestone cache
  project.milestones.empty?      # uses the milestone cache
  project.milestones(true).size  # fetches milestones from the database
  project.milestones             # uses the milestone cache

Eager loading of associations

Eager loading is a way to find objects of a certain class and a number of named associations. This is one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100 posts that each need to display their author triggers 101 database queries. Through the use of eager loading, the 101 queries can be reduced to 2. Example:

  class Post < ActiveRecord::Base
    belongs_to :author
    has_many   :comments
  end

Consider the following loop using the class above:

  for post in Post.all
    puts "Post:            " + post.title
    puts "Written by:      " + post.author.name
    puts "Last comment on: " + post.comments.first.created_on
  end

To iterate over these one hundred posts, we‘ll generate 201 database queries. Let‘s first just optimize it for retrieving the author:

  for post in Post.find(:all, :include => :author)

This references the name of the belongs_to association that also used the :author symbol. After loading the posts, find will collect the author_id from each one and load all the referenced authors with one query. Doing so will cut down the number of queries from 201 to 102.

We can improve upon the situation further by referencing both associations in the finder with:

  for post in Post.find(:all, :include => [ :author, :comments ])

This will load all comments with a single query. This reduces the total number of queries to 3. More generally the number of queries will be 1 plus the number of associations named (except if some of the associations are polymorphic belongs_to - see below).

To include a deep hierarchy of associations, use a hash:

  for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])

That‘ll grab not only all the comments but all their authors and gravatar pictures. You can mix and match symbols, arrays and hashes in any combination to describe the associations you want to load.

All of this power shouldn‘t fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you‘ve reduced the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it‘s no catch-all for performance problems, but it‘s a great way to cut down on the number of queries in a situation as the one described above.

Since only one table is loaded at a time, conditions or orders cannot reference tables other than the main one. If this is the case Active Record falls back to the previously used LEFT OUTER JOIN based strategy. For example

  Post.find(:all, :include => [ :author, :comments ], :conditions => ['comments.approved = ?', true])

will result in a single SQL query with joins along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id and LEFT OUTER JOIN authors ON authors.id = posts.author_id. Note that using conditions like this can have unintended consequences. In the above example posts with no approved comments are not returned at all, because the conditions apply to the SQL statement as a whole and not just to the association. You must disambiguate column references for this fallback to happen, for example :order => "author.name DESC" will work but :order => "name DESC" will not.

If you do want eagerload only some members of an association it is usually more natural to :include an association which has conditions defined on it:

  class Post < ActiveRecord::Base
    has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true]
  end

  Post.find(:all, :include => :approved_comments)

will load posts and eager load the approved_comments association, which contains only those comments that have been approved.

If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects:

  class Picture < ActiveRecord::Base
    has_many :most_recent_comments, :class_name => 'Comment', :order => 'id DESC', :limit => 10
  end

  Picture.find(:first, :include => :most_recent_comments).most_recent_comments # => returns all associated comments.

When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated before the actual model exists.

Eager loading is supported with polymorphic associations.

  class Address < ActiveRecord::Base
    belongs_to :addressable, :polymorphic => true
  end

A call that tries to eager load the addressable model

  Address.find(:all, :include => :addressable)

will execute one query to load the addresses and load the addressables with one query per addressable type. For example if all the addressables are either of class Person or Company then a total of 3 queries will be executed. The list of addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent model‘s type is a column value so its corresponding table name cannot be put in the FROM/JOIN clauses of that query.

Table Aliasing

Active Record uses table aliasing in the case that a table is referenced multiple times in a join. If a table is referenced only once, the standard table name is used. The second time, the table is aliased as #{reflection_name}_#{parent_table_name}. Indexes are appended for any more successive uses of the table name.

  Post.find :all, :joins => :comments
  # => SELECT ... FROM posts INNER JOIN comments ON ...
  Post.find :all, :joins => :special_comments # STI
  # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
  Post.find :all, :joins => [:comments, :special_comments] # special_comments is the reflection name, posts is the parent table name
  # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts

Acts as tree example:

  TreeMixin.find :all, :joins => :children
  # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
  TreeMixin.find :all, :joins => {:children => :parent}
  # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
                              INNER JOIN parents_mixins ...
  TreeMixin.find :all, :joins => {:children => {:parent => :children}}
  # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
                              INNER JOIN parents_mixins ...
                              INNER JOIN mixins childrens_mixins_2

Has and Belongs to Many join tables use the same idea, but add a _join suffix:

  Post.find :all, :joins => :categories
  # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
  Post.find :all, :joins => {:categories => :posts}
  # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
                             INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
  Post.find :all, :joins => {:categories => {:posts => :categories}}
  # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
                             INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
                             INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2

If you wish to specify your own custom joins using a :joins option, those table names will take precedence over the eager associations:

  Post.find :all, :joins => :comments, :joins => "inner join comments ..."
  # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
  Post.find :all, :joins => [:comments, :special_comments], :joins => "inner join comments ..."
  # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
                             INNER JOIN comments special_comments_posts ...
                             INNER JOIN comments ...

Table aliases are automatically truncated according to the maximum length of table identifiers according to the specific database.

Modules

By default, associations will look for objects within the current module scope. Consider:

  module MyApplication
    module Business
      class Firm < ActiveRecord::Base
         has_many :clients
       end

      class Client < ActiveRecord::Base; end
    end
  end

When Firm#clients is called, it will in turn call MyApplication::Business::Client.find_all_by_firm_id(firm.id). If you want to associate with a class in another module scope, this can be done by specifying the complete class name. Example:

  module MyApplication
    module Business
      class Firm < ActiveRecord::Base; end
    end

    module Billing
      class Account < ActiveRecord::Base
        belongs_to :firm, :class_name => "MyApplication::Business::Firm"
      end
    end
  end

Type safety with ActiveRecord::AssociationTypeMismatch

If you attempt to assign an object to an association that doesn‘t match the inferred or specified :class_name, you‘ll get an ActiveRecord::AssociationTypeMismatch.

Options

All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones possible.

Methods

belongs_to has_and_belongs_to_many has_many has_one

Public Instance methods

belongs_to(association_id, options = {})

Specifies a one-to-one association with another class. This method should only be used if this class contains the foreign key. If the other class contains the foreign key, then you should use has_one instead. See also ActiveRecord::Associations::ClassMethods‘s overview on when to use has_one and when to use belongs_to.

Methods will be added for retrieval and query for a single associated object, for which this object holds an id:

association(force_reload = false)
Returns the associated object. nil is returned if none is found.
association=(associate)
Assigns the associate object, extracts the primary key, and sets it as the foreign key.
build_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved.
create_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).

(association is replaced with the symbol passed as the first argument, so belongs_to :author would add among others author.nil?.)

Example

A Post class declares belongs_to :author, which will add:

  • Post#author (similar to Author.find(author_id))
  • Post#author=(author) (similar to post.author_id = author.id)
  • Post#author? (similar to post.author == some_author)
  • Post#build_author (similar to post.author = Author.new)
  • Post#create_author (similar to post.author = Author.new; post.author.save; post.author)

The declaration can also include an options hash to specialize the behavior of the association.

Options

:class_name
Specify the class name of the association. Use it only if that name can‘t be inferred from the association name. So has_one :author will by default be linked to the Author class, but if the real class name is Person, you‘ll have to specify it with this option.
:conditions
Specify the conditions that the associated object must meet in order to be included as a WHERE SQL fragment, such as authorized = 1.
:select
By default, this is * as in SELECT * FROM, but can be changed if, for example, you want to do a join but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
:foreign_key
Specify the foreign key used for the association. By default this is guessed to be the name of the association with an "_id" suffix. So a class that defines a belongs_to :person association will use "person_id" as the default :foreign_key. Similarly, belongs_to :favorite_person, :class_name => "Person" will use a foreign key of "favorite_person_id".
:dependent
If set to :destroy, the associated object is destroyed when this object is. If set to :delete, the associated object is deleted without calling its destroy method. This option should not be specified when belongs_to is used in conjunction with a has_many relationship on another class because of the potential to leave orphaned records behind.
:counter_cache
Caches the number of belonging objects on the associate class through the use of increment_counter and decrement_counter. The counter cache is incremented when an object of this class is created and decremented when it‘s destroyed. This requires that a column named #{table_name}_count (such as comments_count for a belonging Comment class) is used on the associate class (such as a Post class). You can also specify a custom counter cache column by providing a column name instead of a true/false value to this option (e.g., :counter_cache => :my_custom_counter.) Note: Specifying a counter cache will add it to that model‘s list of readonly attributes using attr_readonly.
:include
Specify second-order associations that should be eager loaded when this object is loaded.
:polymorphic
Specify this association is a polymorphic association by passing true. Note: If you‘ve enabled the counter cache, then you may want to add the counter cache attribute to the attr_readonly list in the associated classes (e.g. class Post; attr_readonly :comments_count; end).
:readonly
If true, the associated object is readonly through the association.
:validate
If false, don‘t validate the associated objects when saving the parent object. false by default.
:autosave
If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default.

Option examples:

  belongs_to :firm, :foreign_key => "client_of"
  belongs_to :author, :class_name => "Person", :foreign_key => "author_id"
  belongs_to :valid_coupon, :class_name => "Coupon", :foreign_key => "coupon_id",
             :conditions => 'discounts > #{payments_count}'
  belongs_to :attachable, :polymorphic => true
  belongs_to :project, :readonly => true
  belongs_to :post, :counter_cache => true

[Source]

      # File vendor/rails/activerecord/lib/active_record/associations.rb, line 993
 993:       def belongs_to(association_id, options = {})
 994:         reflection = create_belongs_to_reflection(association_id, options)
 995:
 996:         if reflection.options[:polymorphic]
 997:           association_accessor_methods(reflection, BelongsToPolymorphicAssociation)
 998:         else
 999:           association_accessor_methods(reflection, BelongsToAssociation)
1000:           association_constructor_method(:build,  reflection, BelongsToAssociation)
1001:           association_constructor_method(:create, reflection, BelongsToAssociation)
1002:         end
1003:
1004:         # Create the callbacks to update counter cache
1005:         if options[:counter_cache]
1006:           cache_column = reflection.counter_cache_column
1007:
1008:           method_name = "belongs_to_counter_cache_after_create_for_#{reflection.name}".to_sym
1009:           define_method(method_name) do
1010:             association = send(reflection.name)
1011:             association.class.increment_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
1012:           end
1013:           after_create method_name
1014:
1015:           method_name = "belongs_to_counter_cache_before_destroy_for_#{reflection.name}".to_sym
1016:           define_method(method_name) do
1017:             association = send(reflection.name)
1018:             association.class.decrement_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
1019:           end
1020:           before_destroy method_name
1021:
1022:           module_eval(
1023:             "#{reflection.class_name}.send(:attr_readonly,\"#{cache_column}\".intern) if defined?(#{reflection.class_name}) && #{reflection.class_name}.respond_to?(:attr_readonly)"
1024:           )
1025:         end
1026:
1027:         configure_dependency_for_belongs_to(reflection)
1028:       end
has_and_belongs_to_many(association_id, options = {}, &extension)

Specifies a many-to-many relationship with another class. This associates two classes via an intermediate join table. Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names. So a join between Developer and Project will give the default join table name of "developers_projects" because "D" outranks "P". Note that this precedence is calculated using the < operator for String. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the custom :join_table option if you need to.

The join table should not have a primary key or a model associated with it. You must manually generate the join table with a migration such as this:

  class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
    def self.up
      create_table :developers_projects, :id => false do |t|
        t.integer :developer_id
        t.integer :project_id
      end
    end

    def self.down
      drop_table :developers_projects
    end
  end

Deprecated: Any additional fields added to the join table will be placed as attributes when pulling records out through has_and_belongs_to_many associations. Records returned from join tables with additional attributes will be marked as readonly (because we can‘t save changes to the additional attributes). It‘s strongly recommended that you upgrade any associations with attributes to a real join model (see introduction).

Adds the following methods for retrieval and query:

collection(force_reload = false)
Returns an array of all the associated objects. An empty array is returned if none are found.
collection<<(object, …)
Adds one or more objects to the collection by creating associations in the join table (collection.push and collection.concat are aliases to this method).
collection.delete(object, …)
Removes one or more objects from the collection by removing their associations from the join table. This does not destroy the objects.
collection=objects
Replaces the collection‘s content by deleting and adding objects as appropriate.
collection_singular_ids
Returns an array of the associated objects’ ids.
collection_singular_ids=ids
Replace the collection by the objects identified by the primary keys in ids.
collection.clear
Removes every object from the collection. This does not destroy the objects.
collection.empty?
Returns true if there are no associated objects.
collection.size
Returns the number of associated objects.
collection.find(id)
Finds an associated object responding to the id and that meets the condition that it has to be associated with this object. Uses the same rules as ActiveRecord::Base.find.
collection.exists?(…)
Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::Base.exists?.
collection.build(attributes = {})
Returns a new object of the collection type that has been instantiated with attributes and linked to this object through the join table, but has not yet been saved.
collection.create(attributes = {})
Returns a new object of the collection type that has been instantiated with attributes, linked to this object through the join table, and that has already been saved (if it passed the validation).

(collection is replaced with the symbol passed as the first argument, so has_and_belongs_to_many :categories would add among others categories.empty?.)

Example

A Developer class declares has_and_belongs_to_many :projects, which will add:

  • Developer#projects
  • Developer#projects<<
  • Developer#projects.delete
  • Developer#projects=
  • Developer#project_ids
  • Developer#project_ids=
  • Developer#projects.clear
  • Developer#projects.empty?
  • Developer#projects.size
  • Developer#projects.find(id)
  • Developer#clients.exists?(…)
  • Developer#projects.build (similar to Project.new("project_id" => id))
  • Developer#projects.create (similar to c = Project.new("project_id" => id); c.save; c)

The declaration may include an options hash to specialize the behavior of the association.

Options

:class_name
Specify the class name of the association. Use it only if that name can‘t be inferred from the association name. So has_and_belongs_to_many :projects will by default be linked to the Project class, but if the real class name is SuperProject, you‘ll have to specify it with this option.
:join_table
Specify the name of the join table if the default based on lexical order isn‘t what you want. WARNING: If you‘re overwriting the table name of either class, the table_name method MUST be declared underneath any has_and_belongs_to_many declaration in order to work.
:foreign_key
Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and "_id" suffixed. So a Person class that makes a has_and_belongs_to_many association to Project will use "person_id" as the default :foreign_key.
:association_foreign_key
Specify the foreign key used for the association on the receiving side of the association. By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed. So if a Person class makes a has_and_belongs_to_many association to Project, the association will use "project_id" as the default :association_foreign_key.
:conditions
Specify the conditions that the associated object must meet in order to be included as a WHERE SQL fragment, such as authorized = 1. Record creations from the association are scoped if a hash is used. has_many :posts, :conditions => {:published => true} will create published posts with @blog.posts.create or @blog.posts.build.
:order
Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, such as last_name, first_name DESC
:uniq
If true, duplicate associated objects will be ignored by accessors and query methods.
:finder_sql
Overwrite the default generated SQL statement used to fetch the association with a manual statement
:counter_sql
Specify a complete SQL statement to fetch the size of the association. If :finder_sql is specified but not :counter_sql, :counter_sql will be generated by replacing SELECT … FROM with SELECT COUNT(*) FROM.
:delete_sql
Overwrite the default generated SQL statement used to remove links between the associated classes with a manual statement.
:insert_sql
Overwrite the default generated SQL statement used to add links between the associated classes with a manual statement.
:extend
Anonymous module for extending the proxy, see "Association extensions".
:include
Specify second-order associations that should be eager loaded when the collection is loaded.
:group
An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
:having
Combined with +:group+ this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause.
:limit
An integer determining the limit on the number of rows that should be returned.
:offset
An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
:select
By default, this is * as in SELECT * FROM, but can be changed if, for example, you want to do a join but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
:readonly
If true, all the associated objects are readonly through the association.
:validate
If false, don‘t validate the associated objects when saving the parent object. true by default.
:autosave
If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default.

Option examples:

  has_and_belongs_to_many :projects
  has_and_belongs_to_many :projects, :include => [ :milestones, :manager ]
  has_and_belongs_to_many :nations, :class_name => "Country"
  has_and_belongs_to_many :categories, :join_table => "prods_cats"
  has_and_belongs_to_many :categories, :readonly => true
  has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql =>
  'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}'

[Source]

      # File vendor/rails/activerecord/lib/active_record/associations.rb, line 1190
1190:       def has_and_belongs_to_many(association_id, options = {}, &extension)
1191:         reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
1192:         collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
1193:
1194:         # Don't use a before_destroy callback since users' before_destroy
1195:         # callbacks will be executed after the association is wiped out.
1196:         old_method = "destroy_without_habtm_shim_for_#{reflection.name}"
1197:         class_eval "alias_method :\#{old_method}, :destroy_without_callbacks  # alias_method :destroy_without_habtm_shim_for_posts, :destroy_without_callbacks\ndef destroy_without_callbacks                            # def destroy_without_callbacks\n\#{reflection.name}.clear                               #   posts.clear\n\#{old_method}                                          #   destroy_without_habtm_shim_for_posts\nend                                                      # end\n" unless method_defined?(old_method)
1198:
1199:         add_association_callbacks(reflection.name, options)
1200:       end
has_many(association_id, options = {}, &extension)

Specifies a one-to-many association. The following methods for retrieval and query of collections of associated objects will be added:

collection(force_reload = false)
Returns an array of all the associated objects. An empty array is returned if none are found.
collection<<(object, …)
Adds one or more objects to the collection by setting their foreign keys to the collection‘s primary key.
collection.delete(object, …)
Removes one or more objects from the collection by setting their foreign keys to NULL. Objects will be in addition destroyed if they‘re associated with :dependent => :destroy, and deleted if they‘re associated with :dependent => :delete_all.
collection=objects
Replaces the collections content by deleting and adding objects as appropriate.
collection_singular_ids
Returns an array of the associated objects’ ids
collection_singular_ids=ids
Replace the collection with the objects identified by the primary keys in ids
collection.clear
Removes every object from the collection. This destroys the associated objects if they are associated with :dependent => :destroy, deletes them directly from the database if :dependent => :delete_all, otherwise sets their foreign keys to NULL.
collection.empty?
Returns true if there are no associated objects.
collection.size
Returns the number of associated objects.
collection.find(...)
Finds an associated object according to the same rules as ActiveRecord::Base.find.
collection.exists?(…)
Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::Base.exists?.
collection.build(attributes = {}, …)
Returns one or more new objects of the collection type that have been instantiated with attributes and linked to this object through a foreign key, but have not yet been saved. Note: This only works if an associated object already exists, not if it‘s nil!
collection.create(attributes = {})
Returns a new object of the collection type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation). Note: This only works if an associated object already exists, not if it‘s nil!

(Note: collection is replaced with the symbol passed as the first argument, so has_many :clients would add among others clients.empty?.)

Example

Example: A Firm class declares has_many :clients, which will add:

  • Firm#clients (similar to Clients.find :all, :conditions => ["firm_id = ?", id])
  • Firm#clients<<
  • Firm#clients.delete
  • Firm#clients=
  • Firm#client_ids
  • Firm#client_ids=
  • Firm#clients.clear
  • Firm#clients.empty? (similar to firm.clients.size == 0)
  • Firm#clients.size (similar to Client.count "firm_id = #{id}")
  • Firm#clients.find (similar to Client.find(id, :conditions => "firm_id = #{id}"))
  • Firm#clients.exists?(:name => ‘ACME’) (similar to Client.exists?(:name => ‘ACME’, :firm_id => firm.id))
  • Firm#clients.build (similar to Client.new("firm_id" => id))
  • Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c)

The declaration can also include an options hash to specialize the behavior of the association.

Supported options

:class_name
Specify the class name of the association. Use it only if that name can‘t be inferred from the association name. So has_many :products will by default be linked to the Product class, but if the real class name is SpecialProduct, you‘ll have to specify it with this option.
:conditions
Specify the conditions that the associated objects must meet in order to be included as a WHERE SQL fragment, such as price > 5 AND name LIKE ‘B%’. Record creations from the association are scoped if a hash is used. has_many :posts, :conditions => {:published => true} will create published posts with @blog.posts.create or @blog.posts.build.
:order
Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, such as last_name, first_name DESC.
:foreign_key
Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and "_id" suffixed. So a Person class that makes a has_many association will use "person_id" as the default :foreign_key.
:primary_key
Specify the method that returns the primary key used for the association. By default this is id.
:dependent
If set to :destroy all the associated objects are destroyed alongside this object by calling their destroy method. If set to :delete_all all associated objects are deleted without calling their destroy method. If set to :nullify all associated objects’ foreign keys are set to NULL without calling their save callbacks. *Warning:* This option is ignored when also using the :through option.
:finder_sql
Specify a complete SQL statement to fetch the association. This is a good way to go for complex associations that depend on multiple tables. Note: When this option is used, find_in_collection is not added.
:counter_sql
Specify a complete SQL statement to fetch the size of the association. If :finder_sql is specified but not :counter_sql, :counter_sql will be generated by replacing SELECT … FROM with SELECT COUNT(*) FROM.
:extend
Specify a named module for extending the proxy. See "Association extensions".
:include
Specify second-order associations that should be eager loaded when the collection is loaded.
:group
An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
:having
Combined with +:group+ this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause.
:limit
An integer determining the limit on the number of rows that should be returned.
:offset
An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
:select
By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
:as
Specifies a polymorphic interface (See belongs_to).
:through
Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key are ignored, as the association uses the source reflection. You can only use a :through query through a belongs_to or has_many association on the join model.
:source
Specifies the source association name used by has_many :through queries. Only use it if the name cannot be inferred from the association. has_many :subscribers, :through => :subscriptions will look for either :subscribers or :subscriber on Subscription, unless a :source is given.
:source_type
Specifies type of the source association used by has_many :through queries where the source association is a polymorphic belongs_to.
:uniq
If true, duplicates will be omitted from the collection. Useful in conjunction with :through.
:readonly
If true, all the associated objects are readonly through the association.
:validate
If false, don‘t validate the associated objects when saving the parent object. true by default.
:autosave
If true, always save any loaded members and destroy members marked for destruction, when saving the parent object. Off by default.

Option examples:

  has_many :comments, :order => "posted_on"
  has_many :comments, :include => :author
  has_many :people, :class_name => "Person", :conditions => "deleted = 0", :order => "name"
  has_many :tracks, :order => "position", :dependent => :destroy
  has_many :comments, :dependent => :nullify
  has_many :tags, :as => :taggable
  has_many :reports, :readonly => true
  has_many :subscribers, :through => :subscriptions, :source => :user
  has_many :subscribers, :class_name => "Person", :finder_sql =>
      'SELECT DISTINCT people.* ' +
      'FROM people p, post_subscriptions ps ' +
      'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' +
      'ORDER BY p.first_name'

[Source]

     # File vendor/rails/activerecord/lib/active_record/associations.rb, line 793
793:       def has_many(association_id, options = {}, &extension)
794:         reflection = create_has_many_reflection(association_id, options, &extension)
795:         configure_dependency_for_has_many(reflection)
796:         add_association_callbacks(reflection.name, reflection.options)
797:
798:         if options[:through]
799:           collection_accessor_methods(reflection, HasManyThroughAssociation)
800:         else
801:           collection_accessor_methods(reflection, HasManyAssociation)
802:         end
803:       end
has_one(association_id, options = {})

Specifies a one-to-one association with another class. This method should only be used if the other class contains the foreign key. If the current class contains the foreign key, then you should use belongs_to instead. See also ActiveRecord::Associations::ClassMethods‘s overview on when to use has_one and when to use belongs_to.

The following methods for retrieval and query of a single associated object will be added:

association(force_reload = false)
Returns the associated object. nil is returned if none is found.
association=(associate)
Assigns the associate object, extracts the primary key, sets it as the foreign key, and saves the associate object.
build_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved. Note: This ONLY works if an association already exists. It will NOT work if the association is nil.
create_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).

(association is replaced with the symbol passed as the first argument, so has_one :manager would add among others manager.nil?.)

Example

An Account class declares has_one :beneficiary, which will add:

  • Account#beneficiary (similar to Beneficiary.find(:first, :conditions => "account_id = #{id}"))
  • Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save)
  • Account#build_beneficiary (similar to Beneficiary.new("account_id" => id))
  • Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b)

Options

The declaration can also include an options hash to specialize the behavior of the association.

Options are:

:class_name
Specify the class name of the association. Use it only if that name can‘t be inferred from the association name. So has_one :manager will by default be linked to the Manager class, but if the real class name is Person, you‘ll have to specify it with this option.
:conditions
Specify the conditions that the associated object must meet in order to be included as a WHERE SQL fragment, such as rank = 5.
:order
Specify the order in which the associated objects are returned as an ORDER BY SQL fragment, such as last_name, first_name DESC.
:dependent
If set to :destroy, the associated object is destroyed when this object is. If set to :delete, the associated object is deleted without calling its destroy method. If set to :nullify, the associated object‘s foreign key is set to NULL. Also, association is assigned.
:foreign_key
Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and "_id" suffixed. So a Person class that makes a has_one association will use "person_id" as the default :foreign_key.
:primary_key
Specify the method that returns the primary key used for the association. By default this is id.
:include
Specify second-order associations that should be eager loaded when this object is loaded.
:as
Specifies a polymorphic interface (See belongs_to).
:select
By default, this is * as in SELECT * FROM, but can be changed if, for example, you want to do a join but not include the joined columns. Do not forget to include the primary and foreign keys, otherwise it will raise an error.
:through
Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key are ignored, as the association uses the source reflection. You can only use a :through query through a has_one or belongs_to association on the join model.
:source
Specifies the source association name used by has_one :through queries. Only use it if the name cannot be inferred from the association. has_one :favorite, :through => :favorites will look for a :favorite on Favorite, unless a :source is given.
:source_type
Specifies type of the source association used by has_one :through queries where the source association is a polymorphic belongs_to.
:readonly
If true, the associated object is readonly through the association.
:validate
If false, don‘t validate the associated object when saving the parent object. false by default.
:autosave
If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. Off by default.

Option examples:

  has_one :credit_card, :dependent => :destroy  # destroys the associated credit card
  has_one :credit_card, :dependent => :nullify  # updates the associated records foreign key value to NULL rather than destroying it
  has_one :last_comment, :class_name => "Comment", :order => "posted_on"
  has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'"
  has_one :attachment, :as => :attachable
  has_one :boss, :readonly => :true
  has_one :club, :through => :membership
  has_one :primary_address, :through => :addressables, :conditions => ["addressable.primary = ?", true], :source => :addressable

[Source]

     # File vendor/rails/activerecord/lib/active_record/associations.rb, line 897
897:       def has_one(association_id, options = {})
898:         if options[:through]
899:           reflection = create_has_one_through_reflection(association_id, options)
900:           association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation)
901:         else
902:           reflection = create_has_one_reflection(association_id, options)
903:           association_accessor_methods(reflection, HasOneAssociation)
904:           association_constructor_method(:build,  reflection, HasOneAssociation)
905:           association_constructor_method(:create, reflection, HasOneAssociation)
906:           configure_dependency_for_has_one(reflection)
907:         end
908:       end


Class: ActiveRecord::Associations::ClassMethods::InnerJoinDependency::InnerJoinAssociation

Class | ActiveRecord::Associations::ClassMethods::InnerJoinDependency::InnerJoinAssociation
In: | vendor/rails/activerecord/lib/active_record/associations.rb
Parent: | JoinAssociation


Class: ActiveRecord::Associations::HasOneThroughAssociation

Class | ActiveRecord::Associations::HasOneThroughAssociation
In: | vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb
Parent: | HasManyThroughAssociation


Class: ActiveRecord::AttributeAssignmentError

Class | ActiveRecord::AttributeAssignmentError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when an error occurred while doing a mass assignment to an attribute through the attributes= method. The exception has an attribute property that is the name of the offending attribute.

Methods

new

Attributes

attribute | [R]
exception | [R]

Public Class methods

new(message, exception, attribute)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 134
134:     def initialize(message, exception, attribute)
135:       @exception = exception
136:       @attribute = attribute
137:       @message = message
138:     end


Module: ActiveRecord::AttributeMethods::ClassMethods

Module | ActiveRecord::AttributeMethods::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/attribute_methods.rb

Declare and check for suffixed attribute methods.

Methods

attribute_method_suffix cache_attribute? cache_attributes cached_attributes define_attribute_methods define_read_methods generated_methods? instance_method_already_implemented? match_attribute_method?

Public Instance methods

attribute_method_suffix(*suffixes)

Declares a method available for all attributes with the given suffix. Uses method_missing and respond_to? to rewrite the method

  #{attr}#{suffix}(*args, &block)

to

  attribute#{suffix}(#{attr}, *args, &block)

An attribute#{suffix} instance method must exist and accept at least the attr argument.

For example:

  class Person < ActiveRecord::Base
    attribute_method_suffix '_changed?'

    private
      def attribute_changed?(attr)
        ...
      end
  end

  person = Person.find(1)
  person.name_changed?    # => false
  person.name = 'Hubert'
  person.name_changed?    # => true

[Source]

    # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 46
46:       def attribute_method_suffix(*suffixes)
47:         attribute_method_suffixes.concat suffixes
48:         rebuild_attribute_method_regexp
49:       end
cache_attribute?(attr_name)

Returns true if the provided attribute is being cached.

[Source]

     # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 125
125:       def cache_attribute?(attr_name)
126:         cached_attributes.include?(attr_name)
127:       end
cache_attributes(*attribute_names)

cache_attributes allows you to declare which converted attribute values should be cached. Usually caching only pays off for attributes with expensive conversion methods, like time related columns (e.g. created_at, updated_at).

[Source]

     # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 113
113:       def cache_attributes(*attribute_names)
114:         attribute_names.each {|attr| cached_attributes << attr.to_s}
115:       end
cached_attributes()

Returns the attributes which are cached. By default time related columns with datatype :datetime, :timestamp, :time, :date are cached.

[Source]

     # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 119
119:       def cached_attributes
120:         @cached_attributes ||=
121:           columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map(&:name).to_set
122:       end
define_attribute_methods()

Generates all the attribute related methods for columns in the database accessors, mutators and query methods.

[Source]

    # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 69
69:       def define_attribute_methods
70:         return if generated_methods?
71:         columns_hash.each do |name, column|
72:           unless instance_method_already_implemented?(name)
73:             if self.serialized_attributes[name]
74:               define_read_method_for_serialized_attribute(name)
75:             elsif create_time_zone_conversion_attribute?(name, column)
76:               define_read_method_for_time_zone_conversion(name)
77:             else
78:               define_read_method(name.to_sym, name, column)
79:             end
80:           end
81:
82:           unless instance_method_already_implemented?("#{name}=")
83:             if create_time_zone_conversion_attribute?(name, column)
84:               define_write_method_for_time_zone_conversion(name)
85:             else
86:               define_write_method(name.to_sym)
87:             end
88:           end
89:
90:           unless instance_method_already_implemented?("#{name}?")
91:             define_question_method(name)
92:           end
93:         end
94:       end
define_read_methods()

Alias for define_attribute_methods

generated_methods?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 63
63:       def generated_methods?
64:         !generated_methods.empty?
65:       end
instance_method_already_implemented?(method_name)

Checks whether the method is defined in the model or any of its subclasses that also derive from Active Record. Raises DangerousAttributeError if the method is defined by Active Record though.

[Source]

     # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 99
 99:       def instance_method_already_implemented?(method_name)
100:         method_name = method_name.to_s
101:         return true if method_name =~ /^id(=$|\?$|$)/
102:         @_defined_class_methods         ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.map(&:to_s).to_set
103:         @@_defined_activerecord_methods ||= (ActiveRecord::Base.public_instance_methods(false) | ActiveRecord::Base.private_instance_methods(false) | ActiveRecord::Base.protected_instance_methods(false)).map(&:to_s).to_set
104:         raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord" if @@_defined_activerecord_methods.include?(method_name)
105:         @_defined_class_methods.include?(method_name)
106:       end
match_attribute_method?(method_name)

Returns MatchData if method_name is an attribute method.

[Source]

    # File vendor/rails/activerecord/lib/active_record/attribute_methods.rb, line 52
52:       def match_attribute_method?(method_name)
53:         rebuild_attribute_method_regexp unless defined?(@@attribute_method_regexp) && @@attribute_method_regexp
54:         @@attribute_method_regexp.match(method_name)
55:       end


Module: ActiveRecord::AutosaveAssociation

Module | ActiveRecord::AutosaveAssociation
In: | vendor/rails/activerecord/lib/active_record/autosave_association.rb

AutosaveAssociation is a module that takes care of automatically saving your associations when the parent is saved. In addition to saving, it also destroys any associations that were marked for destruction. (See mark_for_destruction and marked_for_destruction?)

Saving of the parent, its associations, and the destruction of marked associations, all happen inside 1 transaction. This should never leave the database in an inconsistent state after, for instance, mass assigning attributes and saving them.

If validations for any of the associations fail, their error messages will be applied to the parent.

Note that it also means that associations marked for destruction won‘t be destroyed directly. They will however still be marked for destruction.

One-to-one Example

Consider a Post model with one Author:

  class Post
    has_one :author, :autosave => true
  end

Saving changes to the parent and its associated model can now be performed automatically and atomically:

  post = Post.find(1)
  post.title # => "The current global position of migrating ducks"
  post.author.name # => "alloy"

  post.title = "On the migration of ducks"
  post.author.name = "Eloy Duran"

  post.save
  post.reload
  post.title # => "On the migration of ducks"
  post.author.name # => "Eloy Duran"

Destroying an associated model, as part of the parent‘s save action, is as simple as marking it for destruction:

  post.author.mark_for_destruction
  post.author.marked_for_destruction? # => true

Note that the model is not yet removed from the database:

  id = post.author.id
  Author.find_by_id(id).nil? # => false

  post.save
  post.reload.author # => nil

Now it is removed from the database:

  Author.find_by_id(id).nil? # => true

One-to-many Example

Consider a Post model with many Comments:

  class Post
    has_many :comments, :autosave => true
  end

Saving changes to the parent and its associated model can now be performed automatically and atomically:

  post = Post.find(1)
  post.title # => "The current global position of migrating ducks"
  post.comments.first.body # => "Wow, awesome info thanks!"
  post.comments.last.body # => "Actually, your article should be named differently."

  post.title = "On the migration of ducks"
  post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks."

  post.save
  post.reload
  post.title # => "On the migration of ducks"
  post.comments.last.body # => "Actually, your article should be named differently. [UPDATED]: You are right, thanks."

Destroying one of the associated models members, as part of the parent‘s save action, is as simple as marking it for destruction:

  post.comments.last.mark_for_destruction
  post.comments.last.marked_for_destruction? # => true
  post.comments.length # => 2

Note that the model is not yet removed from the database:

  id = post.comments.last.id
  Comment.find_by_id(id).nil? # => false

  post.save
  post.reload.comments.length # => 1

Now it is removed from the database:

  Comment.find_by_id(id).nil? # => true

Validation

Validation is performed on the parent as usual, but also on all autosave enabled associations. If any of the associations fail validation, its error messages will be applied on the parents errors object and validation of the parent will fail.

Consider a Post model with Author which validates the presence of its name attribute:

  class Post
    has_one :author, :autosave => true
  end

  class Author
    validates_presence_of :name
  end

  post = Post.find(1)
  post.author.name = ''
  post.save # => false
  post.errors # => #<ActiveRecord::Errors:0x174498c @errors={"author_name"=>["can't be blank"]}, @base=#<Post ...>>

No validations will be performed on the associated models when validations are skipped for the parent:

  post = Post.find(1)
  post.author.name = ''
  post.save(false) # => true

Methods

included mark_for_destruction marked_for_destruction? reload_with_autosave_associations

Classes and Modules

Module ActiveRecord::AutosaveAssociation::ClassMethods

Constants

ASSOCIATION_TYPES = %w{ has_one belongs_to has_many has_and_belongs_to_many }

Public Class methods

included(base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/autosave_association.rb, line 130
130:     def self.included(base)
131:       base.class_eval do
132:         base.extend(ClassMethods)
133:         alias_method_chain :reload, :autosave_associations
134:
135:         ASSOCIATION_TYPES.each do |type|
136:           base.send("valid_keys_for_#{type}_association") << :autosave
137:         end
138:       end
139:     end

Public Instance methods

mark_for_destruction()

Marks this record to be destroyed as part of the parents save transaction. This does not actually destroy the record yet, rather it will be destroyed when parent.save is called.

Only useful if the :autosave option on the parent is enabled for this associated model.

[Source]

     # File vendor/rails/activerecord/lib/active_record/autosave_association.rb, line 198
198:     def mark_for_destruction
199:       @marked_for_destruction = true
200:     end
marked_for_destruction?()

Returns whether or not this record will be destroyed as part of the parents save transaction.

Only useful if the :autosave option on the parent is enabled for this associated model.

[Source]

     # File vendor/rails/activerecord/lib/active_record/autosave_association.rb, line 205
205:     def marked_for_destruction?
206:       @marked_for_destruction
207:     end
reload_with_autosave_associations(options = nil)

Reloads the attributes of the object as usual and removes a mark for destruction.

[Source]

     # File vendor/rails/activerecord/lib/active_record/autosave_association.rb, line 189
189:     def reload_with_autosave_associations(options = nil)
190:       @marked_for_destruction = false
191:       reload_without_autosave_associations(options)
192:     end


Module: ActiveRecord::AutosaveAssociation::ClassMethods

Module | ActiveRecord::AutosaveAssociation::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/autosave_association.rb


Class: ActiveRecord::Base

Class | ActiveRecord::Base
In: | vendor/rails/activerecord/lib/active_record/base.rb vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
Parent: | Object

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.

See the mapping rules in table_name and the full example in files/README.html for more insight.

Creation

Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when you‘re receiving the data from somewhere else, like an HTTP request. It works like this:

  user = User.new(:name => "David", :occupation => "Code Artist")
  user.name # => "David"

You can also use block initialization:

  user = User.new do |u|
    u.name = "David"
    u.occupation = "Code Artist"
  end

And of course you can just create a bare object and specify the attributes after the fact:

  user = User.new
  user.name = "David"
  user.occupation = "Code Artist"

Conditions

Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement. The array form is to be used when the condition input is tainted and requires sanitization. The string form can be used for statements that don‘t involve tainted data. The hash form works much like the array form, except only equality and range is possible. Examples:

  class User < ActiveRecord::Base
    def self.authenticate_unsafely(user_name, password)
      find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'")
    end

    def self.authenticate_safely(user_name, password)
      find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ])
    end

    def self.authenticate_safely_simply(user_name, password)
      find(:first, :conditions => { :user_name => user_name, :password => password })
    end
  end

The authenticate_unsafely method inserts the parameters directly into the query and is thus susceptible to SQL-injection attacks if the user_name and password parameters come directly from an HTTP request. The authenticate_safely and authenticate_safely_simply both will sanitize the user_name and password before inserting them in the query, which will ensure that an attacker can‘t escape the query and fake the login (or worse).

When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That‘s done by replacing the question marks with symbols and supplying a hash with values for the matching symbol keys:

  Company.find(:first, :conditions => [
    "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
    { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
  ])

Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND operator. For instance:

  Student.find(:all, :conditions => { :first_name => "Harvey", :status => 1 })
  Student.find(:all, :conditions => params[:student])

A range may be used in the hash to use the SQL BETWEEN operator:

  Student.find(:all, :conditions => { :grade => 9..12 })

An array may be used in the hash to use the SQL IN operator:

  Student.find(:all, :conditions => { :grade => [9,11,12] })

Overwriting default accessors

All column values are automatically available through basic accessors on the Active Record object, but sometimes you want to specialize this behavior. This can be done by overwriting the default accessors (using the same name as the attribute) and calling read_attribute(attr_name) and write_attribute(attr_name, value) to actually change things. Example:

  class Song < ActiveRecord::Base
    # Uses an integer of seconds to hold the length of the song

    def length=(minutes)
      write_attribute(:length, minutes.to_i * 60)
    end

    def length
      read_attribute(:length) / 60
    end
  end

You can alternatively use self[:attribute]=(value) and self[:attribute] instead of write_attribute(:attribute, value) and read_attribute(:attribute) as a shorter form.

Attribute query methods

In addition to the basic accessors, query methods are also automatically available on the Active Record object. Query methods allow you to test whether an attribute value is present.

For example, an Active Record User with the name attribute has a name? method that you can call to determine whether the user has a name:

  user = User.new(:name => "David")
  user.name? # => true

  anonymous = User.new(:name => "")
  anonymous.name? # => false

Accessing attributes before they have been typecasted

Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first. That can be done by using the <attribute>_before_type_cast accessors that all attributes have. For example, if your Account model has a balance attribute, you can call account.balance_before_type_cast or account.id_before_type_cast.

This is especially useful in validation situations where the user might supply a string for an integer field and you want to display the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn‘t what you want.

Dynamic attribute-based finders

Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by appending the name of an attribute to find_by_, find_last_by_, or find_all_by_, so you get finders like Person.find_by_user_name, Person.find_all_by_last_name, and Payment.find_by_transaction_id. So instead of writing Person.find(:first, :conditions => ["user_name = ?", user_name]), you just do Person.find_by_user_name(user_name). And instead of writing Person.find(:all, :conditions => ["last_name = ?", last_name]), you just do Person.find_all_by_last_name(last_name).

It‘s also possible to use multiple attributes in the same find by separating them with "and", so you get finders like Person.find_by_user_name_and_password or even Payment.find_by_purchaser_and_state_and_country. So instead of writing Person.find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password]), you just do Person.find_by_user_name_and_password(user_name, password).

It‘s even possible to use all the additional parameters to find. For example, the full interface for Payment.find_all_by_amount is actually Payment.find_all_by_amount(amount, options). And the full interface to Person.find_by_user_name is actually Person.find_by_user_name(user_name, options). So you could call Payment.find_all_by_amount(50, :order => "created_on"). Also you may call Payment.find_last_by_amount(amount, options) returning the last record matching that amount and options.

The same dynamic finder style can be used to create the object if it doesn‘t already exist. This dynamic finder is called with find_or_create_by_ and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won‘t be set unless they are given in a block. For example:

  # No 'Summer' tag exists
  Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")

  # Now the 'Summer' tag does exist
  Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")

  # Now 'Bob' exist and is an 'admin'
  User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }

Use the find_or_initialize_by_ finder if you want to return a new record without saving it first. Protected attributes won‘t be set unless they are given in a block. For example:

  # No 'Winter' tag exists
  winter = Tag.find_or_initialize_by_name("Winter")
  winter.new_record? # true

To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of a list of parameters. For example:

  Tag.find_or_create_by_name(:name => "rails", :creator => current_user)

That will either find an existing tag named "rails", or create a new one while setting the user that created it.

Saving arrays, hashes, and other non-mappable objects in text columns

Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method serialize. This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work. Example:

  class User < ActiveRecord::Base
    serialize :preferences
  end

  user = User.create(:preferences => { "background" => "black", "display" => large })
  User.find(user.id).preferences # => { "background" => "black", "display" => large }

You can also specify a class option as the second parameter that‘ll raise an exception if a serialized object is retrieved as a descendant of a class not in the hierarchy. Example:

  class User < ActiveRecord::Base
    serialize :preferences, Hash
  end

  user = User.create(:preferences => %w( one two three ))
  User.find(user.id).preferences    # raises SerializationTypeMismatch

Single table inheritance

Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:

  class Company < ActiveRecord::Base; end
  class Firm < Company; end
  class Client < Company; end
  class PriorityClient < Client; end

When you do Firm.create(:name => "37signals"), this record will be saved in the companies table with type = "Firm". You can then fetch this row again using Company.find(:first, "name = ‘37signals’") and it will return a Firm object.

If you don‘t have a type column defined in your table, single-table inheritance won‘t be triggered. In that case, it‘ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.

Note, all the attributes for all the cases are kept in the same table. Read more: www.martinfowler.com/eaaCatalog/singleTableInheritance.html

Connection to multiple databases in different models

Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection and Course and all of its subclasses will use this connection instead.

This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is requested, the retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool.

Exceptions

  • ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
  • AdapterNotSpecified - The configuration hash used in establish_connection didn‘t include an :adapter key.
  • AdapterNotFound - The :adapter key used in establish_connection specified a non-existent adapter (or a bad spelling of an existing one).
  • AssociationTypeMismatch - The object assigned to the association wasn‘t of the type specified in the association definition.
  • SerializationTypeMismatch - The serialized object wasn‘t of the class specified as the second parameter.
  • ConnectionNotEstablished+ - No connection has been established. Use establish_connection before querying.
  • RecordNotFound - No record responded to the find method. Either the row with the given ID doesn‘t exist or the row didn‘t meet the additional restrictions. Some find calls do not raise this exception to signal nothing was found, please check its documentation for further details.
  • StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
  • MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the attributes= method. The errors property of this exception contains an array of AttributeAssignmentError objects that should be inspected to determine which attributes triggered the errors.
  • AttributeAssignmentError - An error occurred while doing a mass assignment through the attributes= method. You can inspect the attribute property of the exception object to determine which attribute triggered the error.

Note: The attributes listed are class-level attributes (accessible from both the class and instance level). So it‘s possible to assign a logger to the class through Base.logger= which will then be used by all instances in the current object space.

Methods

== === [] []= abstract_class? aggregate_mapping all allow_concurrency allow_concurrency= attr_accessible attr_protected attr_readonly attribute_for_inspect attribute_names attribute_present? attributes attributes= attributes_before_type_cast base_class becomes benchmark cache_key class_of_active_record_descendant clone column_for_attribute column_names columns columns_hash compute_type connected? connection connection connection_pool content_columns count_by_sql create decrement decrement! decrement_counter default_scope delete delete delete_all descends_from_active_record? destroy destroy destroy_all eql? establish_connection exists? expand_hash_conditions_for_aggregates find find_by_sql first freeze frozen? has_attribute? hash human_attribute_name human_name id id= increment increment! increment_counter inheritance_column inspect inspect last merge_conditions new new_record? primary_key readonly! readonly? readonly_attributes reload remove_connection reset_column_information respond_to? retrieve_connection sanitize_sql_array sanitize_sql_for_assignment sanitize_sql_for_conditions sanitize_sql_hash_for_assignment sanitize_sql_hash_for_conditions save save! serialize serialized_attributes set_inheritance_column set_primary_key set_sequence_name set_table_name silence sti_name table_exists? table_name to_param toggle toggle! update update_all update_attribute update_attributes update_attributes! update_counters verification_timeout verification_timeout= with_exclusive_scope with_scope

Constants

VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock ]

External Aliases

set_table_name | -> | table_name=
set_primary_key | -> | primary_key=
set_inheritance_column | -> | inheritance_column=
set_sequence_name | -> | sequence_name=
sanitize_sql_for_conditions | -> | sanitize_sql
sanitize_sql_hash_for_conditions | -> | sanitize_sql_hash
sanitize_sql | -> | sanitize_conditions

Attributes

abstract_class [RW] Set this to true if this is an abstract class (see abstract_class?).

Public Class methods

===(object)

Overwrite the default class equality method to provide support for association proxies.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1459
1459:       def ===(object)
1460:         object.is_a?(self)
1461:       end
abstract_class?()

Returns whether this class is a base AR class. If A is a base class and B descends from A, then B.base_class will return B.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1475
1475:       def abstract_class?
1476:         defined?(@abstract_class) && @abstract_class == true
1477:       end
all(*args)

This is an alias for find(:all). You can pass in all the same arguments to this method as you can to find(:all)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 634
634:       def all(*args)
635:         find(:all, *args)
636:       end
allow_concurrency()

Deprecated and no longer has any effect.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 92
92:       def allow_concurrency
93:         ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_concurrency has been deprecated and no longer has any effect. Please remove all references to allow_concurrency.")
94:       end
allow_concurrency=(flag)

Deprecated and no longer has any effect.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 97
97:       def allow_concurrency=(flag)
98:         ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_concurrency= has been deprecated and no longer has any effect. Please remove all references to allow_concurrency=.")
99:       end
attr_accessible(*attributes)

Specifies a white list of model attributes that can be set via mass-assignment, such as new(attributes), update_attributes(attributes), or attributes=(attributes)

This is the opposite of the attr_protected macro: Mass-assignment will only set attributes in this list, to assign to the rest of attributes you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms. If you‘d rather start from an all-open default and restrict attributes as needed, have a look at attr_protected.

  class Customer < ActiveRecord::Base
    attr_accessible :name, :nickname
  end

  customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent")
  customer.credit_rating # => nil
  customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" }
  customer.credit_rating # => nil

  customer.credit_rating = "Average"
  customer.credit_rating # => "Average"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1062
1062:       def attr_accessible(*attributes)
1063:         write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
1064:       end
attr_protected(*attributes)

Attributes named in this macro are protected from mass-assignment, such as new(attributes), update_attributes(attributes), or attributes=(attributes).

Mass-assignment to these attributes will simply be ignored, to assign to them you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms.

  class Customer < ActiveRecord::Base
    attr_protected :credit_rating
  end

  customer = Customer.new("name" => David, "credit_rating" => "Excellent")
  customer.credit_rating # => nil
  customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" }
  customer.credit_rating # => nil

  customer.credit_rating = "Average"
  customer.credit_rating # => "Average"

To start from an all-closed default and enable attributes as needed, have a look at attr_accessible.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1029
1029:       def attr_protected(*attributes)
1030:         write_inheritable_attribute(:attr_protected, Set.new(attributes.map(&:to_s)) + (protected_attributes || []))
1031:       end
attr_readonly(*attributes)

Attributes listed as readonly can be set for a new record, but will be ignored in database updates afterwards.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1072
1072:        def attr_readonly(*attributes)
1073:          write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&:to_s)) + (readonly_attributes || []))
1074:        end
base_class()

Returns the base AR subclass that this class descends from. If A extends AR::Base, A.base_class will return A. If B descends from A through some arbitrarily deep hierarchy, B.base_class will return A.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1466
1466:       def base_class
1467:         class_of_active_record_descendant(self)
1468:       end
benchmark(title, log_level = Logger::DEBUG, use_silence = true) {|| ...}

Log and benchmark multiple statements in a single block. Example:

  Project.benchmark("Creating project") do
    project = Project.create("name" => "stuff")
    project.create_manager("name" => "David")
    project.milestones << Milestone.find(:all)
  end

The benchmark is only recorded if the current level of the logger is less than or equal to the log_level, which makes it easy to include benchmarking statements in production software that will remain inexpensive because the benchmark will only be conducted if the log level is low enough.

The logging of the multiple statements is turned off unless use_silence is set to false.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1439
1439:       def benchmark(title, log_level = Logger::DEBUG, use_silence = true)
1440:         if logger && logger.level <= log_level
1441:           result = nil
1442:           ms = Benchmark.ms { result = use_silence ? silence { yield } : yield }
1443:           logger.add(log_level, '%s (%.1fms)' % [title, ms])
1444:           result
1445:         else
1446:           yield
1447:         end
1448:       end
column_names()

Returns an array of column names as strings.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1288
1288:       def column_names
1289:         @column_names ||= columns.map { |column| column.name }
1290:       end
columns()

Returns an array of column objects for the table associated with this class.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1274
1274:       def columns
1275:         unless defined?(@columns) && @columns
1276:           @columns = connection.columns(table_name, "#{name} Columns")
1277:           @columns.each { |column| column.primary = column.name == primary_key }
1278:         end
1279:         @columns
1280:       end
columns_hash()

Returns a hash of column objects for the table associated with this class.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1283
1283:       def columns_hash
1284:         @columns_hash ||= columns.inject({}) { |hash, column| hash[column.name] = column; hash }
1285:       end
connected?()

Returns true if ActiveRecord is connected.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 127
127:       def connected?
128:         connection_handler.connected?(self)
129:       end
connection()

Returns the connection currently associated with the class. This can also be used to "borrow" the connection to do database work unrelated to any of the specific Active Records.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 114
114:       def connection
115:         retrieve_connection
116:       end
connection_pool()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 118
118:       def connection_pool
119:         connection_handler.retrieve_connection_pool(self)
120:       end
content_columns()

Returns an array of column objects where the primary id, all columns ending in "_id" or "_count", and columns used for single table inheritance have been removed.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1294
1294:       def content_columns
1295:         @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
1296:       end
count_by_sql(sql)

Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. The use of this method should be restricted to complicated SQL queries that can‘t be executed using the ActiveRecord::Calculations class methods. Look into those before using this.

Parameters

  • sql - An SQL statement which should return a count query from the database, see the example below.

Examples

  Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 919
919:       def count_by_sql(sql)
920:         sql = sanitize_conditions(sql)
921:         connection.select_value(sql, "#{name} Count").to_i
922:       end
create(attributes = nil) {|object| ...}

Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

The attributes parameter can be either be a Hash or an Array of Hashes. These Hashes describe the attributes on the objects that are to be created.

Examples

  # Create a single new object
  User.create(:first_name => 'Jamie')

  # Create an Array of new objects
  User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])

  # Create a single object and pass it into a block to set other attributes.
  User.create(:first_name => 'Jamie') do |u|
    u.is_admin = false
  end

  # Creating an Array of new objects using a block, where the block is executed for each object:
  User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
    u.is_admin = false
  end

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 722
722:       def create(attributes = nil, &block)
723:         if attributes.is_a?(Array)
724:           attributes.collect { |attr| create(attr, &block) }
725:         else
726:           object = new(attributes)
727:           yield(object) if block_given?
728:           object.save
729:           object
730:         end
731:       end
decrement_counter(counter_name, id)

Decrement a number field by one, usually representing a count.

This works the same as increment_counter but reduces the column value by 1 instead of increasing it.

Parameters

  • counter_name - The name of the field that should be decremented.
  • id - The id of the object that should be decremented.

Examples

  # Decrement the post_count column for the record with an id of 5
  DiscussionBoard.decrement_counter(:post_count, 5)

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1001
1001:       def decrement_counter(counter_name, id)
1002:         update_counters(id, counter_name => -1)
1003:       end
delete(id)

Deletes the row with a primary key matching the id argument, using a SQL DELETE statement, and returns the number of rows deleted. Active Record objects are not instantiated, so the object‘s callbacks are not executed, including any :dependent association options or Observer methods.

You can delete multiple rows at once by passing an Array of ids.

Note: Although it is often much faster than the alternative, destroy, skipping callbacks might bypass business logic in your application that ensures referential integrity or performs other essential jobs.

Examples

  # Delete a single row
  Todo.delete(1)

  # Delete multiple rows
  Todo.delete([2,3,4])

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 780
780:       def delete(id)
781:         delete_all([ "#{connection.quote_column_name(primary_key)} IN (?)", id ])
782:       end
delete_all(conditions = nil)

Deletes the records matching conditions without instantiating the records first, and hence not calling the destroy method nor invoking callbacks. This is a single SQL DELETE statement that goes straight to the database, much more efficient than destroy_all. Be careful with relations though, in particular :dependent rules defined on associations are not honored. Returns the number of rows affected.

Parameters

  • conditions - Conditions are specified the same way as with find method.

Example

  Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
  Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])

Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent associations or call your before_* or after_destroy callbacks, use the destroy_all method instead.

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 902
902:       def delete_all(conditions = nil)
903:         sql = "DELETE FROM #{quoted_table_name} "
904:         add_conditions!(sql, conditions, scope(:find))
905:         connection.delete(sql, "#{name} Delete all")
906:       end
descends_from_active_record?()

True if this isn‘t a concrete subclass needing a STI type condition.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1390
1390:       def descends_from_active_record?
1391:         if superclass.abstract_class?
1392:           superclass.descends_from_active_record?
1393:         else
1394:           superclass == Base || !columns_hash.include?(inheritance_column)
1395:         end
1396:       end
destroy(id)

Destroy an object (or multiple objects) that has the given id, the object is instantiated first, therefore all callbacks and filters are fired off before the object is deleted. This method is less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run.

This essentially finds the object (or multiple objects) with the given id, creates a new object from the attributes, and then calls destroy on it.

Parameters

  • id - Can be either an Integer or an Array of Integers.

Examples

  # Destroy a single object
  Todo.destroy(1)

  # Destroy multiple objects
  todos = [1,2,3]
  Todo.destroy(todos)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 803
803:       def destroy(id)
804:         if id.is_a?(Array)
805:           id.map { |one_id| destroy(one_id) }
806:         else
807:           find(id).destroy
808:         end
809:       end
destroy_all(conditions = nil)

Destroys the records matching conditions by instantiating each record and calling its destroy method. Each object‘s callbacks are executed (including :dependent association options and before_destroy/after_destroy Observer methods). Returns the collection of objects that were destroyed; each will be frozen, to reflect that no changes should be made (since they can‘t be persisted).

Note: Instantiation, callback execution, and deletion of each record can be time consuming when you‘re removing many records at once. It generates at least one SQL DELETE query per record (or possibly more, to enforce your callbacks). If you want to delete many rows quickly, without concern for their associations or callbacks, use delete_all instead.

Parameters

  • conditions - A string, array, or hash that specifies which records to destroy. If omitted, all records are destroyed. See the Conditions section in the introduction to ActiveRecord::Base for more information.

Examples

  Person.destroy_all("last_login < '2004-04-04'")
  Person.destroy_all(:status => "inactive")

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 881
881:       def destroy_all(conditions = nil)
882:         find(:all, :conditions => conditions).each { |object| object.destroy }
883:       end
establish_connection(spec = nil)

Establishes the connection to the database. Accepts a hash as input where the :adapter key must be specified with the name of a database adapter (in lower-case) example for regular databases (MySQL, Postgresql, etc):

  ActiveRecord::Base.establish_connection(
    :adapter  => "mysql",
    :host     => "localhost",
    :username => "myuser",
    :password => "mypass",
    :database => "somedatabase"
  )

Example for SQLite database:

  ActiveRecord::Base.establish_connection(
    :adapter => "sqlite",
    :database  => "path/to/dbfile"
  )

Also accepts keys as strings (for parsing from YAML for example):

  ActiveRecord::Base.establish_connection(
    "adapter" => "sqlite",
    "database"  => "path/to/dbfile"
  )

The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError may be returned on an error.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 51
51:     def self.establish_connection(spec = nil)
52:       case spec
53:         when nil
54:           raise AdapterNotSpecified unless defined? RAILS_ENV
55:           establish_connection(RAILS_ENV)
56:         when ConnectionSpecification
57:           @@connection_handler.establish_connection(name, spec)
58:         when Symbol, String
59:           if configuration = configurations[spec.to_s]
60:             establish_connection(configuration)
61:           else
62:             raise AdapterNotSpecified, "#{spec} database is not configured"
63:           end
64:         else
65:           spec = spec.symbolize_keys
66:           unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end
67:
68:           begin
69:             require 'rubygems'
70:             gem "activerecord-#{spec[:adapter]}-adapter"
71:             require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
72:           rescue LoadError
73:             begin
74:               require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
75:             rescue LoadError
76:               raise "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{$!})"
77:             end
78:           end
79:
80:           adapter_method = "#{spec[:adapter]}_connection"
81:           if !respond_to?(adapter_method)
82:             raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
83:           end
84:
85:           remove_connection
86:           establish_connection(ConnectionSpecification.new(spec, adapter_method))
87:       end
88:     end
exists?(id_or_conditions = {})

Returns true if a record exists in the table that matches the id or conditions given, or false otherwise. The argument can take five forms:

  • Integer - Finds the record with this primary key.
  • String - Finds the record with a primary key corresponding to this string (such as ‘5‘).
  • Array - Finds the record that matches these find-style conditions (such as [‘color = ?’, ‘red’]).
  • Hash - Finds the record that matches these find-style conditions (such as {:color => ‘red’}).
  • No args - Returns false if the table is empty, true otherwise.

For more information about specifying conditions as a Hash or Array, see the Conditions section in the introduction to ActiveRecord::Base.

Note: You can‘t pass in a condition as a string (like name = ‘Jamie‘), since it would be sanitized and then queried against the primary key column, like id = ‘name = \’Jamie\’‘.

Examples

  Person.exists?(5)
  Person.exists?('5')
  Person.exists?(:name => "David")
  Person.exists?(['name LIKE ?', "%#{query}%"])
  Person.exists?

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 689
689:       def exists?(id_or_conditions = {})
690:         connection.select_all(
691:           construct_finder_sql(
692:             :select     => "#{quoted_table_name}.#{primary_key}",
693:             :conditions => expand_id_conditions(id_or_conditions),
694:             :limit      => 1
695:           ),
696:           "#{name} Exists"
697:         ).size > 0
698:       end
find(*args)

Find operates with four different retrieval approaches:

  • Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then RecordNotFound will be raised.
  • Find first - This will return the first record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:first, *args) or its shortcut Model.first(*args).
  • Find last - This will return the last record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:last, *args) or its shortcut Model.last(*args).
  • Find all - This will return all the records matched by the options used. If no records are found, an empty array is returned. Use Model.find(:all, *args) or its shortcut Model.all(*args).

All approaches accept an options hash as their last parameter.

Parameters

  • :conditions - An SQL fragment like "administrator = 1", [ "user_name = ?", username ], or ["user_name = :user_name", { :user_name => user_name }]. See conditions in the intro.
  • :order - An SQL fragment like "created_at DESC, name".
  • :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
  • :having - Combined with +:group+ this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause.
  • :limit - An integer determining the limit on the number of rows that should be returned.
  • :offset - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
  • :joins - Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed), named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s), or an array containing a mixture of both strings and named associations. If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table‘s columns. Pass :readonly => false to override.
  • :include - Names associations that should be loaded alongside. The symbols named refer to already defined associations. See eager loading under Associations.
  • :select - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name").
  • :from - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name of a database view).
  • :readonly - Mark the returned records read-only so they cannot be saved or updated.
  • :lock - An SQL fragment like "FOR UPDATE" or "LOCK IN SHARE MODE". :lock => true gives connection‘s default exclusive lock, usually "FOR UPDATE".

Examples

  # find by id
  Person.find(1)       # returns the object for ID = 1
  Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
  Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
  Person.find([1])     # returns an array for the object with ID = 1
  Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")

Note that returned records may not be in the same order as the ids you provide since database rows are unordered. Give an explicit :order to ensure the results are sorted.

Examples

  # find first
  Person.find(:first) # returns the first object fetched by SELECT * FROM people
  Person.find(:first, :conditions => [ "user_name = ?", user_name])
  Person.find(:first, :conditions => [ "user_name = :u", { :u => user_name }])
  Person.find(:first, :order => "created_on DESC", :offset => 5)

  # find last
  Person.find(:last) # returns the last object fetched by SELECT * FROM people
  Person.find(:last, :conditions => [ "user_name = ?", user_name])
  Person.find(:last, :order => "created_on DESC", :offset => 5)

  # find all
  Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
  Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
  Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] }
  Person.find(:all, :offset => 10, :limit => 10)
  Person.find(:all, :include => [ :account, :friends ])
  Person.find(:all, :group => "category")

Example for find with a lock: Imagine two concurrent transactions: each will read person.visits == 2, add 1 to it, and save, resulting in two saves of person.visits = 3. By locking the row, the second transaction has to wait until the first is finished; we get the expected person.visits == 4.

  Person.transaction do
    person = Person.find(1, :lock => true)
    person.visits += 1
    person.save!
  end

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 607
607:       def find(*args)
608:         options = args.extract_options!
609:         validate_find_options(options)
610:         set_readonly_option!(options)
611:
612:         case args.first
613:           when :first then find_initial(options)
614:           when :last  then find_last(options)
615:           when :all   then find_every(options)
616:           else             find_from_ids(args, options)
617:         end
618:       end
find_by_sql(sql)

Executes a custom SQL query against your database and returns all the results. The results will be returned as an array with columns requested encapsulated as attributes of the model you call this method from. If you call Product.find_by_sql then the results will be returned in a Product object with the attributes you specified in the SQL query.

If you call a complicated SQL query which spans multiple tables the columns specified by the SELECT will be attributes of the model, whether or not they are columns of the corresponding table.

The sql parameter is a full SQL query as a string. It will be called as is, there will be no database agnostic conversions performed. This should be a last resort because using, for example, MySQL specific terms will lock you to using that particular database engine or require you to change your call if you switch engines.

Examples

  # A simple SQL query spanning multiple tables
  Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
  > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]

  # You can use the same string replacement techniques as you can with ActiveRecord#find
  Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
  > [#<Post:0x36bff9c @attributes={"first_name"=>"The Cheap Man Buys Twice"}>, ...]

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 660
660:       def find_by_sql(sql)
661:         connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
662:       end
first(*args)

A convenience wrapper for find(:first, *args). You can pass in all the same arguments to this method as you can to find(:first).

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 622
622:       def first(*args)
623:         find(:first, *args)
624:       end
human_attribute_name(attribute_key_name, options = {})

Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example:

  Person.human_attribute_name("first_name") # => "First name"

This used to be depricated in favor of humanize, but is now preferred, because it automatically uses the I18n module now. Specify options with additional translating options.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1366
1366:       def human_attribute_name(attribute_key_name, options = {})
1367:         defaults = self_and_descendants_from_active_record.map do |klass|
1368:           "#{klass.name.underscore}.#{attribute_key_name}""#{klass.name.underscore}.#{attribute_key_name}"
1369:         end
1370:         defaults << options[:default] if options[:default]
1371:         defaults.flatten!
1372:         defaults << attribute_key_name.humanize
1373:         options[:count] ||= 1
1374:         I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => [:activerecord, :attributes]))
1375:       end
human_name(options = {})

Transform the modelname into a more humane format, using I18n. Defaults to the basic humanize method. Default scope of the translation is activerecord.models Specify options with additional translating options.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1381
1381:       def human_name(options = {})
1382:         defaults = self_and_descendants_from_active_record.map do |klass|
1383:           "#{klass.name.underscore}""#{klass.name.underscore}"
1384:         end
1385:         defaults << self.name.humanize
1386:         I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
1387:       end
increment_counter(counter_name, id)

Increment a number field by one, usually representing a count.

This is used for caching aggregate values, so that they don‘t need to be computed every time. For example, a DiscussionBoard may cache post_count and comment_count otherwise every time the board is shown it would have to run an SQL query to find how many posts and comments there are.

Parameters

  • counter_name - The name of the field that should be incremented.
  • id - The id of the object that should be incremented.

Examples

  # Increment the post_count column for the record with an id of 5
  DiscussionBoard.increment_counter(:post_count, 5)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 984
984:       def increment_counter(counter_name, id)
985:         update_counters(id, counter_name => 1)
986:       end
inheritance_column()

Defines the column name for use with single table inheritance — can be set in subclasses like so: self.inheritance_column = "type_id"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1188
1188:       def inheritance_column
1189:         @inheritance_column ||= "type".freeze
1190:       end
inspect()

Returns a string like ‘Post id:integer, title:string, body:text‘

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1404
1404:       def inspect
1405:         if self == Base
1406:           super
1407:         elsif abstract_class?
1408:           "#{super}(abstract)"
1409:         elsif table_exists?
1410:           attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
1411:           "#{super}(#{attr_list})"
1412:         else
1413:           "#{super}(Table doesn't exist)"
1414:         end
1415:       end
last(*args)

A convenience wrapper for find(:last, *args). You can pass in all the same arguments to this method as you can to find(:last).

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 628
628:       def last(*args)
629:         find(:last, *args)
630:       end
merge_conditions(*conditions)

Merges conditions so that the result is a valid condition

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1494
1494:       def merge_conditions(*conditions)
1495:         segments = []
1496:
1497:         conditions.each do |condition|
1498:           unless condition.blank?
1499:             sql = sanitize_sql(condition)
1500:             segments << sql unless sql.blank?
1501:           end
1502:         end
1503:
1504:         "(#{segments.join(') AND (')})" unless segments.empty?
1505:       end
new(attributes = nil) {|self if block_given?| ...}

New objects can be instantiated as either empty (pass no construction parameter) or pre-set with attributes but not yet saved (pass a hash with key names matching the associated table column names). In both instances, valid attribute keys are determined by the column names of the associated table — hence you can‘t have attributes that aren‘t part of the table columns.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2434
2434:       def initialize(attributes = nil)
2435:         @attributes = attributes_from_column_definition
2436:         @attributes_cache = {}
2437:         @new_record = true
2438:         ensure_proper_type
2439:         self.attributes = attributes unless attributes.nil?
2440:         self.class.send(:scope, :create).each { |att,value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create)
2441:         result = yield self if block_given?
2442:         callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
2443:         result
2444:       end
primary_key()

Defines the primary key field — can be overridden in subclasses. Overwriting will negate any effect of the primary_key_prefix_type setting, though.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1165
1165:       def primary_key
1166:         reset_primary_key
1167:       end
readonly_attributes()

Returns an array of all the attributes that have been specified as readonly.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1077
1077:        def readonly_attributes
1078:          read_inheritable_attribute(:attr_readonly)
1079:        end
remove_connection(klass = self)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 131
131:       def remove_connection(klass = self)
132:         connection_handler.remove_connection(klass)
133:       end
reset_column_information()

Resets all the cached information about columns, which will cause them to be reloaded on the next request.

The most common usage pattern for this method is probably in a migration, when just after creating a table you want to populate it with some default values, eg:

 class CreateJobLevels < ActiveRecord::Migration
   def self.up
     create_table :job_levels do |t|
       t.integer :id
       t.string :name

       t.timestamps
     end

     JobLevel.reset_column_information
     %w{assistant executive manager director}.each do |type|
       JobLevel.create(:name => type)
     end
   end

   def self.down
     drop_table :job_levels
   end
 end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1338
1338:       def reset_column_information
1339:         generated_methods.each { |name| undef_method(name) }
1340:         @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @generated_methods = @inheritance_column = nil
1341:       end
respond_to?(method_id, include_private = false)

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1479
1479:       def respond_to?(method_id, include_private = false)
1480:         if match = DynamicFinderMatch.match(method_id)
1481:           return true if all_attributes_exists?(match.attribute_names)
1482:         elsif match = DynamicScopeMatch.match(method_id)
1483:           return true if all_attributes_exists?(match.attribute_names)
1484:         end
1485:
1486:         super
1487:       end
retrieve_connection()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 122
122:       def retrieve_connection
123:         connection_handler.retrieve_connection(self)
124:       end
serialize(attr_name, class_name = Object)

If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, then specify the name of that attribute using this method and it will be handled automatically. The serialization is done through YAML. If class_name is specified, the serialized object must be of that class on retrieval or SerializationTypeMismatch will be raised.

Parameters

  • attr_name - The field name that should be serialized.
  • class_name - Optional, class name that the object type should be equal to.

Example

  # Serialize a preferences attribute
  class User
    serialize :preferences
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1096
1096:       def serialize(attr_name, class_name = Object)
1097:         serialized_attributes[attr_name.to_s] = class_name
1098:       end
serialized_attributes()

Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1101
1101:       def serialized_attributes
1102:         read_inheritable_attribute(:attr_serialized) or write_inheritable_attribute(:attr_serialized, {})
1103:       end
set_inheritance_column(value = nil, &block)

Sets the name of the inheritance column to use to the given value, or (if the value # is nil or false) to the value returned by the given block.

  class Project < ActiveRecord::Base
    set_inheritance_column do
      original_inheritance_column + "_id"
    end
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1236
1236:       def set_inheritance_column(value = nil, &block)
1237:         define_attr_method :inheritance_column, value, &block
1238:       end
set_primary_key(value = nil, &block)

Sets the name of the primary key column to use to the given value, or (if the value is nil or false) to the value returned by the given block.

  class Project < ActiveRecord::Base
    set_primary_key "sysid"
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1222
1222:       def set_primary_key(value = nil, &block)
1223:         define_attr_method :primary_key, value, &block
1224:       end
set_sequence_name(value = nil, &block)

Sets the name of the sequence to use when generating ids to the given value, or (if the value is nil or false) to the value returned by the given block. This is required for Oracle and is useful for any database which relies on sequences for primary key generation.

If a sequence name is not explicitly set when using Oracle or Firebird, it will default to the commonly used pattern of: #{table_name}_seq

If a sequence name is not explicitly set when using PostgreSQL, it will discover the sequence corresponding to your primary key for you.

  class Project < ActiveRecord::Base
    set_sequence_name "projectseq"   # default would have been "project_seq"
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1255
1255:       def set_sequence_name(value = nil, &block)
1256:         define_attr_method :sequence_name, value, &block
1257:       end
set_table_name(value = nil, &block)

Sets the table name to use to the given value, or (if the value is nil or false) to the value returned by the given block.

  class Project < ActiveRecord::Base
    set_table_name "project"
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1210
1210:       def set_table_name(value = nil, &block)
1211:         define_attr_method :table_name, value, &block
1212:       end
silence() {|| ...}

Silences the logger for the duration of the block.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1451
1451:       def silence
1452:         old_logger_level, logger.level = logger.level, Logger::ERROR if logger
1453:         yield
1454:       ensure
1455:         logger.level = old_logger_level if logger
1456:       end
sti_name()

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1489
1489:       def sti_name
1490:         store_full_sti_class ? name : name.demodulize
1491:       end
table_exists?()

Indicates whether the table associated with this class exists

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1269
1269:       def table_exists?
1270:         connection.table_exists?(table_name)
1271:       end
table_name()

Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.

Nested classes are given table names prefixed by the singular form of the parent‘s table name. Enclosing modules are not considered.

Examples

  class Invoice < ActiveRecord::Base; end;
  file                  class               table_name
  invoice.rb            Invoice             invoices

  class Invoice < ActiveRecord::Base; class Lineitem < ActiveRecord::Base; end; end;
  file                  class               table_name
  invoice.rb            Invoice::Lineitem   invoice_lineitems

  module Invoice; class Lineitem < ActiveRecord::Base; end; end;
  file                  class               table_name
  invoice/lineitem.rb   Invoice::Lineitem   lineitems

Additionally, the class-level table_name_prefix is prepended and the table_name_suffix is appended. So if you have "myapp_" as a prefix, the table name guess for an Invoice class becomes "myapp_invoices". Invoice::Lineitem becomes "myapp_invoice_lineitems".

You can also overwrite this class method to allow for unguessable links, such as a Mouse class with a link to a "mice" table. Example:

  class Mouse < ActiveRecord::Base
    set_table_name "mice"
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 1138
1138:       def table_name
1139:         reset_table_name
1140:       end
update(id, attributes)

Updates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

Parameters

  • id - This should be the id or an array of ids to be updated.
  • attributes - This should be a Hash of attributes to be set on the object, or an array of Hashes.

Examples

  # Updating one record:
  Person.update(15, { :user_name => 'Samuel', :group => 'expert' })

  # Updating multiple records:
  people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
  Person.update(people.keys, people.values)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 749
749:       def update(id, attributes)
750:         if id.is_a?(Array)
751:           idx = -1
752:           id.collect { |one_id| idx += 1; update(one_id, attributes[idx]) }
753:         else
754:           object = find(id)
755:           object.update_attributes(attributes)
756:           object
757:         end
758:       end
update_all(updates, conditions = nil, options = {})

Updates all records with details given if they match a set of conditions supplied, limits and order can also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks.

Parameters

  • updates - A string of column and value pairs that will be set on any records that match conditions. This creates the SET clause of the generated SQL.
  • conditions - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro for more info.
  • options - Additional options are :limit and :order, see the examples for usage.

Examples

  # Update all billing objects with the 3 different attributes given
  Billing.update_all( "category = 'authorized', approved = 1, author = 'David'" )

  # Update records that match our conditions
  Billing.update_all( "author = 'David'", "title LIKE '%Rails%'" )

  # Update records that match our conditions but limit it to 5 ordered by date
  Billing.update_all( "author = 'David'", "title LIKE '%Rails%'",
                        :order => 'created_at', :limit => 5 )

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 832
832:       def update_all(updates, conditions = nil, options = {})
833:         sql  = "UPDATE #{quoted_table_name} SET #{sanitize_sql_for_assignment(updates)} "
834:
835:         scope = scope(:find)
836:
837:         select_sql = ""
838:         add_conditions!(select_sql, conditions, scope)
839:
840:         if options.has_key?(:limit) || (scope && scope[:limit])
841:           # Only take order from scope if limit is also provided by scope, this
842:           # is useful for updating a has_many association with a limit.
843:           add_order!(select_sql, options[:order], scope)
844:
845:           add_limit!(select_sql, options, scope)
846:           sql.concat(connection.limited_update_conditions(select_sql, quoted_table_name, connection.quote_column_name(primary_key)))
847:         else
848:           add_order!(select_sql, options[:order], nil)
849:           sql.concat(select_sql)
850:         end
851:
852:         connection.update(sql, "#{name} Update")
853:       end
update_counters(id, counters)

A generic "counter updater" implementation, intended primarily to be used by increment_counter and decrement_counter, but which may also be useful on its own. It simply does a direct SQL update for the record with the given ID, altering the given hash of counters by the amount given by the corresponding value:

Parameters

  • id - The id of the object you wish to update a counter on or an Array of ids.
  • counters - An Array of Hashes containing the names of the fields to update as keys and the amount to update the field by as values.

Examples

  # For the Post with id of 5, decrement the comment_count by 1, and
  # increment the action_count by 1
  Post.update_counters 5, :comment_count => -1, :action_count => 1
  # Executes the following SQL:
  # UPDATE posts
  #    SET comment_count = comment_count - 1,
  #        action_count = action_count + 1
  #  WHERE id = 5

  # For the Posts with id of 10 and 15, increment the comment_count by 1
  Post.update_counters [10, 15], :comment_count => 1
  # Executes the following SQL:
  # UPDATE posts
  #    SET comment_count = comment_count + 1,
  #  WHERE id IN (10, 15)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 953
953:       def update_counters(id, counters)
954:         updates = counters.inject([]) { |list, (counter_name, increment)|
955:           sign = increment < 0 ? "-" : "+"
956:           list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
957:         }.join(", ")
958:
959:         if id.is_a?(Array)
960:           ids_list = id.map {|i| quote_value(i)}.join(', ')
961:           condition = "IN  (#{ids_list})"
962:         else
963:           condition = "= #{quote_value(id)}"
964:         end
965:
966:         update_all(updates, "#{connection.quote_column_name(primary_key)} #{condition}")
967:       end
verification_timeout()

Deprecated and no longer has any effect.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 102
102:       def verification_timeout
103:         ActiveSupport::Deprecation.warn("ActiveRecord::Base.verification_timeout has been deprecated and no longer has any effect. Please remove all references to verification_timeout.")
104:       end
verification_timeout=(flag)

Deprecated and no longer has any effect.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 107
107:       def verification_timeout=(flag)
108:         ActiveSupport::Deprecation.warn("ActiveRecord::Base.verification_timeout= has been deprecated and no longer has any effect. Please remove all references to verification_timeout=.")
109:       end

Protected Class methods

aggregate_mapping(reflection)

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2253
2253:         def aggregate_mapping(reflection)
2254:           mapping = reflection.options[:mapping] || [reflection.name, reflection.name]
2255:           mapping.first.is_a?(Array) ? mapping : [mapping]
2256:         end
class_of_active_record_descendant(klass)

Returns the class descending directly from ActiveRecord::Base or an abstract class, if any, in the inheritance hierarchy.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2211
2211:         def class_of_active_record_descendant(klass)
2212:           if klass.superclass == Base || klass.superclass.abstract_class?
2213:             klass
2214:           elsif klass.superclass.nil?
2215:             raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
2216:           else
2217:             class_of_active_record_descendant(klass.superclass)
2218:           end
2219:         end
compute_type(type_name)

Returns the class type of the record using the current module as a prefix. So descendants of MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2198
2198:         def compute_type(type_name)
2199:           modularized_name = type_name_with_module(type_name)
2200:           silence_warnings do
2201:             begin
2202:               class_eval(modularized_name, __FILE__, __LINE__)
2203:             rescue NameError
2204:               class_eval(type_name, __FILE__, __LINE__)
2205:             end
2206:           end
2207:         end
default_scope(options = {})

Sets the default options for the model. The format of the options argument is the same as in find.

  class Person < ActiveRecord::Base
    default_scope :order => 'last_name, first_name'
  end

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2170
2170:         def default_scope(options = {})
2171:           self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} }
2172:         end
expand_hash_conditions_for_aggregates(attrs)

Accepts a hash of SQL conditions and replaces those attributes that correspond to a composed_of relationship with their expanded aggregate attribute values. Given:

    class Person < ActiveRecord::Base
      composed_of :address, :class_name => "Address",
        :mapping => [%w(address_street street), %w(address_city city)]
    end

Then:

    { :address => Address.new("813 abc st.", "chicago") }
      # => { :address_street => "813 abc st.", :address_city => "chicago" }

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2269
2269:         def expand_hash_conditions_for_aggregates(attrs)
2270:           expanded_attrs = {}
2271:           attrs.each do |attr, value|
2272:             unless (aggregation = reflect_on_aggregation(attr.to_sym)).nil?
2273:               mapping = aggregate_mapping(aggregation)
2274:               mapping.each do |field_attr, aggregate_attr|
2275:                 if mapping.size == 1 && !value.respond_to?(aggregate_attr)
2276:                   expanded_attrs[field_attr] = value
2277:                 else
2278:                   expanded_attrs[field_attr] = value.send(aggregate_attr)
2279:                 end
2280:               end
2281:             else
2282:               expanded_attrs[attr] = value
2283:             end
2284:           end
2285:           expanded_attrs
2286:         end
sanitize_sql_array(ary)

Accepts an array of conditions. The array has each value sanitized and interpolated into the SQL statement.

  ["name='%s' and group_id='%s'", "foo'bar", 4]  returns  "name='foo''bar' and group_id='4'"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2337
2337:         def sanitize_sql_array(ary)
2338:           statement, *values = ary
2339:           if values.first.is_a?(Hash) and statement =~ /:\w+/
2340:             replace_named_bind_variables(statement, values.first)
2341:           elsif statement.include?('?')
2342:             replace_bind_variables(statement, values)
2343:           else
2344:             statement % values.collect { |value| connection.quote_string(value.to_s) }
2345:           end
2346:         end
sanitize_sql_for_assignment(assignments)

Accepts an array, hash, or string of SQL conditions and sanitizes them into a valid SQL fragment for a SET clause.

  { :name => nil, :group_id => 4 }  returns "name = NULL , group_id='4'"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2245
2245:         def sanitize_sql_for_assignment(assignments)
2246:           case assignments
2247:             when Array; sanitize_sql_array(assignments)
2248:             when Hash;  sanitize_sql_hash_for_assignment(assignments)
2249:             else        assignments
2250:           end
2251:         end
sanitize_sql_for_conditions(condition)

Accepts an array, hash, or string of SQL conditions and sanitizes them into a valid SQL fragment for a WHERE clause.

  ["name='%s' and group_id='%s'", "foo'bar", 4]  returns  "name='foo''bar' and group_id='4'"
  { :name => "foo'bar", :group_id => 4 }  returns "name='foo''bar' and group_id='4'"
  "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2231
2231:         def sanitize_sql_for_conditions(condition)
2232:           return nil if condition.blank?
2233:
2234:           case condition
2235:             when Array; sanitize_sql_array(condition)
2236:             when Hash;  sanitize_sql_hash_for_conditions(condition)
2237:             else        condition
2238:           end
2239:         end
sanitize_sql_hash_for_assignment(attrs)

Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.

  { :status => nil, :group_id => 1 }
    # => "status = NULL , group_id = 1"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2328
2328:         def sanitize_sql_hash_for_assignment(attrs)
2329:           attrs.map do |attr, value|
2330:             "#{connection.quote_column_name(attr)} = #{quote_bound_value(value)}"
2331:           end.join(', ')
2332:         end
sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name)

Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.

  { :name => "foo'bar", :group_id => 4 }
    # => "name='foo''bar' and group_id= 4"
  { :status => nil, :group_id => [1,2,3] }
    # => "status IS NULL and group_id IN (1,2,3)"
  { :age => 13..18 }
    # => "age BETWEEN 13 AND 18"
  { 'other_records.id' => 7 }
    # => "`other_records`.`id` = 7"
  { :other_records => { :id => 7 } }
    # => "`other_records`.`id` = 7"

And for value objects on a composed_of relationship:

  { :address => Address.new("123 abc st.", "chicago") }
    # => "address_street='123 abc st.' and address_city='chicago'"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2302
2302:         def sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name)
2303:           attrs = expand_hash_conditions_for_aggregates(attrs)
2304:
2305:           conditions = attrs.map do |attr, value|
2306:             unless value.is_a?(Hash)
2307:               attr = attr.to_s
2308:
2309:               # Extract table name from qualified attribute names.
2310:               if attr.include?('.')
2311:                 table_name, attr = attr.split('.', 2)
2312:                 table_name = connection.quote_table_name(table_name)
2313:               end
2314:
2315:               attribute_condition("#{table_name}.#{connection.quote_column_name(attr)}", value)
2316:             else
2317:               sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s))
2318:             end
2319:           end.join(' AND ')
2320:
2321:           replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
2322:         end
with_exclusive_scope(method_scoping = {}, &block)

Works like with_scope, but discards any nested properties.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2155
2155:         def with_exclusive_scope(method_scoping = {}, &block)
2156:           with_scope(method_scoping, :overwrite, &block)
2157:         end
with_scope(method_scoping = {}, action = :merge) {|| ...}

Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. method_name may be :find or :create. :find parameters may include the :conditions, :joins, :include, :offset, :limit, and :readonly options. :create parameters are an attributes hash.

  class Article < ActiveRecord::Base
    def self.create_with_scope
      with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do
        find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
        a = create(1)
        a.blog_id # => 1
      end
    end
  end

In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of :conditions, :include, and :joins options in :find, which are merged.

:joins options are uniqued so multiple scopes can join in the same table without table aliasing problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the array of strings format for your joins.

  class Article < ActiveRecord::Base
    def self.find_with_scope
      with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
        with_scope(:find => { :limit => 10 })
          find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
        end
        with_scope(:find => { :conditions => "author_id = 3" })
          find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
        end
      end
    end
  end

You can ignore any previous scopings by using the with_exclusive_scope method.

  class Article < ActiveRecord::Base
    def self.find_with_exclusive_scope
      with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }) do
        with_exclusive_scope(:find => { :limit => 10 })
          find(:all) # => SELECT * from articles LIMIT 10
        end
      end
    end
  end

Note: the +:find+ scope also has effect on update and deletion methods, like update_all and delete_all.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2094
2094:         def with_scope(method_scoping = {}, action = :merge, &block)
2095:           method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)
2096:
2097:           # Dup first and second level of hash (method and params).
2098:           method_scoping = method_scoping.inject({}) do |hash, (method, params)|
2099:             hash[method] = (params == true) ? params : params.dup
2100:             hash
2101:           end
2102:
2103:           method_scoping.assert_valid_keys([ :find, :create ])
2104:
2105:           if f = method_scoping[:find]
2106:             f.assert_valid_keys(VALID_FIND_OPTIONS)
2107:             set_readonly_option! f
2108:           end
2109:
2110:           # Merge scopings
2111:           if [:merge, :reverse_merge].include?(action) && current_scoped_methods
2112:             method_scoping = current_scoped_methods.inject(method_scoping) do |hash, (method, params)|
2113:               case hash[method]
2114:                 when Hash
2115:                   if method == :find
2116:                     (hash[method].keys + params.keys).uniq.each do |key|
2117:                       merge = hash[method][key] && params[key] # merge if both scopes have the same key
2118:                       if key == :conditions && merge
2119:                         if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash)
2120:                           hash[method][key] = merge_conditions(hash[method][key].deep_merge(params[key]))
2121:                         else
2122:                           hash[method][key] = merge_conditions(params[key], hash[method][key])
2123:                         end
2124:                       elsif key == :include && merge
2125:                         hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
2126:                       elsif key == :joins && merge
2127:                         hash[method][key] = merge_joins(params[key], hash[method][key])
2128:                       else
2129:                         hash[method][key] = hash[method][key] || params[key]
2130:                       end
2131:                     end
2132:                   else
2133:                     if action == :reverse_merge
2134:                       hash[method] = hash[method].merge(params)
2135:                     else
2136:                       hash[method] = params.merge(hash[method])
2137:                     end
2138:                   end
2139:                 else
2140:                   hash[method] = params
2141:               end
2142:               hash
2143:             end
2144:           end
2145:
2146:           self.scoped_methods << method_scoping
2147:           begin
2148:             yield
2149:           ensure
2150:             self.scoped_methods.pop
2151:           end
2152:         end

Public Instance methods

==(comparison_object)

Returns true if the comparison_object is the same object, or is of the same type and has the same id.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2816
2816:       def ==(comparison_object)
2817:         comparison_object.equal?(self) ||
2818:           (comparison_object.instance_of?(self.class) &&
2819:             comparison_object.id == id &&
2820:             !comparison_object.new_record?)
2821:       end
[](attr_name)

Returns the value of the attribute identified by attr_name after it has been typecast (for example, "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). (Alias for the protected read_attribute method).

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2703
2703:       def [](attr_name)
2704:         read_attribute(attr_name)
2705:       end
[]=(attr_name, value)

Updates the attribute identified by attr_name with the specified value. (Alias for the protected write_attribute method).

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2709
2709:       def []=(attr_name, value)
2710:         write_attribute(attr_name, value)
2711:       end
attribute_for_inspect(attr_name)

Returns an inspect-like string for the value of the attribute attr_name. String attributes are elided after 50 characters, and Date and Time attributes are returned in the :db format. Other attributes return the value of inspect without modification.

  person = Person.create!(:name => "David Heinemeier Hansson " * 3)

  person.attribute_for_inspect(:name)
  # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'

  person.attribute_for_inspect(:created_at)
  # => '"2009-01-12 04:48:57"'

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2781
2781:       def attribute_for_inspect(attr_name)
2782:         value = read_attribute(attr_name)
2783:
2784:         if value.is_a?(String) && value.length > 50
2785:           "#{value[0..50]}...".inspect
2786:         elsif value.is_a?(Date) || value.is_a?(Time)
2787:           %("#{value.to_s(:db)}")
2788:         else
2789:           value.inspect
2790:         end
2791:       end
attribute_names()

Returns an array of names for the attributes available on this object sorted alphabetically.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2806
2806:       def attribute_names
2807:         @attributes.keys.sort
2808:       end
attribute_present?(attribute)

Returns true if the specified attribute has been set by the user or by a database load and is neither nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2795
2795:       def attribute_present?(attribute)
2796:         value = read_attribute(attribute)
2797:         !value.blank?
2798:       end
attributes()

Returns a hash of all the attributes with their names as keys and the values of the attributes as values.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2753
2753:       def attributes
2754:         self.attribute_names.inject({}) do |attrs, name|
2755:           attrs[name] = read_attribute(name)
2756:           attrs
2757:         end
2758:       end
attributes=(new_attributes, guard_protected_attributes = true)

Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names).

If guard_protected_attributes is true (the default), then sensitive attributes can be protected from this form of mass-assignment by using the attr_protected macro. Or you can alternatively specify which attributes can be accessed with the attr_accessible macro. Then all the attributes not included in that won‘t be allowed to be mass-assigned.

  class User < ActiveRecord::Base
    attr_protected :is_admin
  end

  user = User.new
  user.attributes = { :username => 'Phusion', :is_admin => true }
  user.username   # => "Phusion"
  user.is_admin?  # => false

  user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
  user.is_admin?  # => true

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2733
2733:       def attributes=(new_attributes, guard_protected_attributes = true)
2734:         return if new_attributes.nil?
2735:         attributes = new_attributes.dup
2736:         attributes.stringify_keys!
2737:
2738:         multi_parameter_attributes = []
2739:         attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
2740:
2741:         attributes.each do |k, v|
2742:           if k.include?("(")
2743:             multi_parameter_attributes << [ k, v ]
2744:           else
2745:             respond_to?("#{k}=""#{k}=") ? send("#{k}=""#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
2746:           end
2747:         end
2748:
2749:         assign_multiparameter_attributes(multi_parameter_attributes)
2750:       end
attributes_before_type_cast()

Returns a hash of attributes before typecasting and deserialization.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2761
2761:       def attributes_before_type_cast
2762:         self.attribute_names.inject({}) do |attrs, name|
2763:           attrs[name] = read_attribute_before_type_cast(name)
2764:           attrs
2765:         end
2766:       end
becomes(klass)

Returns an instance of the specified klass with the attributes of the current record. This is mostly useful in relation to single-table inheritance structures where you want a subclass to appear as the superclass. This can be used along with record identification in Action Pack to allow, say, Client < Company to do something like render :partial => @client.becomes(Company) to render that instance using the companies/company partial instead of clients/client.

Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either instance will affect the other.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2608
2608:       def becomes(klass)
2609:         returning klass.new do |became|
2610:           became.instance_variable_set("@attributes", @attributes)
2611:           became.instance_variable_set("@attributes_cache", @attributes_cache)
2612:           became.instance_variable_set("@new_record", new_record?)
2613:         end
2614:       end
cache_key()

Returns a cache key that can be used to identify this record.

Examples

  Product.new.cache_key     # => "products/new"
  Product.find(5).cache_key # => "products/5" (updated_at not available)
  Person.find(5).cache_key  # => "people/5-20071224150000" (updated_at available)

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2492
2492:       def cache_key
2493:         case
2494:         when new_record?
2495:           "#{self.class.model_name.cache_key}/new"
2496:         when timestamp = self[:updated_at]
2497:           "#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}"
2498:         else
2499:           "#{self.class.model_name.cache_key}/#{id}"
2500:         end
2501:       end
clone()

Returns a clone of the record that hasn‘t been assigned an id yet and is treated as a new record. Note that this is a "shallow" clone: it copies the object‘s attributes only, not its associations. The extent of a "deep" clone is application-specific and is therefore left to the application to implement according to its need.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2593
2593:       def clone
2594:         attrs = clone_attributes(:read_attribute_before_type_cast)
2595:         attrs.delete(self.class.primary_key)
2596:         record = self.class.new
2597:         record.send :instance_variable_set, '@attributes', attrs
2598:         record
2599:       end
column_for_attribute(name)

Returns the column object for the named attribute.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2811
2811:       def column_for_attribute(name)
2812:         self.class.columns_hash[name.to_s]
2813:       end
connection()

Returns the connection currently associated with the class. This can also be used to "borrow" the connection to do database work that isn‘t easily done without going straight to SQL.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb, line 19
19:     def connection
20:       self.class.connection
21:     end
decrement(attribute, by = 1)

Initializes attribute to zero if nil and subtracts the value passed as by (default is 1). The decrement is performed directly on the underlying attribute, no setter is invoked. Only makes sense for number-based attributes. Returns self.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2657
2657:       def decrement(attribute, by = 1)
2658:         self[attribute] ||= 0
2659:         self[attribute] -= by
2660:         self
2661:       end
decrement!(attribute, by = 1)

Wrapper around decrement that saves the record. This method differs from its non-bang version in that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true if the record could be saved.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2667
2667:       def decrement!(attribute, by = 1)
2668:         decrement(attribute, by).update_attribute(attribute, self[attribute])
2669:       end
delete()

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can‘t be persisted). Returns the frozen instance.

The row is simply removed with a SQL DELETE statement on the record‘s primary key, and no callbacks are executed.

To enforce the object‘s before_destroy and after_destroy callbacks, Observer methods, or any :dependent association options, use destroy.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2569
2569:       def delete
2570:         self.class.delete(id) unless new_record?
2571:         freeze
2572:       end
destroy()

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can‘t be persisted).

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2576
2576:       def destroy
2577:         unless new_record?
2578:           connection.delete(
2579:             "DELETE FROM #{self.class.quoted_table_name} " +
2580:             "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id}",
2581:             "#{self.class.name} Destroy"
2582:           )
2583:         end
2584:
2585:         freeze
2586:       end
eql?(comparison_object)

Delegates to ==

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2824
2824:       def eql?(comparison_object)
2825:         self == (comparison_object)
2826:       end
freeze()

Freeze the attributes hash such that associations are still accessible, even on destroyed records.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2835
2835:       def freeze
2836:         @attributes.freeze; self
2837:       end
frozen?()

Returns true if the attributes hash has been frozen.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2840
2840:       def frozen?
2841:         @attributes.frozen?
2842:       end
has_attribute?(attr_name)

Returns true if the given attribute is in the attributes hash

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2801
2801:       def has_attribute?(attr_name)
2802:         @attributes.has_key?(attr_name.to_s)
2803:       end
hash()

Delegates to id in order to allow two records of the same type and id to work with something like:

  [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2830
2830:       def hash
2831:         id.hash
2832:       end
id()

A model instance‘s primary key is always available as model.id whether you name it the default ‘id’ or set it to something else.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2448
2448:       def id
2449:         attr_name = self.class.primary_key
2450:         column = column_for_attribute(attr_name)
2451:
2452:         self.class.send(:define_read_method, :id, attr_name, column)
2453:         # now that the method exists, call it
2454:         self.send attr_name.to_sym
2455:
2456:       end
id=(value)

Sets the primary ID.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2512
2512:       def id=(value)
2513:         write_attribute(self.class.primary_key, value)
2514:       end
increment(attribute, by = 1)

Initializes attribute to zero if nil and adds the value passed as by (default is 1). The increment is performed directly on the underlying attribute, no setter is invoked. Only makes sense for number-based attributes. Returns self.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2640
2640:       def increment(attribute, by = 1)
2641:         self[attribute] ||= 0
2642:         self[attribute] += by
2643:         self
2644:       end
increment!(attribute, by = 1)

Wrapper around increment that saves the record. This method differs from its non-bang version in that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true if the record could be saved.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2650
2650:       def increment!(attribute, by = 1)
2651:         increment(attribute, by).update_attribute(attribute, self[attribute])
2652:       end
inspect()

Returns the contents of the record as a nicely formatted string.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2856
2856:       def inspect
2857:         attributes_as_nice_string = self.class.column_names.collect { |name|
2858:           if has_attribute?(name) || new_record?
2859:             "#{name}: #{attribute_for_inspect(name)}"
2860:           end
2861:         }.compact.join(", ")
2862:         "#<#{self.class} #{attributes_as_nice_string}>"
2863:       end
new_record?()

Returns true if this object hasn‘t been saved yet — that is, a record for the object doesn‘t exist yet; otherwise, returns false.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2517
2517:       def new_record?
2518:         @new_record || false
2519:       end
readonly!()

Marks this record as read only.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2851
2851:       def readonly!
2852:         @readonly = true
2853:       end
readonly?()

Returns true if the record is read only. Records loaded through joins with piggy-back attributes will be marked as read only since they cannot be saved.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2846
2846:       def readonly?
2847:         defined?(@readonly) && @readonly == true
2848:       end
reload(options = nil)

Reloads the attributes of this object from the database. The optional options argument is passed to find when reloading so you may do e.g. record.reload(:lock => true) to reload the same record with an exclusive row lock.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2692
2692:       def reload(options = nil)
2693:         clear_aggregation_cache
2694:         clear_association_cache
2695:         @attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
2696:         @attributes_cache = {}
2697:         self
2698:       end
save(perform_validation = true)

Saves the model.

If the model is new a record gets created in the database, otherwise the existing record gets updated.

If perform_validation is true validations run. If any of them fail the action is cancelled and save returns false. If the flag is false validations are bypassed altogether. See ActiveRecord::Validations for more information.

There‘s a series of callbacks associated with save. If any of the before_* callbacks return false the action is cancelled and save returns false. See ActiveRecord::Callbacks for further details.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2538
2538:       def save
2539:         create_or_update
2540:       end
save!()

Saves the model.

If the model is new a record gets created in the database, otherwise the existing record gets updated.

With save! validations always run. If any of them fail ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations for more information.

There‘s a series of callbacks associated with save!. If any of the before_* callbacks return false the action is cancelled and save! raises ActiveRecord::RecordNotSaved. See ActiveRecord::Callbacks for further details.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2555
2555:       def save!
2556:         create_or_update || raise(RecordNotSaved)
2557:       end
to_param()

Returns a String, which Action Pack uses for constructing an URL to this object. The default implementation returns this record‘s id as a String, or nil if this record‘s unsaved.

For example, suppose that you have a User model, and that you have a map.resources :users route. Normally, user_path will construct a path with the user object‘s ‘id’ in it:

  user = User.find_by_name('Phusion')
  user_path(user)  # => "/users/1"

You can override to_param in your model to make user_path construct a path using the user‘s name instead of the user‘s id:

  class User < ActiveRecord::Base
    def to_param  # overridden
      name
    end
  end

  user = User.find_by_name('Phusion')
  user_path(user)  # => "/users/Phusion"

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2480
2480:       def to_param
2481:         # We can't use alias_method here, because method 'id' optimizes itself on the fly.
2482:         (id = self.id) ? id.to_s : nil # Be sure to stringify the id for routes
2483:       end
toggle(attribute)

Assigns to attribute the boolean opposite of attribute?. So if the predicate returns true the attribute will become false. This method toggles directly the underlying value without calling any setter. Returns self.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2675
2675:       def toggle(attribute)
2676:         self[attribute] = !send("#{attribute}?")
2677:         self
2678:       end
toggle!(attribute)

Wrapper around toggle that saves the record. This method differs from its non-bang version in that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true if the record could be saved.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2684
2684:       def toggle!(attribute)
2685:         toggle(attribute).update_attribute(attribute, self[attribute])
2686:       end
update_attribute(name, value)

Updates a single attribute and saves the record without going through the normal validation procedure. This is especially useful for boolean flags on existing records. The regular update_attribute method in Base is replaced with this when the validations module is mixed in, which it is by default.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2619
2619:       def update_attribute(name, value)
2620:         send(name.to_s + '=', value)
2621:         save(false)
2622:       end
update_attributes(attributes)

Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will fail and false will be returned.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2626
2626:       def update_attributes(attributes)
2627:         self.attributes = attributes
2628:         save
2629:       end
update_attributes!(attributes)

Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.

[Source]

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2632
2632:       def update_attributes!(attributes)
2633:         self.attributes = attributes
2634:         save!
2635:       end


Module: ActiveRecord::Batches::ClassMethods

Module | ActiveRecord::Batches::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/batches.rb

When processing large numbers of records, it‘s often a good idea to do so in batches to prevent memory ballooning.

Methods

find_each find_in_batches

Public Instance methods

find_each(options = {}) {|record| ...}

Yields each record that was found by the find options. The find is performed by find_in_batches with a batch size of 1000 (or as specified by the batch_size option).

Example:

  Person.find_each(:conditions => "age > 21") do |person|
    person.party_all_night!
  end

Note: This method is only intended to use for batch processing of large amounts of records that wouldn‘t fit in memory all at once. If you just need to loop over less than 1000 records, it‘s probably better just to use the regular find methods.

[Source]

    # File vendor/rails/activerecord/lib/active_record/batches.rb, line 21
21:       def find_each(options = {})
22:         find_in_batches(options) do |records|
23:           records.each { |record| yield record }
24:         end
25:
26:         self
27:       end
find_in_batches(options = {}) {|records| ...}

Yields each batch of records that was found by the find options as an array. The size of each batch is set by the batch_size option; the default is 1000.

You can control the starting point for the batch processing by supplying the start option. This is especially useful if you want multiple workers dealing with the same processing queue. You can make worker 1 handle all the records between id 0 and 10,000 and worker 2 handle from 10,000 and beyond (by setting the start option on that worker).

It‘s not possible to set the order. That is automatically set to ascending on the primary key ("id ASC") to make the batch ordering work. This also mean that this method only works with integer-based primary keys. You can‘t set the limit either, that‘s used to control the the batch sizes.

Example:

  Person.find_in_batches(:conditions => "age > 21") do |group|
    sleep(50) # Make sure it doesn't get too crowded in there!
    group.each { |person| person.party_all_night! }
  end

[Source]

    # File vendor/rails/activerecord/lib/active_record/batches.rb, line 47
47:       def find_in_batches(options = {})
48:         raise "You can't specify an order, it's forced to be #{batch_order}" if options[:order]
49:         raise "You can't specify a limit, it's forced to be the batch_size"  if options[:limit]
50:
51:         start = options.delete(:start).to_i
52:         batch_size = options.delete(:batch_size) || 1000
53:
54:         with_scope(:find => options.merge(:order => batch_order, :limit => batch_size)) do
55:           records = find(:all, :conditions => [ "#{table_name}.#{primary_key} >= ?", start ])
56:
57:           while records.any?
58:             yield records
59:
60:             break if records.size < batch_size
61:             records = find(:all, :conditions => [ "#{table_name}.#{primary_key} > ?", records.last.id ])
62:           end
63:         end
64:       end


Module: ActiveRecord::Calculations::ClassMethods

Module | ActiveRecord::Calculations::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/calculations.rb

Methods

average calculate construct_count_options_from_args count maximum minimum sum

Public Instance methods

average(column_name, options = {})

Calculates the average value on a given column. The value is returned as a float, or nil if there‘s no row. See calculate for examples with options.

  Person.average('age') # => 35.8

[Source]

    # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 56
56:       def average(column_name, options = {})
57:         calculate(:avg, column_name, options)
58:       end
calculate(operation, column_name, options = {})

This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts. Options such as :conditions, :order, :group, :having, and :joins can be passed to customize the query.

There are two basic forms of output:

  * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float for AVG, and the given column's type for everything else.
  * Grouped values: This returns an ordered hash of the values and groups them by the <tt>:group</tt> option.  It takes either a column name, or the name
    of a belongs_to association.

      values = Person.maximum(:age, :group => 'last_name')
      puts values["Drake"]
      => 43

      drake  = Family.find_by_last_name('Drake')
      values = Person.maximum(:age, :group => :family) # Person belongs_to :family
      puts values[drake]
      => 43

      values.each do |family, max_age|
      ...
      end

Options:

  • :conditions - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro to ActiveRecord::Base.
  • :include: Eager loading, see Associations for details. Since calculations don‘t load anything, the purpose of this is to access fields on joined tables in your conditions, order, or group clauses.
  • :joins - An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". (Rarely needed). The records will be returned read-only since they will have attributes that do not correspond to the table‘s columns.
  • :order - An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations).
  • :group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
  • :select - By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not include the joined columns.
  • :distinct - Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) …

Examples:

  Person.calculate(:count, :all) # The same as Person.count
  Person.average(:age) # SELECT AVG(age) FROM people...
  Person.minimum(:age, :conditions => ['last_name != ?', 'Drake']) # Selects the minimum age for everyone with a last name other than 'Drake'
  Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name) # Selects the minimum age for any family without any minors
  Person.sum("2 * age")

[Source]

     # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 125
125:       def calculate(operation, column_name, options = {})
126:         validate_calculation_options(operation, options)
127:         column_name     = options[:select] if options[:select]
128:         column_name     = '*' if column_name == :all
129:         column          = column_for column_name
130:         catch :invalid_query do
131:           if options[:group]
132:             return execute_grouped_calculation(operation, column_name, column, options)
133:           else
134:             return execute_simple_calculation(operation, column_name, column, options)
135:           end
136:         end
137:         0
138:       end
count(*args)

Count operates using three different approaches.

  • Count all: By not passing any parameters to count, it will return a count of all the rows for the model.
  • Count using column: By passing a column name to count, it will return a count of all the rows for the model with supplied column present
  • Count using options will find the row count matched by the options used.

The third approach, count using options, accepts an option hash as the only parameter. The options are:

  • :conditions: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro to ActiveRecord::Base.
  • :joins: Either an SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id" (rarely needed) or named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s). If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table‘s columns. Pass :readonly => false to override.
  • :include: Named associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer to already defined associations. When using named associations, count returns the number of DISTINCT items for the model you‘re counting. See eager loading under Associations.
  • :order: An SQL fragment like "created_at DESC, name" (really only used with GROUP BY calculations).
  • :group: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
  • :select: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not include the joined columns.
  • :distinct: Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) …
  • :from - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name of a database view).

Examples for counting all:

  Person.count         # returns the total count of all people

Examples for counting by column:

  Person.count(:age)  # returns the total count of all people whose age is present in database

Examples for count with options:

  Person.count(:conditions => "age > 26")
  Person.count(:conditions => "age > 26 AND job.salary > 60000", :include => :job) # because of the named association, it finds the DISTINCT count using LEFT OUTER JOIN.
  Person.count(:conditions => "age > 26 AND job.salary > 60000", :joins => "LEFT JOIN jobs on jobs.person_id = person.id") # finds the number of rows matching the conditions and joins.
  Person.count('id', :conditions => "age > 26") # Performs a COUNT(id)
  Person.count(:all, :conditions => "age > 26") # Performs a COUNT(*) (:all is an alias for '*')

Note: Person.count(:all) will not work because it will use :all as the condition. Use Person.count instead.

[Source]

    # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 47
47:       def count(*args)
48:         calculate(:count, *construct_count_options_from_args(*args))
49:       end
maximum(column_name, options = {})

Calculates the maximum value on a given column. The value is returned with the same data type of the column, or nil if there‘s no row. See calculate for examples with options.

  Person.maximum('age') # => 93

[Source]

    # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 74
74:       def maximum(column_name, options = {})
75:         calculate(:max, column_name, options)
76:       end
minimum(column_name, options = {})

Calculates the minimum value on a given column. The value is returned with the same data type of the column, or nil if there‘s no row. See calculate for examples with options.

  Person.minimum('age') # => 7

[Source]

    # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 65
65:       def minimum(column_name, options = {})
66:         calculate(:min, column_name, options)
67:       end
sum(column_name, options = {})

Calculates the sum of values on a given column. The value is returned with the same data type of the column, 0 if there‘s no row. See calculate for examples with options.

  Person.sum('age') # => 4562

[Source]

    # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 83
83:       def sum(column_name, options = {})
84:         calculate(:sum, column_name, options)
85:       end

Protected Instance methods

construct_count_options_from_args(*args)

[Source]

     # File vendor/rails/activerecord/lib/active_record/calculations.rb, line 141
141:         def construct_count_options_from_args(*args)
142:           options     = {}
143:           column_name = :all
144:
145:           # We need to handle
146:           #   count()
147:           #   count(:column_name=:all)
148:           #   count(options={})
149:           #   count(column_name=:all, options={})
150:           #   selects specified by scopes
151:           case args.size
152:           when 0
153:             column_name = scope(:find)[:select] if scope(:find)
154:           when 1
155:             if args[0].is_a?(Hash)
156:               column_name = scope(:find)[:select] if scope(:find)
157:               options = args[0]
158:             else
159:               column_name = args[0]
160:             end
161:           when 2
162:             column_name, options = args
163:           else
164:             raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}"
165:           end
166:
167:           [column_name || :all, options]
168:         end


Module: ActiveRecord::Callbacks

Module | ActiveRecord::Callbacks
In: | vendor/rails/activerecord/lib/active_record/callbacks.rb

Callbacks are hooks into the lifecycle of an Active Record object that allow you to trigger logic before or after an alteration of the object state. This can be used to make sure that associated and dependent objects are deleted when destroy is called (by overwriting before_destroy) or to massage attributes before they‘re validated (by overwriting before_validation). As an example of the callbacks initiated, consider the Base#save call for a new record:

  • (-) save
  • (-) valid
  • (1) before_validation
  • (2) before_validation_on_create
  • (-) validate
  • (-) validate_on_create
  • (3) after_validation
  • (4) after_validation_on_create
  • (5) before_save
  • (6) before_create
  • (-) create
  • (7) after_create
  • (8) after_save

That‘s a total of eight callbacks, which gives you immense power to react and prepare for each state in the Active Record lifecycle. The sequence for calling Base#save an existing record is similar, except that each _on_create callback is replaced by the corresponding _on_update callback.

Examples:

  class CreditCard < ActiveRecord::Base
    # Strip everything but digits, so the user can specify "555 234 34" or
    # "5552-3434" or both will mean "55523434"
    def before_validation_on_create
      self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
    end
  end

  class Subscription < ActiveRecord::Base
    before_create :record_signup

    private
      def record_signup
        self.signed_up_on = Date.today
      end
  end

  class Firm < ActiveRecord::Base
    # Destroys the associated clients and people when the firm is destroyed
    before_destroy { |record| Person.destroy_all "firm_id = #{record.id}"   }
    before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
  end

Inheritable callback queues

Besides the overwritable callback methods, it‘s also possible to register callbacks through the use of the callback macros. Their main advantage is that the macros add behavior into a callback queue that is kept intact down through an inheritance hierarchy. Example:

  class Topic < ActiveRecord::Base
    before_destroy :destroy_author
  end

  class Reply < Topic
    before_destroy :destroy_readers
  end

Now, when Topic#destroy is run only destroy_author is called. When Reply#destroy is run, both destroy_author and destroy_readers are called. Contrast this to the situation where we‘ve implemented the save behavior through overwriteable methods:

  class Topic < ActiveRecord::Base
    def before_destroy() destroy_author end
  end

  class Reply < Topic
    def before_destroy() destroy_readers end
  end

In that case, Reply#destroy would only run destroy_readers and not destroy_author. So, use the callback macros when you want to ensure that a certain callback is called for the entire hierarchy, and use the regular overwriteable methods when you want to leave it up to each descendant to decide whether they want to call super and trigger the inherited callbacks.

*IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won‘t be inherited.

Types of callbacks

There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects, inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for creating mix-ins), and inline eval methods are deprecated.

The method reference callbacks work by specifying a protected or private method available in the object, like this:

  class Topic < ActiveRecord::Base
    before_destroy :delete_parents

    private
      def delete_parents
        self.class.delete_all "parent_id = #{id}"
      end
  end

The callback objects have methods named after the callback called with the record as the only parameter, such as:

  class BankAccount < ActiveRecord::Base
    before_save      EncryptionWrapper.new
    after_save       EncryptionWrapper.new
    after_initialize EncryptionWrapper.new
  end

  class EncryptionWrapper
    def before_save(record)
      record.credit_card_number = encrypt(record.credit_card_number)
    end

    def after_save(record)
      record.credit_card_number = decrypt(record.credit_card_number)
    end

    alias_method :after_find, :after_save

    private
      def encrypt(value)
        # Secrecy is committed
      end

      def decrypt(value)
        # Secrecy is unveiled
      end
  end

So you specify the object you want messaged on a given callback. When that callback is triggered, the object has a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other initialization data such as the name of the attribute to work with:

  class BankAccount < ActiveRecord::Base
    before_save      EncryptionWrapper.new("credit_card_number")
    after_save       EncryptionWrapper.new("credit_card_number")
    after_initialize EncryptionWrapper.new("credit_card_number")
  end

  class EncryptionWrapper
    def initialize(attribute)
      @attribute = attribute
    end

    def before_save(record)
      record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
    end

    def after_save(record)
      record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
    end

    alias_method :after_find, :after_save

    private
      def encrypt(value)
        # Secrecy is committed
      end

      def decrypt(value)
        # Secrecy is unveiled
      end
  end

The callback macros usually accept a symbol for the method they‘re supposed to run, but you can also pass a "method string", which will then be evaluated within the binding of the callback. Example:

  class Topic < ActiveRecord::Base
    before_destroy 'self.class.delete_all "parent_id = #{id}"'
  end

Notice that single quotes (’) are used so the #{id} part isn‘t evaluated until the callback is triggered. Also note that these inline callbacks can be stacked just like the regular ones:

  class Topic < ActiveRecord::Base
    before_destroy 'self.class.delete_all "parent_id = #{id}"',
                   'puts "Evaluated after parents are destroyed"'
  end

The after_find and after_initialize exceptions

Because after_find and after_initialize are called for each object found and instantiated by a finder, such as Base.find(:all), we‘ve had to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, after_find and after_initialize will only be run if an explicit implementation is defined (def after_find). In that case, all of the callback types will be called.

before_validation* returning statements

If the returning value of a before_validation callback can be evaluated to false, the process will be aborted and Base#save will return false. If Base#save! is called it will raise a ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.

Canceling callbacks

If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.

Transactions

The entire callback chain of a save, save!, or destroy call runs within a transaction. That includes after_* hooks. If everything goes fine a COMMIT is executed once the chain has been completed.

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks. Note, however, that in that case the client needs to be aware of it because an ordinary save will raise such exception instead of quietly returning false.

Methods

after_create after_destroy after_save after_update after_validation after_validation_on_create after_validation_on_update before_create before_destroy before_save before_update before_validation before_validation_on_create before_validation_on_update

Constants

CALLBACKS = %w( after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation after_validation before_validation_on_create after_validation_on_create before_validation_on_update after_validation_on_update before_destroy after_destroy )

Public Instance methods

after_create()

Is called after Base.save on new objects that haven‘t been saved yet (no record exists). Note that this callback is still wrapped in the transaction around save. For example, if you invoke an external indexer at this point it won‘t see the changes in the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 263
263:     def after_create() end
after_destroy()

Is called after Base.destroy (and all the attributes have been frozen).

 class Contact < ActiveRecord::Base
   after_destroy { |record| logger.info( "Contact #{record.id} was destroyed." ) }
 end

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 334
334:     def after_destroy()  end
after_save()

Is called after Base.save (regardless of whether it‘s a create or update save). Note that this callback is still wrapped in the transaction around save. For example, if you invoke an external indexer at this point it won‘t see the changes in the database.

 class Contact < ActiveRecord::Base
   after_save { logger.info( 'New contact saved!' ) }
 end

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 247
247:     def after_save()  end
after_update()

Is called after Base.save on existing objects that have a record. Note that this callback is still wrapped in the transaction around save. For example, if you invoke an external indexer at this point it won‘t see the changes in the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 278
278:     def after_update() end
after_validation()

Is called after Validations.validate (which is part of the Base.save call).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 292
292:     def after_validation() end
after_validation_on_create()

Is called after Validations.validate (which is part of the Base.save call) on new objects that haven‘t been saved yet (no record exists).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 300
300:     def after_validation_on_create()  end
after_validation_on_update()

Is called after Validations.validate (which is part of the Base.save call) on existing objects that have a record.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 308
308:     def after_validation_on_update()  end
before_create()

Is called before Base.save on new objects that haven‘t been saved yet (no record exists).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 258
258:     def before_create() end
before_destroy()

Is called before Base.destroy.

Note: If you need to destroy or nullify associated records first, use the :dependent option on your associations.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 327
327:     def before_destroy() end
before_save()

Is called before Base.save (regardless of whether it‘s a create or update save).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 238
238:     def before_save() end
before_update()

Is called before Base.save on existing objects that have a record.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 273
273:     def before_update() end
before_validation()

Is called before Validations.validate (which is part of the Base.save call).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 289
289:     def before_validation() end
before_validation_on_create()

Is called before Validations.validate (which is part of the Base.save call) on new objects that haven‘t been saved yet (no record exists).

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 296
296:     def before_validation_on_create() end
before_validation_on_update()

Is called before Validations.validate (which is part of the Base.save call) on existing objects that have a record.

[Source]

     # File vendor/rails/activerecord/lib/active_record/callbacks.rb, line 304
304:     def before_validation_on_update() end


Class: ActiveRecord::ConfigurationError

Class | ActiveRecord::ConfigurationError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when association is being configured improperly or user tries to use offset and limit together with has_many or has_and_belongs_to_many associations.


Class: ActiveRecord::ConnectionAdapters::AbstractAdapter

Class | ActiveRecord::ConnectionAdapters::AbstractAdapter
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
Parent: | Object

ActiveRecord supports multiple database systems. AbstractAdapter and related classes form the abstraction layer which makes this possible. An AbstractAdapter represents a connection to a database, and provides an abstract interface for database-specific functionality such as establishing a connection, escaping values, building the right SQL fragments for ’:offset’ and ’:limit’ options, etc.

All the concrete database adapters follow the interface laid down in this class. ActiveRecord::Base.connection returns an AbstractAdapter object, which you can use.

Most of the methods in the adapter are useful during migrations. Most notably, the instance methods provided by SchemaStatement are very useful.

Methods

active? adapter_name create_savepoint current_savepoint_name decrement_open_transactions disable_referential_integrity disconnect! format_log_entry increment_open_transactions log log_info open_transactions prefetch_primary_key? quote_table_name raw_connection reconnect! release_savepoint requires_reloading? reset! rollback_to_savepoint supports_count_distinct? supports_ddl_transactions? supports_migrations? supports_savepoints? transaction_joinable= verify!

Included Modules

Quoting DatabaseStatements SchemaStatements QueryCache ActiveSupport::Callbacks

Public Instance methods

active?()

Checks whether the connection to the database is still active. This includes checking whether the database is actually capable of responding, i.e. whether the connection isn‘t stale.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 108
108:       def active?
109:         @active != false
110:       end
adapter_name()

Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 47
47:       def adapter_name
48:         'Abstract'
49:       end
create_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 173
173:       def create_savepoint
174:       end
current_savepoint_name()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 182
182:       def current_savepoint_name
183:         "active_record_#{open_transactions}"
184:       end
decrement_open_transactions()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 165
165:       def decrement_open_transactions
166:         @open_transactions -= 1
167:       end
disable_referential_integrity() {|| ...}

Override to turn off referential integrity while executing &block.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 99
 99:       def disable_referential_integrity(&block)
100:         yield
101:       end
disconnect!()

Disconnects from the database if already connected. Otherwise, this method does nothing.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 120
120:       def disconnect!
121:         @active = false
122:       end
increment_open_transactions()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 160
160:       def increment_open_transactions
161:         @open_transactions ||= 0
162:         @open_transactions += 1
163:       end
log_info(sql, name, ms)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 186
186:       def log_info(sql, name, ms)
187:         if @logger && @logger.debug?
188:           name = '%s (%.1fms)' % [name || 'SQL', ms]
189:           @logger.debug(format_log_entry(name, sql.squeeze(' ')))
190:         end
191:       end
open_transactions()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 156
156:       def open_transactions
157:         @open_transactions ||= 0
158:       end
prefetch_primary_key?(table_name = nil)

Should primary key values be selected from their corresponding sequence before the insert statement? If true, next_sequence_value is called before each insert to set the record‘s primary key. This is false for all adapters but Firebird.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 80
80:       def prefetch_primary_key?(table_name = nil)
81:         false
82:       end
quote_table_name(name)

Override to return the quoted table name. Defaults to column quoting.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 92
92:       def quote_table_name(name)
93:         quote_column_name(name)
94:       end
raw_connection()

Provides access to the underlying database driver for this adapter. For example, this method returns a Mysql object in case of MysqlAdapter, and a PGconn object in case of PostgreSQLAdapter.

This is useful for when you need to call a proprietary method such as PostgreSQL‘s lo_* methods.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 152
152:       def raw_connection
153:         @connection
154:       end
reconnect!()

Disconnects from the database if already connected, and establishes a new connection with the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 114
114:       def reconnect!
115:         @active = true
116:       end
release_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 179
179:       def release_savepoint
180:       end
requires_reloading?()

Returns true if its safe to reload the connection between requests for development mode.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 135
135:       def requires_reloading?
136:         true
137:       end
reset!()

Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state. Usually a database-dependent operation.

The default implementation does nothing; the implementation should be overridden by concrete adapters.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 130
130:       def reset!
131:         # this should be overridden by concrete adapters
132:       end
rollback_to_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 176
176:       def rollback_to_savepoint
177:       end
supports_count_distinct?()

Does this adapter support using DISTINCT within COUNT? This is true for all adapters except sqlite.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 59
59:       def supports_count_distinct?
60:         true
61:       end
supports_ddl_transactions?()

Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL, SQL Server, and others support this. MySQL and others do not.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 66
66:       def supports_ddl_transactions?
67:         false
68:       end
supports_migrations?()

Does this adapter support migrations? Backend specific, as the abstract adapter always returns false.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 53
53:       def supports_migrations?
54:         false
55:       end
supports_savepoints?()

Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite does not.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 72
72:       def supports_savepoints?
73:         false
74:       end
transaction_joinable=(joinable)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 169
169:       def transaction_joinable=(joinable)
170:         @transaction_joinable = joinable
171:       end
verify!(*ignored)

Checks whether the connection to the database is still active (i.e. not stale). This is done under the hood by calling active?. If the connection is no longer active, then this method will reconnect to the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 142
142:       def verify!(*ignored)
143:         reconnect! unless active?
144:       end

Protected Instance methods

format_log_entry(message, dump = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 215
215:         def format_log_entry(message, dump = nil)
216:           if ActiveRecord::Base.colorize_logging
217:             if @@row_even
218:               @@row_even = false
219:               message_color, dump_color = "4;36;1", "0;1"
220:             else
221:               @@row_even = true
222:               message_color, dump_color = "4;35;1", "0"
223:             end
224:
225:             log_entry = "  \e[#{message_color}m#{message}\e[0m   "
226:             log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
227:             log_entry
228:           else
229:             "%s  %s" % [message, dump]
230:           end
231:         end
log(sql, name) {|| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 194
194:         def log(sql, name)
195:           if block_given?
196:             result = nil
197:             ms = Benchmark.ms { result = yield }
198:             @runtime += ms
199:             log_info(sql, name, ms)
200:             result
201:           else
202:             log_info(sql, name, 0)
203:             nil
204:           end
205:         rescue Exception => e
206:           # Log message and raise exception.
207:           # Set last_verification to 0, so that connection gets verified
208:           # upon reentering the request loop
209:           @last_verification = 0
210:           message = "#{e.class.name}: #{e.message}: #{sql}"
211:           log_info(message, name, 0)
212:           raise ActiveRecord::StatementInvalid, message
213:         end


Class: ActiveRecord::ConnectionAdapters::Column

Class | ActiveRecord::ConnectionAdapters::Column
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
Parent: | Object

An abstract definition of a column in a table.

Methods

binary_to_string extract_default fallback_string_to_date fallback_string_to_time fast_string_to_date fast_string_to_time has_default? human_name klass microseconds new new_date new_time number? string_to_binary string_to_date string_to_dummy_time string_to_time text? type_cast type_cast_code value_to_boolean value_to_decimal

Classes and Modules

Module ActiveRecord::ConnectionAdapters::Column::Format

Constants

TRUE_VALUES | = | [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
FALSE_VALUES | = | [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set

Attributes

default | [R]
limit | [R]
name | [R]
null | [R]
precision | [R]
primary | [RW]
scale | [R]
sql_type | [R]
type | [R]

Public Class methods

binary_to_string(value)

Used to convert from BLOBs to Strings

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 121
121:         def binary_to_string(value)
122:           value
123:         end
new(name, default, sql_type = nil, null = true)

Instantiates a new column in the table.

name is the column‘s name, such as supplier_id in supplier_id int(11). default is the type-casted default value, such as new in sales_stage varchar(20) default ‘new‘. sql_type is only used to extract the column‘s length, if necessary. For example +60+ in company_name varchar(60). null determines if this column allows NULL values.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 27
27:       def initialize(name, default, sql_type = nil, null = true)
28:         @name, @sql_type, @null = name, sql_type, null
29:         @limit, @precision, @scale = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type)
30:         @type = simplified_type(sql_type)
31:         @default = extract_default(default)
32:
33:         @primary = nil
34:       end
string_to_binary(value)

Used to convert from Strings to BLOBs

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 116
116:         def string_to_binary(value)
117:           value
118:         end
string_to_date(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 125
125:         def string_to_date(string)
126:           return string unless string.is_a?(String)
127:           return nil if string.empty?
128:
129:           fast_string_to_date(string) || fallback_string_to_date(string)
130:         end
string_to_dummy_time(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 139
139:         def string_to_dummy_time(string)
140:           return string unless string.is_a?(String)
141:           return nil if string.empty?
142:
143:           string_to_time "2000-01-01 #{string}"
144:         end
string_to_time(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 132
132:         def string_to_time(string)
133:           return string unless string.is_a?(String)
134:           return nil if string.empty?
135:
136:           fast_string_to_time(string) || fallback_string_to_time(string)
137:         end
value_to_boolean(value)

convert something to a boolean

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 147
147:         def value_to_boolean(value)
148:           if value.is_a?(String) && value.blank?
149:             nil
150:           else
151:             TRUE_VALUES.include?(value)
152:           end
153:         end
value_to_decimal(value)

convert something to a BigDecimal

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 156
156:         def value_to_decimal(value)
157:           # Using .class is faster than .is_a? and
158:           # subclasses of BigDecimal will be handled
159:           # in the else clause
160:           if value.class == BigDecimal
161:             value
162:           elsif value.respond_to?(:to_d)
163:             value.to_d
164:           else
165:             value.to_s.to_d
166:           end
167:         end

Protected Class methods

fallback_string_to_date(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 203
203:           def fallback_string_to_date(string)
204:             new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
205:           end
fallback_string_to_time(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 207
207:           def fallback_string_to_time(string)
208:             time_hash = Date._parse(string)
209:             time_hash[:sec_fraction] = microseconds(time_hash)
210:
211:             new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
212:           end
fast_string_to_date(string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 189
189:           def fast_string_to_date(string)
190:             if string =~ Format::ISO_DATE
191:               new_date $1.to_i, $2.to_i, $3.to_i
192:             end
193:           end
fast_string_to_time(string)

Doesn‘t handle time zones.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 196
196:           def fast_string_to_time(string)
197:             if string =~ Format::ISO_DATETIME
198:               microsec = ($7.to_f * 1_000_000).to_i
199:               new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
200:             end
201:           end
microseconds(time)

‘0.123456’ -> 123456 ‘1.123456’ -> 123456

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 172
172:           def microseconds(time)
173:             ((time[:sec_fraction].to_f % 1) * 1_000_000).to_i
174:           end
new_date(year, mon, mday)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 176
176:           def new_date(year, mon, mday)
177:             if year && year != 0
178:               Date.new(year, mon, mday) rescue nil
179:             end
180:           end
new_time(year, mon, mday, hour, min, sec, microsec)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 182
182:           def new_time(year, mon, mday, hour, min, sec, microsec)
183:             # Treat 0000-00-00 00:00:00 as nil.
184:             return nil if year.nil? || year == 0
185:
186:             Time.time_with_datetime_fallback(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
187:           end

Public Instance methods

extract_default(default)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 110
110:       def extract_default(default)
111:         type_cast(default)
112:       end
has_default?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 46
46:       def has_default?
47:         !default.nil?
48:       end
human_name()

Returns the human name of the column name.

Examples
 Column.new('sales_stage', ...).human_name # => 'Sales stage'

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 106
106:       def human_name
107:         Base.human_attribute_name(@name)
108:       end
klass()

Returns the Ruby class that corresponds to the abstract data type.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 51
51:       def klass
52:         case type
53:           when :integer       then Fixnum
54:           when :float         then Float
55:           when :decimal       then BigDecimal
56:           when :datetime      then Time
57:           when :date          then Date
58:           when :timestamp     then Time
59:           when :time          then Time
60:           when :text, :string then String
61:           when :binary        then String
62:           when :boolean       then Object
63:         end
64:       end
number?()

Returns true if the column is either of type integer, float or decimal.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 42
42:       def number?
43:         type == :integer || type == :float || type == :decimal
44:       end
text?()

Returns true if the column is either of type string or text.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 37
37:       def text?
38:         type == :string || type == :text
39:       end
type_cast(value)

Casts value (which is a String) to an appropriate instance.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 67
67:       def type_cast(value)
68:         return nil if value.nil?
69:         case type
70:           when :string    then value
71:           when :text      then value
72:           when :integer   then value.to_i rescue value ? 1 : 0
73:           when :float     then value.to_f
74:           when :decimal   then self.class.value_to_decimal(value)
75:           when :datetime  then self.class.string_to_time(value)
76:           when :timestamp then self.class.string_to_time(value)
77:           when :time      then self.class.string_to_dummy_time(value)
78:           when :date      then self.class.string_to_date(value)
79:           when :binary    then self.class.binary_to_string(value)
80:           when :boolean   then self.class.value_to_boolean(value)
81:           else value
82:         end
83:       end
type_cast_code(var_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 85
 85:       def type_cast_code(var_name)
 86:         case type
 87:           when :string    then nil
 88:           when :text      then nil
 89:           when :integer   then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
 90:           when :float     then "#{var_name}.to_f"
 91:           when :decimal   then "#{self.class.name}.value_to_decimal(#{var_name})"
 92:           when :datetime  then "#{self.class.name}.string_to_time(#{var_name})"
 93:           when :timestamp then "#{self.class.name}.string_to_time(#{var_name})"
 94:           when :time      then "#{self.class.name}.string_to_dummy_time(#{var_name})"
 95:           when :date      then "#{self.class.name}.string_to_date(#{var_name})"
 96:           when :binary    then "#{self.class.name}.binary_to_string(#{var_name})"
 97:           when :boolean   then "#{self.class.name}.value_to_boolean(#{var_name})"
 98:           else nil
 99:         end
100:       end


Module: ActiveRecord::ConnectionAdapters::Column::Format

Module | ActiveRecord::ConnectionAdapters::Column::Format
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb

Constants

ISO_DATE | = | /\A(\d{4})-(\d\d)-(\d\d)\z/
ISO_DATETIME | = | /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/


Class: ActiveRecord::ConnectionAdapters::ConnectionHandler

Class | ActiveRecord::ConnectionAdapters::ConnectionHandler
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
Parent: | Object

ConnectionHandler is a collection of ConnectionPool objects. It is used for keeping separate connection pools for ActiveRecord models that connect to different databases.

For example, suppose that you have 5 models, with the following hierarchy:

 |
 +-- Book
 |    |
 |    +-- ScaryBook
 |    +-- GoodBook
 +-- Author
 +-- BankAccount

Suppose that Book is to connect to a separate database (i.e. one other than the default database). Then Book, ScaryBook and GoodBook will all use the same connection pool. Likewise, Author and BankAccount will use the same connection pool. However, the connection pool used by Author/BankAccount is not the same as the one used by Book/ScaryBook/GoodBook.

Normally there is only a single ConnectionHandler instance, accessible via ActiveRecord::Base.connection_handler. ActiveRecord models use this to determine that connection pool that they should use.

Methods

clear_active_connections! clear_all_connections! clear_reloadable_connections! connected? connection_pools establish_connection new remove_connection retrieve_connection_pool

Public Class methods

new(pools = {})

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 287
287:       def initialize(pools = {})
288:         @connection_pools = pools
289:       end

Public Instance methods

clear_active_connections!()

Returns any connections in use by the current thread back to the pool, and also returns connections to the pool cached by threads that are no longer alive.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 302
302:       def clear_active_connections!
303:         @connection_pools.each_value {|pool| pool.release_connection }
304:       end
clear_all_connections!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 311
311:       def clear_all_connections!
312:         @connection_pools.each_value {|pool| pool.disconnect! }
313:       end
clear_reloadable_connections!()

Clears the cache which maps classes

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 307
307:       def clear_reloadable_connections!
308:         @connection_pools.each_value {|pool| pool.clear_reloadable_connections! }
309:       end
connected?(klass)

Returns true if a connection that‘s accessible to this class has already been opened.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 331
331:       def connected?(klass)
332:         conn = retrieve_connection_pool(klass)
333:         conn ? conn.connected? : false
334:       end
connection_pools()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 291
291:       def connection_pools
292:         @connection_pools ||= {}
293:       end
establish_connection(name, spec)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 295
295:       def establish_connection(name, spec)
296:         @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
297:       end
remove_connection(klass)

Remove the connection for this class. This will close the active connection and the defined connection (if they exist). The result can be used as an argument for establish_connection, for easily re-establishing the connection.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 340
340:       def remove_connection(klass)
341:         pool = @connection_pools[klass.name]
342:         @connection_pools.delete_if { |key, value| value == pool }
343:         pool.disconnect! if pool
344:         pool.spec.config if pool
345:       end
retrieve_connection_pool(klass)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 347
347:       def retrieve_connection_pool(klass)
348:         pool = @connection_pools[klass.name]
349:         return pool if pool
350:         return nil if ActiveRecord::Base == klass
351:         retrieve_connection_pool klass.superclass
352:       end


Class: ActiveRecord::ConnectionAdapters::ConnectionManagement

Class | ActiveRecord::ConnectionAdapters::ConnectionManagement
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 356
356:       def initialize(app)
357:         @app = app
358:       end

Public Instance methods

call(env)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 360
360:       def call(env)
361:         @app.call(env)
362:       ensure
363:         # Don't return connection (and peform implicit rollback) if
364:         # this request is a part of integration test
365:         unless env.key?("rack.test")
366:           ActiveRecord::Base.clear_active_connections!
367:         end
368:       end


Class: ActiveRecord::ConnectionAdapters::ConnectionPool

Class | ActiveRecord::ConnectionAdapters::ConnectionPool
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
Parent: | Object

Connection pool base class for managing ActiveRecord database connections.

Introduction

A connection pool synchronizes thread access to a limited number of database connections. The basic idea is that each thread checks out a database connection from the pool, uses that connection, and checks the connection back in. ConnectionPool is completely thread-safe, and will ensure that a connection cannot be used by two threads at the same time, as long as ConnectionPool‘s contract is correctly followed. It will also handle cases in which there are more threads than connections: if all connections have been checked out, and a thread tries to checkout a connection anyway, then ConnectionPool will wait until some other thread has checked in a connection.

Obtaining (checking out) a connection

Connections can be obtained and used from a connection pool in several ways:

  1. Simply use ActiveRecord::Base.connection as with ActiveRecord 2.1 and earlier (pre-connection-pooling). Eventually, when you‘re done with the connection(s) and wish it to be returned to the pool, you call ActiveRecord::Base.clear_active_connections!. This will be the default behavior for ActiveRecord when used in conjunction with ActionPack‘s request handling cycle.
  2. Manually check out a connection from the pool with ActiveRecord::Base.connection_pool.checkout. You are responsible for returning this connection to the pool when finished by calling ActiveRecord::Base.connection_pool.checkin(connection).
  3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which obtains a connection, yields it as the sole argument to the block, and returns it to the pool after the block completes.

Connections in the pool are actually AbstractAdapter objects (or objects compatible with AbstractAdapter‘s interface).

Options

There are two connection-pooling-related options that you can add to your database connection configuration:

  • pool: number indicating size of connection pool (default 5)
  • wait_timeout: number of seconds to block and wait for a connection before giving up and raising a timeout error (default 5 seconds).

Methods

checkin checkout clear_reloadable_connections! clear_stale_cached_connections! connected? connection disconnect! new release_connection with_connection

Attributes

spec [R]

Public Class methods

new(spec)

Creates a new ConnectionPool object. spec is a ConnectionSpecification object which describes database connection information (e.g. adapter, host name, username, password, etc), as well as the maximum size for this ConnectionPool.

The default ConnectionPool maximum size is 5.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 66
66:       def initialize(spec)
67:         @spec = spec
68:
69:         # The cache of reserved connections mapped to threads
70:         @reserved_connections = {}
71:
72:         # The mutex used to synchronize pool access
73:         @connection_mutex = Monitor.new
74:         @queue = @connection_mutex.new_cond
75:
76:         # default 5 second timeout unless on ruby 1.9
77:         @timeout =
78:           if RUBY_VERSION < '1.9'
79:             spec.config[:wait_timeout] || 5
80:           end
81:
82:         # default max pool size to 5
83:         @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
84:
85:         @connections = []
86:         @checked_out = []
87:       end

Public Instance methods

checkin(conn)

Check-in a database connection back into the pool, indicating that you no longer need this connection.

conn: an AbstractAdapter object, which was obtained by earlier by calling checkout on this pool.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 210
210:       def checkin(conn)
211:         @connection_mutex.synchronize do
212:           conn.run_callbacks :checkin
213:           @checked_out.delete conn
214:           @queue.signal
215:         end
216:       end
checkout()

Check-out a database connection from the pool, indicating that you want to use it. You should call checkin when you no longer need this.

This is done by either returning an existing connection, or by creating a new connection. If the maximum number of connections for this pool has already been reached, but the pool is empty (i.e. they‘re all being used), then this method will wait until a thread has checked in a connection. The wait time is bounded however: if no connection can be checked out within the timeout specified for this pool, then a ConnectionTimeoutError exception will be raised.

Returns: an AbstractAdapter object.

Raises:

  • ConnectionTimeoutError: no connection can be obtained from the pool within the timeout period.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 181
181:       def checkout
182:         # Checkout an available connection
183:         @connection_mutex.synchronize do
184:           loop do
185:             conn = if @checked_out.size < @connections.size
186:                      checkout_existing_connection
187:                    elsif @connections.size < @size
188:                      checkout_new_connection
189:                    end
190:             return conn if conn
191:             # No connections available; wait for one
192:             if @queue.wait(@timeout)
193:               next
194:             else
195:               # try looting dead threads
196:               clear_stale_cached_connections!
197:               if @size == @checked_out.size
198:                 raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}.  The max pool size is currently #{@size}; consider increasing it."
199:               end
200:             end
201:           end
202:         end
203:       end
clear_reloadable_connections!()

Clears the cache which maps classes

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 137
137:       def clear_reloadable_connections!
138:         @reserved_connections.each do |name, conn|
139:           checkin conn
140:         end
141:         @reserved_connections = {}
142:         @connections.each do |conn|
143:           conn.disconnect! if conn.requires_reloading?
144:         end
145:         @connections = []
146:       end
clear_stale_cached_connections!()

Return any checked-out connections back to the pool by threads that are no longer alive.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 159
159:       def clear_stale_cached_connections!
160:         remove_stale_cached_threads!(@reserved_connections) do |name, conn|
161:           checkin conn
162:         end
163:       end
connected?()

Returns true if a connection has already been opened.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 120
120:       def connected?
121:         !@connections.empty?
122:       end
connection()

Retrieve the connection associated with the current thread, or call checkout to obtain one if necessary.

connection can be called any number of times; the connection is held in a hash keyed by the thread id.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 94
 94:       def connection
 95:         if conn = @reserved_connections[current_connection_id]
 96:           conn
 97:         else
 98:           @reserved_connections[current_connection_id] = checkout
 99:         end
100:       end
disconnect!()

Disconnects all connections in the pool, and clears the pool.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 125
125:       def disconnect!
126:         @reserved_connections.each do |name,conn|
127:           checkin conn
128:         end
129:         @reserved_connections = {}
130:         @connections.each do |conn|
131:           conn.disconnect!
132:         end
133:         @connections = []
134:       end
release_connection()

Signal that the thread is finished with the current connection. release_connection releases the connection-thread association and returns the connection to the pool.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 105
105:       def release_connection
106:         conn = @reserved_connections.delete(current_connection_id)
107:         checkin conn if conn
108:       end
with_connection() {|conn| ...}

Reserve a connection, and yield it to a block. Ensure the connection is checked back in when finished.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 112
112:       def with_connection
113:         conn = checkout
114:         yield conn
115:       ensure
116:         checkin conn
117:       end


Module: ActiveRecord::ConnectionAdapters::DatabaseStatements

Module | ActiveRecord::ConnectionAdapters::DatabaseStatements
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb

Methods

add_limit! add_limit_offset! add_lock! begin_db_transaction case_sensitive_equality_operator commit_db_transaction default_sequence_name delete delete_sql empty_insert_statement execute insert insert_fixture insert_sql limited_update_conditions outside_transaction? reset_sequence! rollback_db_transaction sanitize_limit select select_all select_one select_rows select_value select_values transaction update update_sql

Public Instance methods

add_limit!(sql, options)

Alias for add_limit_offset!.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 185
185:       def add_limit!(sql, options)
186:         add_limit_offset!(sql, options) if options
187:       end
add_limit_offset!(sql, options)

Appends LIMIT and OFFSET options to an SQL statement, or some SQL fragment that has the same semantics as LIMIT and OFFSET.

options must be a Hash which contains a +:limit+ option (required) and an +:offset+ option (optional).

This method modifies the sql parameter.

Examples
 add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})

generates

 SELECT * FROM suppliers LIMIT 10 OFFSET 50

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 201
201:       def add_limit_offset!(sql, options)
202:         if limit = options[:limit]
203:           sql << " LIMIT #{sanitize_limit(limit)}"
204:           if offset = options[:offset]
205:             sql << " OFFSET #{offset.to_i}"
206:           end
207:         end
208:         sql
209:       end
add_lock!(sql, options)

Appends a locking clause to an SQL statement. This method modifies the sql parameter.

  # SELECT * FROM suppliers FOR UPDATE
  add_lock! 'SELECT * FROM suppliers', :lock => true
  add_lock! 'SELECT * FROM suppliers', :lock => ' FOR UPDATE'

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 216
216:       def add_lock!(sql, options)
217:         case lock = options[:lock]
218:           when true;   sql << ' FOR UPDATE'
219:           when String; sql << " #{lock}"
220:         end
221:       end
begin_db_transaction()

Begins the transaction (and turns off auto-committing).

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 175
175:       def begin_db_transaction()    end
case_sensitive_equality_operator()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 242
242:       def case_sensitive_equality_operator
243:         "="
244:       end
commit_db_transaction()

Commits the transaction (and turns on auto-committing).

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 178
178:       def commit_db_transaction()   end
default_sequence_name(table, column)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 223
223:       def default_sequence_name(table, column)
224:         nil
225:       end
delete(sql, name = nil)

Executes the delete statement and returns the number of rows affected.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 53
53:       def delete(sql, name = nil)
54:         delete_sql(sql, name)
55:       end
empty_insert_statement(table_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 238
238:       def empty_insert_statement(table_name)
239:         "INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
240:       end
execute(sql, name = nil, skip_logging = false)

Executes the SQL statement in the context of this connection.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 38
38:       def execute(sql, name = nil, skip_logging = false)
39:       end
insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)

Returns the last auto-generated ID from the affected table.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 43
43:       def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
44:         insert_sql(sql, name, pk, id_value, sequence_name)
45:       end
insert_fixture(fixture, table_name)

Inserts the given fixture into the table. Overridden in adapters that require something beyond a simple insert (eg. Oracle).

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 234
234:       def insert_fixture(fixture, table_name)
235:         execute "INSERT INTO #{quote_table_name(table_name)} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
236:       end
limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 246
246:       def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
247:         "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{quoted_table_name} #{where_sql})"
248:       end
outside_transaction?()

Checks whether there is currently no transaction active. This is done by querying the database driver, and does not use the transaction house-keeping information recorded by increment_open_transactions and friends.

Returns true if there is no transaction active, false if there is a transaction active, and nil if this information is unknown.

Not all adapters supports transaction state introspection. Currently, only the PostgreSQL adapter supports this.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 67
67:       def outside_transaction?
68:         nil
69:       end
reset_sequence!(table, column, sequence = nil)

Set the sequence to the max value of the table‘s column.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 228
228:       def reset_sequence!(table, column, sequence = nil)
229:         # Do nothing by default.  Implement for PostgreSQL, Oracle, ...
230:       end
rollback_db_transaction()

Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block raises an exception or returns false.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 182
182:       def rollback_db_transaction() end
select_all(sql, name = nil)

Returns an array of record hashes with the column names as keys and column values as values.

[Source]

   # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 6
6:       def select_all(sql, name = nil)
7:         select(sql, name)
8:       end
select_one(sql, name = nil)

Returns a record hash with the column names as keys and column values as values.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 12
12:       def select_one(sql, name = nil)
13:         result = select_all(sql, name)
14:         result.first if result
15:       end
select_rows(sql, name = nil)

Returns an array of arrays containing the field values. Order is the same as that returned by columns.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 33
33:       def select_rows(sql, name = nil)
34:       end
select_value(sql, name = nil)

Returns a single value from a record

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 18
18:       def select_value(sql, name = nil)
19:         if result = select_one(sql, name)
20:           result.values.first
21:         end
22:       end
select_values(sql, name = nil)

Returns an array of the values of the first column in a select:

  select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 26
26:       def select_values(sql, name = nil)
27:         result = select_rows(sql, name)
28:         result.map { |v| v[0] }
29:       end
transaction(options = {}) {|| ...}

Runs the given block in a database transaction, and returns the result of the block.

Nested transactions support

Most databases don‘t support true nested transactions. At the time of writing, the only database that supports true nested transactions that we‘re aware of, is MS-SQL.

In order to get around this problem, transaction will emulate the effect of nested transactions, by using savepoints: dev.mysql.com/doc/refman/5.0/en/savepoints.html Savepoints are supported by MySQL and PostgreSQL, but not SQLite3.

It is safe to call this method if a database transaction is already open, i.e. if transaction is called within another transaction block. In case of a nested call, transaction will behave as follows:

  • The block will be run without doing anything. All database statements that happen within the block are effectively appended to the already open database transaction.
  • However, if +:requires_new+ is set, the block will be wrapped in a database savepoint acting as a sub-transaction.

Caveats

MySQL doesn‘t support DDL transactions. If you perform a DDL operation, then any created savepoints will be automatically released. For example, if you‘ve created a savepoint, then you execute a CREATE TABLE statement, then the savepoint that was created will be automatically released.

This means that, on MySQL, you shouldn‘t execute DDL operations inside a transaction call that you know might create a savepoint. Otherwise, transaction will raise exceptions when it tries to release the already-automatically-released savepoints:

  Model.connection.transaction do  # BEGIN
    Model.connection.transaction(:requires_new => true) do  # CREATE SAVEPOINT active_record_1
      Model.connection.create_table(...)
      # active_record_1 now automatically released
    end  # RELEASE SAVEPOINT active_record_1  <--- BOOM! database error!
  end

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 113
113:       def transaction(options = {})
114:         options.assert_valid_keys :requires_new, :joinable
115:
116:         last_transaction_joinable = @transaction_joinable
117:         if options.has_key?(:joinable)
118:           @transaction_joinable = options[:joinable]
119:         else
120:           @transaction_joinable = true
121:         end
122:         requires_new = options[:requires_new] || !last_transaction_joinable
123:
124:         transaction_open = false
125:         begin
126:           if block_given?
127:             if requires_new || open_transactions == 0
128:               if open_transactions == 0
129:                 begin_db_transaction
130:               elsif requires_new
131:                 create_savepoint
132:               end
133:               increment_open_transactions
134:               transaction_open = true
135:             end
136:             yield
137:           end
138:         rescue Exception => database_transaction_rollback
139:           if transaction_open && !outside_transaction?
140:             transaction_open = false
141:             decrement_open_transactions
142:             if open_transactions == 0
143:               rollback_db_transaction
144:             else
145:               rollback_to_savepoint
146:             end
147:           end
148:           raise unless database_transaction_rollback.is_a?(ActiveRecord::Rollback)
149:         end
150:       ensure
151:         @transaction_joinable = last_transaction_joinable
152:
153:         if outside_transaction?
154:           @open_transactions = 0
155:         elsif transaction_open
156:           decrement_open_transactions
157:           begin
158:             if open_transactions == 0
159:               commit_db_transaction
160:             else
161:               release_savepoint
162:             end
163:           rescue Exception => database_transaction_rollback
164:             if open_transactions == 0
165:               rollback_db_transaction
166:             else
167:               rollback_to_savepoint
168:             end
169:             raise
170:           end
171:         end
172:       end
update(sql, name = nil)

Executes the update statement and returns the number of rows affected.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 48
48:       def update(sql, name = nil)
49:         update_sql(sql, name)
50:       end

Protected Instance methods

delete_sql(sql, name = nil)

Executes the delete statement and returns the number of rows affected.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 269
269:         def delete_sql(sql, name = nil)
270:           update_sql(sql, name)
271:         end
insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)

Returns the last auto-generated ID from the affected table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 258
258:         def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
259:           execute(sql, name)
260:           id_value
261:         end
sanitize_limit(limit)

Sanitizes the given LIMIT parameter in order to prevent SQL injection.

limit may be anything that can evaluate to a string via to_s. It should look like an integer, or a comma-delimited list of integers.

Returns the sanitized limit parameter, either as an integer, or as a string which contains a comma-delimited list of integers.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 280
280:         def sanitize_limit(limit)
281:           if limit.to_s =~ /,/
282:             limit.to_s.split(',').map{ |i| i.to_i }.join(',')
283:           else
284:             limit.to_i
285:           end
286:         end
select(sql, name = nil)

Returns an array of record hashes with the column names as keys and column values as values.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 253
253:         def select(sql, name = nil)
254:         end
update_sql(sql, name = nil)

Executes the update statement and returns the number of rows affected.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 264
264:         def update_sql(sql, name = nil)
265:           execute(sql, name)
266:         end


Class: ActiveRecord::ConnectionAdapters::MysqlAdapter

Class | ActiveRecord::ConnectionAdapters::MysqlAdapter
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
Parent: | AbstractAdapter

The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with the faster C-based MySQL/Ruby adapter (available both as a gem and from www.tmtm.org/en/mysql/ruby/).

Options:

  • :host - Defaults to "localhost".
  • :port - Defaults to 3306.
  • :socket - Defaults to "/tmp/mysql.sock".
  • :username - Defaults to "root"
  • :password - Defaults to nothing.
  • :database - The name of the database. No default, must be provided.
  • :encoding - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
  • :reconnect - Defaults to false (See MySQL documentation: dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
  • :sslca - Necessary to use MySQL with an SSL connection.
  • :sslkey - Necessary to use MySQL with an SSL connection.
  • :sslcert - Necessary to use MySQL with an SSL connection.
  • :sslcapath - Necessary to use MySQL with an SSL connection.
  • :sslcipher - Necessary to use MySQL with an SSL connection.

Methods

active? case_sensitive_equality_operator change_column_null charset collation create_database create_savepoint current_database disconnect! drop_table limited_update_conditions new quote quoted_false quoted_true reconnect! release_savepoint rename_table reset! rollback_to_savepoint select_rows show_variable type_to_sql

Constants

ADAPTER_NAME | = | 'MySQL'.freeze
LOST_CONNECTION_ERROR_MESSAGES | = | [ "Server shutdown in progress", "Broken pipe", "Lost connection to MySQL server during query", "MySQL server has gone away" ]
QUOTED_FALSE | = | '1'.freeze, '0'.freeze
NATIVE_DATABASE_TYPES | = | { :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY".freeze, :string => { :name => "varchar", :limit => 255 }, :text => { :name => "text" }, :integer => { :name => "int", :limit => 4 }, :float => { :name => "float" }, :decimal => { :name => "decimal" }, :datetime => { :name => "datetime" }, :timestamp => { :name => "datetime" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "blob" }, :boolean => { :name => "tinyint", :limit => 1 }

Public Class methods

new(connection, logger, connection_options, config)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 202
202:       def initialize(connection, logger, connection_options, config)
203:         super(connection, logger)
204:         @connection_options, @config = connection_options, config
205:         @quoted_column_names, @quoted_table_names = {}, {}
206:         connect
207:       end

Public Instance methods

active?()

CONNECTION MANAGEMENT ====================================

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 274
274:       def active?
275:         if @connection.respond_to?(:stat)
276:           @connection.stat
277:         else
278:           @connection.query 'select 1'
279:         end
280:
281:         # mysql-ruby doesn't raise an exception when stat fails.
282:         if @connection.respond_to?(:errno)
283:           @connection.errno.zero?
284:         else
285:           true
286:         end
287:       rescue Mysql::Error
288:         false
289:       end
case_sensitive_equality_operator()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 559
559:       def case_sensitive_equality_operator
560:         "= BINARY"
561:       end
change_column_null(table_name, column_name, null, default = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 487
487:       def change_column_null(table_name, column_name, null, default = nil)
488:         column = column_for(table_name, column_name)
489:
490:         unless null || default.nil?
491:           execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
492:         end
493:
494:         change_column table_name, column_name, column.sql_type, :null => null
495:       end
charset()

Returns the database character set.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 427
427:       def charset
428:         show_variable 'character_set_database'
429:       end
collation()

Returns the database collation strategy.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 432
432:       def collation
433:         show_variable 'collation_database'
434:       end
create_database(name, options = {})

Create a new MySQL database with optional :charset and :collation. Charset defaults to utf8.

Example:

  create_database 'charset_test', :charset => 'latin1', :collation => 'latin1_bin'
  create_database 'matt_development'
  create_database 'matt_development', :charset => :big5

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 410
410:       def create_database(name, options = {})
411:         if options[:collation]
412:           execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`"
413:         else
414:           execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`"
415:         end
416:       end
create_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 359
359:       def create_savepoint
360:         execute("SAVEPOINT #{current_savepoint_name}")
361:       end
current_database()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 422
422:       def current_database
423:         select_value 'SELECT DATABASE() as db'
424:       end
disconnect!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 296
296:       def disconnect!
297:         @connection.close rescue nil
298:       end
drop_table(table_name, options = {})

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 444
444:       def drop_table(table_name, options = {})
445:         super(table_name, options)
446:       end
limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 563
563:       def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
564:         where_sql
565:       end
quote(value, column = nil)

QUOTING ==================================================

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 228
228:       def quote(value, column = nil)
229:         if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
230:           s = column.class.string_to_binary(value).unpack("H*")[0]
231:           "x'#{s}'"
232:         elsif value.kind_of?(BigDecimal)
233:           value.to_s("F")
234:         else
235:           super
236:         end
237:       end
quoted_false()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 255
255:       def quoted_false
256:         QUOTED_FALSE
257:       end
quoted_true()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 251
251:       def quoted_true
252:         QUOTED_TRUE
253:       end
reconnect!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 291
291:       def reconnect!
292:         disconnect!
293:         connect
294:       end
release_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 367
367:       def release_savepoint
368:         execute("RELEASE SAVEPOINT #{current_savepoint_name}")
369:       end
rename_table(table_name, new_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 478
478:       def rename_table(table_name, new_name)
479:         execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
480:       end
reset!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 300
300:       def reset!
301:         if @connection.respond_to?(:change_user)
302:           # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to
303:           # reset the connection is to change the user to the same user.
304:           @connection.change_user(@config[:username], @config[:password], @config[:database])
305:           configure_connection
306:         end
307:       end
rollback_to_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 363
363:       def rollback_to_savepoint
364:         execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
365:       end
select_rows(sql, name = nil)

DATABASE STATEMENTS ======================================

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 311
311:       def select_rows(sql, name = nil)
312:         @connection.query_with_result = true
313:         result = execute(sql, name)
314:         rows = []
315:         result.each { |row| rows << row }
316:         result.free
317:         rows
318:       end
show_variable(name)

SHOW VARIABLES LIKE ‘name‘

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 543
543:       def show_variable(name)
544:         variables = select_all("SHOW VARIABLES LIKE '#{name}'")
545:         variables.first['Value'] unless variables.empty?
546:       end
type_to_sql(type, limit = nil, precision = nil, scale = nil)

Maps logical Rails types to MySQL-specific data types.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb, line 528
528:       def type_to_sql(type, limit = nil, precision = nil, scale = nil)
529:         return super unless type.to_s == 'integer'
530:
531:         case limit
532:         when 1; 'tinyint'
533:         when 2; 'smallint'
534:         when 3; 'mediumint'
535:         when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
536:         when 5..8; 'bigint'
537:         else raise(ActiveRecordError, "No integer type has byte size #{limit}")
538:         end
539:       end


Class: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

Class | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
Parent: | AbstractAdapter

The PostgreSQL adapter works both with the native C (ruby.scripting.ca/postgres/) and the pure Ruby (available both as gem and from rubyforge.org/frs/?group_id=234&release_id=1944) drivers.

Options:

  • :host - Defaults to "localhost".
  • :port - Defaults to 5432.
  • :username - Defaults to nothing.
  • :password - Defaults to nothing.
  • :database - The name of the database. No default, must be provided.
  • :schema_search_path - An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.
  • :encoding - An optional client encoding that is used in a SET client_encoding TO <encoding> call on the connection.
  • :min_messages - An optional client min messages that is used in a SET client_min_messages TO <min_messages> call on the connection.
  • :allow_concurrency - If true, use async query methods so Ruby threads don‘t deadlock; otherwise, use blocking query methods.

Methods

active? adapter_name add_column begin_db_transaction change_column change_column_default change_column_null client_min_messages client_min_messages= columns commit_db_transaction create_database create_savepoint current_database disconnect! encoding escape_bytea execute indexes insert new outside_transaction? postgresql_version reconnect! release_savepoint remove_index rename_column rename_table rollback_db_transaction rollback_to_savepoint schema_search_path schema_search_path= select_rows supports_ddl_transactions? supports_insert_with_returning? supports_migrations? supports_savepoints? supports_standard_conforming_strings? table_alias_length tables type_to_sql unescape_bytea update_sql

Constants

ADAPTER_NAME | = | 'PostgreSQL'.freeze
NATIVE_DATABASE_TYPES | = | { :primary_key => "serial primary key".freeze, :string => { :name => "character varying", :limit => 255 }, :text => { :name => "text" }, :integer => { :name => "integer" }, :float => { :name => "float" }, :decimal => { :name => "decimal" }, :datetime => { :name => "timestamp" }, :timestamp => { :name => "timestamp" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "bytea" }, :boolean => { :name => "boolean" }

Public Class methods

new(connection, logger, connection_parameters, config)

Initializes and connects a PostgreSQL adapter.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 206
206:       def initialize(connection, logger, connection_parameters, config)
207:         super(connection, logger)
208:         @connection_parameters, @config = connection_parameters, config
209:
210:         connect
211:       end

Public Instance methods

active?()

Is this connection alive and ready for queries?

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 214
214:       def active?
215:         if @connection.respond_to?(:status)
216:           @connection.status == PGconn::CONNECTION_OK
217:         else
218:           # We're asking the driver, not ActiveRecord, so use @connection.query instead of #query
219:           @connection.query 'SELECT 1'
220:           true
221:         end
222:       # postgres-pr raises a NoMethodError when querying if no connection is available.
223:       rescue PGError, NoMethodError
224:         false
225:       end
adapter_name()

Returns ‘PostgreSQL’ as adapter name for identification purposes.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 201
201:       def adapter_name
202:         ADAPTER_NAME
203:       end
add_column(table_name, column_name, type, options = {})

Adds a new column to the named table. See TableDefinition#column for details of the options you can use.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 792
792:       def add_column(table_name, column_name, type, options = {})
793:         default = options[:default]
794:         notnull = options[:null] == false
795:
796:         # Add the column.
797:         execute("ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}")
798:
799:         change_column_default(table_name, column_name, default) if options_include_default?(options)
800:         change_column_null(table_name, column_name, false, default) if notnull
801:       end
begin_db_transaction()

Begins a transaction.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 522
522:       def begin_db_transaction
523:         execute "BEGIN"
524:       end
change_column(table_name, column_name, type, options = {})

Changes the column of a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 804
804:       def change_column(table_name, column_name, type, options = {})
805:         quoted_table_name = quote_table_name(table_name)
806:
807:         begin
808:           execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
809:         rescue ActiveRecord::StatementInvalid => e
810:           raise e if postgresql_version > 80000
811:           # This is PostgreSQL 7.x, so we have to use a more arcane way of doing it.
812:           begin
813:             begin_db_transaction
814:             tmp_column_name = "#{column_name}_ar_tmp"
815:             add_column(table_name, tmp_column_name, type, options)
816:             execute "UPDATE #{quoted_table_name} SET #{quote_column_name(tmp_column_name)} = CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit], options[:precision], options[:scale])})"
817:             remove_column(table_name, column_name)
818:             rename_column(table_name, tmp_column_name, column_name)
819:             commit_db_transaction
820:           rescue
821:             rollback_db_transaction
822:           end
823:         end
824:
825:         change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
826:         change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
827:       end
change_column_default(table_name, column_name, default)

Changes the default value of a table column.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 830
830:       def change_column_default(table_name, column_name, default)
831:         execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
832:       end
change_column_null(table_name, column_name, null, default = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 834
834:       def change_column_null(table_name, column_name, null, default = nil)
835:         unless null || default.nil?
836:           execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
837:         end
838:         execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
839:       end
client_min_messages()

Returns the current client message level.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 698
698:       def client_min_messages
699:         query('SHOW client_min_messages')[0][0]
700:       end
client_min_messages=(level)

Set the client message level.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 703
703:       def client_min_messages=(level)
704:         execute("SET client_min_messages TO '#{level}'")
705:       end
columns(table_name, name = nil)

Returns the list of all column definitions for a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 659
659:       def columns(table_name, name = nil)
660:         # Limit, precision, and scale are all handled by the superclass.
661:         column_definitions(table_name).collect do |name, type, default, notnull|
662:           PostgreSQLColumn.new(name, default, type, notnull == 'f')
663:         end
664:       end
commit_db_transaction()

Commits a transaction.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 527
527:       def commit_db_transaction
528:         execute "COMMIT"
529:       end
create_database(name, options = {})

Create a new PostgreSQL database. Options include :owner, :template, :encoding, :tablespace, and :connection_limit (note that MySQL uses :charset while PostgreSQL uses :encoding).

Example:

  create_database config[:database], config
  create_database 'foo_development', :encoding => 'unicode'

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 570
570:       def create_database(name, options = {})
571:         options = options.reverse_merge(:encoding => "utf8")
572:
573:         option_string = options.symbolize_keys.sum do |key, value|
574:           case key
575:           when :owner
576:             " OWNER = \"#{value}\""
577:           when :template
578:             " TEMPLATE = \"#{value}\""
579:           when :encoding
580:             " ENCODING = '#{value}'"
581:           when :tablespace
582:             " TABLESPACE = \"#{value}\""
583:           when :connection_limit
584:             " CONNECTION LIMIT = #{value}"
585:           else
586:             ""
587:           end
588:         end
589:
590:         execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
591:       end
create_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 544
544:       def create_savepoint
545:         execute("SAVEPOINT #{current_savepoint_name}")
546:       end
current_database()

Returns the current database name.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 667
667:       def current_database
668:         query('select current_database()')[0][0]
669:       end
disconnect!()

Close the connection.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 239
239:       def disconnect!
240:         @connection.close rescue nil
241:       end
encoding()

Returns the current database encoding format.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 672
672:       def encoding
673:         query("SELECT pg_encoding_to_char(pg_database.encoding) FROM pg_database\nWHERE pg_database.datname LIKE '\#{current_database}'\n")[0][0]
674:       end
escape_bytea(value)

Escapes binary strings for bytea input to the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 289
289:       def escape_bytea(value)
290:         if PGconn.respond_to?(:escape_bytea)
291:           self.class.instance_eval do
292:             define_method(:escape_bytea) do |value|
293:               PGconn.escape_bytea(value) if value
294:             end
295:           end
296:         else
297:           self.class.instance_eval do
298:             define_method(:escape_bytea) do |value|
299:               if value
300:                 result = ''
301:                 value.each_byte { |c| result << sprintf('\\\\%03o', c) }
302:                 result
303:               end
304:             end
305:           end
306:         end
307:         escape_bytea(value)
308:       end
execute(sql, name = nil)

Executes an SQL statement, returning a PGresult object on success or raising a PGError exception otherwise.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 506
506:       def execute(sql, name = nil)
507:         log(sql, name) do
508:           if @async
509:             @connection.async_exec(sql)
510:           else
511:             @connection.exec(sql)
512:           end
513:         end
514:       end
indexes(table_name, name = nil)

Returns the list of all indexes for a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 622
622:       def indexes(table_name, name = nil)
623:          schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
624:          result = query("SELECT distinct i.relname, d.indisunique, a.attname\nFROM pg_class t, pg_class i, pg_index d, pg_attribute a\nWHERE i.relkind = 'i'\nAND d.indexrelid = i.oid\nAND d.indisprimary = 'f'\nAND t.oid = d.indrelid\nAND t.relname = '\#{table_name}'\nAND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (\#{schemas}) )\nAND a.attrelid = t.oid\nAND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum\nOR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum\nOR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum\nOR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum\nOR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum )\nORDER BY i.relname\n", name)
625:
626:         current_index = nil
627:         indexes = []
628:
629:         result.each do |row|
630:           if current_index != row[0]
631:             indexes << IndexDefinition.new(table_name, row[0], row[1] == "t", [])
632:             current_index = row[0]
633:           end
634:
635:           indexes.last.columns << row[2]
636:         end
637:
638:         indexes
639:       end
insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)

Executes an INSERT query and returns the new record‘s ID

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 439
439:       def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
440:         # Extract the table from the insert sql. Yuck.
441:         table = sql.split(" ", 4)[2].gsub('"', '')
442:
443:         # Try an insert with 'returning id' if available (PG >= 8.2)
444:         if supports_insert_with_returning?
445:           pk, sequence_name = *pk_and_sequence_for(table) unless pk
446:           if pk
447:             id = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
448:             clear_query_cache
449:             return id
450:           end
451:         end
452:
453:         # Otherwise, insert then grab last_insert_id.
454:         if insert_id = super
455:           insert_id
456:         else
457:           # If neither pk nor sequence name is given, look them up.
458:           unless pk || sequence_name
459:             pk, sequence_name = *pk_and_sequence_for(table)
460:           end
461:
462:           # If a pk is given, fallback to default sequence name.
463:           # Don't fetch last insert id for a table without a pk.
464:           if pk && sequence_name ||= default_sequence_name(table, pk)
465:             last_insert_id(table, sequence_name)
466:           end
467:         end
468:       end
outside_transaction?()

The ruby-pg driver supports inspecting the transaction status, while the ruby-postgres driver does not.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 539
539:         def outside_transaction?
540:           @connection.transaction_status == PGconn::PQTRANS_IDLE
541:         end
reconnect!()

Close then reopen the connection.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 228
228:       def reconnect!
229:         if @connection.respond_to?(:reset)
230:           @connection.reset
231:           configure_connection
232:         else
233:           disconnect!
234:           connect
235:         end
236:       end
release_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 552
552:       def release_savepoint
553:         execute("RELEASE SAVEPOINT #{current_savepoint_name}")
554:       end
remove_index(table_name, options = {})

Drops an index from a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 847
847:       def remove_index(table_name, options = {})
848:         execute "DROP INDEX #{index_name(table_name, options)}"
849:       end
rename_column(table_name, column_name, new_column_name)

Renames a column in a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 842
842:       def rename_column(table_name, column_name, new_column_name)
843:         execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
844:       end
rename_table(name, new_name)

Renames a table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 786
786:       def rename_table(name, new_name)
787:         execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
788:       end
rollback_db_transaction()

Aborts a transaction.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 532
532:       def rollback_db_transaction
533:         execute "ROLLBACK"
534:       end
rollback_to_savepoint()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 548
548:       def rollback_to_savepoint
549:         execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
550:       end
schema_search_path()

Returns the active schema search path.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 693
693:       def schema_search_path
694:         @schema_search_path ||= query('SHOW search_path')[0][0]
695:       end
schema_search_path=(schema_csv)

Sets the schema search path to a string of comma-separated schema names. Names beginning with $ have to be quoted (e.g. $user => ’$user’). See: www.postgresql.org/docs/current/static/ddl-schemas.html

This should be not be called manually but set in database.yml.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 685
685:       def schema_search_path=(schema_csv)
686:         if schema_csv
687:           execute "SET search_path TO #{schema_csv}"
688:           @schema_search_path = schema_csv
689:         end
690:       end
select_rows(sql, name = nil)

Executes a SELECT query and returns an array of rows. Each row is an array of field values.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 434
434:       def select_rows(sql, name = nil)
435:         select_raw(sql, name).last
436:       end
supports_ddl_transactions?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 272
272:       def supports_ddl_transactions?
273:         true
274:       end
supports_insert_with_returning?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 268
268:       def supports_insert_with_returning?
269:         postgresql_version >= 80200
270:       end
supports_migrations?()

Does PostgreSQL support migrations?

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 248
248:       def supports_migrations?
249:         true
250:       end
supports_savepoints?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 276
276:       def supports_savepoints?
277:         true
278:       end
supports_standard_conforming_strings?()

Does PostgreSQL support standard conforming strings?

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 253
253:       def supports_standard_conforming_strings?
254:         # Temporarily set the client message level above error to prevent unintentional
255:         # error messages in the logs when working on a PostgreSQL database server that
256:         # does not support standard conforming strings.
257:         client_min_messages_old = client_min_messages
258:         self.client_min_messages = 'panic'
259:
260:         # postgres-pr does not raise an exception when client_min_messages is set higher
261:         # than error and "SHOW standard_conforming_strings" fails, but returns an empty
262:         # PGresult instead.
263:         has_support = query('SHOW standard_conforming_strings')[0][0] rescue false
264:         self.client_min_messages = client_min_messages_old
265:         has_support
266:       end
table_alias_length()

Returns the configured supported identifier length supported by PostgreSQL, or report the default of 63 on PostgreSQL 7.x.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 282
282:       def table_alias_length
283:         @table_alias_length ||= (postgresql_version >= 80000 ? query('SHOW max_identifier_length')[0][0].to_i : 63)
284:       end
tables(name = nil)

Returns the list of all tables in the schema search path or a specified schema.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 611
611:       def tables(name = nil)
612:         schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
613:         query("SELECT tablename\nFROM pg_tables\nWHERE schemaname IN (\#{schemas})\n", name).map { |row| row[0] }
614:       end
type_to_sql(type, limit = nil, precision = nil, scale = nil)

Maps logical Rails types to PostgreSQL-specific data types.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 852
852:       def type_to_sql(type, limit = nil, precision = nil, scale = nil)
853:         return super unless type.to_s == 'integer'
854:
855:         case limit
856:           when 1..2;      'smallint'
857:           when 3..4, nil; 'integer'
858:           when 5..8;      'bigint'
859:           else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
860:         end
861:       end
unescape_bytea(value)

Unescapes bytea output from a database to the binary string it represents. NOTE: This is NOT an inverse of escape_bytea! This is only to be used

      on escaped binary output from database drive.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 313
313:       def unescape_bytea(value)
314:         # In each case, check if the value actually is escaped PostgreSQL bytea output
315:         # or an unescaped Active Record attribute that was just written.
316:         if PGconn.respond_to?(:unescape_bytea)
317:           self.class.instance_eval do
318:             define_method(:unescape_bytea) do |value|
319:               if value =~ /\\\d{3}/
320:                 PGconn.unescape_bytea(value)
321:               else
322:                 value
323:               end
324:             end
325:           end
326:         else
327:           self.class.instance_eval do
328:             define_method(:unescape_bytea) do |value|
329:               if value =~ /\\\d{3}/
330:                 result = ''
331:                 i, max = 0, value.size
332:                 while i < max
333:                   char = value[i]
334:                   if char == ?\\
335:                     if value[i+1] == ?\\
336:                       char = ?\\
337:                       i += 1
338:                     else
339:                       char = value[i+1..i+3].oct
340:                       i += 3
341:                     end
342:                   end
343:                   result << char
344:                   i += 1
345:                 end
346:                 result
347:               else
348:                 value
349:               end
350:             end
351:           end
352:         end
353:         unescape_bytea(value)
354:       end
update_sql(sql, name = nil)

Executes an UPDATE query and returns the number of affected tuples.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 517
517:       def update_sql(sql, name = nil)
518:         super.cmd_tuples
519:       end

Protected Instance methods

postgresql_version()

Returns the version of the connected PostgreSQL version.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 900
900:         def postgresql_version
901:           @postgresql_version ||=
902:             if @connection.respond_to?(:server_version)
903:               @connection.server_version
904:             else
905:               # Mimic PGconn.server_version behavior
906:               begin
907:                 query('SELECT version()')[0][0] =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
908:                 ($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
909:               rescue
910:                 0
911:               end
912:             end
913:         end


Module: ActiveRecord::ConnectionAdapters::QueryCache

Module | ActiveRecord::ConnectionAdapters::QueryCache
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb

Methods

cache clear_query_cache columns_with_query_cache dirties_query_cache included select_all_with_query_cache uncached

Attributes

query_cache | [R]
query_cache_enabled | [R]

Public Class methods

dirties_query_cache(base, *method_names)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 14
14:         def dirties_query_cache(base, *method_names)
15:           method_names.each do |method_name|
16:             base.class_eval "def \#{method_name}_with_query_dirty(*args)        # def update_with_query_dirty(*args)\nclear_query_cache if @query_cache_enabled       #   clear_query_cache if @query_cache_enabled\n\#{method_name}_without_query_dirty(*args)       #   update_without_query_dirty(*args)\nend                                               # end\n#\nalias_method_chain :\#{method_name}, :query_dirty  # alias_method_chain :update, :query_dirty\n", __FILE__, __LINE__
17:           end
18:         end
included(base)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 5
 5:         def included(base)
 6:           base.class_eval do
 7:             alias_method_chain :columns, :query_cache
 8:             alias_method_chain :select_all, :query_cache
 9:           end
10:
11:           dirties_query_cache base, :insert, :update, :delete
12:         end

Public Instance methods

cache() {|| ...}

Enable the query cache within the block.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 32
32:       def cache
33:         old, @query_cache_enabled = @query_cache_enabled, true
34:         @query_cache ||= {}
35:         yield
36:       ensure
37:         clear_query_cache
38:         @query_cache_enabled = old
39:       end
clear_query_cache()

Clears the query cache.

One reason you may wish to call this method explicitly is between queries that ask the database to randomize results. Otherwise the cache would see the same SQL query and repeatedly return the same result each time, silently undermining the randomness you were expecting.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 55
55:       def clear_query_cache
56:         @query_cache.clear if @query_cache
57:       end
columns_with_query_cache(*args)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 67
67:       def columns_with_query_cache(*args)
68:         if @query_cache_enabled
69:           @query_cache["SHOW FIELDS FROM #{args.first}"] ||= columns_without_query_cache(*args)
70:         else
71:           columns_without_query_cache(*args)
72:         end
73:       end
select_all_with_query_cache(*args)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 59
59:       def select_all_with_query_cache(*args)
60:         if @query_cache_enabled
61:           cache_sql(args.first) { select_all_without_query_cache(*args) }
62:         else
63:           select_all_without_query_cache(*args)
64:         end
65:       end
uncached() {|| ...}

Disable the query cache within the block.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 42
42:       def uncached
43:         old, @query_cache_enabled = @query_cache_enabled, false
44:         yield
45:       ensure
46:         @query_cache_enabled = old
47:       end


Module: ActiveRecord::ConnectionAdapters::Quoting

Module | ActiveRecord::ConnectionAdapters::Quoting
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb

Methods

quote quote_column_name quote_string quote_table_name quoted_date quoted_false quoted_string_prefix quoted_true

Public Instance methods

quote(value, column = nil)

Quotes the column value to help prevent SQL injection attacks.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 6
 6:       def quote(value, column = nil)
 7:         # records are quoted as their primary key
 8:         return value.quoted_id if value.respond_to?(:quoted_id)
 9:
10:         case value
11:           when String, ActiveSupport::Multibyte::Chars
12:             value = value.to_s
13:             if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
14:               "#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
15:             elsif column && [:integer, :float].include?(column.type)
16:               value = column.type == :integer ? value.to_i : value.to_f
17:               value.to_s
18:             else
19:               "#{quoted_string_prefix}'#{quote_string(value)}'" # ' (for ruby-mode)
20:             end
21:           when NilClass                 then "NULL"
22:           when TrueClass                then (column && column.type == :integer ? '1' : quoted_true)
23:           when FalseClass               then (column && column.type == :integer ? '0' : quoted_false)
24:           when Float, Fixnum, Bignum    then value.to_s
25:           # BigDecimals need to be output in a non-normalized form and quoted.
26:           when BigDecimal               then value.to_s('F')
27:           else
28:             if value.acts_like?(:date) || value.acts_like?(:time)
29:               "'#{quoted_date(value)}'"
30:             else
31:               "#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
32:             end
33:         end
34:       end
quote_column_name(column_name)

Quotes the column name. Defaults to no quoting.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 43
43:       def quote_column_name(column_name)
44:         column_name
45:       end
quote_string(s)

Quotes a string, escaping any ’ (single quote) and \ (backslash) characters.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 38
38:       def quote_string(s)
39:         s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
40:       end
quote_table_name(table_name)

Quotes the table name. Defaults to column name quoting.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 48
48:       def quote_table_name(table_name)
49:         quote_column_name(table_name)
50:       end
quoted_date(value)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 60
60:       def quoted_date(value)
61:         value.to_s(:db)
62:       end
quoted_false()

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 56
56:       def quoted_false
57:         "'f'"
58:       end
quoted_string_prefix()

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 64
64:       def quoted_string_prefix
65:         ''
66:       end
quoted_true()

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 52
52:       def quoted_true
53:         "'t'"
54:       end


Class: ActiveRecord::ConnectionAdapters::SQLiteAdapter

Class | ActiveRecord::ConnectionAdapters::SQLiteAdapter
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
Parent: | AbstractAdapter

The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby drivers (available both as gems and from rubyforge.org/projects/sqlite-ruby/).

Options:

  • :database - Path to the database file.

Methods

catch_schema_changes change_column_null default_primary_key_type disconnect! empty_insert_statement new rename_table requires_reloading? select_rows sqlite_version supports_add_column? supports_ddl_transactions? table_structure valid_alter_table_options

Classes and Modules

Class ActiveRecord::ConnectionAdapters::SQLiteAdapter::Version

External Aliases

remove_column -> remove_columns

Public Class methods

new(connection, logger, config)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 87
87:       def initialize(connection, logger, config)
88:         super(connection, logger)
89:         @config = config
90:       end

Public Instance methods

change_column_null(table_name, column_name, null, default = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 272
272:       def change_column_null(table_name, column_name, null, default = nil)
273:         unless null || default.nil?
274:           execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
275:         end
276:         alter_table(table_name) do |definition|
277:           definition[column_name].null = null
278:         end
279:       end
disconnect!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 112
112:       def disconnect!
113:         super
114:         @connection.close rescue nil
115:       end
empty_insert_statement(table_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 300
300:       def empty_insert_statement(table_name)
301:         "INSERT INTO #{table_name} VALUES(NULL)"
302:       end
rename_table(name, new_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 237
237:       def rename_table(name, new_name)
238:         execute "ALTER TABLE #{name} RENAME TO #{new_name}"
239:       end
requires_reloading?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 104
104:       def requires_reloading?
105:         true
106:       end
select_rows(sql, name = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 174
174:       def select_rows(sql, name = nil)
175:         execute(sql, name).map do |row|
176:           (0...(row.size / 2)).map { |i| row[i] }
177:         end
178:       end
supports_add_column?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 108
108:       def supports_add_column?
109:         sqlite_version >= '3.1.6'
110:       end
supports_ddl_transactions?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 96
96:       def supports_ddl_transactions?
97:         sqlite_version >= '2.0.0'
98:       end
valid_alter_table_options( type, options)

See: www.sqlite.org/lang_altertable.html SQLite has an additional restriction on the ALTER TABLE statement

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 243
243:       def valid_alter_table_options( type, options)
244:         type.to_sym != :primary_key
245:       end

Protected Instance methods

catch_schema_changes() {|| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 402
402:         def catch_schema_changes
403:           return yield
404:         rescue ActiveRecord::StatementInvalid => exception
405:           if exception.message =~ /database schema has changed/
406:             reconnect!
407:             retry
408:           else
409:             raise
410:           end
411:         end
default_primary_key_type()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 417
417:         def default_primary_key_type
418:           if supports_autoincrement?
419:             'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'.freeze
420:           else
421:             'INTEGER PRIMARY KEY NOT NULL'.freeze
422:           end
423:         end
sqlite_version()

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 413
413:         def sqlite_version
414:           @sqlite_version ||= SQLiteAdapter::Version.new(select_value('select sqlite_version(*)'))
415:         end
table_structure(table_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 317
317:         def table_structure(table_name)
318:           returning structure = execute("PRAGMA table_info(#{quote_table_name(table_name)})") do
319:             raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
320:           end
321:         end


Class: ActiveRecord::ConnectionAdapters::SQLiteAdapter::Version

Class | ActiveRecord::ConnectionAdapters::SQLiteAdapter::Version
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
Parent: | Object

Methods

<=> new

Included Modules

Comparable

Public Class methods

new(version_string)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 78
78:         def initialize(version_string)
79:           @version = version_string.split('.').map(&:to_i)
80:         end

Public Instance methods

<=>(version_string)

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb, line 82
82:         def <=>(version_string)
83:           @version <=> version_string.split('.').map(&:to_i)
84:         end


Module: ActiveRecord::ConnectionAdapters::SchemaStatements

Module | ActiveRecord::ConnectionAdapters::SchemaStatements
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb

Methods

add_column add_index add_order_by_for_association_limiting! add_timestamps assume_migrated_upto_version change_column change_column_default change_table columns create_table distinct drop_table initialize_schema_migrations_table native_database_types options_include_default? remove_column remove_columns remove_index remove_timestamps rename_column rename_table structure_dump table_alias_for table_alias_length table_exists?

Public Instance methods

add_column(table_name, column_name, type, options = {})

Adds a new column to the named table. See TableDefinition#column for details of the options you can use.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 192
192:       def add_column(table_name, column_name, type, options = {})
193:         add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
194:         add_column_options!(add_column_sql, options)
195:         execute(add_column_sql)
196:       end
add_index(table_name, column_name, options = {})

Adds a new index to the table. column_name can be a single Symbol, or an Array of Symbols.

The index will be named after the table and the first column name, unless you pass :name as an option.

When creating an index on multiple columns, the first column is used as a name for the index. For example, when you specify an index on two columns [:first, :last], the DBMS creates an index for both columns as well as an index for the first column :first. Using just the first name for this index makes sense, because you will never have to create a singular index with this name.

Examples
Creating a simple index
 add_index(:suppliers, :name)

generates

 CREATE INDEX suppliers_name_index ON suppliers(name)
Creating a unique index
 add_index(:accounts, [:branch_id, :party_id], :unique => true)

generates

 CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
Creating a named index
 add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')

generates

 CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 261
261:       def add_index(table_name, column_name, options = {})
262:         column_names = Array(column_name)
263:         index_name   = index_name(table_name, :column => column_names)
264:
265:         if Hash === options # legacy support, since this param was a string
266:           index_type = options[:unique] ? "UNIQUE" : ""
267:           index_name = options[:name] || index_name
268:         else
269:           index_type = options
270:         end
271:         quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
272:         execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
273:       end
add_order_by_for_association_limiting!(sql, options)

ORDER BY clause for the passed order option. PostgreSQL overrides this due to its stricter standards compliance.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 408
408:       def add_order_by_for_association_limiting!(sql, options)
409:         sql << " ORDER BY #{options[:order]}"
410:       end
add_timestamps(table_name)

Adds timestamps (created_at and updated_at) columns to the named table.

Examples
 add_timestamps(:suppliers)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 415
415:       def add_timestamps(table_name)
416:         add_column table_name, :created_at, :datetime
417:         add_column table_name, :updated_at, :datetime
418:       end
assume_migrated_upto_version(version)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 339
339:       def assume_migrated_upto_version(version)
340:         version = version.to_i
341:         sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
342:
343:         migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
344:         versions = Dir['db/migrate/[0-9]*_*.rb'].map do |filename|
345:           filename.split('/').last.split('_').first.to_i
346:         end
347:
348:         unless migrated.include?(version)
349:           execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
350:         end
351:
352:         inserted = Set.new
353:         (versions - migrated).each do |v|
354:           if inserted.include?(v)
355:             raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
356:           elsif v < version
357:             execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
358:             inserted << v
359:           end
360:         end
361:       end
change_column(table_name, column_name, type, options = {})

Changes the column‘s definition according to the new options. See TableDefinition#column for details of the options you can use.

Examples
 change_column(:suppliers, :name, :string, :limit => 80)
 change_column(:accounts, :description, :text)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 214
214:       def change_column(table_name, column_name, type, options = {})
215:         raise NotImplementedError, "change_column is not implemented"
216:       end
change_column_default(table_name, column_name, default)

Sets a new default value for a column. If you want to set the default value to NULL, you are out of luck. You need to DatabaseStatements#execute the appropriate SQL statement yourself.

Examples
 change_column_default(:suppliers, :qualification, 'new')
 change_column_default(:accounts, :authorized, 1)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 224
224:       def change_column_default(table_name, column_name, default)
225:         raise NotImplementedError, "change_column_default is not implemented"
226:       end
change_table(table_name) {|Table.new(table_name, self)| ...}

A block for changing columns in table.

Example

 # change_table() yields a Table instance
 change_table(:suppliers) do |t|
   t.column :name, :string, :limit => 60
   # Other column alterations here
 end
Examples
Add a column
 change_table(:suppliers) do |t|
   t.column :name, :string, :limit => 60
 end
Add 2 integer columns
 change_table(:suppliers) do |t|
   t.integer :width, :height, :null => false, :default => 0
 end
Add created_at/updated_at columns
 change_table(:suppliers) do |t|
   t.timestamps
 end
Add a foreign key column
 change_table(:suppliers) do |t|
   t.references :company
 end

Creates a company_id(integer) column

Add a polymorphic foreign key column
 change_table(:suppliers) do |t|
   t.belongs_to :company, :polymorphic => true
 end

Creates company_type(varchar) and company_id(integer) columns

Remove a column
 change_table(:suppliers) do |t|
   t.remove :company
 end
Remove several columns
 change_table(:suppliers) do |t|
   t.remove :company_id
   t.remove :width, :height
 end
Remove an index
 change_table(:suppliers) do |t|
   t.remove_index :company_id
 end

See also Table for details on all of the various column transformation

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 174
174:       def change_table(table_name)
175:         yield Table.new(table_name, self)
176:       end
columns(table_name, name = nil)

Returns an array of Column objects for the table specified by table_name. See the concrete implementation for details on the expected parameter values.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 32
32:       def columns(table_name, name = nil) end
create_table(table_name, options = {}) {|table_definition| ...}

Creates a new table with the name table_name. table_name may either be a String or a Symbol.

There are two ways to work with create_table. You can use the block form or the regular form, like this:

Block form

 # create_table() passes a TableDefinition object to the block.
 # This form will not only create the table, but also columns for the
 # table.
 create_table(:suppliers) do |t|
   t.column :name, :string, :limit => 60
   # Other fields here
 end

Regular form

 # Creates a table called 'suppliers' with no columns.
 create_table(:suppliers)
 # Add a column to 'suppliers'.
 add_column(:suppliers, :name, :string, {:limit => 60})

The options hash can include the following keys:

:id
Whether to automatically add a primary key column. Defaults to true. Join tables for has_and_belongs_to_many should set :id => false.
:primary_key
The name of the primary key, if one is to be added automatically. Defaults to id.
:options
Any extra options you want appended to the table definition.
:temporary
Make a temporary table.
:force
Set to true to drop the table before creating it. Defaults to false.
Examples
Add a backend specific option to the generated SQL (MySQL)
 create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')

generates:

 CREATE TABLE suppliers (
   id int(11) DEFAULT NULL auto_increment PRIMARY KEY
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
Rename the primary key column
 create_table(:objects, :primary_key => 'guid') do |t|
   t.column :name, :string, :limit => 80
 end

generates:

 CREATE TABLE objects (
   guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
   name varchar(80)
 )
Do not add a primary key column
 create_table(:categories_suppliers, :id => false) do |t|
   t.column :category_id, :integer
   t.column :supplier_id, :integer
 end

generates:

 CREATE TABLE categories_suppliers (
   category_id int,
   supplier_id int
 )

See also TableDefinition#column for details on how to create columns.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 100
100:       def create_table(table_name, options = {})
101:         table_definition = TableDefinition.new(self)
102:         table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
103:
104:         yield table_definition
105:
106:         if options[:force] && table_exists?(table_name)
107:           drop_table(table_name, options)
108:         end
109:
110:         create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
111:         create_sql << "#{quote_table_name(table_name)} ("
112:         create_sql << table_definition.to_sql
113:         create_sql << ") #{options[:options]}"
114:         execute create_sql
115:       end
distinct(columns, order_by)

SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause. Both PostgreSQL and Oracle overrides this for custom DISTINCT syntax.

  distinct("posts.id", "posts.created_at desc")

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 402
402:       def distinct(columns, order_by)
403:         "DISTINCT #{columns}"
404:       end
drop_table(table_name, options = {})

Drops a table from the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 186
186:       def drop_table(table_name, options = {})
187:         execute "DROP TABLE #{quote_table_name(table_name)}"
188:       end
initialize_schema_migrations_table()

Should not be called normally, but this operation is non-destructive. The migrations module handles this automatically.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 316
316:       def initialize_schema_migrations_table
317:         sm_table = ActiveRecord::Migrator.schema_migrations_table_name
318:
319:         unless tables.detect { |t| t == sm_table }
320:           create_table(sm_table, :id => false) do |schema_migrations_table|
321:             schema_migrations_table.column :version, :string, :null => false
322:           end
323:           add_index sm_table, :version, :unique => true,
324:             :name => 'unique_schema_migrations'
325:
326:           # Backwards-compatibility: if we find schema_info, assume we've
327:           # migrated up to that point:
328:           si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix
329:
330:           if tables.detect { |t| t == si_table }
331:
332:             old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i
333:             assume_migrated_upto_version(old_version)
334:             drop_table(si_table)
335:           end
336:         end
337:       end
native_database_types()

Returns a Hash of mappings from the abstract data types to the native database types. See TableDefinition#column for details on the recognized abstract data types.

[Source]

   # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 7
7:       def native_database_types
8:         {}
9:       end
remove_column(table_name, *column_names)

Removes the column(s) from the table definition.

Examples
 remove_column(:suppliers, :qualification)
 remove_columns(:suppliers, :qualification, :experience)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 202
202:       def remove_column(table_name, *column_names)
203:         column_names.flatten.each do |column_name|
204:           execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
205:         end
206:       end
remove_columns(table_name, *column_names)

Alias for remove_column

remove_index(table_name, options = {})

Remove the given index from the table.

Remove the suppliers_name_index in the suppliers table.

  remove_index :suppliers, :name

Remove the index named accounts_branch_id_index in the accounts table.

  remove_index :accounts, :column => :branch_id

Remove the index named accounts_branch_id_party_id_index in the accounts table.

  remove_index :accounts, :column => [:branch_id, :party_id]

Remove the index named by_branch_party in the accounts table.

  remove_index :accounts, :name => :by_branch_party

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 285
285:       def remove_index(table_name, options = {})
286:         execute "DROP INDEX #{quote_column_name(index_name(table_name, options))} ON #{table_name}"
287:       end
remove_timestamps(table_name)

Removes the timestamp columns (created_at and updated_at) from the table definition.

Examples
 remove_timestamps(:suppliers)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 423
423:       def remove_timestamps(table_name)
424:         remove_column table_name, :updated_at
425:         remove_column table_name, :created_at
426:       end
rename_column(table_name, column_name, new_column_name)

Renames a column.

Example
 rename_column(:suppliers, :description, :name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 231
231:       def rename_column(table_name, column_name, new_column_name)
232:         raise NotImplementedError, "rename_column is not implemented"
233:       end
rename_table(table_name, new_name)

Renames a table.

Example
 rename_table('octopuses', 'octopi')

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 181
181:       def rename_table(table_name, new_name)
182:         raise NotImplementedError, "rename_table is not implemented"
183:       end
structure_dump()

Returns a string of CREATE TABLE SQL statement(s) for recreating the entire structure of the database.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 305
305:       def structure_dump
306:       end
table_alias_for(table_name)

Truncates a table alias according to the limits of the current adapter.

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 17
17:       def table_alias_for(table_name)
18:         table_name[0..table_alias_length-1].gsub(/\./, '_')
19:       end
table_alias_length()

This is the maximum length a table alias can be

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 12
12:       def table_alias_length
13:         255
14:       end
table_exists?(table_name)

def tables(name = nil) end

[Source]

    # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 23
23:       def table_exists?(table_name)
24:         tables.include?(table_name.to_s)
25:       end

Protected Instance methods

options_include_default?(options)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 429
429:         def options_include_default?(options)
430:           options.include?(:default) && !(options[:null] == false && options[:default].nil?)
431:         end


Class: ActiveRecord::ConnectionAdapters::Table

Class | ActiveRecord::ConnectionAdapters::Table
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
Parent: | Object

Represents a SQL table in an abstract way for updating a table. Also see TableDefinition and SchemaStatements#create_table

Available transformations are:

  change_table :table do |t|
    t.column
    t.index
    t.timestamps
    t.change
    t.change_default
    t.rename
    t.references
    t.belongs_to
    t.string
    t.text
    t.integer
    t.float
    t.decimal
    t.datetime
    t.timestamp
    t.time
    t.date
    t.binary
    t.boolean
    t.remove
    t.remove_references
    t.remove_belongs_to
    t.remove_index
    t.remove_timestamps
  end

Methods

belongs_to change change_default column index new references remove remove_belongs_to remove_index remove_references remove_timestamps rename timestamps

Public Class methods

new(table_name, base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 554
554:       def initialize(table_name, base)
555:         @table_name = table_name
556:         @base = base
557:       end

Public Instance methods

belongs_to(*args)

Alias for references

change(column_name, type, options = {})

Changes the column‘s definition according to the new options. See TableDefinition#column for details of the options you can use.

Examples
 t.change(:name, :string, :limit => 80)
 t.change(:description, :text)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 594
594:       def change(column_name, type, options = {})
595:         @base.change_column(@table_name, column_name, type, options)
596:       end
change_default(column_name, default)

Sets a new default value for a column. See SchemaStatements#change_column_default

Examples
 t.change_default(:qualification, 'new')
 t.change_default(:authorized, 1)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 602
602:       def change_default(column_name, default)
603:         @base.change_column_default(@table_name, column_name, default)
604:       end
column(column_name, type, options = {})

Adds a new column to the named table. See TableDefinition#column for details of the options you can use.

Example
Creating a simple column
 t.column(:name, :string)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 564
564:       def column(column_name, type, options = {})
565:         @base.add_column(@table_name, column_name, type, options)
566:       end
index(column_name, options = {})

Adds a new index to the table. column_name can be a single Symbol, or an Array of Symbols. See SchemaStatements#add_index

Examples
Creating a simple index
 t.index(:name)
Creating a unique index
 t.index([:branch_id, :party_id], :unique => true)
Creating a named index
 t.index([:branch_id, :party_id], :unique => true, :name => 'by_branch_party')

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 578
578:       def index(column_name, options = {})
579:         @base.add_index(@table_name, column_name, options)
580:       end
references(*args)

Adds a reference. Optionally adds a type column. references and belongs_to are acceptable.

Examples
 t.references(:goat)
 t.references(:goat, :polymorphic => true)
 t.belongs_to(:goat)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 649
649:       def references(*args)
650:         options = args.extract_options!
651:         polymorphic = options.delete(:polymorphic)
652:         args.each do |col|
653:           @base.add_column(@table_name, "#{col}_id", :integer, options)
654:           @base.add_column(@table_name, "#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
655:         end
656:       end
remove(*column_names)

Removes the column(s) from the table definition.

Examples
 t.remove(:qualification)
 t.remove(:qualification, :experience)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 610
610:       def remove(*column_names)
611:         @base.remove_column(@table_name, column_names)
612:       end
remove_belongs_to(*args)

Alias for remove_references

remove_index(options = {})

Removes the given index from the table.

Examples
Remove the suppliers_name_index in the suppliers table
  t.remove_index :name
Remove the index named accounts_branch_id_index in the accounts table
  t.remove_index :column => :branch_id
Remove the index named accounts_branch_id_party_id_index in the accounts table
  t.remove_index :column => [:branch_id, :party_id]
Remove the index named by_branch_party in the accounts table
  t.remove_index :name => :by_branch_party

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 625
625:       def remove_index(options = {})
626:         @base.remove_index(@table_name, options)
627:       end
remove_references(*args)

Removes a reference. Optionally removes a type column. remove_references and remove_belongs_to are acceptable.

Examples
 t.remove_references(:goat)
 t.remove_references(:goat, :polymorphic => true)
 t.remove_belongs_to(:goat)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 665
665:       def remove_references(*args)
666:         options = args.extract_options!
667:         polymorphic = options.delete(:polymorphic)
668:         args.each do |col|
669:           @base.remove_column(@table_name, "#{col}_id")
670:           @base.remove_column(@table_name, "#{col}_type") unless polymorphic.nil?
671:         end
672:       end
remove_timestamps()

Removes the timestamp columns (created_at and updated_at) from the table.

Example
 t.remove_timestamps

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 632
632:       def remove_timestamps
633:         @base.remove_timestamps(@table_name)
634:       end
rename(column_name, new_column_name)

Renames a column.

Example
 t.rename(:description, :name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 639
639:       def rename(column_name, new_column_name)
640:         @base.rename_column(@table_name, column_name, new_column_name)
641:       end
timestamps()

Adds timestamps (created_at and updated_at) columns to the table. See SchemaStatements#add_timestamps

Example
 t.timestamps

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 585
585:       def timestamps
586:         @base.add_timestamps(@table_name)
587:       end


Class: ActiveRecord::ConnectionAdapters::TableDefinition

Class | ActiveRecord::ConnectionAdapters::TableDefinition
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
Parent: | Object

Represents the schema of an SQL table in an abstract way. This class provides methods for manipulating the schema representation.

Inside migration files, the t object in create_table and change_table is actually of this type:

  class SomeMigration < ActiveRecord::Migration
    def self.up
      create_table :foo do |t|
        puts t.class  # => "ActiveRecord::ConnectionAdapters::TableDefinition"
      end
    end

    def self.down
      ...
    end
  end

The table definitions The Columns are stored as a ColumnDefinition in the columns attribute.

Methods

[] belongs_to column new primary_key references timestamps to_sql

Attributes

columns [RW] An array of ColumnDefinition objects, representing the column changes that have been defined.

Public Class methods

new(base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 314
314:       def initialize(base)
315:         @columns = []
316:         @base = base
317:       end

Public Instance methods

[](name)

Returns a ColumnDefinition for the column with name name.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 326
326:       def [](name)
327:         @columns.find {|column| column.name.to_s == name.to_s}
328:       end
belongs_to(*args)

Alias for references

column(name, type, options = {})

Instantiates a new column for the table. The type parameter is normally one of the migrations native types, which is one of the following: :primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean.

You may use a type not in this list as long as it is supported by your database (for example, "polygon" in MySQL), but this will not be database agnostic and should usually be avoided.

Available options are (none of these exists by default):

  • :limit - Requests a maximum column length. This is number of characters for :string and :text columns and number of bytes for :binary and :integer columns.
  • :default - The column‘s default value. Use nil for NULL.
  • :null - Allows or disallows NULL values in the column. This option could have been named :null_allowed.
  • :precision - Specifies the precision for a :decimal column.
  • :scale - Specifies the scale for a :decimal column.

For clarity‘s sake: the precision is the number of significant digits, while the scale is the number of digits that can be stored following the decimal point. For example, the number 123.45 has a precision of 5 and a scale of 2. A decimal with a precision of 5 and a scale of 2 can range from -999.99 to 999.99.

Please be aware of different RDBMS implementations behavior with :decimal columns:

  • The SQL standard says the default scale should be 0, :scale <= :precision, and makes no comments about the requirements of :precision.
  • MySQL: :precision [1..63], :scale [0..30]. Default is (10,0).
  • PostgreSQL: :precision [1..infinity], :scale [0..infinity]. No default.
  • SQLite2: Any :precision and :scale may be used. Internal storage as strings. No default.
  • SQLite3: No restrictions on :precision and :scale, but the maximum supported :precision is 16. No default.
  • Oracle: :precision [1..38], :scale [-84..127]. Default is (38,0).
  • DB2: :precision [1..63], :scale [0..62]. Default unknown.
  • Firebird: :precision [1..18], :scale [0..18]. Default (9,0). Internal types NUMERIC and DECIMAL have different storage rules, decimal being better.
  • FrontBase?: :precision [1..38], :scale [0..38]. Default (38,0). WARNING Max :precision/:scale for NUMERIC is 19, and DECIMAL is 38.
  • SqlServer?: :precision [1..38], :scale [0..38]. Default (38,0).
  • Sybase: :precision [1..38], :scale [0..38]. Default (38,0).
  • OpenBase?: Documentation unclear. Claims storage in double.

This method returns self.

Examples

 # Assuming td is an instance of TableDefinition
 td.column(:granted, :boolean)
 # granted BOOLEAN

 td.column(:picture, :binary, :limit => 2.megabytes)
 # => picture BLOB(2097152)

 td.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false)
 # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL

 td.column(:bill_gates_money, :decimal, :precision => 15, :scale => 2)
 # => bill_gates_money DECIMAL(15,2)

 td.column(:sensor_reading, :decimal, :precision => 30, :scale => 20)
 # => sensor_reading DECIMAL(30,20)

 # While <tt>:scale</tt> defaults to zero on most databases, it
 # probably wouldn't hurt to include it.
 td.column(:huge_integer, :decimal, :precision => 30)
 # => huge_integer DECIMAL(30)

 # Defines a column with a database-specific type.
 td.column(:foo, 'polygon')
 # => foo polygon

Short-hand examples

Instead of calling column directly, you can also work with the short-hand definitions for the default types. They use the type as the method name instead of as a parameter and allow for multiple columns to be defined in a single statement.

What can be written like this with the regular calls to column:

  create_table "products", :force => true do |t|
    t.column "shop_id",    :integer
    t.column "creator_id", :integer
    t.column "name",       :string,   :default => "Untitled"
    t.column "value",      :string,   :default => "Untitled"
    t.column "created_at", :datetime
    t.column "updated_at", :datetime
  end

Can also be written as follows using the short-hand:

  create_table :products do |t|
    t.integer :shop_id, :creator_id
    t.string  :name, :value, :default => "Untitled"
    t.timestamps
  end

There‘s a short-hand method for each of the type values declared at the top. And then there‘s TableDefinition#timestamps that‘ll add created_at and updated_at as datetimes.

TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type column if the :polymorphic option is supplied. If :polymorphic is a hash of options, these will be used when creating the _type column. So what can be written like this:

  create_table :taggings do |t|
    t.integer :tag_id, :tagger_id, :taggable_id
    t.string  :tagger_type
    t.string  :taggable_type, :default => 'Photo'
  end

Can also be written as follows using references:

  create_table :taggings do |t|
    t.references :tag
    t.references :tagger, :polymorphic => true
    t.references :taggable, :polymorphic => { :default => 'Photo' }
  end

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 463
463:       def column(name, type, options = {})
464:         column = self[name] || ColumnDefinition.new(@base, name, type)
465:         if options[:limit]
466:           column.limit = options[:limit]
467:         elsif native[type.to_sym].is_a?(Hash)
468:           column.limit = native[type.to_sym][:limit]
469:         end
470:         column.precision = options[:precision]
471:         column.scale = options[:scale]
472:         column.default = options[:default]
473:         column.null = options[:null]
474:         @columns << column unless @columns.include? column
475:         self
476:       end
primary_key(name)

Appends a primary key definition to the table definition. Can be called multiple times, but this is probably not a good idea.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 321
321:       def primary_key(name)
322:         column(name, :primary_key)
323:       end
references(*args)

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 498
498:       def references(*args)
499:         options = args.extract_options!
500:         polymorphic = options.delete(:polymorphic)
501:         args.each do |col|
502:           column("#{col}_id", :integer, options)
503:           column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
504:         end
505:       end
timestamps(*args)

Appends :datetime columns :created_at and :updated_at to the table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 492
492:       def timestamps(*args)
493:         options = args.extract_options!
494:         column(:created_at, :datetime, options)
495:         column(:updated_at, :datetime, options)
496:       end
to_sql()

Returns a String whose contents are the column definitions concatenated together. This string can then be prepended and appended to to generate the final SQL to create the table.

[Source]

     # File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 511
511:       def to_sql
512:         @columns * ', '
513:       end


Class: ActiveRecord::ConnectionNotEstablished

Class | ActiveRecord::ConnectionNotEstablished
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when connection to the database could not been established (for example when connection= is given a nil object).


Class: ActiveRecord::ConnectionTimeoutError

Class | ActiveRecord::ConnectionTimeoutError
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
Parent: | ConnectionNotEstablished

Raised when a connection could not be obtained within the connection acquisition timeout period.


Class: ActiveRecord::DangerousAttributeError

Class | ActiveRecord::DangerousAttributeError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when attribute has a name reserved by Active Record (when attribute has name of one of Active Record instance methods).


Module: ActiveRecord::Dirty

Module | ActiveRecord::Dirty
In: | vendor/rails/activerecord/lib/active_record/dirty.rb

Track unsaved attribute changes.

A newly instantiated object is unchanged:

  person = Person.find_by_name('uncle bob')
  person.changed?       # => false

Change the name:

  person.name = 'Bob'
  person.changed?       # => true
  person.name_changed?  # => true
  person.name_was       # => 'uncle bob'
  person.name_change    # => ['uncle bob', 'Bob']
  person.name = 'Bill'
  person.name_change    # => ['uncle bob', 'Bill']

Save the changes:

  person.save
  person.changed?       # => false
  person.name_changed?  # => false

Assigning the same value leaves the attribute unchanged:

  person.name = 'Bill'
  person.name_changed?  # => false
  person.name_change    # => nil

Which attributes have changed?

  person.name = 'bob'
  person.changed        # => ['name']
  person.changes        # => { 'name' => ['Bill', 'bob'] }

Before modifying an attribute in-place:

  person.name_will_change!
  person.name << 'by'
  person.name_change    # => ['uncle bob', 'uncle bobby']

Methods

changed changed? changes included

Classes and Modules

Module ActiveRecord::Dirty::ClassMethods

Constants

DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']

Public Class methods

included(base)

[Source]

    # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 39
39:     def self.included(base)
40:       base.attribute_method_suffix *DIRTY_SUFFIXES
41:       base.alias_method_chain :write_attribute, :dirty
42:       base.alias_method_chain :save,            :dirty
43:       base.alias_method_chain :save!,           :dirty
44:       base.alias_method_chain :update,          :dirty
45:       base.alias_method_chain :reload,          :dirty
46:
47:       base.superclass_delegating_accessor :partial_updates
48:       base.partial_updates = true
49:
50:       base.send(:extend, ClassMethods)
51:     end

Public Instance methods

changed()

List of attributes with unsaved changes.

  person.changed # => []
  person.name = 'bob'
  person.changed # => ['name']

[Source]

    # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 65
65:     def changed
66:       changed_attributes.keys
67:     end
changed?()

Do any attributes have unsaved changes?

  person.changed? # => false
  person.name = 'bob'
  person.changed? # => true

[Source]

    # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 57
57:     def changed?
58:       !changed_attributes.empty?
59:     end
changes()

Map of changed attrs => [original value, new value].

  person.changes # => {}
  person.name = 'bob'
  person.changes # => { 'name' => ['bill', 'bob'] }

[Source]

    # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 73
73:     def changes
74:       changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
75:     end


Module: ActiveRecord::Dirty::ClassMethods

Module | ActiveRecord::Dirty::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/dirty.rb

Methods

alias_attribute_with_dirty extended

Public Class methods

extended(base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 169
169:       def self.extended(base)
170:         base.metaclass.alias_method_chain(:alias_attribute, :dirty)
171:       end

Public Instance methods

alias_attribute_with_dirty(new_name, old_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/dirty.rb, line 173
173:       def alias_attribute_with_dirty(new_name, old_name)
174:         alias_attribute_without_dirty(new_name, old_name)
175:         DIRTY_SUFFIXES.each do |suffix|
176:           module_eval "def \#{new_name}\#{suffix}; self.\#{old_name}\#{suffix}; end  # def subject_changed?; self.title_changed?; end\n", __FILE__, __LINE__+1
177:         end
178:       end


Class: ActiveRecord::DynamicFinderMatch

Class | ActiveRecord::DynamicFinderMatch
In: | vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb
Parent: | Object

Methods

bang? finder? instantiator? match new

Attributes

attribute_names | [R]
finder | [R]
instantiator | [R]

Public Class methods

match(method)

[Source]

   # File vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb, line 3
3:     def self.match(method)
4:       df_match = self.new(method)
5:       df_match.finder ? df_match : nil
6:     end
new(method)

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb, line 8
 8:     def initialize(method)
 9:       @finder = :first
10:       case method.to_s
11:       when /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/
12:         @finder = :last if $1 == 'last_by'
13:         @finder = :all if $1 == 'all_by'
14:         names = $2
15:       when /^find_by_([_a-zA-Z]\w*)\!$/
16:         @bang = true
17:         names = $1
18:       when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
19:         @instantiator = $1 == 'initialize' ? :new : :create
20:         names = $2
21:       else
22:         @finder = nil
23:       end
24:       @attribute_names = names && names.split('_and_')
25:     end

Public Instance methods

bang?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb, line 37
37:     def bang?
38:       @bang
39:     end
finder?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb, line 29
29:     def finder?
30:       !@finder.nil? && @instantiator.nil?
31:     end
instantiator?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb, line 33
33:     def instantiator?
34:       @finder == :first && !@instantiator.nil?
35:     end


Class: ActiveRecord::DynamicScopeMatch

Class | ActiveRecord::DynamicScopeMatch
In: | vendor/rails/activerecord/lib/active_record/dynamic_scope_match.rb
Parent: | Object

Methods

match new scope?

Attributes

attribute_names | [R]
scope | [R]

Public Class methods

match(method)

[Source]

   # File vendor/rails/activerecord/lib/active_record/dynamic_scope_match.rb, line 3
3:     def self.match(method)
4:       ds_match = self.new(method)
5:       ds_match.scope ? ds_match : nil
6:     end
new(method)

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_scope_match.rb, line 8
 8:     def initialize(method)
 9:       @scope = true
10:       case method.to_s
11:       when /^scoped_by_([_a-zA-Z]\w*)$/
12:         names = $1
13:       else
14:         @scope = nil
15:       end
16:       @attribute_names = names && names.split('_and_')
17:     end

Public Instance methods

scope?()

[Source]

    # File vendor/rails/activerecord/lib/active_record/dynamic_scope_match.rb, line 21
21:     def scope?
22:       !@scope.nil?
23:     end


Class: ActiveRecord::Errors

Class | ActiveRecord::Errors
In: | vendor/rails/activerecord/lib/active_record/validations.rb
Parent: | Object

Active Record validation is reported to and from this object, which is used by Base#save to determine whether the object is in a valid state to be saved. See usage example in Validations.

Methods

[] add add_on_blank add_on_empty add_to_base clear count default_error_messages each each_full empty? full_messages generate_message invalid? length on on_base size to_xml

Included Modules

Enumerable

Public Class methods

default_error_messages()

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 23
23:       def default_error_messages
24:         ActiveSupport::Deprecation.warn("ActiveRecord::Errors.default_error_messages has been deprecated. Please use I18n.translate('activerecord.errors.messages').")
25:         I18n.translate 'activerecord.errors.messages'
26:       end

Public Instance methods

[](attribute)

Alias for on

add(attribute, message = nil, options = {})

Adds an error message (messsage) to the attribute, which will be returned on a call to on(attribute) for the same attribute and ensure that this error object returns false when asked if empty?. More than one error can be added to the same attribute in which case an array will be returned on a call to on(attribute). If no messsage is supplied, :invalid is assumed. If message is a Symbol, it will be translated, using the appropriate scope (see translate_error).

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 46
46:     def add(attribute, message = nil, options = {})
47:       message ||= :invalid
48:       message = generate_message(attribute, message, options) if message.is_a?(Symbol)
49:       @errors[attribute.to_s] ||= []
50:       @errors[attribute.to_s] << message
51:     end
add_on_blank(attributes, custom_message = nil)

Will add an error message to each of the attributes in attributes that is blank (using Object#blank?).

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 63
63:     def add_on_blank(attributes, custom_message = nil)
64:       for attr in [attributes].flatten
65:         value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s]
66:         add(attr, :blank, :default => custom_message) if value.blank?
67:       end
68:     end
add_on_empty(attributes, custom_message = nil)

Will add an error message to each of the attributes in attributes that is empty.

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 54
54:     def add_on_empty(attributes, custom_message = nil)
55:       for attr in [attributes].flatten
56:         value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s]
57:         is_empty = value.respond_to?(:empty?) ? value.empty? : false
58:         add(attr, :empty, :default => custom_message) unless !value.nil? && !is_empty
59:       end
60:     end
add_to_base(msg)

Adds an error to the base object instead of any particular attribute. This is used to report errors that don‘t tie to any specific attribute, but rather to the object as a whole. These error messages don‘t get prepended with any field name when iterating with each_full, so they should be complete sentences.

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 37
37:     def add_to_base(msg)
38:       add(:base, msg)
39:     end
clear()

Removes all errors that have been added.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 220
220:     def clear
221:       @errors = {}
222:     end
count()

Alias for size

each() {|attr, msg| ...}

Yields each attribute and associated message per error added.

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.each{|attr,msg| puts "#{attr} - #{msg}" }
  # => name - is too short (minimum is 5 characters)
  #    name - can't be blank
  #    address - can't be blank

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 165
165:     def each
166:       @errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } }
167:     end
each_full() {|msg| ...}

Yields each full error message added. So Person.errors.add("first_name", "can‘t be empty") will be returned through iteration as "First name can‘t be empty".

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.each_full{|msg| puts msg }
  # => Name is too short (minimum is 5 characters)
  #    Name can't be blank
  #    Address can't be blank

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 182
182:     def each_full
183:       full_messages.each { |msg| yield msg }
184:     end
empty?()

Returns true if no errors have been added.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 215
215:     def empty?
216:       @errors.empty?
217:     end
full_messages(options = {})

Returns all the full error messages in an array.

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.full_messages # =>
    ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"]

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 196
196:     def full_messages(options = {})
197:       full_messages = []
198:
199:       @errors.each_key do |attr|
200:         @errors[attr].each do |message|
201:           next unless message
202:
203:           if attr == "base"
204:             full_messages << message
205:           else
206:             attr_name = @base.class.human_attribute_name(attr)
207:             full_messages << attr_name + I18n.t('activerecord.errors.format.separator', :default => ' ') + message
208:           end
209:         end
210:       end
211:       full_messages
212:     end
generate_message(attribute, message = :invalid, options = {})

Translates an error message in it‘s default scope (activerecord.errrors.messages). Error messages are first looked up in models.MODEL.attributes.ATTRIBUTE.MESSAGE, if it‘s not there, it‘s looked up in models.MODEL.MESSAGE and if that is not there it returns the translation of the default message (e.g. activerecord.errors.messages.MESSAGE). The translated model name, translated attribute name and the value are available for interpolation.

When using inheritence in your models, it will check all the inherited models too, but only if the model itself hasn‘t been found. Say you have class Admin < User; end and you wanted the translation for the :blank error message for the title attribute, it looks for these translations:

<ol> <li>activerecord.errors.models.admin.attributes.title.blank</li> <li>activerecord.errors.models.admin.blank</li> <li>activerecord.errors.models.user.attributes.title.blank</li> <li>activerecord.errors.models.user.blank</li> <li>activerecord.errors.messages.blank</li> <li>any default you provided through the options hash (in the activerecord.errors scope)</li> </ol>

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 88
 88:     def generate_message(attribute, message = :invalid, options = {})
 89:
 90:       message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
 91:
 92:       defaults = @base.class.self_and_descendants_from_active_record.map do |klass|
 93:         [ "models.#{klass.name.underscore}.attributes.#{attribute}.#{message}""models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
 94:           "models.#{klass.name.underscore}.#{message}""models.#{klass.name.underscore}.#{message}" ]
 95:       end
 96:
 97:       defaults << options.delete(:default)
 98:       defaults = defaults.compact.flatten << "messages.#{message}""messages.#{message}"
 99:
100:       key = defaults.shift
101:       value = @base.respond_to?(attribute) ? @base.send(attribute) : nil
102:
103:       options = { :default => defaults,
104:         :model => @base.class.human_name,
105:         :attribute => @base.class.human_attribute_name(attribute.to_s),
106:         :value => value,
107:         :scope => [:activerecord, :errors]
108:       }.merge(options)
109:
110:       I18n.translate(key, options)
111:     end
invalid?(attribute)

Returns true if the specified attribute has errors associated with it.

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.invalid?(:name)      # => true
  company.errors.invalid?(:address)   # => false

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 123
123:     def invalid?(attribute)
124:       !@errors[attribute.to_s].nil?
125:     end
length()

Alias for size

on(attribute)

Returns nil, if no errors are associated with the specified attribute. Returns the error message, if one error is associated with the specified attribute. Returns an array of error messages, if more than one error is associated with the specified attribute.

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.on(:name)      # => ["is too short (minimum is 5 characters)", "can't be blank"]
  company.errors.on(:email)     # => "can't be blank"
  company.errors.on(:address)   # => nil

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 140
140:     def on(attribute)
141:       errors = @errors[attribute.to_s]
142:       return nil if errors.nil?
143:       errors.size == 1 ? errors.first : errors
144:     end
on_base()

Returns errors assigned to the base object through add_to_base according to the normal rules of on(attribute).

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 149
149:     def on_base
150:       on(:base)
151:     end
size()

Returns the total number of errors added. Two errors added to the same attribute will be counted as such.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 225
225:     def size
226:       @errors.values.inject(0) { |error_count, attribute| error_count + attribute.size }
227:     end
to_xml(options={})

Returns an XML representation of this error object.

  class Company < ActiveRecord::Base
    validates_presence_of :name, :address, :email
    validates_length_of :name, :in => 5..30
  end

  company = Company.create(:address => '123 First St.')
  company.errors.to_xml
  # =>  <?xml version="1.0" encoding="UTF-8"?>
  #     <errors>
  #       <error>Name is too short (minimum is 5 characters)</error>
  #       <error>Name can't be blank</error>
  #       <error>Address can't be blank</error>
  #     </errors>

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 247
247:     def to_xml(options={})
248:       options[:root] ||= "errors"
249:       options[:indent] ||= 2
250:       options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
251:
252:       options[:builder].instruct! unless options.delete(:skip_instruct)
253:       options[:builder].errors do |e|
254:         full_messages.each { |msg| e.error(msg) }
255:       end
256:     end


Module: ActiveRecord::Locking

Module | ActiveRecord::Locking
In: | vendor/rails/activerecord/lib/active_record/locking/optimistic.rb vendor/rails/activerecord/lib/active_record/locking/pessimistic.rb

Classes and Modules

Module ActiveRecord::Locking::Optimistic
Module ActiveRecord::Locking::Pessimistic


Module: ActiveRecord::Locking::Optimistic

Module | ActiveRecord::Locking::Optimistic
In: | vendor/rails/activerecord/lib/active_record/locking/optimistic.rb

What is Optimistic Locking

Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened, an ActiveRecord::StaleObjectError is thrown if that has occurred and the update is ignored.

Check out ActiveRecord::Locking::Pessimistic for an alternative.

Usage

Active Records support optimistic locking if the field lock_version is present. Each update to the record increments the lock_version column and the locking facilities ensure that records instantiated twice will let the last one saved raise a StaleObjectError if the first was also updated. Example:

  p1 = Person.find(1)
  p2 = Person.find(1)

  p1.first_name = "Michael"
  p1.save

  p2.first_name = "should fail"
  p2.save # Raises a ActiveRecord::StaleObjectError

Optimistic locking will also check for stale data when objects are destroyed. Example:

  p1 = Person.find(1)
  p2 = Person.find(1)

  p1.first_name = "Michael"
  p1.save

  p2.destroy # Raises a ActiveRecord::StaleObjectError

You‘re then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.

You must ensure that your database schema defaults the lock_version column to 0.

This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false. To override the name of the lock_version column, invoke the set_locking_column method. This method uses the same syntax as set_table_name

Classes and Modules

Module ActiveRecord::Locking::Optimistic::ClassMethods


Module: ActiveRecord::Locking::Optimistic::ClassMethods

Module | ActiveRecord::Locking::Optimistic::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/locking/optimistic.rb

Methods

extended locking_column locking_enabled? quoted_locking_column reset_locking_column set_locking_column update_counters_with_lock

Constants

DEFAULT_LOCKING_COLUMN = 'lock_version'

Public Class methods

extended(base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 138
138:         def self.extended(base)
139:           class <<base
140:             alias_method_chain :update_counters, :lock
141:           end
142:         end

Public Instance methods

locking_column()

The version column used for optimistic locking. Defaults to lock_version.

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 159
159:         def locking_column
160:           reset_locking_column
161:         end
locking_enabled?()

Is optimistic locking enabled for this table? Returns true if the lock_optimistically flag is set to true (which it is, by default) and the table includes the locking_column column (defaults to lock_version).

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 148
148:         def locking_enabled?
149:           lock_optimistically && columns_hash[locking_column]
150:         end
quoted_locking_column()

Quote the column name used for optimistic locking.

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 164
164:         def quoted_locking_column
165:           connection.quote_column_name(locking_column)
166:         end
reset_locking_column()

Reset the column used for optimistic locking back to the lock_version default.

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 169
169:         def reset_locking_column
170:           set_locking_column DEFAULT_LOCKING_COLUMN
171:         end
set_locking_column(value = nil, &block)

Set the column to use for optimistic locking. Defaults to lock_version.

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 153
153:         def set_locking_column(value = nil, &block)
154:           define_attr_method :locking_column, value, &block
155:           value
156:         end
update_counters_with_lock(id, counters)

Make sure the lock version column gets updated when counters are updated.

[Source]

     # File vendor/rails/activerecord/lib/active_record/locking/optimistic.rb, line 175
175:         def update_counters_with_lock(id, counters)
176:           counters = counters.merge(locking_column => 1) if locking_enabled?
177:           update_counters_without_lock(id, counters)
178:         end


Module: ActiveRecord::Locking::Pessimistic

Module | ActiveRecord::Locking::Pessimistic
In: | vendor/rails/activerecord/lib/active_record/locking/pessimistic.rb

Locking::Pessimistic provides support for row-level locking using SELECT … FOR UPDATE and other lock types.

Pass :lock => true to ActiveRecord::Base.find to obtain an exclusive lock on the selected rows:

  # select * from accounts where id=1 for update
  Account.find(1, :lock => true)

Pass :lock => ‘some locking clause‘ to give a database-specific locking clause of your own such as ‘LOCK IN SHARE MODE’ or ‘FOR UPDATE NOWAIT’.

Example:

  Account.transaction do
    # select * from accounts where name = 'shugo' limit 1 for update
    shugo = Account.find(:first, :conditions => "name = 'shugo'", :lock => true)
    yuko = Account.find(:first, :conditions => "name = 'yuko'", :lock => true)
    shugo.balance -= 100
    shugo.save!
    yuko.balance += 100
    yuko.save!
  end

You can also use ActiveRecord::Base#lock! method to lock one record by id. This may be better if you don‘t need to lock every row. Example:

  Account.transaction do
    # select * from accounts where ...
    accounts = Account.find(:all, :conditions => ...)
    account1 = accounts.detect { |account| ... }
    account2 = accounts.detect { |account| ... }
    # select * from accounts where id=? for update
    account1.lock!
    account2.lock!
    account1.balance -= 100
    account1.save!
    account2.balance += 100
    account2.save!
  end

Database-specific information on row locking:

  MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
  PostgreSQL: http://www.postgresql.org/docs/8.1/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE

Methods

lock!

Public Instance methods

lock!(lock = true)

Obtain a row lock on this record. Reloads the record to obtain the requested lock. Pass an SQL locking clause to append the end of the SELECT statement or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns the locked record.

[Source]

    # File vendor/rails/activerecord/lib/active_record/locking/pessimistic.rb, line 71
71:       def lock!(lock = true)
72:         reload(:lock => lock) unless new_record?
73:         self
74:       end


Class: ActiveRecord::Migration

Class | ActiveRecord::Migration
In: | vendor/rails/activerecord/lib/active_record/migration.rb
Parent: | Object

Migrations can manage the evolution of a schema used by several physical databases. It‘s a solution to the common problem of adding a field to make a new feature work in your local database, but being unsure of how to push that change to other developers and to the production server. With migrations, you can describe the transformations in self-contained classes that can be checked into version control systems and executed against another database that might be one, two, or five versions behind.

Example of a simple migration:

  class AddSsl < ActiveRecord::Migration
    def self.up
      add_column :accounts, :ssl_enabled, :boolean, :default => 1
    end

    def self.down
      remove_column :accounts, :ssl_enabled
    end
  end

This migration will add a boolean flag to the accounts table and remove it if you‘re backing out of the migration. It shows how all migrations have two class methods up and down that describes the transformations required to implement or remove the migration. These methods can consist of both the migration specific methods like add_column and remove_column, but may also contain regular Ruby code for generating data needed for the transformations.

Example of a more complex migration that also needs to initialize data:

  class AddSystemSettings < ActiveRecord::Migration
    def self.up
      create_table :system_settings do |t|
        t.string  :name
        t.string  :label
        t.text  :value
        t.string  :type
        t.integer  :position
      end

      SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
    end

    def self.down
      drop_table :system_settings
    end
  end

This migration first adds the system_settings table, then creates the very first row in it using the Active Record model that relies on the table. It also uses the more advanced create_table syntax where you can specify a complete table schema in one block call.

Available transformations

  • create_table(name, options) Creates a table called name and makes the table object available to a block that can then add columns to it, following the same format as add_column. See example above. The options hash is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create table definition.
  • drop_table(name): Drops the table called name.
  • rename_table(old_name, new_name): Renames the table called old_name to new_name.
  • add_column(table_name, column_name, type, options): Adds a new column to the table called table_name named column_name specified to be one of the following types: :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean. A default value can be specified by passing an options hash like { :default => 11 }. Other options include :limit and :null (e.g. { :limit => 50, :null => false }) — see ActiveRecord::ConnectionAdapters::TableDefinition#column for details.
  • rename_column(table_name, column_name, new_column_name): Renames a column but keeps the type and content.
  • change_column(table_name, column_name, type, options): Changes the column to a different type using the same parameters as add_column.
  • remove_column(table_name, column_name): Removes the column named column_name from the table called table_name.
  • add_index(table_name, column_names, options): Adds a new index with the name of the column. Other options include :name and :unique (e.g. { :name => "users_name_index", :unique => true }).
  • remove_index(table_name, index_name): Removes the index specified by index_name.

Irreversible transformations

Some transformations are destructive in a manner that cannot be reversed. Migrations of that kind should raise an ActiveRecord::IrreversibleMigration exception in their down method.

Running migrations from within Rails

The Rails package has several tools to help create and apply migrations.

To generate a new migration, you can use

  script/generate migration MyNewMigration

where MyNewMigration is the name of your migration. The generator will create an empty migration file nnn_my_new_migration.rb in the db/migrate/ directory where nnn is the next largest migration number.

You may then edit the self.up and self.down methods of MyNewMigration.

There is a special syntactic shortcut to generate migrations that add fields to a table.

  script/generate migration add_fieldname_to_tablename fieldname:string

This will generate the file nnn_add_fieldname_to_tablename, which will look like this:

  class AddFieldnameToTablename < ActiveRecord::Migration
    def self.up
      add_column :tablenames, :fieldname, :string
    end

    def self.down
      remove_column :tablenames, :fieldname
    end
  end

To run migrations against the currently configured database, use rake db:migrate. This will update the database by running all of the pending migrations, creating the schema_migrations table (see "About the schema_migrations table" section below) if missing. It will also invoke the db:schema:dump task, which will update your db/schema.rb file to match the structure of your database.

To roll the database back to a previous migration version, use rake db:migrate VERSION=X where X is the version to which you wish to downgrade. If any of the migrations throw an ActiveRecord::IrreversibleMigration exception, that step will fail and you‘ll have some manual work to do.

Database support

Migrations are currently supported in MySQL, PostgreSQL, SQLite, SQL Server, Sybase, and Oracle (all supported databases except DB2).

More examples

Not all migrations change the schema. Some just fix the data:

  class RemoveEmptyTags < ActiveRecord::Migration
    def self.up
      Tag.find(:all).each { |tag| tag.destroy if tag.pages.empty? }
    end

    def self.down
      # not much we can do to restore deleted data
      raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags"
    end
  end

Others remove columns when they migrate up instead of down:

  class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration
    def self.up
      remove_column :items, :incomplete_items_count
      remove_column :items, :completed_items_count
    end

    def self.down
      add_column :items, :incomplete_items_count
      add_column :items, :completed_items_count
    end
  end

And sometimes you need to do something in SQL not abstracted directly by migrations:

  class MakeJoinUnique < ActiveRecord::Migration
    def self.up
      execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
    end

    def self.down
      execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`"
    end
  end

Using a model after changing its table

Sometimes you‘ll want to add a column in a migration and populate it immediately after. In that case, you‘ll need to make a call to Base#reset_column_information in order to ensure that the model has the latest column data from after the new column was added. Example:

  class AddPeopleSalary < ActiveRecord::Migration
    def self.up
      add_column :people, :salary, :integer
      Person.reset_column_information
      Person.find(:all).each do |p|
        p.update_attribute :salary, SalaryCalculator.compute(p)
      end
    end
  end

Controlling verbosity

By default, migrations will describe the actions they are taking, writing them to the console as they happen, along with benchmarks describing how long each step took.

You can quiet them down by setting ActiveRecord::Migration.verbose = false.

You can also insert your own messages and benchmarks by using the say_with_time method:

  def self.up
    ...
    say_with_time "Updating salaries..." do
      Person.find(:all).each do |p|
        p.update_attribute :salary, SalaryCalculator.compute(p)
      end
    end
    ...
  end

The phrase "Updating salaries…" would then be printed, along with the benchmark for the block when the block completes.

About the schema_migrations table

Rails versions 2.0 and prior used to create a table called schema_info when using migrations. This table contained the version of the schema as of the last applied migration.

Starting with Rails 2.1, the schema_info table is (automatically) replaced by the schema_migrations table, which contains the version numbers of all the migrations applied.

As a result, it is now possible to add migration files that are numbered lower than the current schema version: when migrating up, those never-applied "interleaved" migrations will be automatically applied, and when migrating down, never-applied "interleaved" migrations will be skipped.

Timestamped Migrations

By default, Rails generates migrations that look like:

   20080717013526_your_migration_name.rb

The prefix is a generation timestamp (in UTC).

If you‘d prefer to use numeric prefixes, you can turn timestamped migrations off by setting:

   config.active_record.timestamped_migrations = false

In environment.rb.

Methods

announce connection method_missing migrate say say_with_time suppress_messages write

Public Class methods

announce(message)

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 315
315:       def announce(message)
316:         text = "#{@version} #{name}: #{message}"
317:         length = [0, 75 - text.length].max
318:         write "== %s %s" % [text, "=" * length]
319:       end
connection()

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 341
341:       def connection
342:         ActiveRecord::Base.connection
343:       end
method_missing(method, *arguments, &block)

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 345
345:       def method_missing(method, *arguments, &block)
346:         arg_list = arguments.map(&:inspect) * ', '
347:
348:         say_with_time "#{method}(#{arg_list})" do
349:           unless arguments.empty? || method == :execute
350:             arguments[0] = Migrator.proper_table_name(arguments.first)
351:           end
352:           connection.send(method, *arguments, &block)
353:         end
354:       end
migrate(direction)

Execute this migration in the named direction

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 273
273:       def migrate(direction)
274:         return unless respond_to?(direction)
275:
276:         case direction
277:           when :up   then announce "migrating"
278:           when :down then announce "reverting"
279:         end
280:
281:         result = nil
282:         time = Benchmark.measure { result = send("#{direction}_without_benchmarks") }
283:
284:         case direction
285:           when :up   then announce "migrated (%.4fs)" % time.real; write
286:           when :down then announce "reverted (%.4fs)" % time.real; write
287:         end
288:
289:         result
290:       end
say(message, subitem=false)

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 321
321:       def say(message, subitem=false)
322:         write "#{subitem ? "   ->" : "--"} #{message}"
323:       end
say_with_time(message) {|| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 325
325:       def say_with_time(message)
326:         say(message)
327:         result = nil
328:         time = Benchmark.measure { result = yield }
329:         say "%.4fs" % time.real, :subitem
330:         say("#{result} rows", :subitem) if result.is_a?(Integer)
331:         result
332:       end
suppress_messages() {|| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 334
334:       def suppress_messages
335:         save, self.verbose = verbose, false
336:         yield
337:       ensure
338:         self.verbose = save
339:       end
write(text="")

[Source]

     # File vendor/rails/activerecord/lib/active_record/migration.rb, line 311
311:       def write(text="")
312:         puts(text) if verbose
313:       end


Class: ActiveRecord::MigrationProxy

Class | ActiveRecord::MigrationProxy
In: | vendor/rails/activerecord/lib/active_record/migration.rb
Parent: | Object

MigrationProxy is used to defer loading of the actual migration classes until they are needed

Attributes

filename | [RW]
name | [RW]
version | [RW]


Class: ActiveRecord::MissingAttributeError

Class | ActiveRecord::MissingAttributeError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | NoMethodError

Raised when you‘ve tried to access a column which wasn‘t loaded by your finder. Typically this is because :select has been specified.


Class: ActiveRecord::MultiparameterAssignmentErrors

Class | ActiveRecord::MultiparameterAssignmentErrors
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when there are multiple errors while doing a mass assignment through the attributes method. The exception has an errors property that contains an array of AttributeAssignmentError objects, each corresponding to the error while assigning to an attribute.

Methods

new

Attributes

errors [R]

Public Class methods

new(errors)

[Source]

     # File vendor/rails/activerecord/lib/active_record/base.rb, line 146
146:     def initialize(errors)
147:       @errors = errors
148:     end


Module: ActiveRecord::NamedScope

Module | ActiveRecord::NamedScope
In: | vendor/rails/activerecord/lib/active_record/named_scope.rb

Methods

included

Classes and Modules

Module ActiveRecord::NamedScope::ClassMethods
Class ActiveRecord::NamedScope::Scope

Public Class methods

included(base)

All subclasses of ActiveRecord::Base have one named scope:

  • scoped - which allows for the creation of anonymous \scopes, on the fly: Shirt.scoped(:conditions => {:color => ‘red’}).scoped(:include => :washing_instructions)

These anonymous \scopes tend to be useful when procedurally generating complex queries, where passing intermediate values (scopes) around as first-class objects is convenient.

You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.

[Source]

    # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 10
10:     def self.included(base)
11:       base.class_eval do
12:         extend ClassMethods
13:         named_scope :scoped, lambda { |scope| scope }
14:       end
15:     end


Module: ActiveRecord::NamedScope::ClassMethods

Module | ActiveRecord::NamedScope::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/named_scope.rb

Methods

named_scope scopes

Public Instance methods

named_scope(name, options = {}, &block)

Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query, such as :conditions => {:color => :red}, :select => ‘shirts.*’, :include => :washing_instructions.

  class Shirt < ActiveRecord::Base
    named_scope :red, :conditions => {:color => 'red'}
    named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
  end

The above calls to named_scope define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, in effect, represents the query Shirt.find(:all, :conditions => {:color => ‘red’}).

Unlike Shirt.find(...), however, the object returned by Shirt.red is not an Array; it resembles the association object constructed by a has_many declaration. For instance, you can invoke Shirt.red.find(:first), Shirt.red.count, Shirt.red.find(:all, :conditions => {:size => ‘small’}). Also, just as with the association objects, named \scopes act like an Array, implementing Enumerable; Shirt.red.each(&block), Shirt.red.first, and Shirt.red.inject(memo, &block) all behave as if Shirt.red really was an Array.

These named \scopes are composable. For instance, Shirt.red.dry_clean_only will produce all shirts that are both red and dry clean only. Nested finds and calculations also work with these compositions: Shirt.red.dry_clean_only.count returns the number of garments for which these criteria obtain. Similarly with Shirt.red.dry_clean_only.average(:thread_count).

All \scopes are available as class methods on the ActiveRecord::Base descendant upon which the \scopes were defined. But they are also available to has_many associations. If,

  class Person < ActiveRecord::Base
    has_many :shirts
  end

then elton.shirts.red.dry_clean_only will return all of Elton‘s red, dry clean only shirts.

Named \scopes can also be procedural:

  class Shirt < ActiveRecord::Base
    named_scope :colored, lambda { |color|
      { :conditions => { :color => color } }
    }
  end

In this example, Shirt.colored(‘puce’) finds all puce shirts.

Named \scopes can also have extensions, just as with has_many declarations:

  class Shirt < ActiveRecord::Base
    named_scope :red, :conditions => {:color => 'red'} do
      def dom_id
        'red_shirts'
      end
    end
  end

For testing complex named \scopes, you can examine the scoping options using the proxy_options method on the proxy itself.

  class Shirt < ActiveRecord::Base
    named_scope :colored, lambda { |color|
      { :conditions => { :color => color } }
    }
  end

  expected_options = { :conditions => { :colored => 'red' } }
  assert_equal expected_options, Shirt.colored('red').proxy_options

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 85
 85:       def named_scope(name, options = {}, &block)
 86:         name = name.to_sym
 87:         scopes[name] = lambda do |parent_scope, *args|
 88:           Scope.new(parent_scope, case options
 89:             when Hash
 90:               options
 91:             when Proc
 92:               case parent_scope
 93:               when Scope
 94:                 with_scope(:find => parent_scope.proxy_options) { options.call(*args) }
 95:               else
 96:                 options.call(*args)
 97:               end
 98:           end, &block)
 99:         end
100:         (class << self; self end).instance_eval do
101:           define_method name do |*args|
102:             scopes[name].call(self, *args)
103:           end
104:         end
105:       end
scopes()

[Source]

    # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 18
18:       def scopes
19:         read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
20:       end


Class: ActiveRecord::NamedScope::Scope

Class | ActiveRecord::NamedScope::Scope
In: | vendor/rails/activerecord/lib/active_record/named_scope.rb
Parent: | Object

Methods

any? empty? first last new proxy_found reload respond_to? size

Constants

NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set

Attributes

current_scoped_methods_when_defined | [R]
proxy_options | [R]
proxy_scope | [R]

Public Class methods

new(proxy_scope, options, &block)

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 119
119:       def initialize(proxy_scope, options, &block)
120:         options ||= {}
121:         [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
122:         extend Module.new(&block) if block_given?
123:         unless Scope === proxy_scope
124:           @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
125:         end
126:         @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
127:       end

Public Instance methods

any?() {|*block_args| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 161
161:       def any?
162:         if block_given?
163:           proxy_found.any? { |*block_args| yield(*block_args) }
164:         else
165:           !empty?
166:         end
167:       end
empty?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 153
153:       def empty?
154:         @found ? @found.empty? : count.zero?
155:       end
first(*args)

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 133
133:       def first(*args)
134:         if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
135:           proxy_found.first(*args)
136:         else
137:           find(:first, *args)
138:         end
139:       end
last(*args)

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 141
141:       def last(*args)
142:         if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
143:           proxy_found.last(*args)
144:         else
145:           find(:last, *args)
146:         end
147:       end
reload()

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 129
129:       def reload
130:         load_found; self
131:       end
respond_to?(method, include_private = false)

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 157
157:       def respond_to?(method, include_private = false)
158:         super || @proxy_scope.respond_to?(method, include_private)
159:       end
size()

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 149
149:       def size
150:         @found ? @found.length : count
151:       end

Protected Instance methods

proxy_found()

[Source]

     # File vendor/rails/activerecord/lib/active_record/named_scope.rb, line 170
170:       def proxy_found
171:         @found || load_found
172:       end


Module: ActiveRecord::NestedAttributes::ClassMethods

Module | ActiveRecord::NestedAttributes::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/nested_attributes.rb

Nested Attributes

Nested attributes allow you to save attributes on associated records through the parent. By default nested attribute updating is turned off, you can enable it using the accepts_nested_attributes_for class method. When you enable nested attributes an attribute writer is defined on the model.

The attribute writer is named after the association, which means that in the following example, two new methods are added to your model: author_attributes=(attributes) and pages_attributes=(attributes).

  class Book < ActiveRecord::Base
    has_one :author
    has_many :pages

    accepts_nested_attributes_for :author, :pages
  end

Note that the :autosave option is automatically enabled on every association that accepts_nested_attributes_for is used for.

One-to-one

Consider a Member model that has one Avatar:

  class Member < ActiveRecord::Base
    has_one :avatar
    accepts_nested_attributes_for :avatar
  end

Enabling nested attributes on a one-to-one association allows you to create the member and avatar in one go:

  params = { :member => { :name => 'Jack', :avatar_attributes => { :icon => 'smiling' } } }
  member = Member.create(params)
  member.avatar.id # => 2
  member.avatar.icon # => 'smiling'

It also allows you to update the avatar through the member:

  params = { :member' => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }
  member.update_attributes params['member']
  member.avatar.icon # => 'sad'

By default you will only be able to set and update attributes on the associated model. If you want to destroy the associated model through the attributes hash, you have to enable it first using the :allow_destroy option.

  class Member < ActiveRecord::Base
    has_one :avatar
    accepts_nested_attributes_for :avatar, :allow_destroy => true
  end

Now, when you add the _delete key to the attributes hash, with a value that evaluates to true, you will destroy the associated model:

  member.avatar_attributes = { :id => '2', :_delete => '1' }
  member.avatar.marked_for_destruction? # => true
  member.save
  member.avatar #=> nil

Note that the model will not be destroyed until the parent is saved.

One-to-many

Consider a member that has a number of posts:

  class Member < ActiveRecord::Base
    has_many :posts
    accepts_nested_attributes_for :posts
  end

You can now set or update attributes on an associated post model through the attribute hash.

For each hash that does not have an id key a new record will be instantiated, unless the hash also contains a _delete key that evaluates to true.

  params = { :member => {
    :name => 'joe', :posts_attributes => [
      { :title => 'Kari, the awesome Ruby documentation browser!' },
      { :title => 'The egalitarian assumption of the modern citizen' },
      { :title => '', :_delete => '1' } # this will be ignored
    ]
  }}

  member = Member.create(params['member'])
  member.posts.length # => 2
  member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
  member.posts.second.title # => 'The egalitarian assumption of the modern citizen'

You may also set a :reject_if proc to silently ignore any new record hashes if they fail to pass your criteria. For example, the previous example could be rewritten as:

   class Member < ActiveRecord::Base
     has_many :posts
     accepts_nested_attributes_for :posts, :reject_if => proc { |attributes| attributes['title'].blank? }
   end

  params = { :member => {
    :name => 'joe', :posts_attributes => [
      { :title => 'Kari, the awesome Ruby documentation browser!' },
      { :title => 'The egalitarian assumption of the modern citizen' },
      { :title => '' } # this will be ignored because of the :reject_if proc
    ]
  }}

  member = Member.create(params['member'])
  member.posts.length # => 2
  member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
  member.posts.second.title # => 'The egalitarian assumption of the modern citizen'

If the hash contains an id key that matches an already associated record, the matching record will be modified:

  member.attributes = {
    :name => 'Joe',
    :posts_attributes => [
      { :id => 1, :title => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
      { :id => 2, :title => '[UPDATED] other post' }
    ]
  }

  member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!'
  member.posts.second.title # => '[UPDATED] other post'

By default the associated records are protected from being destroyed. If you want to destroy any of the associated records through the attributes hash, you have to enable it first using the :allow_destroy option. This will allow you to also use the _delete key to destroy existing records:

  class Member < ActiveRecord::Base
    has_many :posts
    accepts_nested_attributes_for :posts, :allow_destroy => true
  end

  params = { :member => {
    :posts_attributes => [{ :id => '2', :_delete => '1' }]
  }}

  member.attributes = params['member']
  member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true
  member.posts.length #=> 2
  member.save
  member.posts.length # => 1

Saving

All changes to models, including the destruction of those marked for destruction, are saved and destroyed automatically and atomically when the parent model is saved. This happens inside the transaction initiated by the parents save method. See ActiveRecord::AutosaveAssociation.

Methods

accepts_nested_attributes_for

Public Instance methods

accepts_nested_attributes_for(*attr_names)

Defines an attributes writer for the specified association(s). If you are using attr_protected or attr_accessible, then you will need to add the attribute writer to the allowed list.

Supported options:

:allow_destroy
If true, destroys any members from the attributes hash with a _delete key and a value that evaluates to true (eg. 1, ‘1’, true, or ‘true’). This option is off by default.
:reject_if
Allows you to specify a Proc that checks whether a record should be built for a certain attribute hash. The hash is passed to the Proc and the Proc should return either true or false. When no Proc is specified a record will be built for all attribute hashes that do not have a _delete that evaluates to true.

Examples:

  # creates avatar_attributes=
  accepts_nested_attributes_for :avatar, :reject_if => proc { |attributes| attributes['name'].blank? }
  # creates avatar_attributes= and posts_attributes=
  accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true

[Source]

     # File vendor/rails/activerecord/lib/active_record/nested_attributes.rb, line 189
189:       def accepts_nested_attributes_for(*attr_names)
190:         options = { :allow_destroy => false }
191:         options.update(attr_names.extract_options!)
192:         options.assert_valid_keys(:allow_destroy, :reject_if)
193:
194:         attr_names.each do |association_name|
195:           if reflection = reflect_on_association(association_name)
196:             type = case reflection.macro
197:             when :has_one, :belongs_to
198:               :one_to_one
199:             when :has_many, :has_and_belongs_to_many
200:               :collection
201:             end
202:
203:             reflection.options[:autosave] = true
204:             self.reject_new_nested_attributes_procs[association_name.to_sym] = options[:reject_if]
205:
206:             # def pirate_attributes=(attributes)
207:             #   assign_nested_attributes_for_one_to_one_association(:pirate, attributes, false)
208:             # end
209:             class_eval %{
210:               def #{association_name}_attributes=(attributes)
211:                 assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes, #{options[:allow_destroy]})
212:               end
213:             }, __FILE__, __LINE__
214:           else
215:             raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
216:           end
217:         end
218:       end


Class: ActiveRecord::Observer

Class | ActiveRecord::Observer
In: | vendor/rails/activerecord/lib/active_record/observer.rb
Parent: | Object

Observer classes respond to lifecycle callbacks to implement trigger-like behavior outside the original class. This is a great way to reduce the clutter that normally comes when the model class is burdened with functionality that doesn‘t pertain to the core responsibility of the class. Example:

  class CommentObserver < ActiveRecord::Observer
    def after_save(comment)
      Notifications.deliver_comment("admin@do.com", "New comment was posted", comment)
    end
  end

This Observer sends an email when a Comment#save is finished.

  class ContactObserver < ActiveRecord::Observer
    def after_create(contact)
      contact.logger.info('New contact added!')
    end

    def after_destroy(contact)
      contact.logger.warn("Contact with an id of #{contact.id} was destroyed!")
    end
  end

This Observer uses logger to log when specific callbacks are triggered.

Observing a class that can‘t be inferred

Observers will by default be mapped to the class with which they share a name. So CommentObserver will be tied to observing Comment, ProductManagerObserver to ProductManager, and so on. If you want to name your observer differently than the class you‘re interested in observing, you can use the Observer.observe class method which takes either the concrete class (Product) or a symbol for that class (:product):

  class AuditObserver < ActiveRecord::Observer
    observe :account

    def after_update(account)
      AuditTrail.new(account, "UPDATED")
    end
  end

If the audit observer needs to watch more than one kind of object, this can be specified with multiple arguments:

  class AuditObserver < ActiveRecord::Observer
    observe :account, :balance

    def after_update(record)
      AuditTrail.new(record, "UPDATED")
    end
  end

The AuditObserver will now act on both updates to Account and Balance by treating them both as records.

Available callback methods

The observer can implement callback methods for each of the methods described in the Callbacks module.

Storing Observers in Rails

If you‘re using Active Record within Rails, observer classes are usually stored in app/models with the naming convention of app/models/audit_observer.rb.

Configuration

In order to activate an observer, list it in the config.active_record.observers configuration setting in your config/environment.rb file.

  config.active_record.observers = :comment_observer, :signup_observer

Observers will not be invoked unless you define these in your application configuration.

Loading

Observers register themselves in the model class they observe, since it is the class that notifies them of events when they occur. As a side-effect, when an observer is loaded its corresponding model class is loaded.

Up to (and including) Rails 2.0.2 observers were instantiated between plugins and application initializers. Now observers are loaded after application initializers, so observed models can make use of extensions.

If by any chance you are using observed models in the initialization you can still load their observers by calling ModelObserver.instance before. Observers are singletons and that call instantiates and registers them.

Methods

add_observer! new observe observed_class observed_classes observed_subclasses

Included Modules

Singleton

Public Class methods

new()

Start observing the declared classes and their subclasses.

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 165
165:     def initialize
166:       Set.new(observed_classes + observed_subclasses).each { |klass| add_observer! klass }
167:     end
observe(*models)

Attaches the observer to the supplied model classes.

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 147
147:       def observe(*models)
148:         models.flatten!
149:         models.collect! { |model| model.is_a?(Symbol) ? model.to_s.camelize.constantize : model }
150:         define_method(:observed_classes) { Set.new(models) }
151:       end
observed_class()

The class observed by default is inferred from the observer‘s class name:

  assert_equal Person, PersonObserver.observed_class

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 155
155:       def observed_class
156:         if observed_class_name = name[/(.*)Observer/, 1]
157:           observed_class_name.constantize
158:         else
159:           nil
160:         end
161:       end

Protected Instance methods

add_observer!(klass)

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 190
190:       def add_observer!(klass)
191:         klass.add_observer(self)
192:         if respond_to?(:after_find) && !klass.method_defined?(:after_find)
193:           klass.class_eval 'def after_find() end'
194:         end
195:       end
observed_classes()

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 182
182:       def observed_classes
183:         Set.new([self.class.observed_class].compact.flatten)
184:       end
observed_subclasses()

[Source]

     # File vendor/rails/activerecord/lib/active_record/observer.rb, line 186
186:       def observed_subclasses
187:         observed_classes.sum([]) { |klass| klass.send(:subclasses) }
188:       end


Module: ActiveRecord::Observing::ClassMethods

Module | ActiveRecord::Observing::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/observer.rb

Methods

inherited instantiate_observers observers observers=

Public Instance methods

instantiate_observers()

Instantiate the global Active Record observers.

[Source]

    # File vendor/rails/activerecord/lib/active_record/observer.rb, line 34
34:       def instantiate_observers
35:         return if @observers.blank?
36:         @observers.each do |observer|
37:           if observer.respond_to?(:to_sym) # Symbol or String
38:             observer.to_s.camelize.constantize.instance
39:           elsif observer.respond_to?(:instance)
40:             observer.instance
41:           else
42:             raise ArgumentError, "#{observer} must be a lowercase, underscored class name (or an instance of the class itself) responding to the instance method. Example: Person.observers = :big_brother # calls BigBrother.instance"
43:           end
44:         end
45:       end
observers()

Gets the current observers.

[Source]

    # File vendor/rails/activerecord/lib/active_record/observer.rb, line 29
29:       def observers
30:         @observers ||= []
31:       end
observers=(*observers)

Activates the observers assigned. Examples:

  # Calls PersonObserver.instance
  ActiveRecord::Base.observers = :person_observer

  # Calls Cacher.instance and GarbageCollector.instance
  ActiveRecord::Base.observers = :cacher, :garbage_collector

  # Same as above, just using explicit class references
  ActiveRecord::Base.observers = Cacher, GarbageCollector

Note: Setting this does not instantiate the observers yet. instantiate_observers is called during startup, and before each development request.

[Source]

    # File vendor/rails/activerecord/lib/active_record/observer.rb, line 24
24:       def observers=(*observers)
25:         @observers = observers.flatten
26:       end

Protected Instance methods

inherited(subclass)

Notify observers when the observed class is subclassed.

[Source]

    # File vendor/rails/activerecord/lib/active_record/observer.rb, line 49
49:         def inherited(subclass)
50:           super
51:           changed
52:           notify_observers :observed_class_inherited, subclass
53:         end


Class: ActiveRecord::PreparedStatementInvalid

Class | ActiveRecord::PreparedStatementInvalid
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when number of bind variables in statement given to :condition key (for example, when using find method) does not match number of expected variables.

For example, in

  Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]

two placeholders are given but only one variable to fill them.


Class: ActiveRecord::QueryCache

Class | ActiveRecord::QueryCache
In: | vendor/rails/activerecord/lib/active_record/query_cache.rb
Parent: | Object

Methods

call new

Classes and Modules

Module ActiveRecord::QueryCache::ClassMethods

Public Class methods

new(app)

[Source]

    # File vendor/rails/activerecord/lib/active_record/query_cache.rb, line 23
23:     def initialize(app)
24:       @app = app
25:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/activerecord/lib/active_record/query_cache.rb, line 27
27:     def call(env)
28:       ActiveRecord::Base.cache do
29:         @app.call(env)
30:       end
31:     end


Module: ActiveRecord::QueryCache::ClassMethods

Module | ActiveRecord::QueryCache::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/query_cache.rb

Methods

cache uncached

Public Instance methods

cache() {|| ...}

Enable the query cache within the block if Active Record is configured.

[Source]

    # File vendor/rails/activerecord/lib/active_record/query_cache.rb, line 5
 5:       def cache(&block)
 6:         if ActiveRecord::Base.configurations.blank?
 7:           yield
 8:         else
 9:           connection.cache(&block)
10:         end
11:       end
uncached() {|| ...}

Disable the query cache within the block if Active Record is configured.

[Source]

    # File vendor/rails/activerecord/lib/active_record/query_cache.rb, line 14
14:       def uncached(&block)
15:         if ActiveRecord::Base.configurations.blank?
16:           yield
17:         else
18:           connection.uncached(&block)
19:         end
20:       end


Class: ActiveRecord::ReadOnlyRecord

Class | ActiveRecord::ReadOnlyRecord
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised on attempt to update record that is instantiated as read only.


Class: ActiveRecord::RecordInvalid

Class | ActiveRecord::RecordInvalid
In: | vendor/rails/activerecord/lib/active_record/validations.rb
Parent: | ActiveRecordError

Raised by save! and create! when the record is invalid. Use the record method to retrieve the record which did not validate.

  begin
    complex_operation_that_calls_save!_internally
  rescue ActiveRecord::RecordInvalid => invalid
    puts invalid.record.errors
  end

Methods

new

Attributes

record [R]

Public Class methods

new(record)

[Source]

    # File vendor/rails/activerecord/lib/active_record/validations.rb, line 11
11:     def initialize(record)
12:       @record = record
13:       super("Validation failed: #{@record.errors.full_messages.join(", ")}")
14:     end


Class: ActiveRecord::RecordNotFound

Class | ActiveRecord::RecordNotFound
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when Active Record cannot find record by given id or set of ids.


Class: ActiveRecord::RecordNotSaved

Class | ActiveRecord::RecordNotSaved
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be saved because record is invalid.


Module: ActiveRecord::Reflection::ClassMethods

Module | ActiveRecord::Reflection::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/reflection.rb

Reflection allows you to interrogate Active Record classes and objects about their associations and aggregations. This information can, for example, be used in a form builder that took an Active Record object and created input fields for all of the attributes depending on their type and displayed the associations to other objects.

You can find the interface for the AggregateReflection and AssociationReflection classes in the abstract MacroReflection class.

Methods

create_reflection reflect_on_aggregation reflect_on_all_aggregations reflect_on_all_associations reflect_on_all_autosave_associations reflect_on_association reflections

Public Instance methods

create_reflection(macro, name, options, active_record)

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 13
13:       def create_reflection(macro, name, options, active_record)
14:         case macro
15:           when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
16:             klass = options[:through] ? ThroughReflection : AssociationReflection
17:             reflection = klass.new(macro, name, options, active_record)
18:           when :composed_of
19:             reflection = AggregateReflection.new(macro, name, options, active_record)
20:         end
21:         write_inheritable_hash :reflections, name => reflection
22:         reflection
23:       end
reflect_on_aggregation(aggregation)

Returns the AggregateReflection object for the named aggregation (use the symbol). Example:

  Account.reflect_on_aggregation(:balance) # returns the balance AggregateReflection

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 44
44:       def reflect_on_aggregation(aggregation)
45:         reflections[aggregation].is_a?(AggregateReflection) ? reflections[aggregation] : nil
46:       end
reflect_on_all_aggregations()

Returns an array of AggregateReflection objects for all the aggregations in the class.

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 36
36:       def reflect_on_all_aggregations
37:         reflections.values.select { |reflection| reflection.is_a?(AggregateReflection) }
38:       end
reflect_on_all_associations(macro = nil)

Returns an array of AssociationReflection objects for all the associations in the class. If you only want to reflect on a certain association type, pass in the symbol (:has_many, :has_one, :belongs_to) for that as the first parameter. Example:

  Account.reflect_on_all_associations             # returns an array of all associations
  Account.reflect_on_all_associations(:has_many)  # returns an array of all has_many associations

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 55
55:       def reflect_on_all_associations(macro = nil)
56:         association_reflections = reflections.values.select { |reflection| reflection.is_a?(AssociationReflection) }
57:         macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections
58:       end
reflect_on_all_autosave_associations()

Returns an array of AssociationReflection objects for all associations which have :autosave enabled.

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 70
70:       def reflect_on_all_autosave_associations
71:         reflections.values.select { |reflection| reflection.options[:autosave] }
72:       end
reflect_on_association(association)

Returns the AssociationReflection object for the named association (use the symbol). Example:

  Account.reflect_on_association(:owner) # returns the owner AssociationReflection
  Invoice.reflect_on_association(:line_items).macro  # returns :has_many

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 65
65:       def reflect_on_association(association)
66:         reflections[association].is_a?(AssociationReflection) ? reflections[association] : nil
67:       end
reflections()

Returns a hash containing all AssociationReflection objects for the current class Example:

  Invoice.reflections
  Account.reflections

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 31
31:       def reflections
32:         read_inheritable_attribute(:reflections) || write_inheritable_attribute(:reflections, {})
33:       end


Class: ActiveRecord::Reflection::MacroReflection

Class | ActiveRecord::Reflection::MacroReflection
In: | vendor/rails/activerecord/lib/active_record/reflection.rb
Parent: | Object

Abstract base class for AggregateReflection and AssociationReflection that describes the interface available for both of those classes. Objects of AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.

Methods

== belongs_to? class_name klass macro name new options

Attributes

active_record [R]

Public Class methods

new(macro, name, options, active_record)

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 81
81:       def initialize(macro, name, options, active_record)
82:         @macro, @name, @options, @active_record = macro, name, options, active_record
83:       end

Public Instance methods

==(other_aggregation)

Returns true if self and other_aggregation have the same name attribute, active_record attribute, and other_aggregation has an options hash assigned to it.

[Source]

     # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 117
117:       def ==(other_aggregation)
118:         other_aggregation.kind_of?(self.class) && name == other_aggregation.name && other_aggregation.options && active_record == other_aggregation.active_record
119:       end
belongs_to?()

Returns true if self is a belongs_to reflection.

[Source]

     # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 126
126:       def belongs_to?
127:         macro == :belongs_to
128:       end
class_name()

Returns the class name for the macro. For example, composed_of :balance, :class_name => ‘Money‘ returns ‘Money‘ and has_many :clients returns ‘Client‘.

[Source]

     # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 111
111:       def class_name
112:         @class_name ||= options[:class_name] || derive_class_name
113:       end
klass()

Returns the class for the macro. For example, composed_of :balance, :class_name => ‘Money‘ returns the Money class and has_many :clients returns the Client class.

[Source]

     # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 105
105:       def klass
106:         @klass ||= class_name.constantize
107:       end
macro()

Returns the macro type. For example, composed_of :balance, :class_name => ‘Money‘ will return :composed_of or for has_many :clients will return :has_many.

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 93
93:       def macro
94:         @macro
95:       end
name()

Returns the name of the macro. For example, composed_of :balance, :class_name => ‘Money‘ will return :balance or for has_many :clients it will return :clients.

[Source]

    # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 87
87:       def name
88:         @name
89:       end
options()

Returns the hash of options used for the macro. For example, it would return { :class_name => "Money" } for composed_of :balance, :class_name => ‘Money‘ or +{}+ for has_many :clients.

[Source]

     # File vendor/rails/activerecord/lib/active_record/reflection.rb, line 99
 99:       def options
100:         @options
101:       end


Class: ActiveRecord::Rollback

Class | ActiveRecord::Rollback
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

ActiveRecord::Transactions::ClassMethods.transaction uses this exception to distinguish a deliberate rollback from other exceptional situations. Normally, raising an exception will cause the transaction method to rollback the database transaction and pass on the exception. But if you raise an ActiveRecord::Rollback exception, then the database transaction will be rolled back, without passing on the exception.

For example, you could do this in your controller to rollback a transaction:

  class BooksController < ActionController::Base
    def create
      Book.transaction do
        book = Book.new(params[:book])
        book.save!
        if today_is_friday?
          # The system must fail on Friday so that our support department
          # won't be out of job. We silently rollback this transaction
          # without telling the user.
          raise ActiveRecord::Rollback, "Call tech support!"
        end
      end
      # ActiveRecord::Rollback is the only exception that won't be passed on
      # by ActiveRecord::Base.transaction, so this line will still be reached
      # even on Friday.
      redirect_to root_url
    end
  end


Class: ActiveRecord::Schema

Class | ActiveRecord::Schema
In: | vendor/rails/activerecord/lib/active_record/schema.rb
Parent: | Migration

Allows programmers to programmatically define a schema in a portable DSL. This means you can define tables, indexes, etc. without using SQL directly, so your applications can more easily support multiple databases.

Usage:

  ActiveRecord::Schema.define do
    create_table :authors do |t|
      t.string :name, :null => false
    end

    add_index :authors, :name, :unique

    create_table :posts do |t|
      t.integer :author_id, :null => false
      t.string :subject
      t.text :body
      t.boolean :private, :default => false
    end

    add_index :posts, :author_id
  end

ActiveRecord::Schema is only supported by database adapters that also support migrations, the two features being very similar.

Methods

define

Public Class methods

define(info={}, &block)

Eval the given block. All methods available to the current connection adapter are available within the block, so you can easily use the database definition DSL to build up your schema (create_table, add_index, etc.).

The info hash is optional, and if given is used to define metadata about the current schema (currently, only the schema‘s version):

  ActiveRecord::Schema.define(:version => 20380119000001) do
    ...
  end

[Source]

    # File vendor/rails/activerecord/lib/active_record/schema.rb, line 42
42:     def self.define(info={}, &block)
43:       instance_eval(&block)
44:
45:       unless info[:version].blank?
46:         initialize_schema_migrations_table
47:         assume_migrated_upto_version info[:version]
48:       end
49:     end


Module: ActiveRecord::Serialization

Module | ActiveRecord::Serialization
In: | vendor/rails/activerecord/lib/active_record/serialization.rb vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb vendor/rails/activerecord/lib/active_record/serializers/xml_serializer.rb

Methods

from_json from_xml included to_json to_xml

Classes and Modules

Module ActiveRecord::Serialization::ClassMethods

Public Class methods

included(base)

[Source]

   # File vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb, line 3
3:     def self.included(base)
4:       base.cattr_accessor :include_root_in_json, :instance_writer => false
5:       base.extend ClassMethods
6:     end

Public Instance methods

from_json(json)

[Source]

    # File vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb, line 82
82:     def from_json(json)
83:       self.attributes = ActiveSupport::JSON.decode(json)
84:       self
85:     end
from_xml(xml)

[Source]

     # File vendor/rails/activerecord/lib/active_record/serializers/xml_serializer.rb, line 159
159:     def from_xml(xml)
160:       self.attributes = Hash.from_xml(xml).values.first
161:       self
162:     end
to_json(options = {})

Returns a JSON string representing the model. Some configuration is available through options.

The option ActiveRecord::Base.include_root_in_json controls the top-level behavior of to_json. In a new Rails application, it is set to true in initializers/new_rails_defaults.rb. When it is true, to_json will emit a single root node named after the object‘s type. For example:

  konata = User.find(1)
  ActiveRecord::Base.include_root_in_json = true
  konata.to_json
  # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
                  "created_at": "2006/08/01", "awesome": true} }

  ActiveRecord::Base.include_root_in_json = false
  konata.to_json
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true}

The remainder of the examples in this section assume include_root_in_json is set to false.

Without any options, the returned JSON string will include all the model‘s attributes. For example:

  konata = User.find(1)
  konata.to_json
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true}

The :only and :except options can be used to limit the attributes included, and work similar to the attributes method. For example:

  konata.to_json(:only => [ :id, :name ])
  # => {"id": 1, "name": "Konata Izumi"}

  konata.to_json(:except => [ :id, :created_at, :age ])
  # => {"name": "Konata Izumi", "awesome": true}

To include any methods on the model, use :methods.

  konata.to_json(:methods => :permalink)
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true,
        "permalink": "1-konata-izumi"}

To include associations, use :include.

  konata.to_json(:include => :posts)
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true,
        "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
                  {"id": 2, author_id: 1, "title": "So I was thinking"}]}

2nd level and higher order associations work as well:

  konata.to_json(:include => { :posts => {
                                 :include => { :comments => {
                                               :only => :body } },
                                 :only => :title } })
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true,
        "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
                   "title": "Welcome to the weblog"},
                  {"comments": [{"body": "Don't think too hard"}],
                   "title": "So I was thinking"}]}

[Source]

    # File vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb, line 74
74:     def to_json(options = {})
75:       if include_root_in_json
76:         "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
77:       else
78:         JsonSerializer.new(self, options).to_s
79:       end
80:     end
to_xml(options = {}, &block)

Builds an XML document to represent the model. Some configuration is available through options. However more complicated cases should override ActiveRecord::Base#to_xml.

By default the generated XML document will include the processing instruction and all the object‘s attributes. For example:

  <?xml version="1.0" encoding="UTF-8"?>
  <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <id type="integer">1</id>
    <approved type="boolean">false</approved>
    <replies-count type="integer">0</replies-count>
    <bonus-time type="datetime">2000-01-01T08:28:00+12:00</bonus-time>
    <written-on type="datetime">2003-07-16T09:28:00+1200</written-on>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

This behavior can be controlled with :only, :except, :skip_instruct, :skip_types, :dasherize and :camelize . The :only and :except options are the same as for the attributes method. The default is to dasherize all column names, but you can disable this setting :dasherize to false. Setting :camelize to true will camelize all column names - this also overrides :dasherize. To not have the column type included in the XML output set :skip_types to true.

For instance:

  topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])

  <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <approved type="boolean">false</approved>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

To include first level associations use :include:

  firm.to_xml :include => [ :account, :clients ]

  <?xml version="1.0" encoding="UTF-8"?>
  <firm>
    <id type="integer">1</id>
    <rating type="integer">1</rating>
    <name>37signals</name>
    <clients type="array">
      <client>
        <rating type="integer">1</rating>
        <name>Summit</name>
      </client>
      <client>
        <rating type="integer">1</rating>
        <name>Microsoft</name>
      </client>
    </clients>
    <account>
      <id type="integer">1</id>
      <credit-limit type="integer">50</credit-limit>
    </account>
  </firm>

To include deeper levels of associations pass a hash like this:

  firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
  <?xml version="1.0" encoding="UTF-8"?>
  <firm>
    <id type="integer">1</id>
    <rating type="integer">1</rating>
    <name>37signals</name>
    <clients type="array">
      <client>
        <rating type="integer">1</rating>
        <name>Summit</name>
        <address>
          ...
        </address>
      </client>
      <client>
        <rating type="integer">1</rating>
        <name>Microsoft</name>
        <address>
          ...
        </address>
      </client>
    </clients>
    <account>
      <id type="integer">1</id>
      <credit-limit type="integer">50</credit-limit>
    </account>
  </firm>

To include any methods on the model being called use :methods:

  firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]

  <firm>
    # ... normal attributes as shown above ...
    <calculated-earnings>100000000000000000</calculated-earnings>
    <real-earnings>5</real-earnings>
  </firm>

To call any additional Procs use :procs. The Procs are passed a modified version of the options hash that was given to to_xml:

  proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
  firm.to_xml :procs => [ proc ]

  <firm>
    # ... normal attributes as shown above ...
    <abc>def</abc>
  </firm>

Alternatively, you can yield the builder object as part of the to_xml call:

  firm.to_xml do |xml|
    xml.creator do
      xml.first_name "David"
      xml.last_name "Heinemeier Hansson"
    end
  end

  <firm>
    # ... normal attributes as shown above ...
    <creator>
      <first_name>David</first_name>
      <last_name>Heinemeier Hansson</last_name>
    </creator>
  </firm>

As noted above, you may override to_xml in your ActiveRecord::Base subclasses to have complete control about what‘s generated. The general form of doing this is:

  class IHaveMyOwnXML < ActiveRecord::Base
    def to_xml(options = {})
      options[:indent] ||= 2
      xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
      xml.instruct! unless options[:skip_instruct]
      xml.level_one do
        xml.tag!(:second_level, 'content')
      end
    end
  end

[Source]

     # File vendor/rails/activerecord/lib/active_record/serializers/xml_serializer.rb, line 154
154:     def to_xml(options = {}, &block)
155:       serializer = XmlSerializer.new(self, options)
156:       block_given? ? serializer.to_s(&block) : serializer.to_s
157:     end


Module: ActiveRecord::Serialization::ClassMethods

Module | ActiveRecord::Serialization::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb

Methods

json_class_name

Public Instance methods

json_class_name()

[Source]

    # File vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb, line 94
94:       def json_class_name
95:         @json_class_name ||= name.demodulize.underscore.inspect
96:       end


Class: ActiveRecord::SerializationTypeMismatch

Class | ActiveRecord::SerializationTypeMismatch
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when unserialized object‘s type mismatches one specified for serializable field.


Class: ActiveRecord::SessionStore

Class | ActiveRecord::SessionStore
In: | vendor/rails/activerecord/lib/active_record/session_store.rb
Parent: | ActionController::Session::AbstractStore

A session store backed by an Active Record class. A default class is provided, but any object duck-typing to an Active Record Session class with text session_id and data attributes is sufficient.

The default assumes a sessions tables with columns:

  +id+ (numeric primary key),
  +session_id+ (text, or longtext if your session data exceeds 65K), and
  +data+ (text or longtext; careful if your session data exceeds 65KB).

The session_id column should always be indexed for speedy lookups. Session data is marshaled to the data column in Base64 format. If the data you write is larger than the column‘s size limit, ActionController::SessionOverflowError will be raised.

You may configure the table name, primary key, and data column. For example, at the end of config/environment.rb:

  ActiveRecord::SessionStore::Session.table_name = 'legacy_session_table'
  ActiveRecord::SessionStore::Session.primary_key = 'session_id'
  ActiveRecord::SessionStore::Session.data_column_name = 'legacy_session_data'

Note that setting the primary key to the session_id frees you from having a separate id column if you don‘t want it. However, you must set session.model.id = session.session_id by hand! A before filter on ApplicationController is a good place.

Since the default class is a simple Active Record, you get timestamps for free if you add created_at and updated_at datetime columns to the sessions table, making periodic session expiration a snap.

You may provide your own session class implementation, whether a feature-packed Active Record or a bare-metal high-performance SQL store, by setting

  ActiveRecord::SessionStore.session_class = MySessionClass

You must implement these methods:

  self.find_by_session_id(session_id)
  initialize(hash_of_session_id_and_data)
  attr_reader :session_id
  attr_accessor :data
  save
  destroy

The example SqlBypass class is a generic SQL session store. You may use it as a basis for high-performance database-specific stores.

Classes and Modules

Class ActiveRecord::SessionStore::Session
Class ActiveRecord::SessionStore::SqlBypass

Constants

SESSION_RECORD_KEY = 'rack.session.record'.freeze


Class: ActiveRecord::SessionStore::Session

Class | ActiveRecord::SessionStore::Session
In: | vendor/rails/activerecord/lib/active_record/session_store.rb
Parent: | ActiveRecord::Base

The default Active Record class.

Methods

create_table! data data_column_size_limit drop_table! find_by_session_id loaded? marshal unmarshal

Attributes

data [W]

Public Class methods

create_table!()

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 74
74:         def create_table!
75:           connection.execute "CREATE TABLE \#{table_name} (\nid INTEGER PRIMARY KEY,\n\#{connection.quote_column_name('session_id')} TEXT UNIQUE,\n\#{connection.quote_column_name(@@data_column_name)} TEXT(255)\n)\n"
76:         end
data_column_size_limit()

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 56
56:         def data_column_size_limit
57:           @data_column_size_limit ||= columns_hash[@@data_column_name].limit
58:         end
drop_table!()

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 85
85:         def drop_table!
86:           connection.execute "DROP TABLE #{table_name}"
87:         end
find_by_session_id(session_id)

Hook to set up sessid compatibility.

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 61
61:         def find_by_session_id(session_id)
62:           setup_sessid_compatibility!
63:           find_by_session_id(session_id)
64:         end
marshal(data)

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 66
66:         def marshal(data)
67:           ActiveSupport::Base64.encode64(Marshal.dump(data)) if data
68:         end
unmarshal(data)

[Source]

    # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 70
70:         def unmarshal(data)
71:           Marshal.load(ActiveSupport::Base64.decode64(data)) if data
72:         end

Public Instance methods

data()

Lazy-unmarshal session state.

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 110
110:       def data
111:         @data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
112:       end
loaded?()

Has the session been loaded yet?

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 117
117:       def loaded?
118:         !!@data
119:       end


Class: ActiveRecord::SessionStore::SqlBypass

Class | ActiveRecord::SessionStore::SqlBypass
In: | vendor/rails/activerecord/lib/active_record/session_store.rb
Parent: | Object

A barebones session store which duck-types with the default session store but bypasses Active Record and issues SQL directly. This is an example session model class meant as a basis for your own classes.

The database connection, table name, and session id and data columns are configurable class attributes. Marshaling and unmarshaling are implemented as class methods that you may override. By default, marshaling data is

  ActiveSupport::Base64.encode64(Marshal.dump(data))

and unmarshaling data is

  Marshal.load(ActiveSupport::Base64.decode64(data))

This marshaling behavior is intended to store the widest range of binary session data in a text column. For higher performance, store in a blob column instead and forgo the Base64 encoding.

Methods

connection create_table! data destroy drop_table! find_by_session_id loaded? marshal new new_record? save unmarshal

Attributes

data | [W]
session_id | [R]

Public Class methods

connection()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 182
182:         def connection
183:           @@connection ||= ActiveRecord::Base.connection
184:         end
create_table!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 201
201:         def create_table!
202:           @@connection.execute "CREATE TABLE \#{table_name} (\nid INTEGER PRIMARY KEY,\n\#{@@connection.quote_column_name(session_id_column)} TEXT UNIQUE,\n\#{@@connection.quote_column_name(data_column)} TEXT\n)\n"
203:         end
drop_table!()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 212
212:         def drop_table!
213:           @@connection.execute "DROP TABLE #{table_name}"
214:         end
find_by_session_id(session_id)

Look up a session by id and unmarshal its data if found.

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 187
187:         def find_by_session_id(session_id)
188:           if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}")
189:             new(:session_id => session_id, :marshaled_data => record['data'])
190:           end
191:         end
marshal(data)

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 193
193:         def marshal(data)
194:           ActiveSupport::Base64.encode64(Marshal.dump(data)) if data
195:         end
new(attributes)

Look for normal and marshaled data, self.find_by_session_id‘s way of telling us to postpone unmarshaling until the data is requested. We need to handle a normal data attribute in case of a new record.

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 223
223:       def initialize(attributes)
224:         @session_id, @data, @marshaled_data = attributes[:session_id], attributes[:data], attributes[:marshaled_data]
225:         @new_record = @marshaled_data.nil?
226:       end
unmarshal(data)

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 197
197:         def unmarshal(data)
198:           Marshal.load(ActiveSupport::Base64.decode64(data)) if data
199:         end

Public Instance methods

data()

Lazy-unmarshal session state.

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 233
233:       def data
234:         unless @data
235:           if @marshaled_data
236:             @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil
237:           else
238:             @data = {}
239:           end
240:         end
241:         @data
242:       end
destroy()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 273
273:       def destroy
274:         unless @new_record
275:           @@connection.delete "DELETE FROM \#{@@table_name}\nWHERE \#{@@connection.quote_column_name(@@session_id_column)}=\#{@@connection.quote(session_id)}\n", 'Destroy session'
276:         end
277:       end
loaded?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 244
244:       def loaded?
245:         !!@data
246:       end
new_record?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 228
228:       def new_record?
229:         @new_record
230:       end
save()

[Source]

     # File vendor/rails/activerecord/lib/active_record/session_store.rb, line 248
248:       def save
249:         return false if !loaded?
250:         marshaled_data = self.class.marshal(data)
251:
252:         if @new_record
253:           @new_record = false
254:           @@connection.update "INSERT INTO \#{@@table_name} (\n\#{@@connection.quote_column_name(@@session_id_column)},\n\#{@@connection.quote_column_name(@@data_column)} )\nVALUES (\n\#{@@connection.quote(session_id)},\n\#{@@connection.quote(marshaled_data)} )\n", 'Create session'
255:         else
256:           @@connection.update "UPDATE \#{@@table_name}\nSET \#{@@connection.quote_column_name(@@data_column)}=\#{@@connection.quote(marshaled_data)}\nWHERE \#{@@connection.quote_column_name(@@session_id_column)}=\#{@@connection.quote(session_id)}\n", 'Update session'
257:         end
258:       end


Class: ActiveRecord::StaleObjectError

Class | ActiveRecord::StaleObjectError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised on attempt to save stale record. Record is stale when it‘s being saved in another query after instantiation, for example, when two users edit the same wiki page and one starts editing and saves the page before the other.

Read more about optimistic locking in ActiveRecord::Locking module RDoc.


Class: ActiveRecord::StatementInvalid

Class | ActiveRecord::StatementInvalid
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | ActiveRecordError

Raised when SQL statement cannot be executed by the database (for example, it‘s often the case for MySQL when Ruby driver used is too old).


Module: ActiveRecord::TestFixtures

Module | ActiveRecord::TestFixtures
In: | vendor/rails/activerecord/lib/active_record/fixtures.rb

Methods

included run_in_transaction? setup_fixtures teardown_fixtures

Classes and Modules

Module ActiveRecord::TestFixtures::ClassMethods

Public Class methods

included(base)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 808
808:     def self.included(base)
809:       base.class_eval do
810:         setup :setup_fixtures
811:         teardown :teardown_fixtures
812:
813:         superclass_delegating_accessor :fixture_path
814:         superclass_delegating_accessor :fixture_table_names
815:         superclass_delegating_accessor :fixture_class_names
816:         superclass_delegating_accessor :use_transactional_fixtures
817:         superclass_delegating_accessor :use_instantiated_fixtures   # true, false, or :no_instances
818:         superclass_delegating_accessor :pre_loaded_fixtures
819:
820:         self.fixture_table_names = []
821:         self.use_transactional_fixtures = false
822:         self.use_instantiated_fixtures = true
823:         self.pre_loaded_fixtures = false
824:
825:         self.fixture_class_names = {}
826:       end
827:
828:       base.extend ClassMethods
829:     end

Public Instance methods

run_in_transaction?()

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 905
905:     def run_in_transaction?
906:       use_transactional_fixtures &&
907:         !self.class.uses_transaction?(method_name)
908:     end
setup_fixtures()

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 910
910:     def setup_fixtures
911:       return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
912:
913:       if pre_loaded_fixtures && !use_transactional_fixtures
914:         raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
915:       end
916:
917:       @fixture_cache = {}
918:       @@already_loaded_fixtures ||= {}
919:
920:       # Load fixtures once and begin transaction.
921:       if run_in_transaction?
922:         if @@already_loaded_fixtures[self.class]
923:           @loaded_fixtures = @@already_loaded_fixtures[self.class]
924:         else
925:           load_fixtures
926:           @@already_loaded_fixtures[self.class] = @loaded_fixtures
927:         end
928:         ActiveRecord::Base.connection.increment_open_transactions
929:         ActiveRecord::Base.connection.transaction_joinable = false
930:         ActiveRecord::Base.connection.begin_db_transaction
931:       # Load fixtures for every test.
932:       else
933:         Fixtures.reset_cache
934:         @@already_loaded_fixtures[self.class] = nil
935:         load_fixtures
936:       end
937:
938:       # Instantiate fixtures for every test if requested.
939:       instantiate_fixtures if use_instantiated_fixtures
940:     end
teardown_fixtures()

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 942
942:     def teardown_fixtures
943:       return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
944:
945:       unless run_in_transaction?
946:         Fixtures.reset_cache
947:       end
948:
949:       # Rollback changes if a transaction is active.
950:       if run_in_transaction? && ActiveRecord::Base.connection.open_transactions != 0
951:         ActiveRecord::Base.connection.rollback_db_transaction
952:         ActiveRecord::Base.connection.decrement_open_transactions
953:       end
954:       ActiveRecord::Base.clear_active_connections!
955:     end


Module: ActiveRecord::TestFixtures::ClassMethods

Module | ActiveRecord::TestFixtures::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/fixtures.rb

Methods

fixtures require_fixture_classes set_fixture_class setup_fixture_accessors try_to_load_dependency uses_transaction uses_transaction?

Public Instance methods

fixtures(*table_names)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 836
836:       def fixtures(*table_names)
837:         if table_names.first == :all
838:           table_names = Dir["#{fixture_path}/*.yml"] + Dir["#{fixture_path}/*.csv"]
839:           table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
840:         else
841:           table_names = table_names.flatten.map { |n| n.to_s }
842:         end
843:
844:         self.fixture_table_names |= table_names
845:         require_fixture_classes(table_names)
846:         setup_fixture_accessors(table_names)
847:       end
require_fixture_classes(table_names = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 861
861:       def require_fixture_classes(table_names = nil)
862:         (table_names || fixture_table_names).each do |table_name|
863:           file_name = table_name.to_s
864:           file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
865:           try_to_load_dependency(file_name)
866:         end
867:       end
set_fixture_class(class_names = {})

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 832
832:       def set_fixture_class(class_names = {})
833:         self.fixture_class_names = self.fixture_class_names.merge(class_names)
834:       end
setup_fixture_accessors(table_names = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 869
869:       def setup_fixture_accessors(table_names = nil)
870:         table_names = [table_names] if table_names && !table_names.respond_to?(:each)
871:         (table_names || fixture_table_names).each do |table_name|
872:           table_name = table_name.to_s.tr('.', '_')
873:
874:           define_method(table_name) do |*fixtures|
875:             force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
876:
877:             @fixture_cache[table_name] ||= {}
878:
879:             instances = fixtures.map do |fixture|
880:               @fixture_cache[table_name].delete(fixture) if force_reload
881:
882:               if @loaded_fixtures[table_name][fixture.to_s]
883:                 @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find
884:               else
885:                 raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
886:               end
887:             end
888:
889:             instances.size == 1 ? instances.first : instances
890:           end
891:         end
892:       end
try_to_load_dependency(file_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 849
849:       def try_to_load_dependency(file_name)
850:         require_dependency file_name
851:       rescue LoadError => e
852:         # Let's hope the developer has included it himself
853:
854:         # Let's warn in case this is a subdependency, otherwise
855:         # subdependency error messages are totally cryptic
856:         if ActiveRecord::Base.logger
857:           ActiveRecord::Base.logger.warn("Unable to load #{file_name}, underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
858:         end
859:       end
uses_transaction(*methods)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 894
894:       def uses_transaction(*methods)
895:         @uses_transaction = [] unless defined?(@uses_transaction)
896:         @uses_transaction.concat methods.map(&:to_s)
897:       end
uses_transaction?(method)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 899
899:       def uses_transaction?(method)
900:         @uses_transaction = [] unless defined?(@uses_transaction)
901:         @uses_transaction.include?(method.to_s)
902:       end


Module: ActiveRecord::Timestamp

Module | ActiveRecord::Timestamp
In: | vendor/rails/activerecord/lib/active_record/timestamp.rb

Active Record automatically timestamps create and update operations if the table has fields named created_at/created_on or updated_at/updated_on.

Timestamping can be turned off by setting

  <tt>ActiveRecord::Base.record_timestamps = false</tt>

Timestamps are in the local timezone by default but you can use UTC by setting

  <tt>ActiveRecord::Base.default_timezone = :utc</tt>


Module: ActiveRecord::Transactions

Module | ActiveRecord::Transactions
In: | vendor/rails/activerecord/lib/active_record/transactions.rb

See ActiveRecord::Transactions::ClassMethods for documentation.

Methods

included rollback_active_record_state! transaction with_transaction_returning_status

Classes and Modules

Module ActiveRecord::Transactions::ClassMethods

Public Class methods

included(base)

[Source]

    # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 9
 9:     def self.included(base)
10:       base.extend(ClassMethods)
11:
12:       base.class_eval do
13:         [:destroy, :save, :save!].each do |method|
14:           alias_method_chain method, :transactions
15:         end
16:       end
17:     end

Public Instance methods

rollback_active_record_state!() {|| ...}

Reset id and @new_record if the transaction rolls back.

[Source]

     # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 204
204:     def rollback_active_record_state!
205:       id_present = has_attribute?(self.class.primary_key)
206:       previous_id = id
207:       previous_new_record = new_record?
208:       yield
209:     rescue Exception
210:       @new_record = previous_new_record
211:       if id_present
212:         self.id = previous_id
213:       else
214:         @attributes.delete(self.class.primary_key)
215:         @attributes_cache.delete(self.class.primary_key)
216:       end
217:       raise
218:     end
transaction(&block)

See ActiveRecord::Transactions::ClassMethods for detailed documentation.

[Source]

     # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 187
187:     def transaction(&block)
188:       self.class.transaction(&block)
189:     end
with_transaction_returning_status(method, *args)

Executes method within a transaction and captures its return value as a status flag. If the status is true the transaction is committed, otherwise a ROLLBACK is issued. In any case the status flag is returned.

This method is available within the context of an ActiveRecord::Base instance.

[Source]

     # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 226
226:     def with_transaction_returning_status(method, *args)
227:       status = nil
228:       self.class.transaction do
229:         status = send(method, *args)
230:         raise ActiveRecord::Rollback unless status
231:       end
232:       status
233:     end


Module: ActiveRecord::Transactions::ClassMethods

Module | ActiveRecord::Transactions::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/transactions.rb

Transactions are protective blocks where SQL statements are only permanent if they can all succeed as one atomic action. The classic example is a transfer between two accounts where you can only have a deposit if the withdrawal succeeded and vice versa. Transactions enforce the integrity of the database and guard the data against program errors or database break-downs. So basically you should use transaction blocks whenever you have a number of statements that must be executed together or not at all. Example:

  ActiveRecord::Base.transaction do
    david.withdrawal(100)
    mary.deposit(100)
  end

This example will only take money from David and give to Mary if neither withdrawal nor deposit raises an exception. Exceptions will force a ROLLBACK that returns the database to the state before the transaction was begun. Be aware, though, that the objects will not have their instance data returned to their pre-transactional state.

Different Active Record classes in a single transaction

Though the transaction class method is called on some Active Record class, the objects within the transaction block need not all be instances of that class. This is because transactions are per-database connection, not per-model.

In this example a Balance record is transactionally saved even though transaction is called on the Account class:

  Account.transaction do
    balance.save!
    account.save!
  end

Note that the transaction method is also available as a model instance method. For example, you can also do this:

  balance.transaction do
    balance.save!
    account.save!
  end

Transactions are not distributed across database connections

A transaction acts on a single database connection. If you have multiple class-specific databases, the transaction will not protect interaction among them. One workaround is to begin a transaction on each class whose models you alter:

  Student.transaction do
    Course.transaction do
      course.enroll(student)
      student.units += course.units
    end
  end

This is a poor solution, but full distributed transactions are beyond the scope of Active Record.

Save and destroy are automatically wrapped in a transaction

Both Base#save and Base#destroy come wrapped in a transaction that ensures that whatever you do in validations or callbacks will happen under the protected cover of a transaction. So you can use validations to check for values that the transaction depends on or you can raise exceptions in the callbacks to rollback, including after_* callbacks.

Exception handling and rolling back

Also have in mind that exceptions thrown within a transaction block will be propagated (after triggering the ROLLBACK), so you should be ready to catch those in your application code.

One exception is the ActiveRecord::Rollback exception, which will trigger a ROLLBACK when raised, but not be re-raised by the transaction block.

Warning: one should not catch ActiveRecord::StatementInvalid exceptions inside a transaction block. StatementInvalid exceptions indicate that an error occurred at the database level, for example when a unique constraint is violated. On some database systems, such as PostgreSQL, database errors inside a transaction causes the entire transaction to become unusable until it‘s restarted from the beginning. Here is an example which demonstrates the problem:

  # Suppose that we have a Number model with a unique column called 'i'.
  Number.transaction do
    Number.create(:i => 0)
    begin
      # This will raise a unique constraint error...
      Number.create(:i => 0)
    rescue ActiveRecord::StatementInvalid
      # ...which we ignore.
    end

    # On PostgreSQL, the transaction is now unusable. The following
    # statement will cause a PostgreSQL error, even though the unique
    # constraint is no longer violated:
    Number.create(:i => 1)
    # => "PGError: ERROR:  current transaction is aborted, commands
    #     ignored until end of transaction block"
  end

One should restart the entire transaction if a StatementError occurred.

Nested transactions

transaction calls can be nested. By default, this makes all database statements in the nested transaction block become part of the parent transaction. For example:

  User.transaction do
    User.create(:username => 'Kotori')
    User.transaction do
      User.create(:username => 'Nemu')
      raise ActiveRecord::Rollback
    end
  end

  User.find(:all)  # => empty

It is also possible to requires a sub-transaction by passing :requires_new => true. If anything goes wrong, the database rolls back to the beginning of the sub-transaction without rolling back the parent transaction. For example:

  User.transaction do
    User.create(:username => 'Kotori')
    User.transaction(:requires_new => true) do
      User.create(:username => 'Nemu')
      raise ActiveRecord::Rollback
    end
  end

  User.find(:all)  # => Returns only Kotori

Most databases don‘t support true nested transactions. At the time of writing, the only database that we‘re aware of that supports true nested transactions, is MS-SQL. Because of this, Active Record emulates nested transactions by using savepoints. See dev.mysql.com/doc/refman/5.0/en/savepoints.html for more information about savepoints.

Caveats

If you‘re on MySQL, then do not use DDL operations in nested transactions blocks that are emulated with savepoints. That is, do not execute statements like ‘CREATE TABLE’ inside such blocks. This is because MySQL automatically releases all savepoints upon executing a DDL operation. When transaction is finished and tries to release the savepoint it created earlier, a database error will occur because the savepoint has already been automatically released. The following example demonstrates the problem:

  Model.connection.transaction do                           # BEGIN
    Model.connection.transaction(:requires_new => true) do  # CREATE SAVEPOINT active_record_1
      Model.connection.create_table(...)                    # active_record_1 now automatically released
    end                                                     # RELEASE savepoint active_record_1
                                                            # ^^^^ BOOM! database error!
  end

Methods

transaction

Public Instance methods

transaction(options = {}, &block)

See ActiveRecord::Transactions::ClassMethods for detailed documentation.

[Source]

     # File vendor/rails/activerecord/lib/active_record/transactions.rb, line 180
180:       def transaction(options = {}, &block)
181:         # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
182:         connection.transaction(options, &block)
183:       end


Class: ActiveRecord::UnknownAttributeError

Class | ActiveRecord::UnknownAttributeError
In: | vendor/rails/activerecord/lib/active_record/base.rb
Parent: | NoMethodError

Raised when unknown attributes are supplied via mass assignment.


Module: ActiveRecord::Validations

Module | ActiveRecord::Validations
In: | vendor/rails/activerecord/lib/active_record/validations.rb

Please do have a look at ActiveRecord::Validations::ClassMethods for a higher level of validations.

Active Records implement validation by overwriting Base#validate (or the variations, validate_on_create and validate_on_update). Each of these methods can inspect the state of the object, which usually means ensuring that a number of attributes have a certain value (such as not empty, within a given range, matching a certain regular expression).

Example:

  class Person < ActiveRecord::Base
    protected
      def validate
        errors.add_on_empty %w( first_name last_name )
        errors.add("phone_number", "has invalid format") unless phone_number =~ /[0-9]*/
      end

      def validate_on_create # is only run the first time a new object is saved
        unless valid_discount?(membership_discount)
          errors.add("membership_discount", "has expired")
        end
      end

      def validate_on_update
        errors.add_to_base("No changes have occurred") if unchanged_attributes?
      end
  end

  person = Person.new("first_name" => "David", "phone_number" => "what?")
  person.save                         # => false (and doesn't do the save)
  person.errors.empty?                # => false
  person.errors.count                 # => 2
  person.errors.on "last_name"        # => "can't be empty"
  person.errors.on "phone_number"     # => "has invalid format"
  person.errors.each_full { |msg| puts msg }
                                      # => "Last name can't be empty\n" +
                                      #    "Phone number has invalid format"

  person.attributes = { "last_name" => "Heinemeier", "phone_number" => "555-555" }
  person.save # => true (and person is now saved in the database)

An Errors object is automatically created for every Active Record.

Methods

errors invalid? save_with_validation save_with_validation! valid? validate validate_on_create validate_on_update

Classes and Modules

Module ActiveRecord::Validations::ClassMethods

Constants

VALIDATIONS = %w( validate validate_on_create validate_on_update )

Public Instance methods

errors()

Returns the Errors object that holds all information about attribute error messages.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1049
1049:     def errors
1050:       @errors ||= Errors.new(self)
1051:     end
invalid?()

Performs the opposite of valid?. Returns true if errors were added, false otherwise.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1044
1044:     def invalid?
1045:       !valid?
1046:     end
save_with_validation(perform_validation = true)

The validation process on save can be skipped by passing false. The regular Base#save method is replaced with this when the validations module is mixed in, which it is by default.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1007
1007:     def save_with_validation(perform_validation = true)
1008:       if perform_validation && valid? || !perform_validation
1009:         save_without_validation
1010:       else
1011:         false
1012:       end
1013:     end
save_with_validation!()

Attempts to save the record just like Base#save but will raise a RecordInvalid exception instead of returning false if the record is not valid.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1017
1017:     def save_with_validation!
1018:       if valid?
1019:         save_without_validation!
1020:       else
1021:         raise RecordInvalid.new(self)
1022:       end
1023:     end
valid?()

Runs validate and validate_on_create or validate_on_update and returns true if no errors were added otherwise false.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1026
1026:     def valid?
1027:       errors.clear
1028:
1029:       run_callbacks(:validate)
1030:       validate
1031:
1032:       if new_record?
1033:         run_callbacks(:validate_on_create)
1034:         validate_on_create
1035:       else
1036:         run_callbacks(:validate_on_update)
1037:         validate_on_update
1038:       end
1039:
1040:       errors.empty?
1041:     end

Protected Instance methods

validate()

Overwrite this method for validation checks on all saves and use Errors.add(field, msg) for invalid attributes.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1055
1055:       def validate
1056:       end
validate_on_create()

Overwrite this method for validation checks used only on creation.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1059
1059:       def validate_on_create
1060:       end
validate_on_update()

Overwrite this method for validation checks used only on updates.

[Source]

      # File vendor/rails/activerecord/lib/active_record/validations.rb, line 1063
1063:       def validate_on_update
1064:       end


Module: ActiveRecord::Validations::ClassMethods

Module | ActiveRecord::Validations::ClassMethods
In: | vendor/rails/activerecord/lib/active_record/validations.rb

Active Record classes can implement validations in several ways. The highest level, easiest to read, and recommended approach is to use the declarative validates_..._of class methods (and validates_associated) documented below. These are sufficient for most model validations.

Slightly lower level is validates_each. It provides some of the same options as the purely declarative validation methods, but like all the lower-level approaches it requires manually adding to the errors collection when the record is invalid.

At a yet lower level, a model can use the class methods validate, validate_on_create and validate_on_update to add validation methods or blocks. These are ActiveSupport::Callbacks and follow the same rules of inheritance and chaining.

The lowest level style is to define the instance methods validate, validate_on_create and validate_on_update as documented in ActiveRecord::Validations.

validate, validate_on_create and validate_on_update Class Methods

Calls to these methods add a validation method or block to the class. Again, this approach is recommended only when the higher-level methods documented below (validates_..._of and validates_associated) are insufficient to handle the required validation.

This can be done with a symbol pointing to a method:

  class Comment < ActiveRecord::Base
    validate :must_be_friends

    def must_be_friends
      errors.add_to_base("Must be friends to leave a comment") unless commenter.friend_of?(commentee)
    end
  end

Or with a block which is passed the current record to be validated:

  class Comment < ActiveRecord::Base
    validate do |comment|
      comment.must_be_friends
    end

    def must_be_friends
      errors.add_to_base("Must be friends to leave a comment") unless commenter.friend_of?(commentee)
    end
  end

This usage applies to validate_on_create and validate_on_update as well.

Methods

create! validates_acceptance_of validates_associated validates_confirmation_of validates_each validates_exclusion_of validates_format_of validates_inclusion_of validates_length_of validates_numericality_of validates_presence_of validates_size_of validates_uniqueness_of

Constants

DEFAULT_VALIDATION_OPTIONS | = | { :on => :save, :allow_nil => false, :allow_blank => false, :message => nil
ALL_RANGE_OPTIONS | = | [ :is, :within, :in, :minimum, :maximum ].freeze
ALL_NUMERICALITY_CHECKS | = | { :greater_than => '>', :greater_than_or_equal_to => '>=', :equal_to => '==', :less_than => '<', :less_than_or_equal_to => '<=', :odd => 'odd?', :even => 'even?' }.freeze

Public Instance methods

create!(attributes = nil) {|object| ...}

Creates an object just like Base.create but calls save! instead of save so an exception is raised if the record is invalid.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 984
984:       def create!(attributes = nil, &block)
985:         if attributes.is_a?(Array)
986:           attributes.collect { |attr| create!(attr, &block) }
987:         else
988:           object = new(attributes)
989:           yield(object) if block_given?
990:           object.save!
991:           object
992:         end
993:       end
validates_acceptance_of(*attr_names)

Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:

  class Person < ActiveRecord::Base
    validates_acceptance_of :terms_of_service
    validates_acceptance_of :eula, :message => "must be abided"
  end

If the database column does not exist, the terms_of_service attribute is entirely virtual. This check is performed only if terms_of_service is not nil and by default on save.

Configuration options:

  • :message - A custom error message (default is: "must be accepted").
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :allow_nil - Skip validation if attribute is nil (default is true).
  • :accept - Specifies value that is considered accepted. The default value is a string "1", which makes it easy to relate to an HTML checkbox. This should be set to true if you are validating a database column, since the attribute is typecast from "1" to true before validation.
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 468
468:       def validates_acceptance_of(*attr_names)
469:         configuration = { :on => :save, :allow_nil => true, :accept => "1" }
470:         configuration.update(attr_names.extract_options!)
471:
472:         db_cols = begin
473:           column_names
474:         rescue Exception # To ignore both statement and connection errors
475:           []
476:         end
477:         names = attr_names.reject { |name| db_cols.include?(name.to_s) }
478:         attr_accessor(*names)
479:
480:         validates_each(attr_names,configuration) do |record, attr_name, value|
481:           unless value == configuration[:accept]
482:             record.errors.add(attr_name, :accepted, :default => configuration[:message])
483:           end
484:         end
485:       end
validates_associated(*attr_names)

Validates whether the associated object or objects are all valid themselves. Works with any kind of association.

  class Book < ActiveRecord::Base
    has_many :pages
    belongs_to :library

    validates_associated :pages, :library
  end

Warning: If, after the above definition, you then wrote:

  class Page < ActiveRecord::Base
    belongs_to :book

    validates_associated :book
  end

this would specify a circular dependency and cause infinite recursion.

NOTE: This validation will not fail if the association hasn‘t been assigned. If you want to ensure that the association is both present and guaranteed to be valid, you also need to use validates_presence_of.

Configuration options:

  • :message - A custom error message (default is: "is invalid")
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 901
901:       def validates_associated(*attr_names)
902:         configuration = { :on => :save }
903:         configuration.update(attr_names.extract_options!)
904:
905:         validates_each(attr_names, configuration) do |record, attr_name, value|
906:           unless (value.is_a?(Array) ? value : [value]).collect { |r| r.nil? || r.valid? }.all?
907:             record.errors.add(attr_name, :invalid, :default => configuration[:message], :value => value)
908:           end
909:         end
910:       end
validates_confirmation_of(*attr_names)

Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:

  Model:
    class Person < ActiveRecord::Base
      validates_confirmation_of :user_name, :password
      validates_confirmation_of :email_address, :message => "should match confirmation"
    end

  View:
    <%= password_field "person", "password" %>
    <%= password_field "person", "password_confirmation" %>

The added password_confirmation attribute is virtual; it exists only as an in-memory attribute for validating the password. To achieve this, the validation adds accessors to the model for the confirmation attribute. NOTE: This check is performed only if password_confirmation is not nil, and by default only on save. To require confirmation, make sure to add a presence check for the confirmation attribute:

  validates_presence_of :password_confirmation, :if => :password_changed?

Configuration options:

  • :message - A custom error message (default is: "doesn‘t match confirmation").
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 432
432:       def validates_confirmation_of(*attr_names)
433:         configuration = { :on => :save }
434:         configuration.update(attr_names.extract_options!)
435:
436:         attr_accessor(*(attr_names.map { |n| "#{n}_confirmation" }))
437:
438:         validates_each(attr_names, configuration) do |record, attr_name, value|
439:           unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation")
440:             record.errors.add(attr_name, :confirmation, :default => configuration[:message])
441:           end
442:         end
443:       end
validates_each(*attrs) {|record, attr, value| ...}

Validates each attribute against a block.

  class Person < ActiveRecord::Base
    validates_each :first_name, :last_name do |record, attr, value|
      record.errors.add attr, 'starts with z.' if value[0] == ?z
    end
  end

Options:

  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :allow_nil - Skip validation if attribute is nil.
  • :allow_blank - Skip validation if attribute is blank.
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 390
390:       def validates_each(*attrs)
391:         options = attrs.extract_options!.symbolize_keys
392:         attrs   = attrs.flatten
393:
394:         # Declare the validation.
395:         send(validation_method(options[:on] || :save), options) do |record|
396:           attrs.each do |attr|
397:             value = record.send(attr)
398:             next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
399:             yield record, attr, value
400:           end
401:         end
402:       end
validates_exclusion_of(*attr_names)

Validates that the value of the specified attribute is not in a particular enumerable object.

  class Person < ActiveRecord::Base
    validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here"
    validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60"
    validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension {{value}} is not allowed"
  end

Configuration options:

  • :in - An enumerable object of items that the value shouldn‘t be part of.
  • :message - Specifies a custom error message (default is: "is reserved").
  • :allow_nil - If set to true, skips this validation if the attribute is nil (default is false).
  • :allow_blank - If set to true, skips this validation if the attribute is blank (default is false).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 855
855:       def validates_exclusion_of(*attr_names)
856:         configuration = { :on => :save }
857:         configuration.update(attr_names.extract_options!)
858:
859:         enum = configuration[:in] || configuration[:within]
860:
861:         raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?(:include?)
862:
863:         validates_each(attr_names, configuration) do |record, attr_name, value|
864:           if enum.include?(value)
865:             record.errors.add(attr_name, :exclusion, :default => configuration[:message], :value => value)
866:           end
867:         end
868:       end
validates_format_of(*attr_names)

Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.

  class Person < ActiveRecord::Base
    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
  end

Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line.

A regular expression must be provided or else an exception will be raised.

Configuration options:

  • :message - A custom error message (default is: "is invalid").
  • :allow_nil - If set to true, skips this validation if the attribute is nil (default is false).
  • :allow_blank - If set to true, skips this validation if the attribute is blank (default is false).
  • :with - The regular expression used to validate the format with (note: must be supplied!).
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 789
789:       def validates_format_of(*attr_names)
790:         configuration = { :on => :save, :with => nil }
791:         configuration.update(attr_names.extract_options!)
792:
793:         raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp)
794:
795:         validates_each(attr_names, configuration) do |record, attr_name, value|
796:           unless value.to_s =~ configuration[:with]
797:             record.errors.add(attr_name, :invalid, :default => configuration[:message], :value => value)
798:           end
799:         end
800:       end
validates_inclusion_of(*attr_names)

Validates whether the value of the specified attribute is available in a particular enumerable object.

  class Person < ActiveRecord::Base
    validates_inclusion_of :gender, :in => %w( m f ), :message => "woah! what are you then!??!!"
    validates_inclusion_of :age, :in => 0..99
    validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension {{value}} is not included in the list"
  end

Configuration options:

  • :in - An enumerable object of available items.
  • :message - Specifies a custom error message (default is: "is not included in the list").
  • :allow_nil - If set to true, skips this validation if the attribute is nil (default is false).
  • :allow_blank - If set to true, skips this validation if the attribute is blank (default is false).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 821
821:       def validates_inclusion_of(*attr_names)
822:         configuration = { :on => :save }
823:         configuration.update(attr_names.extract_options!)
824:
825:         enum = configuration[:in] || configuration[:within]
826:
827:         raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?(:include?)
828:
829:         validates_each(attr_names, configuration) do |record, attr_name, value|
830:           unless enum.include?(value)
831:             record.errors.add(attr_name, :inclusion, :default => configuration[:message], :value => value)
832:           end
833:         end
834:       end
validates_length_of(*attrs)

Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:

  class Person < ActiveRecord::Base
    validates_length_of :first_name, :maximum=>30
    validates_length_of :last_name, :maximum=>30, :message=>"less than {{count}} if you don't mind"
    validates_length_of :fax, :in => 7..32, :allow_nil => true
    validates_length_of :phone, :in => 7..32, :allow_blank => true
    validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
    validates_length_of :fav_bra_size, :minimum => 1, :too_short => "please enter at least {{count}} character"
    validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with {{count}} characters... don't play me."
    validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least {{count}} words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
  end

Configuration options:

  • :minimum - The minimum size of the attribute.
  • :maximum - The maximum size of the attribute.
  • :is - The exact size of the attribute.
  • :within - A range specifying the minimum and maximum size of the attribute.
  • :in - A synonym(or alias) for :within.
  • :allow_nil - Attribute may be nil; skip validation.
  • :allow_blank - Attribute may be blank; skip validation.
  • :too_long - The error message if the attribute goes over the maximum (default is: "is too long (maximum is {{count}} characters)").
  • :too_short - The error message if the attribute goes under the minimum (default is: "is too short (min is {{count}} characters)").
  • :wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be {{count}} characters)").
  • :message - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message.
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :tokenizer - Specifies how to split up the attribute string. (e.g. :tokenizer => lambda {|str| str.scan(/\w+/)} to count words as in above example.) Defaults to lambda{ |value| value.split(//) } which counts individual characters.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 557
557:       def validates_length_of(*attrs)
558:         # Merge given options with defaults.
559:         options = {
560:           :tokenizer => lambda {|value| value.split(//)}
561:         }.merge(DEFAULT_VALIDATION_OPTIONS)
562:         options.update(attrs.extract_options!.symbolize_keys)
563:
564:         # Ensure that one and only one range option is specified.
565:         range_options = ALL_RANGE_OPTIONS & options.keys
566:         case range_options.size
567:           when 0
568:             raise ArgumentError, 'Range unspecified.  Specify the :within, :maximum, :minimum, or :is option.'
569:           when 1
570:             # Valid number of options; do nothing.
571:           else
572:             raise ArgumentError, 'Too many range options specified.  Choose only one.'
573:         end
574:
575:         # Get range option and value.
576:         option = range_options.first
577:         option_value = options[range_options.first]
578:         key = {:is => :wrong_length, :minimum => :too_short, :maximum => :too_long}[option]
579:         custom_message = options[:message] || options[key]
580:
581:         case option
582:           when :within, :in
583:             raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
584:
585:             validates_each(attrs, options) do |record, attr, value|
586:               value = options[:tokenizer].call(value) if value.kind_of?(String)
587:               if value.nil? or value.size < option_value.begin
588:                 record.errors.add(attr, :too_short, :default => custom_message || options[:too_short], :count => option_value.begin)
589:               elsif value.size > option_value.end
590:                 record.errors.add(attr, :too_long, :default => custom_message || options[:too_long], :count => option_value.end)
591:               end
592:             end
593:           when :is, :minimum, :maximum
594:             raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
595:
596:             # Declare different validations per option.
597:             validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
598:
599:             validates_each(attrs, options) do |record, attr, value|
600:               value = options[:tokenizer].call(value) if value.kind_of?(String)
601:               unless !value.nil? and value.size.method(validity_checks[option])[option_value]
602:                 record.errors.add(attr, key, :default => custom_message, :count => option_value)
603:               end
604:             end
605:         end
606:       end
validates_numericality_of(*attr_names)

Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float (if only_integer is false) or applying it to the regular expression /\A[+\-]?\d+\Z/ (if only_integer is set to true).

  class Person < ActiveRecord::Base
    validates_numericality_of :value, :on => :create
  end

Configuration options:

  • :message - A custom error message (default is: "is not a number").
  • :on - Specifies when this validation is active (default is :save, other options :create, :update).
  • :only_integer - Specifies whether the value has to be an integer, e.g. an integral value (default is false).
  • :allow_nil - Skip validation if attribute is nil (default is false). Notice that for fixnum and float columns empty strings are converted to nil.
  • :greater_than - Specifies the value must be greater than the supplied value.
  • :greater_than_or_equal_to - Specifies the value must be greater than or equal the supplied value.
  • :equal_to - Specifies the value must be equal to the supplied value.
  • :less_than - Specifies the value must be less than the supplied value.
  • :less_than_or_equal_to - Specifies the value must be less than or equal the supplied value.
  • :odd - Specifies the value must be an odd number.
  • :even - Specifies the value must be an even number.
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 938
938:       def validates_numericality_of(*attr_names)
939:         configuration = { :on => :save, :only_integer => false, :allow_nil => false }
940:         configuration.update(attr_names.extract_options!)
941:
942:
943:         numericality_options = ALL_NUMERICALITY_CHECKS.keys & configuration.keys
944:
945:         (numericality_options - [ :odd, :even ]).each do |option|
946:           raise ArgumentError, ":#{option} must be a number" unless configuration[option].is_a?(Numeric)
947:         end
948:
949:         validates_each(attr_names,configuration) do |record, attr_name, value|
950:           raw_value = record.send("#{attr_name}_before_type_cast") || value
951:
952:           next if configuration[:allow_nil] and raw_value.nil?
953:
954:           if configuration[:only_integer]
955:             unless raw_value.to_s =~ /\A[+-]?\d+\Z/
956:               record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message])
957:               next
958:             end
959:             raw_value = raw_value.to_i
960:           else
961:             begin
962:               raw_value = Kernel.Float(raw_value)
963:             rescue ArgumentError, TypeError
964:               record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message])
965:               next
966:             end
967:           end
968:
969:           numericality_options.each do |option|
970:             case option
971:               when :odd, :even
972:                 unless raw_value.to_i.method(ALL_NUMERICALITY_CHECKS[option])[]
973:                   record.errors.add(attr_name, option, :value => raw_value, :default => configuration[:message])
974:                 end
975:               else
976:                 record.errors.add(attr_name, option, :default => configuration[:message], :value => raw_value, :count => configuration[option]) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]]
977:             end
978:           end
979:         end
980:       end
validates_presence_of(*attr_names)

Validates that the specified attributes are not blank (as defined by Object#blank?). Happens by default on save. Example:

  class Person < ActiveRecord::Base
    validates_presence_of :first_name
  end

The first_name attribute must be in the object and it cannot be blank.

If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, :in => [true, false].

This is due to the way Object#blank? handles boolean values: false.blank? # => true.

Configuration options:

  • message - A custom error message (default is: "can‘t be blank").
  • on - Specifies when this validation is active (default is :save, other options :create, :update).
  • if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 511
511:       def validates_presence_of(*attr_names)
512:         configuration = { :on => :save }
513:         configuration.update(attr_names.extract_options!)
514:
515:         # can't use validates_each here, because it cannot cope with nonexistent attributes,
516:         # while errors.add_on_empty can
517:         send(validation_method(configuration[:on]), configuration) do |record|
518:           record.errors.add_on_blank(attr_names, configuration[:message])
519:         end
520:       end
validates_size_of(*attrs)

Alias for validates_length_of

validates_uniqueness_of(*attr_names)

Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named "davidhh".

  class Person < ActiveRecord::Base
    validates_uniqueness_of :user_name, :scope => :account_id
  end

It can also validate whether the value of the specified attributes are unique based on multiple scope parameters. For example, making sure that a teacher can only be on the schedule once per semester for a particular class.

  class TeacherSchedule < ActiveRecord::Base
    validates_uniqueness_of :teacher_id, :scope => [:semester_id, :class_id]
  end

When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

Configuration options:

  • :message - Specifies a custom error message (default is: "has already been taken").
  • :scope - One or more columns by which to limit the scope of the uniqueness constraint.
  • :case_sensitive - Looks for an exact match. Ignored by non-text columns (true by default).
  • :allow_nil - If set to true, skips this validation if the attribute is nil (default is false).
  • :allow_blank - If set to true, skips this validation if the attribute is blank (default is false).
  • :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
  • :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

Concurrency and integrity

Using this validation method in conjunction with ActiveRecord::Base#save does not guarantee the absence of duplicate record insertions, because uniqueness checks on the application level are inherently prone to race conditions. For example, suppose that two users try to post a Comment at the same time, and a Comment‘s title must be unique. At the database-level, the actions performed by these users could be interleaved in the following manner:

              User 1                 |               User 2
 ------------------------------------+--------------------------------------
 # User 1 checks whether there's     |
 # already a comment with the title  |
 # 'My Post'. This is not the case.  |
 SELECT * FROM comments              |
 WHERE title = 'My Post'             |
                                     |
                                     | # User 2 does the same thing and also
                                     | # infers that his title is unique.
                                     | SELECT * FROM comments
                                     | WHERE title = 'My Post'
                                     |
 # User 1 inserts his comment.       |
 INSERT INTO comments                |
 (title, content) VALUES             |
 ('My Post', 'hi!')                  |
                                     |
                                     | # User 2 does the same thing.
                                     | INSERT INTO comments
                                     | (title, content) VALUES
                                     | ('My Post', 'hello!')
                                     |
                                     | # ^^^^^^
                                     | # Boom! We now have a duplicate
                                     | # title!

This could even happen if you use transactions with the ‘serializable’ isolation level. There are several ways to get around this problem:

  • By locking the database table before validating, and unlocking it after saving. However, table locking is very expensive, and thus not recommended.
  • By locking a lock file before validating, and unlocking it after saving. This does not work if you‘ve scaled your Rails application across multiple web servers (because they cannot share lock files, or cannot do that efficiently), and thus not recommended.
  • Creating a unique index on the field, by using ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the rare case that a race condition occurs, the database will guarantee the field‘s uniqueness.

    When the database catches such a duplicate insertion, ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid exception. You can either choose to let this error propagate (which will result in the default Rails exception page being shown), or you can catch it and restart the transaction (e.g. by telling the user that the title already exists, and asking him to re-enter the title). This technique is also known as optimistic concurrency control: en.wikipedia.org/wiki/Optimistic_concurrency_control

    Active Record currently provides no way to distinguish unique index constraint errors from other types of database errors, so you will have to parse the (database-specific) exception message to detect such a case.

[Source]

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 704
704:       def validates_uniqueness_of(*attr_names)
705:         configuration = { :case_sensitive => true }
706:         configuration.update(attr_names.extract_options!)
707:
708:         validates_each(attr_names,configuration) do |record, attr_name, value|
709:           # The check for an existing value should be run from a class that
710:           # isn't abstract. This means working down from the current class
711:           # (self), to the first non-abstract class. Since classes don't know
712:           # their subclasses, we have to build the hierarchy between self and
713:           # the record's class.
714:           class_hierarchy = [record.class]
715:           while class_hierarchy.first != self
716:             class_hierarchy.insert(0, class_hierarchy.first.superclass)
717:           end
718:
719:           # Now we can work our way down the tree to the first non-abstract
720:           # class (which has a database table to query from).
721:           finder_class = class_hierarchy.detect { |klass| !klass.abstract_class? }
722:
723:           column = finder_class.columns_hash[attr_name.to_s]
724:
725:           if value.nil?
726:             comparison_operator = "IS ?"
727:           elsif column.text?
728:             comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
729:             value = column.limit ? value.to_s[0, column.limit] : value.to_s
730:           else
731:             comparison_operator = "= ?"
732:           end
733:
734:           sql_attribute = "#{record.class.quoted_table_name}.#{connection.quote_column_name(attr_name)}"
735:
736:           if value.nil? || (configuration[:case_sensitive] || !column.text?)
737:             condition_sql = "#{sql_attribute} #{comparison_operator}"
738:             condition_params = [value]
739:           else
740:             condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}"
741:             condition_params = [value.mb_chars.downcase]
742:           end
743:
744:           if scope = configuration[:scope]
745:             Array(scope).map do |scope_item|
746:               scope_value = record.send(scope_item)
747:               condition_sql << " AND " << attribute_condition("#{record.class.quoted_table_name}.#{scope_item}", scope_value)
748:               condition_params << scope_value
749:             end
750:           end
751:
752:           unless record.new_record?
753:             condition_sql << " AND #{record.class.quoted_table_name}.#{record.class.primary_key} <> ?"
754:             condition_params << record.send(:id)
755:           end
756:
757:           finder_class.with_exclusive_scope do
758:             if finder_class.exists?([condition_sql, *condition_params])
759:               record.errors.add(attr_name, :taken, :default => configuration[:message], :value => value)
760:             end
761:           end
762:         end
763:       end


File: aggregations.rb

aggregations.rb

Path: | vendor/rails/activerecord/lib/active_record/aggregations.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: association_preload.rb

association_preload.rb

Path: | vendor/rails/activerecord/lib/active_record/association_preload.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: associations.rb

associations.rb

Path: | vendor/rails/activerecord/lib/active_record/associations.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: association_collection.rb

association_collection.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/association_collection.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

set


File: association_proxy.rb

association_proxy.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: belongs_to_association.rb

belongs_to_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: belongs_to_polymorphic_association.rb

belongs_to_polymorphic_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: has_and_belongs_to_many_association.rb

has_and_belongs_to_many_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: has_many_association.rb

has_many_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: has_many_through_association.rb

has_many_through_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: has_one_association.rb

has_one_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: has_one_through_association.rb

has_one_through_association.rb

Path: | vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: attribute_methods.rb

attribute_methods.rb

Path: | vendor/rails/activerecord/lib/active_record/attribute_methods.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: autosave_association.rb

autosave_association.rb

Path: | vendor/rails/activerecord/lib/active_record/autosave_association.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: base.rb

base.rb

Path: | vendor/rails/activerecord/lib/active_record/base.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

yaml set active_record/connection_adapters/abstract_adapter


File: batches.rb

batches.rb

Path: | vendor/rails/activerecord/lib/active_record/batches.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: calculations.rb

calculations.rb

Path: | vendor/rails/activerecord/lib/active_record/calculations.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: callbacks.rb

callbacks.rb

Path: | vendor/rails/activerecord/lib/active_record/callbacks.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

observer


File: connection_pool.rb

connection_pool.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

monitor set


File: connection_specification.rb

connection_specification.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

rubygems


File: database_statements.rb

database_statements.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: query_cache.rb

query_cache.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: quoting.rb

quoting.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: schema_definitions.rb

schema_definitions.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

date set bigdecimal bigdecimal/util


File: schema_statements.rb

schema_statements.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: abstract_adapter.rb

abstract_adapter.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

benchmark date bigdecimal bigdecimal/util active_record/connection_adapters/abstract/schema_definitions active_record/connection_adapters/abstract/schema_statements active_record/connection_adapters/abstract/database_statements active_record/connection_adapters/abstract/quoting active_record/connection_adapters/abstract/connection_pool active_record/connection_adapters/abstract/connection_specification active_record/connection_adapters/abstract/query_cache


File: mysql_adapter.rb

mysql_adapter.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_record/connection_adapters/abstract_adapter set


File: postgresql_adapter.rb

postgresql_adapter.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_record/connection_adapters/abstract_adapter


File: sqlite3_adapter.rb

sqlite3_adapter.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_record/connection_adapters/sqlite_adapter


File: sqlite_adapter.rb

sqlite_adapter.rb

Path: | vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_record/connection_adapters/abstract_adapter


File: dirty.rb

dirty.rb

Path: | vendor/rails/activerecord/lib/active_record/dirty.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: dynamic_finder_match.rb

dynamic_finder_match.rb

Path: | vendor/rails/activerecord/lib/active_record/dynamic_finder_match.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: dynamic_scope_match.rb

dynamic_scope_match.rb

Path: | vendor/rails/activerecord/lib/active_record/dynamic_scope_match.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: fixtures.rb

fixtures.rb

Path: | vendor/rails/activerecord/lib/active_record/fixtures.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

erb yaml csv active_support/dependencies active_support/test_case


File: i18n_interpolation_deprecation.rb

i18n_interpolation_deprecation.rb

Path: | vendor/rails/activerecord/lib/active_record/i18n_interpolation_deprecation.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Deprecates the use of the former message interpolation syntax in activerecord as in "must have %d characters". The new syntax uses explicit variable names as in "{{value}} must have {{count}} characters".

Required files

i18n/backend/simple


File: optimistic.rb

optimistic.rb

Path: | vendor/rails/activerecord/lib/active_record/locking/optimistic.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: pessimistic.rb

pessimistic.rb

Path: | vendor/rails/activerecord/lib/active_record/locking/pessimistic.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Copyright (c) 2006 Shugo Maeda <shugo@ruby-lang.org>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


File: migration.rb

migration.rb

Path: | vendor/rails/activerecord/lib/active_record/migration.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: named_scope.rb

named_scope.rb

Path: | vendor/rails/activerecord/lib/active_record/named_scope.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: nested_attributes.rb

nested_attributes.rb

Path: | vendor/rails/activerecord/lib/active_record/nested_attributes.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: observer.rb

observer.rb

Path: | vendor/rails/activerecord/lib/active_record/observer.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

singleton set


File: query_cache.rb

query_cache.rb

Path: | vendor/rails/activerecord/lib/active_record/query_cache.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: reflection.rb

reflection.rb

Path: | vendor/rails/activerecord/lib/active_record/reflection.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: schema.rb

schema.rb

Path: | vendor/rails/activerecord/lib/active_record/schema.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: schema_dumper.rb

schema_dumper.rb

Path: | vendor/rails/activerecord/lib/active_record/schema_dumper.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

stringio bigdecimal


File: serialization.rb

serialization.rb

Path: | vendor/rails/activerecord/lib/active_record/serialization.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_support/json active_record/serializers/xml_serializer active_record/serializers/json_serializer


File: json_serializer.rb

json_serializer.rb

Path: | vendor/rails/activerecord/lib/active_record/serializers/json_serializer.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: xml_serializer.rb

xml_serializer.rb

Path: | vendor/rails/activerecord/lib/active_record/serializers/xml_serializer.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: session_store.rb

session_store.rb

Path: | vendor/rails/activerecord/lib/active_record/session_store.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: test_case.rb

test_case.rb

Path: | vendor/rails/activerecord/lib/active_record/test_case.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

active_support/test_case


File: timestamp.rb

timestamp.rb

Path: | vendor/rails/activerecord/lib/active_record/timestamp.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: transactions.rb

transactions.rb

Path: | vendor/rails/activerecord/lib/active_record/transactions.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009

Required files

thread


File: validations.rb

validations.rb

Path: | vendor/rails/activerecord/lib/active_record/validations.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: version.rb

version.rb

Path: | vendor/rails/activerecord/lib/active_record/version.rb
Last Update: | Sun Mar 15 23:31:34 -0500 2009


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/activerecord/CHANGELOG
Last Update: | Sun Mar 15 23:31:34 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • Added ActiveRecord::Base.find_each and ActiveRecord::Base.find_in_batches for batch processing [DHH/Jamis Buck]
  • Added that ActiveRecord::Base.exists? can be called with no arguments 1817 [Scott Taylor]
  • Add Support for updating deeply nested models from a single form. 1202 [Eloy Duran]
          class Book < ActiveRecord::Base
        has_one :author
        has_many :pages

        accepts_nested_attributes_for :author, :pages
      end
  • Make after_save callbacks fire only if the record was successfully saved. 1735 [Michael Lovitt]

    Previously the callbacks would fire if a before_save cancelled saving.

  • Support nested transactions using database savepoints. 383 [Jonathan Viney, Hongli Lai]
  • Added dynamic scopes ala dynamic finders 1648 [Yaroslav Markin]
  • Fixed that ActiveRecord::Base#new_record? should return false (not nil) for existing records 1219 [Yaroslav Markin]
  • I18n the word separator for error messages. Introduces the activerecord.errors.format.separator translation key. 1294 [Akira Matsuda]
  • Add :having as a key to find and the relevant associations. [Emilio Tagua]
  • Added default_scope to Base 1381 [Paweł Kondzior]. Example:
      class Person < ActiveRecord::Base
    default_scope :order => 'last_name, first_name'
  end

  class Company < ActiveRecord::Base
    has_many :people
  end

  Person.all             # => Person.find(:all, :order => 'last_name, first_name')
  Company.find(1).people # => Person.find(:all, :order => 'last_name, first_name', :conditions => { :company_id => 1 })

*2.2.1 [RC2] (November 14th, 2008)*

  • Ensure indices don‘t flip order in schema.rb 1266 [Jordi Bunster]
  • Fixed that serialized strings should never be type-casted (i.e. turning "Yes" to a boolean) 857 [Andreas Korth]

*2.2.0 [RC1] (October 24th, 2008)*

  • Skip collection ids reader optimization if using :finder_sql [Jeremy Kemper]
  • Add Model#delete instance method, similar to Model.delete class method. 1086 [Hongli Lai (Phusion)]
  • MySQL: cope with quirky default values for not-null text columns. 1043 [Frederick Cheung]
  • Multiparameter attributes skip time zone conversion for time-only columns [1030 state:resolved] [Geoff Buesing]
  • Base.skip_time_zone_conversion_for_attributes uses class_inheritable_accessor, so that subclasses don‘t overwrite Base [346 state:resolved] [Emilio Tagua]
  • Added find_last_by dynamic finder 762 [Emilio Tagua]
  • Internal API: configurable association options and build_association method for reflections so plugins may extend and override. 985 [Hongli Lai (Phusion)]
  • Changed benchmarks to be reported in milliseconds [David Heinemeier Hansson]
  • Connection pooling. 936 [Nick Sieger]
  • Merge scoped :joins together instead of overwriting them. May expose scoping bugs in your code! 501 [Andrew White]
  • before_save, before_validation and before_destroy callbacks that return false will now ROLLBACK the transaction. Previously this would have been committed before the processing was aborted. 891 [Xavier Noria]
  • Transactional migrations for databases which support them. 834 [divoxx, Adam Wiggins, Tarmo Tänav]
  • Set config.active_record.timestamped_migrations = false to have migrations with numeric prefix instead of UTC timestamp. 446. [Andrew Stone, Nik Wakelin]
  • change_column_default preserves the not-null constraint. 617 [Tarmo Tänav]
  • Fixed that create database statements would always include "DEFAULT NULL" (Nick Sieger) [334]
  • Add :tokenizer option to validates_length_of to specify how to split up the attribute string. 507. [David Lowenfels] Example :

    # Ensure essay contains at least 100 words. validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least %d words."), :tokenizer => lambda {|str| str.scan(/\w+/) }

  • Allow conditions on multiple tables to be specified using hash. [Pratik Naik]. Example:

    User.all :joins => :items, :conditions => { :age => 10, :items => { :color => ‘black’ } } Item.first :conditions => { :items => { :color => ‘red’ } }

  • Always treat integer :limit as byte length. 420 [Tarmo Tänav]
  • Partial updates don‘t update lock_version if nothing changed. 426 [Daniel Morrison]
  • Fix column collision with named_scope and :joins. 46 [Duncan Beevers, Mark Catley]
  • db:migrate:down and :up update schema_migrations. 369 [Michael Raidel, RaceCondition]
  • PostgreSQL: support :conditions => [’:foo::integer’, { :foo => 1 }] without treating the ::integer typecast as a bind variable. [Tarmo Tänav]
  • MySQL: rename_column preserves column defaults. 466 [Diego Algorta]
  • Add :from option to calculations. 397 [Ben Munat]
  • Add :validate option to associations to enable/disable the automatic validation of associated models. Resolves 301. [Jan De Poorter]
  • PostgreSQL: use ‘INSERT … RETURNING id’ for 8.2 and later. [Jeremy Kemper]
  • Added SQL escaping for :limit and :offset in MySQL [Jonathan Wiess]

*2.1.0 (May 31st, 2008)*

  • Add ActiveRecord::Base.sti_name that checks ActiveRecord::Base#store_full_sti_class? and returns either the full or demodulized name. [Rick Olson]
  • Add first/last methods to associations/named_scope. Resolved 226. [Ryan Bates]
  • Added SQL escaping for :limit and :offset 288 [Aaron Bedra, Steven Bristol, Jonathan Wiess]
  • Added first/last methods to associations/named_scope. Resolved 226. [Ryan Bates]
  • Ensure hm:t preloading honours reflection options. Resolves 137. [Frederick Cheung]
  • Added protection against duplicate migration names (Aslak Hellesøy) [112]
  • Base#instantiate_time_object: eliminate check for Time.zone, since we can assume this is set if time_zone_aware_attributes is set to true [Geoff Buesing]
  • Time zone aware attribute methods use Time.zone.parse instead of to_time for String arguments, so that offset information in String is respected. Resolves 105. [Scott Fleckenstein, Geoff Buesing]
  • Added change_table for migrations (Jeff Dean) [71]. Example:
      change_table :videos do |t|
    t.timestamps                          # adds created_at, updated_at
    t.belongs_to :goat                    # adds goat_id integer
    t.string :name, :email, :limit => 20  # adds name and email both with a 20 char limit
    t.remove :name, :email                # removes the name and email columns
  end
  • Fixed has_many :through .create with no parameters caused a "can‘t dup NilClass" error (Steven Soroka) [85]
  • Added block-setting of attributes for Base.create like Base.new already has (Adam Meehan) [39]
  • Fixed that pessimistic locking you reference the quoted table name (Josh Susser) [67]
  • Fixed that change_column should be able to use :null => true on a field that formerly had false [Nate Wiger] [26]
  • Added that the MySQL adapter should map integer to either smallint, int, or bigint depending on the :limit just like PostgreSQL [David Heinemeier Hansson]
  • Change validates_uniqueness_of :case_sensitive option default back to true (from [9160]). Love your database columns, don‘t LOWER them. [Rick Olson]
  • Add support for interleaving migrations by storing which migrations have run in the new schema_migrations table. Closes 11493 [Jordi Bunster]
  • ActiveRecord::Base#sum defaults to 0 if no rows are returned. Closes 11550 [Kamal Fariz Mahyuddin]
  • Ensure that respond_to? considers dynamic finder methods. Closes 11538. [James Mead]
  • Ensure that save on parent object fails for invalid has_one association. Closes 10518. [Pratik Naik]
  • Remove duplicate code from associations. [Pratik Naik]
  • Refactor HasManyThroughAssociation to inherit from HasManyAssociation. Association callbacks and <association>_ids= now work with hm:t. 11516 [Ruy Asan]
  • Ensure HABTM#create and HABTM#build do not load entire association. [Pratik Naik]
  • Improve documentation. [Xavier Noria, Jack Danger Canty, leethal]
  • Tweak ActiveRecord::Base#to_json to include a root value in the returned hash: {"post": {"title": …}} [Rick Olson]

    Post.find(1).to_json # => {"title": …}
config.active_record.include_root_in_json = true Post.find(1).to_json #
=> {"post": {"title": …}}

  • Add efficient include? to AssociationCollection (for has_many/has_many :through/habtm). [stopdropandrew]
  • PostgreSQL: create_ and drop_database support. 9042 [ez, pedz, Nick Sieger]
  • Ensure that validates_uniqueness_of works with with_scope. Closes 9235. [Nik Wakelin, cavalle]
  • Partial updates include only unsaved attributes. Off by default; set YourClass.partial_updates = true to enable. [Jeremy Kemper]
  • Removing unnecessary uses_tzinfo helper from tests, given that TZInfo is now bundled [Geoff Buesing]
  • Fixed that validates_size_of :within works in associations 11295, 10019 [cavalle]
  • Track changes to unsaved attributes. [Jeremy Kemper]
  • Switched to UTC-timebased version numbers for migrations and the schema. This will as good as eliminate the problem of multiple migrations getting the same version assigned in different branches. Also added rake db:migrate:up/down to apply individual migrations that may need to be run when you merge branches 11458 [John Barnette]
  • Fixed that has_many :through would ignore the hash conditions 11447 [Emilio Tagua]
  • Fix issue where the :uniq option of a has_many :through association is ignored when find(:all) is called. Closes 9407 [cavalle]
  • Fix duplicate table alias error when including an association with a has_many :through association on the same join table. Closes 7310 [cavalle]
  • More efficient association preloading code that compacts a through_records array in a central location. Closes 11427 [Jack Danger Canty]
  • Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert]
  • Fixed that ActiveRecord#Base.find_or_create/initialize would not honor attr_protected/accessible when used with a hash 11422 [Emilio Tagua]
  • Added ActiveRecord#Base.all/first/last as aliases for find(:all/:first/:last) 11413 [nkallen, Chris O‘Sullivan]
  • Merge the has_finder gem, renamed as ‘named_scope’. 11404 [nkallen]

    class Article < ActiveRecord::Base

      named_scope :published, :conditions => {:published => true}
  named_scope :popular, :conditions => ...

    end

    Article.published.paginate(:page => 1) Article.published.popular.count Article.popular.find(:first) Article.popular.find(:all, :conditions => {…})

    See pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries

  • Add has_one :through support. 4756 [Chris O‘Sullivan]
  • Migrations: create_table supports primary_key_prefix_type. 10314 [student, Chris O‘Sullivan]
  • Added logging for dependency load errors with fixtures 11056 [stuthulhu]
  • Time zone aware attributes use Time#in_time_zone [Geoff Buesing]
  • Fixed that scoped joins would not always be respected 6821 [Theory/Jack Danger Canty]
  • Ensure that ActiveRecord::Calculations disambiguates field names with the table name. 11027 [cavalle]
  • Added add/remove_timestamps to the schema statements for adding the created_at/updated_at columns on existing tables 11129 [jramirez]
  • Added ActiveRecord::Base.find(:last) 11338 [Emilio Tagua]
  • test_native_types expects DateTime.local_offset instead of DateTime.now.offset; fixes test breakage due to dst transition [Geoff Buesing]
  • Add :readonly option to HasManyThrough associations. 11156 [Emilio Tagua]
  • Improve performance on :include/:conditions/:limit queries by selectively joining in the pre-query. 9560 [dasil003]
  • Perf fix: Avoid the use of named block arguments. Closes 11109 [adymo]
  • PostgreSQL: support server versions 7.4 through 8.0 and the ruby-pg driver. 11127 [jdavis]
  • Ensure association preloading doesn‘t break when an association returns nil. #11145 [GMFlash]
  • Make dynamic finders respect the :include on HasManyThrough associations. 10998. [cpytel]
  • Base#instantiate_time_object only uses Time.zone when Base.time_zone_aware_attributes is true; leverages Time#time_with_datetime_fallback for readability [Geoff Buesing]
  • Refactor ConnectionAdapters::Column.new_time: leverage DateTime failover behavior of Time#time_with_datetime_fallback [Geoff Buesing]
  • Improve associations performance by using symbol callbacks instead of string callbacks. 11108 [adymo]
  • Optimise the BigDecimal conversion code. 11110 [adymo]
  • Introduce the :readonly option to all associations. Records from the association cannot be saved. 11084 [Emilio Tagua]
  • Multiparameter attributes for time columns fail over to DateTime when out of range of Time [Geoff Buesing]
  • Base#instantiate_time_object uses Time.zone.local() [Geoff Buesing]
  • Add timezone-aware attribute readers and writers. 10982 [Geoff Buesing]
  • Instantiating time objects in multiparameter attributes uses Time.zone if available. 10982 [Rick Olson]
  • Add note about how ActiveRecord::Observer classes are initialized in a Rails app. 10980 [Xavier Noria]
  • MySQL: omit text/blob defaults from the schema instead of using an empty string. 10963 [mdeiters]
  • belongs_to supports :dependent => :destroy and :delete. 10592 [Jonathan Viney]
  • Introduce preload query strategy for eager :includes. 9640 [Frederick Cheung, Aliaksey Kandratsenka, codafoo]
  • Support aggregations in finder conditions. 10572 [Ryan Kinderman]
  • Organize and clean up the Active Record test suite. 10742 [John Barnette]
  • Ensure that modifying has_and_belongs_to_many actions clear the query cache. Closes 10840 [john.andrews]
  • Fix issue where Table#references doesn‘t pass a :null option to a *_type attribute for polymorphic associations. Closes 10753 [railsjitsu]
  • Fixtures: removed support for the ancient pre-YAML file format. 10736 [John Barnette]
  • More thoroughly quote table names. 10698 [dimdenis, lotswholetime, Jeremy Kemper]
  • update_all ignores scoped :order and :limit, so post.comments.update_all doesn‘t try to include the comment order in the update statement. 10686 [Brendan Ribera]
  • Added ActiveRecord::Base.cache_key to make it easier to cache Active Records in combination with the new ActiveSupport::Cache::* libraries [David Heinemeier Hansson]
  • Make sure CSV fixtures are compatible with ruby 1.9‘s new csv implementation. [JEG2]
  • Added by parameter to increment, decrement, and their bang varieties so you can do player1.increment!(:points, 5) 10542 [Sam]
  • Optimize ActiveRecord::Base#exists? to use select_all instead of find. Closes 10605 [jamesh, Frederick Cheung, protocool]
  • Don‘t unnecessarily load has_many associations in after_update callbacks. Closes 6822 [stopdropandrew, canadaduane]
  • Eager belongs_to :include infers the foreign key from the association name rather than the class name. 10517 [Jonathan Viney]
  • SQLite: fix rename_ and remove_column for columns with unique indexes. 10576 [Brandon Keepers]
  • Ruby 1.9 compatibility. 10655 [Jeremy Kemper, Dirkjan Bussink]

*2.0.2* (December 16th, 2007)

  • Ensure optimistic locking handles nil lock_version values properly. Closes 10510 [Rick Olson]
  • Make the Fixtures Test::Unit enhancements more supporting for double-loaded test cases. Closes 10379 [brynary]
  • Fix that validates_acceptance_of still works for non-existent tables (useful for bootstrapping new databases). Closes 10474 [Josh Susser]
  • Ensure that the :uniq option for has_many :through associations retains the order. 10463 [remvee]
  • Base.exists? doesn‘t rescue exceptions to avoid hiding SQL errors. 10458 [Michael Klishin]
  • Documentation: Active Record exceptions, destroy_all and delete_all. 10444, 10447 [Michael Klishin]

*2.0.1* (December 7th, 2007)

  • Removed query cache rescue as it could cause code to be run twice (closes 10408) [David Heinemeier Hansson]

*2.0.0* (December 6th, 2007)

  • Anchor DateTimeTest to fixed DateTime instead of a variable value based on Time.now#advance#to_datetime, so that this test passes on 64-bit platforms running Ruby 1.8.6+ [Geoff Buesing]
  • Fixed that the Query Cache should just be ignored if the database is misconfigured (so that the "About your applications environment" works even before the database has been created) [David Heinemeier Hansson]
  • Fixed that the truncation of strings longer than 50 chars should use inspect

so newlines etc are escaped 10385 [Norbert Crombach]

  • Fixed that habtm associations should be able to set :select as part of their definition and have that honored [David Heinemeier Hansson]
  • Document how the :include option can be used in Calculations::calculate. Closes 7446 [adamwiggins, ultimoamore]
  • Fix typo in documentation for polymorphic associations w/STI. Closes 7461 [johnjosephbachir]
  • Reveal that the type option in migrations can be any supported column type for your database but also include caveat about agnosticism. Closes 7531 [adamwiggins, mikong]
  • More complete documentation for find_by_sql. Closes 7912 [fearoffish]
  • Added ActiveRecord::Base#becomes to turn a record into one of another class (mostly relevant for STIs) [David Heinemeier Hansson]. Example:
      render :partial => @client.becomes(Company) # renders companies/company instead of clients/client
  • Fixed that to_xml should not automatically pass :procs to associations included with :include 10162 [Cheah Chu Yeow]
  • Fix documentation typo introduced in [8250]. Closes 10339 [Henrik N]
  • Foxy fixtures: support single-table inheritance. 10234 [tom]
  • Foxy fixtures: allow mixed usage to make migration easier and more attractive. 10004 [lotswholetime]
  • Make the record_timestamps class-inheritable so it can be set per model. 10004 [tmacedo]
  • Allow validates_acceptance_of to use a real attribute instead of only virtual (so you can record that the acceptance occured) 7457 [ambethia]
  • DateTimes use Ruby‘s default calendar reform setting. 10201 [Geoff Buesing]
  • Dynamic finders on association collections respect association :order and :limit. 10211, 10227 [Patrick Joyce, Rick Olson, Jack Danger Canty]
  • Add ‘foxy’ support for fixtures of polymorphic associations. 10183 [John Barnette, David Lowenfels]
  • validates_inclusion_of and validates_exclusion_of allow formatted :message strings. 8132 [devrieda, Mike Naberezny]
  • attr_readonly behaves well with optimistic locking. 10188 [Nick Bugajski]
  • Base#to_xml supports the nil="true" attribute like Hash#to_xml. 8268 [Jonathan del Strother]
  • Change plings to the more conventional quotes in the documentation. Closes 10104 [Jack Danger Canty]
  • Fix HasManyThrough Association so it uses :conditions on the HasMany Association. Closes 9729 [Jack Danger Canty]
  • Ensure that column names are quoted. Closes 10134 [wesley.moxam]
  • Smattering of grammatical fixes to documentation. Closes 10083 [Bob Silva]
  • Enhance explanation with more examples for attr_accessible macro. Closes 8095 [fearoffish, Marcel Molina Jr.]
  • Update association/method mapping table to refected latest collection methods for has_many :through. Closes 8772 [Pratik Naik]
  • Explain semantics of having several different AR instances in a transaction block. Closes 9036 [jacobat, Marcel Molina Jr.]
  • Update Schema documentation to use updated sexy migration notation. Closes 10086 [Sam Granieri]
  • Make fixtures work with the new test subclasses. [Tarmo Tänav, Michael Koziarski]
  • Introduce finder :joins with associations. Same :include syntax but with inner rather than outer joins. 10012 [RubyRedRick]
      # Find users with an avatar
  User.find(:all, :joins => :avatar)

  # Find posts with a high-rated comment.
  Post.find(:all, :joins => :comments, :conditions => 'comments.rating > 3')
  • Associations: speedup duplicate record check. 10011 [Pratik Naik]
  • Make sure that << works on has_many associations on unsaved records. Closes 9989 [Josh Susser]
  • Allow association redefinition in subclasses. 9346 [wildchild]
  • Fix has_many :through delete with custom foreign keys. 6466 [naffis]
  • Foxy fixtures, from rathole (svn.geeksomnia.com/rathole/trunk/README)
      - stable, autogenerated IDs
  - specify associations (belongs_to, has_one, has_many) by label, not ID
  - specify HABTM associations as inline lists
  - autofill timestamp columns
  - support YAML defaults
  - fixture label interpolation

    Enabled for fixtures that correspond to a model class and don‘t specify a primary key value. 9981 [John Barnette]

  • Add docs explaining how to protect all attributes using attr_accessible with no arguments. Closes 9631 [boone, rmm5t]
  • Update add_index documentation to use new options api. Closes 9787 [Kamal Fariz Mahyuddin]
  • Allow find on a has_many association defined with :finder_sql to accept id arguments as strings like regular find does. Closes 9916 [krishna]
  • Use VALID_FIND_OPTIONS when resolving :find scoping rather than hard coding the list of valid find options. Closes 9443 [sur]
  • Limited eager loading no longer ignores scoped :order. Closes 9561 [Jack Danger Canty, Josh Peek]
  • Assigning an instance of a foreign class to a composed_of aggregate calls an optional conversion block. Refactor and simplify composed_of implementation. 6322 [brandon, Chris Cruft]
  • Assigning nil to a composed_of aggregate also sets its immediate value to nil. 9843 [Chris Cruft]
  • Ensure that mysql quotes table names with database names correctly. Closes 9911 [crayz]

    "foo.bar" => "`foo`.`bar`"

  • Complete the assimilation of Sexy Migrations from ErrFree [Chris Wanstrath, PJ Hyett]
          http://errtheblog.com/post/2381
  • Qualified column names work in hash conditions, like :conditions => { ‘comments.created_at’ => … }. 9733 [Jack Danger Canty]
  • Fix regression where the association would not construct new finder SQL on save causing bogus queries for "WHERE owner_id = NULL" even after owner was saved. 8713 [Bryan Helmkamp]
  • Refactor association create and build so before & after callbacks behave consistently. 8854 [Pratik Naik, mortent]
  • Quote table names. Defaults to column quoting. 4593 [Justin Lynn, gwcoffey, eadz, Dmitry V. Sabanin, Jeremy Kemper]
  • Alias association build to new so it behaves predictably. 8787 [Pratik Naik]
  • Add notes to documentation regarding attr_readonly behavior with counter caches and polymorphic associations. Closes 9835 [saimonmoore, Rick Olson]
  • Observers can observe model names as symbols properly now. Closes 9869 [queso]
  • find_and_(initialize|create)_by methods can now properly initialize protected attributes [Tobias Lütke]
  • belongs_to infers the foreign key from the association name instead of from the class name. [Jeremy Kemper]
  • PostgreSQL: support multiline default values. 7533 [Carl Lerche, aguynamedryan, Rein Henrichs, Tarmo Tänav]
  • MySQL: fix change_column on not-null columns that don‘t accept dfeault values of ’’. 6663 [Jonathan Viney, Tarmo Tänav]
  • validates_uniqueness_of behaves well with abstract superclasses and

single-table inheritance. 3833, 9886 [Gabriel Gironda, rramdas, François Beausoleil, Josh Peek, Tarmo Tänav, pat]

  • Warn about protected attribute assigments in development and test environments when mass-assigning to an attr_protected attribute. 9802 [Henrik N]
  • Speedup database date/time parsing. [Jeremy Kemper, Tarmo Tänav]
  • Fix calling .clear on a has_many :dependent=>:delete_all association. [Tarmo Tänav]
  • Allow change_column to set NOT NULL in the PostgreSQL adapter [Tarmo Tänav]
  • Fix that ActiveRecord would create attribute methods and override custom attribute getters if the method is also defined in Kernel.methods. [Rick Olson]
  • Don‘t call attr_readonly on polymorphic belongs_to associations, in case it matches the name of some other non-ActiveRecord class/module. [Rick Olson]
  • Try loading activerecord-<adaptername>-adapter gem before trying a plain require so you can use custom gems for the bundled adapters. Also stops gems from requiring an adapter from an old Active Record gem. [Jeremy Kemper, Derrick Spell]

*2.0.0 [Preview Release]* (September 29th, 2007) [Includes duplicates of changes from 1.14.2 - 1.15.3]

  • Add attr_readonly to specify columns that are skipped during a normal ActiveRecord save operation. Closes 6896 [Dan Manges]

    class Comment < ActiveRecord::Base

      # Automatically sets Article#comments_count as readonly.
  belongs_to :article, :counter_cache => :comments_count

    end

    class Article < ActiveRecord::Base

      attr_readonly :approved_comments_count

    end

  • Make size for has_many :through use counter cache if it exists. Closes 9734 [Xavier Shay]
  • Remove DB2 adapter since IBM chooses to maintain their own adapter instead. [Jeremy Kemper]
  • Extract Oracle, SQLServer, and Sybase adapters into gems. [Jeremy Kemper]
  • Added fixture caching that‘ll speed up a normal fixture-powered test suite between 50% and 100% 9682 [Frederick Cheung]
  • Correctly quote id list for limited eager loading. 7482 [tmacedo]
  • Fixed that using version-targetted migrates would fail on loggers other than the default one 7430 [valeksenko]
  • Fixed rename_column for SQLite when using symbols for the column names 8616 [drodriguez]
  • Added the possibility of using symbols in addition to concrete classes with ActiveRecord::Observer#observe. 3998 [Robby Russell, Tarmo Tänav]
  • Added ActiveRecord::Base#to_json/from_json [David Heinemeier Hansson, Cheah Chu Yeow]
  • Added ActiveRecord::Base#from_xml [David Heinemeier Hansson]. Example:
      xml = "<person><name>David</name></person>"
  Person.new.from_xml(xml).name # => "David"
  • Define dynamic finders as real methods after first usage. [bscofield]
  • Deprecation: remove deprecated threaded_connections methods. Use allow_concurrency instead. [Jeremy Kemper]
  • Associations macros accept extension blocks alongside modules. 9346 [Josh Peek]
  • Speed up and simplify query caching. [Jeremy Kemper]
  • connection.select_rows ‘sql’ returns an array (rows) of arrays (field values). 2329 [Michael Schuerig]
  • Eager loading respects explicit :joins. 9496 [dasil003]
  • Extract Firebird, FrontBase, and OpenBase adapters into gems. 9508, 9509, 9510 [Jeremy Kemper]
  • RubyGem database adapters: expects a gem named activerecord-<database>-adapter with active_record/connection_adapters/<database>_adapter.rb in its load path. [Jeremy Kemper]
  • Fixed that altering join tables in migrations would fail w/ sqlite3 7453 [TimoMihaljov/brandon]
  • Fix association writer with :dependent => :nullify. 7314 [Jonathan Viney]
  • OpenBase: update for new lib and latest Rails. Support migrations. 8748 [dcsesq]
  • Moved acts_as_tree into a plugin of the same name on the official Rails svn. 9514 [Pratik Naik]
  • Moved acts_as_nested_set into a plugin of the same name on the official Rails svn. 9516 [Josh Peek]
  • Moved acts_as_list into a plugin of the same name on the official Rails svn. [Josh Peek]
  • Explicitly require active_record/query_cache before using it. [Jeremy Kemper]
  • Fix bug where unserializing an attribute attempts to modify a frozen @attributes hash for a deleted record. [Rick Olson, marclove]
  • Performance: absorb instantiate and initialize_with_callbacks into the Base methods. [Jeremy Kemper]
  • Fixed that eager loading queries and with_scope should respect the :group option [David Heinemeier Hansson]
  • Improve performance and functionality of the postgresql adapter. Closes 8049 [roderickvd]
          For more information see: http://dev.rubyonrails.org/ticket/8049
  • Don‘t clobber includes passed to has_many.count [Jack Danger Canty]
  • Make sure has_many uses :include when counting [Jack Danger Canty]
  • Change the implementation of ActiveRecord‘s attribute reader and writer methods [Michael Koziarski]
 - Generate Reader and Writer methods which cache attribute values in hashes.  This is to avoid repeatedly parsing the same date or integer columns.
 - Change exception raised when users use find with :select then try to access a skipped column.  Plugins could override missing_attribute() to lazily load the columns.
 - Move method definition to the class, instead of the instance
 - Always generate the readers, writers and predicate methods.
  • Perform a deep dup on query cache results so that modifying activerecord attributes does not modify the cached attributes. [Rick Olson]

# Ensure that has_many :through associations use a count query instead of loading the target when size is called. Closes 8800 [Pratik Naik]

  • Added :unless clause to validations 8003 [monki]. Example:
      def using_open_id?
    !identity_url.blank?
  end

  validates_presence_of :identity_url, :if => using_open_id?
  validates_presence_of :username, :unless => using_open_id?
  validates_presence_of :password, :unless => using_open_id?
  • Fix count on a has_many :through association so that it recognizes the :uniq option. Closes 8801 [Pratik Naik]
  • Fix and properly document/test count(column_name) usage. Closes 8999 [Pratik Naik]
  • Remove deprecated count(conditions=nil, joins=nil) usage. Closes 8993 [Pratik Naik]
  • Change belongs_to so that the foreign_key assumption is taken from the association name, not the class name. Closes 8992 [Josh Susser]

    OLD

      belongs_to :visitor, :class_name => 'User' # => inferred foreign_key is user_id

    NEW

      belongs_to :visitor, :class_name => 'User' # => inferred foreign_key is visitor_id
  • Remove spurious tests from deprecated_associations_test, most of these aren‘t deprecated, and are duplicated in associations_test. Closes 8987 [Pratik Naik]
  • Make create! on a has_many :through association return the association object. Not the collection. Closes 8786 [Pratik Naik]
  • Move from select * to select tablename.* to avoid clobbering IDs. Closes 8889 [dasil003]
  • Don‘t call unsupported methods on associated objects when using :include, :method with to_xml 7307, [Manfred Stienstra, jwilger]
  • Define collection singular ids method for has_many :through associations. 8763 [Pratik Naik]
  • Array attribute conditions work with proxied association collections. 8318 [Kamal Fariz Mahyuddin, theamazingrando]
  • Fix polymorphic has_one associations declared in an abstract class. 8638 [Pratik Naik, Dax Huiberts]
  • Fixed validates_associated should not stop on the first error. 4276 [mrj, Manfred Stienstra, Josh Peek]
  • Rollback if commit raises an exception. 8642 [kik, Jeremy Kemper]
  • Update tests’ use of fixtures for the new collections api. 8726 [Kamal Fariz Mahyuddin]
  • Save associated records only if the association is already loaded. 8713 [Blaine]
  • MySQL: fix show_variable. 8448 [matt, Jeremy Kemper]
  • Fixtures: correctly delete and insert fixtures in a single transaction. 8553 [Michael Schuerig]
  • Fixtures: people(:technomancy, :josh) returns both fixtures. 7880 [technomancy, Josh Peek]
  • Calculations support non-numeric foreign keys. 8154 [Kamal Fariz Mahyuddin]
  • with_scope is protected. 8524 [Josh Peek]
  • Quickref for association methods. 7723 [marclove, Mindsweeper]
  • Calculations: return nil average instead of 0 when there are no rows to average. 8298 [davidw]
  • acts_as_nested_set: direct_children is sorted correctly. 4761 [Josh Peek, rails@33lc0.net]
  • Raise an exception if both attr_protected and attr_accessible are declared. 8507 [stellsmi]
  • SQLite, MySQL, PostgreSQL, Oracle: quote column names in column migration SQL statements. 8466 [marclove, lorenjohnson]
  • Allow nil serialized attributes with a set class constraint. 7293 [sandofsky]
  • Oracle: support binary fixtures. 7987 [Michael Schoen]
  • Fixtures: pull fixture insertion into the database adapters. 7987 [Michael Schoen]
  • Announce migration versions as they‘re performed. [Jeremy Kemper]
  • find gracefully copes with blank :conditions. 7599 [Dan Manges, johnnyb]
  • validates_numericality_of takes :greater_than, :greater_than_or_equal_to, :equal_to, :less_than, :less_than_or_equal_to, :odd, and :even options. 3952 [Bob Silva, Dan Kubb, Josh Peek]
  • MySQL: create_database takes :charset and :collation options. Charset defaults to utf8. 8448 [matt]
  • Find with a list of ids supports limit/offset. 8437 [hrudududu]
  • Optimistic locking: revert the lock version when an update fails. 7840 [plang]
  • Migrations: add_column supports custom column types. 7742 [jsgarvin, Theory]
  • Load database adapters on demand. Eliminates config.connection_adapters and RAILS_CONNECTION_ADAPTERS. Add your lib directory to the $LOAD_PATH and put your custom adapter in lib/active_record/connection_adapters/adaptername_adapter.rb. This way you can provide custom adapters as plugins or gems without modifying Rails. [Jeremy Kemper]
  • Ensure that associations with :dependent => :delete_all respect :conditions option. Closes 8034 [Jack Danger Canty, Josh Peek, Rick Olson]
  • belongs_to assignment creates a new proxy rather than modifying its target in-place. 8412 [mmangino@elevatedrails.com]
  • Fix column type detection while loading fixtures. Closes 7987 [roderickvd]
  • Document deep eager includes. 6267 [Josh Susser, Dan Manges]
  • Document warning that associations names shouldn‘t be reserved words. 4378 [murphy@cYcnus.de, Josh Susser]
  • Sanitize Base#inspect. 8392, 8623 [Nik Wakelin, jnoon]
  • Replace the transaction {|transaction|..} semantics with a new Exception ActiveRecord::Rollback. [Michael Koziarski]
  • Oracle: extract column length for CHAR also. 7866 [ymendel]
  • Document :allow_nil option for validates_acceptance_of since it defaults to true. [tzaharia]
  • Update documentation for :dependent declaration so that it explicitly uses the non-deprecated API. [Jack Danger Canty]
  • Add documentation caveat about when to use count_by_sql. [fearoffish]
  • Enhance documentation for increment_counter and decrement_counter. [fearoffish]
  • Provide brief introduction to what optimistic locking is. [fearoffish]
  • Add documentation for :encoding option to mysql adapter. [marclove]
  • Added short-hand declaration style to migrations (inspiration from Sexy Migrations, errtheblog.com/post/2381) [David Heinemeier Hansson]. Example:
      create_table "products" do |t|
    t.column "shop_id",    :integer
    t.column "creator_id", :integer
    t.column "name",       :string,   :default => "Untitled"
    t.column "value",      :string,   :default => "Untitled"
    t.column "created_at", :datetime
    t.column "updated_at", :datetime
  end

    …can now be written as:

      create_table :products do |t|
    t.integer :shop_id, :creator_id
    t.string  :name, :value, :default => "Untitled"
    t.timestamps
  end
  • Use association name for the wrapper element when using .to_xml. Previous behavior lead to non-deterministic situations with STI and polymorphic associations. [Michael Koziarski, jstrachan]
  • Improve performance of calling .create on has_many :through associations. [evan]
  • Improved cloning performance by relying less on exception raising 8159 [Blaine]
  • Added ActiveRecord::Base.inspect to return a column-view like #<Post id:integer, title:string, body:text> [David Heinemeier Hansson]
  • Added yielding of Builder instance for ActiveRecord::Base#to_xml calls [David Heinemeier Hansson]
  • Small additions and fixes for ActiveRecord documentation. Closes 7342 [Jeremy McAnally]
  • Add helpful debugging info to the ActiveRecord::StatementInvalid exception in ActiveRecord::ConnectionAdapters::SqliteAdapter#table_structure. Closes 7925. [court3nay]
  • SQLite: binary escaping works with $KCODE=’u’. 7862 [tsuka]
  • Base#to_xml supports serialized attributes. 7502 [jonathan]
  • Base.update_all :order and :limit options. Useful for MySQL updates that must be ordered to avoid violating unique constraints. [Jeremy Kemper]
  • Remove deprecated object transactions. People relying on this functionality should install the object_transactions plugin at code.bitsweat.net/svn/object_transactions. Closes 5637 [Michael Koziarski, Jeremy Kemper]
  • PostgreSQL: remove DateTime -> Time downcast. Warning: do not enable translate_results for the C bindings if you have timestamps outside Time‘s domain. [Jeremy Kemper]
  • find_or_create_by_* takes a hash so you can create with more attributes than are in the method name. For example, Person.find_or_create_by_name(:name => ‘Henry’, :comments => ‘Hi new user!’) is equivalent to Person.find_by_name(‘Henry’) || Person.create(:name => ‘Henry’, :comments => ‘Hi new user!’). 7368 [Josh Susser]
  • Make sure with_scope takes both :select and :joins into account when setting :readonly. Allows you to save records you retrieve using method_missing on a has_many :through associations. [Michael Koziarski]
  • Allow a polymorphic :source for has_many :through associations. Closes 7143 [protocool]
  • Consistent public/protected/private visibility for chained methods. 7813 [Dan Manges]
  • Oracle: fix quoted primary keys and datetime overflow. 7798 [Michael Schoen]
  • Consistently quote primary key column names. 7763 [toolmantim]
  • Fixtures: fix YAML ordered map support. 2665 [Manuel Holtgrewe, nfbuckley]
  • DateTimes assume the default timezone. 7764 [Geoff Buesing]
  • Sybase: hide timestamp columns since they‘re inherently read-only. 7716 [Mike Joyce]
  • Oracle: overflow Time to DateTime. 7718 [Michael Schoen]
  • PostgreSQL: don‘t use async_exec and async_query with postgres-pr. 7727, 7762 [flowdelic, toolmantim]
  • Fix has_many :through << with custom foreign keys. 6466, 7153 [naffis, Rich Collins]
  • Test DateTime native type in migrations, including an edge case with dates

during calendar reform. 7649, 7724 [fedot, Geoff Buesing]

  • SQLServer: correctly schema-dump tables with no indexes or descending indexes. 7333, 7703 [Jakob Skjerning, Tom Ward]
  • SQLServer: recognize real column type as Ruby float. 7057 [sethladd, Tom Ward]
  • Added fixtures :all as a way of loading all fixtures in the fixture directory at once 7214 [Manfred Stienstra]
  • Added database connection as a yield parameter to ActiveRecord::Base.transaction so you can manually rollback [David Heinemeier Hansson]. Example:
      transaction do |transaction|
    david.withdrawal(100)
    mary.deposit(100)
    transaction.rollback! # rolls back the transaction that was otherwise going to be successful
  end
  • Made increment_counter/decrement_counter play nicely with optimistic locking, and added a more general update_counters method [Jamis Buck]
  • Reworked David‘s query cache to be available as Model.cache {…}. For the duration of the block no select query should be run more then once. Any inserts/deletes/executes will flush the whole cache however [Tobias Lütke] Task.cache { Task.find(1); Task.find(1) } #=> 1 query
  • When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck]
  • Oracle: fix lob and text default handling. 7344 [gfriedrich, Michael Schoen]
  • SQLServer: don‘t choke on strings containing ‘null’. 7083 [Jakob Skjerning]
  • MySQL: blob and text columns may not have defaults in 5.x. Update fixtures schema for strict mode. 6695 [Dan Kubb]
  • update_all can take a Hash argument. sanitize_sql splits into two methods for conditions and assignment since NULL values and delimiters are handled differently. 6583, 7365 [sandofsky, Assaf]
  • MySQL: SET SQL_AUTO_IS_NULL=0 so ‘where id is null’ doesn‘t select the last inserted id. 6778 [Jonathan Viney, timc]
  • Use Date#to_s(:db) for quoted dates. 7411 [Michael Schoen]
  • Don‘t create instance writer methods for class attributes. Closes 7401 [Rick Olson]
  • Docs: validations examples. 7343 [zackchandler]
  • Add missing tests ensuring callbacks work with class inheritance. Closes 7339 [sandofsky]
  • Fixtures use the table name and connection from set_fixture_class. 7330 [Anthony Eden]
  • Remove useless code in attribute_present? since 0 != blank?. Closes 7249 [Josh Susser]
  • Fix minor doc typos. Closes 7157 [Josh Susser]
  • Fix incorrect usage of classify when creating the eager loading join statement. Closes 7044 [Josh Susser]
  • SQLServer: quote table name in indexes query. 2928 [keithm@infused.org]
  • Subclasses of an abstract class work with single-table inheritance. 5704, 7284 [BertG, nick+rails@ag.arizona.edu]
  • Make sure sqlite3 driver closes open connections on disconnect [Rob Rasmussen]
  • [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. 7072 [Jeremy McAnally]
  • change_column accepts :default => nil. Skip column options for primary keys. 6956, 7048 [Dan Manges, Jeremy Kemper]
  • MySQL, PostgreSQL: change_column_default quotes the default value and doesn‘t lose column type information. 3987, 6664 [Jonathan Viney, Manfred Stienstra, altano@bigfoot.com]
  • Oracle: create_table takes a :sequence_name option to override the ‘tablename_seq’ default. 7000 [Michael Schoen]
  • MySQL: retain SSL settings on reconnect. 6976 [randyv2]
  • Apply scoping during initialize instead of create. Fixes setting of foreign key when using find_or_initialize_by with scoping. [Cody Fauser]
  • SQLServer: handle [quoted] table names. 6635 [rrich]
  • acts_as_nested_set works with single-table inheritance. 6030 [Josh Susser]
  • PostgreSQL, Oracle: correctly perform eager finds with :limit and :order. 4668, 7021 [eventualbuddha, Michael Schoen]
  • Pass a range in :conditions to use the SQL BETWEEN operator. 6974 [Dan Manges]
      Student.find(:all, :conditions => { :grade => 9..12 })
  • Fix the Oracle adapter for serialized attributes stored in CLOBs. Closes 6825 [mschoen, tdfowler]
  • [DOCS] Apply more documentation for ActiveRecord Reflection. Closes 4055 [Robby Russell]
  • [DOCS] Document :allow_nil option of validate_uniqueness_of. Closes 3143 [Caio Chassot]
  • Bring the sybase adapter up to scratch for 1.2 release. [jsheets]
  • Rollback new_record? and id when an exception is raised in a save callback. 6910 [Ben Curren, outerim]
  • Pushing a record on an association collection doesn‘t unnecessarily load all the associated records. [Obie Fernandez, Jeremy Kemper]
  • Oracle: fix connection reset failure. 6846 [leonlleslie]
  • Subclass instantiation doesn‘t try to explicitly require the corresponding subclass. 6840 [leei, Jeremy Kemper]
  • fix faulty inheritance tests and that eager loading grabs the wrong inheritance column when the class of your association is an STI subclass. Closes 6859 [protocool]
  • Consolidated different create and create! versions to call through to the base class with scope. This fixes inconsistencies, especially related to protected attribtues. Closes 5847 [Alexander Dymo, Tobias Lütke]
  • find supports :lock with :include. Check whether your database allows SELECT … FOR UPDATE with outer joins before using. 6764 [vitaly, Jeremy Kemper]
  • Add AssociationCollection#create! to be consistent with AssociationCollection#create when dealing with a foreign key that is a protected attribute [Cody Fauser]
  • Added counter optimization for AssociationCollection#any? so person.friends.any? won‘t actually load the full association if we have the count in a cheaper form [David Heinemeier Hansson]
  • Change fixture_path to a class inheritable accessor allowing test cases to have their own custom set of fixtures. 6672 [Zach Dennis]
  • Quote ActiveSupport::Multibyte::Chars. 6653 [Julian Tarkhanov]
  • Simplify query_attribute by typecasting the attribute value and checking whether it‘s nil, false, zero or blank. 6659 [Jonathan Viney]
  • validates_numericality_of uses \A \Z to ensure the entire string matches rather than ^ $ which may match one valid line of a multiline string. 5716 [Andreas Schwarz]
  • Run validations in the order they were declared. 6657 [obrie]
  • MySQL: detect when a NOT NULL column without a default value is misreported as default ’’. Can‘t detect for string, text, and binary columns since ’’ is a legitimate default. 6156 [simon@redhillconsulting.com.au, obrie, Jonathan Viney, Jeremy Kemper]
  • Simplify association proxy implementation by factoring construct_scope out of method_missing. 6643 [martin]
  • Oracle: automatically detect the primary key. 6594 [vesaria, Michael Schoen]
  • Oracle: to increase performance, prefetch 100 rows and enable similar cursor sharing. Both are configurable in database.yml. 6607 [philbogle@gmail.com, ray.fortna@jobster.com, Michael Schoen]
  • Don‘t inspect unloaded associations. 2905 [lmarlow]
  • SQLite: use AUTOINCREMENT primary key in >= 3.1.0. 6588, 6616 [careo, lukfugl]
  • Cache inheritance_column. 6592 [Stefan Kaes]
  • Firebird: decimal/numeric support. 6408 [macrnic]
  • make add_order a tad faster. 6567 [Stefan Kaes]
  • Find with :include respects scoped :order. 5850
  • Support nil and Array in :conditions => { attr => value } hashes. 6548 [Assaf, Jeremy Kemper]
      find(:all, :conditions => { :topic_id => [1, 2, 3], :last_read => nil }
  • Consistently use LOWER() for uniqueness validations (rather than mixing with UPPER()) so the database can always use a functional index on the lowercased column. 6495 [Si]
  • SQLite: fix calculations workaround, remove count(distinct) query rewrite, cleanup test connection scripts. [Jeremy Kemper]
  • SQLite: count(distinct) queries supported in >= 3.2.6. 6544 [Bob Silva]
  • Dynamically generate reader methods for serialized attributes. 6362 [Stefan Kaes]
  • Deprecation: object transactions warning. [Jeremy Kemper]
  • has_one :dependent => :nullify ignores nil associates. 4848, 6528 [bellis@deepthought.org, janovetz, Jeremy Kemper]
  • Oracle: resolve test failures, use prefetched primary key for inserts, check for null defaults, fix limited id selection for eager loading. Factor out some common methods from all adapters. 6515 [Michael Schoen]
  • Make add_column use the options hash with the Sqlite Adapter. Closes 6464 [obrie]
  • Document other options available to migration‘s add_column. 6419 [grg]
  • MySQL: all_hashes compatibility with old MysqlRes class. 6429, 6601 [Jeremy Kemper]
  • Fix has_many :through to add the appropriate conditions when going through an association using STI. Closes 5783. [Jonathan Viney]
  • fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick Olson]
  • Restore eager condition interpolation, document it‘s differences [Rick Olson]
  • Don‘t rollback in teardown unless a transaction was started. Don‘t start a transaction in create_fixtures if a transaction is started. 6282 [Jacob Fugal, Jeremy Kemper]
  • Add delete support to has_many :through associations. Closes 6049 [Martin Landers]
  • Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes 5851 [Rick Olson]
  • Removes the ability for eager loaded conditions to be interpolated, since there is no model instance to use as a context for interpolation. 5553 [turnip@turnipspatch.com]
  • Added timeout option to SQLite3 configurations to deal more gracefully with SQLite3::BusyException, now the connection can instead retry for x seconds to see if the db clears up before throwing that exception 6126 [wreese@gmail.com]
  • Added update_attributes! which uses save! to raise an exception if a validation error prevents saving 6192 [jonathan]
  • Deprecated add_on_boundary_breaking (use validates_length_of instead) 6292 [Bob Silva]
  • The has_many create method works with polymorphic associations. 6361 [Dan Peterson]
  • MySQL: introduce Mysql::Result#all_hashes to support further optimization. 5581 [Stefan Kaes]
  • save! shouldn‘t validate twice. 6324 [maiha, Bob Silva]
  • Association collections have an _ids reader method to match the existing writer for collection_select convenience (e.g. employee.task_ids). The writer method skips blank ids so you can safely do @employee.task_ids = params[:tasks] without checking every time for an empty list or blank values. 1887, 5780 [Michael Schuerig]
  • Add an attribute reader method for ActiveRecord::Base.observers [Rick Olson]
  • Deprecation: count class method should be called with an options hash rather than two args for conditions and joins. 6287 [Bob Silva]
  • has_one associations with a nil target may be safely marshaled. 6279 [norbauer, Jeremy Kemper]
  • Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Michael Koziarski]
  • Add a :namespace option to AR::Base#to_xml [Michael Koziarski]
  • Deprecation tests. Remove warnings for dynamic finders and for the foo_count method if it‘s also an attribute. [Jeremy Kemper]
  • Mock Time.now for more accurate Touch mixin tests. 6213 [Dan Peterson]
  • Improve yaml fixtures error reporting. 6205 [Bruce Williams]
  • Rename AR::Base#quote so people can use that name in their models. 3628 [Michael Koziarski]
  • Add deprecation warning for inferred foreign key. 6029 [Josh Susser]
  • Fixed the Ruby/MySQL adapter we ship with Active Record to work with the new authentication handshake that was introduced in MySQL 4.1, along with the other protocol changes made at that time 5723 [jimw@mysql.com]
  • Deprecation: use :dependent => :delete_all rather than :exclusively_dependent => true. 6024 [Josh Susser]
  • Document validates_presences_of behavior with booleans: you probably want validates_inclusion_of :attr, :in => [true, false]. 2253 [Bob Silva]
  • Optimistic locking: gracefully handle nil versions, treat as zero. 5908 [Tom Ward]
  • to_xml: the :methods option works on arrays of records. 5845 [Josh Starcher]
  • Deprecation: update docs. 5998 [Jakob Skjerning, Kevin Clark]
  • Add some XmlSerialization tests for ActiveRecord [Rick Olson]
  • has_many :through conditions are sanitized by the associating class. 5971 [martin.emde@gmail.com]
  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Fix spurious newlines and spaces in AR::Base#to_xml output [Jamis Buck]
  • has_one supports the :dependent => :delete option which skips the typical callback chain and deletes the associated object directly from the database. 5927 [Chris Mear, Jonathan Viney]
  • Nested subclasses are not prefixed with the parent class’ table_name since they should always use the base class’ table_name. 5911 [Jonathan Viney]
  • SQLServer: work around bug where some unambiguous date formats are not correctly identified if the session language is set to german. 5894 [Tom Ward, kruth@bfpi]
  • SQLServer: fix eager association test. 5901 [Tom Ward]
  • Clashing type columns due to a sloppy join shouldn‘t wreck single-table inheritance. 5838 [Kevin Clark]
  • Fixtures: correct escaping of \n and \r. 5859 [evgeny.zislis@gmail.com]
  • Migrations: gracefully handle missing migration files. 5857 [eli.gordon@gmail.com]
  • MySQL: update test schema for MySQL 5 strict mode. 5861 [Tom Ward]
  • to_xml: correct naming of included associations. 5831 [Josh Starcher]
  • Pushing a record onto a has_many :through sets the association‘s foreign key to the associate‘s primary key and adds it to the correct association. 5815, 5829 [Josh Susser]
  • Add records to has_many :through using <<, push, and concat by creating the association record. Raise if base or associate are new records since both ids are required to create the association. build raises since you can‘t associate an unsaved record. create! takes an attributes hash and creates the associated record and its association in a transaction. [Jeremy Kemper]
      # Create a tagging to associate the post and tag.
  post.tags << Tag.find_by_name('old')
  post.tags.create! :name => 'general'

  # Would have been:
  post.taggings.create!(:tag => Tag.find_by_name('finally')
  transaction do
    post.taggings.create!(:tag => Tag.create!(:name => 'general'))
  end
  • Cache nil results for :included has_one associations also. 5787 [Michael Schoen]
  • Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Lütke]
  • Nested classes are given table names prefixed by the singular form of the parent‘s table name. [Jeremy Kemper]
      Example: Invoice::Lineitem is given table name invoice_lineitems
  • Migrations: uniquely name multicolumn indexes so you don‘t have to. [Jeremy Kemper]
      # people_active_last_name_index, people_active_deactivated_at_index
  add_index    :people, [:active, :last_name]
  add_index    :people, [:active, :deactivated_at]
  remove_index :people, [:active, :last_name]
  remove_index :people, [:active, :deactivated_at]

    WARNING: backward-incompatibility. Multicolumn indexes created before this revision were named using the first column name only. Now they‘re uniquely named using all indexed columns.

    To remove an old multicolumn index, remove_index :table_name, :first_column

  • Fix for deep includes on the same association. [richcollins@gmail.com]
  • Tweak fixtures so they don‘t try to use a non-ActiveRecord class. [Kevin Clark]
  • Remove ActiveRecord::Base.reset since Dispatcher doesn‘t use it anymore. [Rick Olson]
  • Document find‘s :from option. Closes 5762. [andrew@redlinesoftware.com]
  • PostgreSQL: autodetected sequences work correctly with multiple schemas. Rely on the schema search_path instead of explicitly qualifying the sequence name with its schema. 5280 [guy.naor@famundo.com]
  • Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
  • Cache nil results for has_one associations so multiple calls don‘t call the database. Closes 5757. [Michael Schoen]
  • Add documentation for how to disable timestamps on a per model basis. Closes 5684. [matt@mattmargolis.net Marcel Molina Jr.]
  • Don‘t save has_one associations unnecessarily. 5735 [Jonathan Viney]
  • Refactor ActiveRecord::Base.reset_subclasses to reset, and add global observer resetting. [Rick Olson]
  • Formally deprecate the deprecated finders. [Michael Koziarski]
  • Formally deprecate rich associations. [Michael Koziarski]
  • Fixed that default timezones for new / initialize should uphold utc setting 5709 [daniluk@yahoo.com]
  • Fix announcement of very long migration names. 5722 [blake@near-time.com]
  • The exists? class method should treat a string argument as an id rather than as conditions. 5698 [jeremy@planetargon.com]
  • Fixed to_xml with :include misbehaviors when invoked on array of model instances 5690 [alexkwolfe@gmail.com]
  • Added support for conditions on Base.exists? 5689 [Josh Peek]. Examples:
      assert (Topic.exists?(:author_name => "David"))
        assert (Topic.exists?(:author_name => "Mary", :approved => true))
        assert (Topic.exists?(["parent_id = ?", 1]))
  • Schema dumper quotes date :default values. [Dave Thomas]
  • Calculate sum with SQL, not Enumerable on HasManyThrough Associations. [Dan Peterson]
  • Factor the attribute#{suffix} methods out of method_missing for easier extension. [Jeremy Kemper]
  • Patch sql injection vulnerability when using integer or float columns. [Jamis Buck]
  • Allow count through a has_many association to accept :include. [Dan Peterson]
  • create_table rdoc: suggest :id => false for habtm join tables. [Zed Shaw]
  • PostgreSQL: return array fields as strings. 4664 [Robby Russell]
  • SQLServer: added tests to ensure all database statements are closed, refactored identity_insert management code to use blocks, removed update/delete rowcount code out of execute and into update/delete, changed insert to go through execute method, removed unused quoting methods, disabled pessimistic locking tests as feature is currently unsupported, fixed RakeFile to load sqlserver specific tests whether running in ado or odbc mode, fixed support for recently added decimal types, added support for limits on integer types. 5670 [Tom Ward]
  • SQLServer: fix db:schema:dump case-sensitivity. 4684 [Will Rogers]
  • Oracle: BigDecimal support. 5667 [Michael Schoen]
  • Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. 5454 [robbat2@gentoo.org, work@ashleymoran.me.uk]
  • Firebird migrations support. 5337 [Ken Kunz <kennethkunz@gmail.com>]
  • PostgreSQL: create/drop as postgres user. 4790 [mail@matthewpainter.co.uk, mlaster@metavillage.com]
  • Update callbacks documentation. 3970 [Robby Russell <robby@planetargon.com>]
  • PostgreSQL: correctly quote the ’ in pk_and_sequence_for. 5462 [tietew@tietew.net]
  • PostgreSQL: correctly quote microseconds in timestamps. 5641 [rick@rickbradley.com]
  • Clearer has_one/belongs_to model names (account has_one :user). 5632 [matt@mattmargolis.net]
  • Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don‘t guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. 5635 [Michael Schoen]
  • Fixed a few Oracle issues: Allows Oracle‘s odd date handling to still work consistently within to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for exec 5294 [Michael Schoen]
  • Added :group to available options for finds done on associations 5516 [mike@michaeldewey.org]
  • Minor tweak to improve performance of ActiveRecord::Base#to_param.
  • Observers also watch subclasses created after they are declared. 5535 [daniels@pronto.com.au]
  • Removed deprecated timestamps_gmt class methods. [Jeremy Kemper]
  • rake build_mysql_database grants permissions to rails@localhost. 5501 [brianegge@yahoo.com]
  • PostgreSQL: support microsecond time resolution. 5492 [alex@msgpad.com]
  • Add AssociationCollection#sum since the method_missing invokation has been shadowed by Enumerable#sum.
  • Added find_or_initialize_by_X which works like find_or_create_by_X but doesn‘t save the newly instantiated record. [Sam Stephenson]
  • Row locking. Provide a locking clause with the :lock finder option or true for the default "FOR UPDATE". Use the lock! method to obtain a row lock on a single record (reloads the record with :lock => true). [Shugo Maeda]
      # Obtain an exclusive lock on person 1 so we can safely increment visits.
  Person.transaction do
    # select * from people where id=1 for update
    person = Person.find(1, :lock => true)
    person.visits += 1
    person.save!
  end
  • PostgreSQL: introduce allow_concurrency option which determines whether to use blocking or asynchronous execute. Adapters with blocking execute will deadlock Ruby threads. The default value is ActiveRecord::Base.allow_concurrency. [Jeremy Kemper]
  • Use a per-thread (rather than global) transaction mutex so you may execute concurrent transactions on separate connections. [Jeremy Kemper]
  • Change AR::Base#to_param to return a String instead of a Fixnum. Closes 5320. [Nicholas Seckar]
  • Use explicit delegation instead of method aliasing for AR::Base.to_param -> AR::Base.id. 5299 (skaes@web.de)
  • Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [David Heinemeier Hansson]
  • Added simple hash conditions to find that‘ll just convert hash to an AND-based condition string 5143 [Hampton Catlin]. Example:
      Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 }, :limit => 2)

…is the same as:

    Person.find(:all, :conditions => [ "last_name = ? and status = ?", "Catlin", 1 ], :limit => 2)

  This makes it easier to pass in the options from a form or otherwise outside.
  • Fixed issues with BLOB limits, charsets, and booleans for Firebird 5194, 5191, 5189 [kennethkunz@gmail.com]
  • Fixed usage of :limit and with_scope when the association in scope is a 1:m 5208 [alex@purefiction.net]
  • Fixed migration trouble with SQLite when NOT NULL is used in the new definition 5215 [greg@lapcominc.com]
  • Fixed problems with eager loading and counting on SQL Server 5212 [kajism@yahoo.com]
  • Fixed that count distinct should use the selected column even when using :include 5251 [anna@wota.jp]
  • Fixed that :includes merged from with_scope won‘t cause the same association to be loaded more than once if repetition occurs in the clauses 5253 [alex@purefiction.net]
  • Allow models to override to_xml. 4989 [Blair Zajac <blair@orcaware.com>]
  • PostgreSQL: don‘t ignore port when host is nil since it‘s often used to label the domain socket. 5247 [shimbo@is.naist.jp]
  • Records and arrays of records are bound as quoted ids. [Jeremy Kemper]
      Foo.find(:all, :conditions => ['bar_id IN (?)', bars])
  Foo.find(:first, :conditions => ['bar_id = ?', bar])
  • Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [David Heinemeier Hansson]
  • Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick Olson]
  • Fix the has_and_belongs_to_many create doesn‘t populate the join for new records. Closes 3692 [Josh Susser]
  • Provide Association Extensions access to the instance that the association is being accessed from. Closes 4433 [Josh Susser]
  • Update OpenBase adaterp‘s maintainer‘s email address. Closes 5176. [Derrick Spell]
  • Add a quick note about :select and eagerly included associations. [Rick Olson]
  • Add docs for the :as option in has_one associations. Closes 5144 [cdcarter@gmail.com]
  • Fixed that has_many collections shouldn‘t load the entire association to do build or create [David Heinemeier Hansson]
  • Added :allow_nil option for aggregations 5091 [Ian White]
  • Fix Oracle boolean support and tests. Closes 5139. [Michael Schoen]
  • create! no longer blows up when no attributes are passed and a :create scope is in effect (e.g. foo.bars.create! failed whereas foo.bars.create!({}) didn‘t.) [Jeremy Kemper]
  • Call Inflector#demodulize on the class name when eagerly including an STI model. Closes 5077 [info@loobmedia.com]
  • Preserve MySQL boolean column defaults when changing a column in a migration. Closes 5015. [pdcawley@bofh.org.uk]
  • PostgreSQL: migrations support :limit with :integer columns by mapping limit < 4 to smallint, > 4 to bigint, and anything else to integer. 2900 [keegan@thebasement.org]
  • Dates and times interpret empty strings as nil rather than 2000-01-01. 4830 [kajism@yahoo.com]
  • Allow :uniq => true with has_many :through associations. [Jeremy Kemper]
  • Ensure that StringIO is always available for the Schema dumper. [Marcel Molina Jr.]
  • Allow AR::Base#to_xml to include methods too. Closes 4921. [johan@textdrive.com]
  • Replace superfluous name_to_class_name variant with camelize. [Marcel Molina Jr.]
  • Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Remove duplicate fixture entry in comments.yml. Closes 4923. [Blair Zajac <blair@orcaware.com>]
  • Update FrontBase adapter to check binding version. Closes 4920. [mlaster@metavillage.com]
  • New Frontbase connections don‘t start in auto-commit mode. Closes 4922. [mlaster@metavillage.com]
  • When grouping, use the appropriate option key. [Marcel Molina Jr.]
  • Only modify the sequence name in the FrontBase adapter if the FrontBase adapter is actually being used. [Marcel Molina Jr.]
  • Add support for FrontBase (www.frontbase.com/) with a new adapter thanks to the hard work of one Mike Laster. Closes 4093. [mlaster@metavillage.com]
  • Add warning about the proper way to validate the presence of a foreign key. Closes 4147. [Francois Beausoleil <francois.beausoleil@gmail.com>]
  • Fix syntax error in documentation. Closes 4679. [Mislav Marohnić]
  • Add Oracle support for CLOB inserts. Closes 4748. [schoenm@earthlink.net sandra.metz@duke.edu]
  • Various fixes for sqlserver_adapter (odbc statement finishing, ado schema dumper, drop index). Closes 4831. [kajism@yahoo.com]
  • Add support for :order option to with_scope. Closes 3887. [eric.daspet@survol.net]
  • Prettify output of schema_dumper by making things line up. Closes 4241 [Caio Chassot <caio@v2studio.com>]
  • Make build_postgresql_databases task make databases owned by the postgres user. Closes 4790. [mlaster@metavillage.com]
  • Sybase Adapter type conversion cleanup. Closes 4736. [dev@metacasa.net]
  • Fix bug where calculations with long alias names return null. [Rick Olson]
  • Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick Olson]
      @post.tags << @tag                  # BAD
  @post.taggings.create(:tag => @tag) # GOOD
  • Allow all calculations to take the :include option, not just COUNT (closes 4840) [Rick Olson]
  • Update inconsistent migrations documentation. 4683 [machomagna@gmail.com]
  • Add ActiveRecord::Errors#to_xml [Jamis Buck]
  • Properly quote index names in migrations (closes 4764) [John Long]
  • Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick Olson]
  • Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson]
  • Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson]
  • DRY up association collection reader method generation. [Marcel Molina Jr.]
  • DRY up and tweak style of the validation error object. [Marcel Molina Jr.]
  • Add :case_sensitive option to validates_uniqueness_of (closes 3090) [Rick Olson]
      class Account < ActiveRecord::Base
    validates_uniqueness_of :email, :case_sensitive => false
  end
  • Allow multiple association extensions with :extend option (closes 4666) [Josh Susser]
      class Account < ActiveRecord::Base
    has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
  end

  *1.15.3* (March 12th, 2007)

  * Allow a polymorphic :source for has_many :through associations. Closes #7143 [protocool]

  * Consistently quote primary key column names.  #7763 [toolmantim]

  * Fixtures: fix YAML ordered map support.  #2665 [Manuel Holtgrewe, nfbuckley]

  * Fix has_many :through << with custom foreign keys.  #6466, #7153 [naffis, Rich Collins]

*1.15.2* (February 5th, 2007)

  • Pass a range in :conditions to use the SQL BETWEEN operator. 6974 [Dan Manges]
      Student.find(:all, :conditions => { :grade => 9..12 })
  • Don‘t create instance writer methods for class attributes. [Rick Olson]
  • When dealing with SQLite3, use the table_info pragma helper, so that the bindings can do some translation for when sqlite3 breaks incompatibly between point releases. [Jamis Buck]
  • SQLServer: don‘t choke on strings containing ‘null’. 7083 [Jakob Skjerning]
  • Consistently use LOWER() for uniqueness validations (rather than mixing with UPPER()) so the database can always use a functional index on the lowercased column. 6495 [Si]
  • MySQL: SET SQL_AUTO_IS_NULL=0 so ‘where id is null’ doesn‘t select the last inserted id. 6778 [Jonathan Viney, timc]
  • Fixtures use the table name and connection from set_fixture_class. 7330 [Anthony Eden]
  • SQLServer: quote table name in indexes query. 2928 [keithm@infused.org]

*1.15.1* (January 17th, 2007)

  • Fix nodoc breaking of adapters

*1.15.0* (January 16th, 2007)

  • [DOC] clear up some ambiguity with the way has_and_belongs_to_many creates the default join table name. 7072 [Jeremy McAnally]
  • change_column accepts :default => nil. Skip column options for primary keys. 6956, 7048 [Dan Manges, Jeremy Kemper]
  • MySQL, PostgreSQL: change_column_default quotes the default value and doesn‘t lose column type information. 3987, 6664 [Jonathan Viney, Manfred Stienstra, altano@bigfoot.com]
  • Oracle: create_table takes a :sequence_name option to override the ‘tablename_seq’ default. 7000 [Michael Schoen]
  • MySQL: retain SSL settings on reconnect. 6976 [randyv2]
  • SQLServer: handle [quoted] table names. 6635 [rrich]
  • acts_as_nested_set works with single-table inheritance. 6030 [Josh Susser]
  • PostgreSQL, Oracle: correctly perform eager finds with :limit and :order. 4668, 7021 [eventualbuddha, Michael Schoen]
  • Fix the Oracle adapter for serialized attributes stored in CLOBs. Closes 6825 [mschoen, tdfowler]
  • [DOCS] Apply more documentation for ActiveRecord Reflection. Closes 4055 [Robby Russell]
  • [DOCS] Document :allow_nil option of validate_uniqueness_of. Closes 3143 [Caio Chassot]
  • Bring the sybase adapter up to scratch for 1.2 release. [jsheets]
  • Oracle: fix connection reset failure. 6846 [leonlleslie]
  • Subclass instantiation doesn‘t try to explicitly require the corresponding subclass. 6840 [leei, Jeremy Kemper]
  • fix faulty inheritance tests and that eager loading grabs the wrong inheritance column when the class of your association is an STI subclass. Closes 6859 [protocool]
  • find supports :lock with :include. Check whether your database allows SELECT … FOR UPDATE with outer joins before using. 6764 [vitaly, Jeremy Kemper]
  • Support nil and Array in :conditions => { attr => value } hashes. 6548 [Assaf, Jeremy Kemper]
      find(:all, :conditions => { :topic_id => [1, 2, 3], :last_read => nil }
  • Quote ActiveSupport::Multibyte::Chars. 6653 [Julian Tarkhanov]
  • MySQL: detect when a NOT NULL column without a default value is misreported as default ’’. Can‘t detect for string, text, and binary columns since ’’ is a legitimate default. 6156 [simon@redhillconsulting.com.au, obrie, Jonathan Viney, Jeremy Kemper]
  • validates_numericality_of uses \A \Z to ensure the entire string matches rather than ^ $ which may match one valid line of a multiline string. 5716 [Andreas Schwarz]
  • Oracle: automatically detect the primary key. 6594 [vesaria, Michael Schoen]
  • Oracle: to increase performance, prefetch 100 rows and enable similar cursor sharing. Both are configurable in database.yml. 6607 [philbogle@gmail.com, ray.fortna@jobster.com, Michael Schoen]
  • Firebird: decimal/numeric support. 6408 [macrnic]
  • Find with :include respects scoped :order. 5850
  • Dynamically generate reader methods for serialized attributes. 6362 [Stefan Kaes]
  • Deprecation: object transactions warning. [Jeremy Kemper]
  • has_one :dependent => :nullify ignores nil associates. 6528 [janovetz, Jeremy Kemper]
  • Oracle: resolve test failures, use prefetched primary key for inserts, check for null defaults, fix limited id selection for eager loading. Factor out some common methods from all adapters. 6515 [Michael Schoen]
  • Make add_column use the options hash with the Sqlite Adapter. Closes 6464 [obrie]
  • Document other options available to migration‘s add_column. 6419 [grg]
  • MySQL: all_hashes compatibility with old MysqlRes class. 6429, 6601 [Jeremy Kemper]
  • Fix has_many :through to add the appropriate conditions when going through an association using STI. Closes 5783. [Jonathan Viney]
  • fix select_limited_ids_list issues in postgresql, retain current behavior in other adapters [Rick Olson]
  • Restore eager condition interpolation, document it‘s differences [Rick Olson]
  • Don‘t rollback in teardown unless a transaction was started. Don‘t start a transaction in create_fixtures if a transaction is started. 6282 [Jacob Fugal, Jeremy Kemper]
  • Add delete support to has_many :through associations. Closes 6049 [Martin Landers]
  • Reverted old select_limited_ids_list postgresql fix that caused issues in mysql. Closes 5851 [Rick Olson]
  • Removes the ability for eager loaded conditions to be interpolated, since there is no model instance to use as a context for interpolation. 5553 [turnip@turnipspatch.com]
  • Added timeout option to SQLite3 configurations to deal more gracefully with SQLite3::BusyException, now the connection can instead retry for x seconds to see if the db clears up before throwing that exception 6126 [wreese@gmail.com]
  • Added update_attributes! which uses save! to raise an exception if a validation error prevents saving 6192 [jonathan]
  • Deprecated add_on_boundary_breaking (use validates_length_of instead) 6292 [Bob Silva]
  • The has_many create method works with polymorphic associations. 6361 [Dan Peterson]
  • MySQL: introduce Mysql::Result#all_hashes to support further optimization. 5581 [Stefan Kaes]
  • save! shouldn‘t validate twice. 6324 [maiha, Bob Silva]
  • Association collections have an _ids reader method to match the existing writer for collection_select convenience (e.g. employee.task_ids). The writer method skips blank ids so you can safely do @employee.task_ids = params[:tasks] without checking every time for an empty list or blank values. 1887, 5780 [Michael Schuerig]
  • Add an attribute reader method for ActiveRecord::Base.observers [Rick Olson]
  • Deprecation: count class method should be called with an options hash rather than two args for conditions and joins. 6287 [Bob Silva]
  • has_one associations with a nil target may be safely marshaled. 6279 [norbauer, Jeremy Kemper]
  • Duplicate the hash provided to AR::Base#to_xml to prevent unexpected side effects [Michael Koziarski]
  • Add a :namespace option to AR::Base#to_xml [Michael Koziarski]
  • Deprecation tests. Remove warnings for dynamic finders and for the foo_count method if it‘s also an attribute. [Jeremy Kemper]
  • Mock Time.now for more accurate Touch mixin tests. 6213 [Dan Peterson]
  • Improve yaml fixtures error reporting. 6205 [Bruce Williams]
  • Rename AR::Base#quote so people can use that name in their models. 3628 [Michael Koziarski]
  • Add deprecation warning for inferred foreign key. 6029 [Josh Susser]
  • Fixed the Ruby/MySQL adapter we ship with Active Record to work with the new authentication handshake that was introduced in MySQL 4.1, along with the other protocol changes made at that time 5723 [jimw@mysql.com]
  • Deprecation: use :dependent => :delete_all rather than :exclusively_dependent => true. 6024 [Josh Susser]
  • Optimistic locking: gracefully handle nil versions, treat as zero. 5908 [Tom Ward]
  • to_xml: the :methods option works on arrays of records. 5845 [Josh Starcher]
  • has_many :through conditions are sanitized by the associating class. 5971 [martin.emde@gmail.com]
  • Fix spurious newlines and spaces in AR::Base#to_xml output [Jamis Buck]
  • has_one supports the :dependent => :delete option which skips the typical callback chain and deletes the associated object directly from the database. 5927 [Chris Mear, Jonathan Viney]
  • Nested subclasses are not prefixed with the parent class’ table_name since they should always use the base class’ table_name. 5911 [Jonathan Viney]
  • SQLServer: work around bug where some unambiguous date formats are not correctly identified if the session language is set to german. 5894 [Tom Ward, kruth@bfpi]
  • Clashing type columns due to a sloppy join shouldn‘t wreck single-table inheritance. 5838 [Kevin Clark]
  • Fixtures: correct escaping of \n and \r. 5859 [evgeny.zislis@gmail.com]
  • Migrations: gracefully handle missing migration files. 5857 [eli.gordon@gmail.com]
  • MySQL: update test schema for MySQL 5 strict mode. 5861 [Tom Ward]
  • to_xml: correct naming of included associations. 5831 [Josh Starcher]
  • Pushing a record onto a has_many :through sets the association‘s foreign key to the associate‘s primary key and adds it to the correct association. 5815, 5829 [Josh Susser]
  • Add records to has_many :through using <<, push, and concat by creating the association record. Raise if base or associate are new records since both ids are required to create the association. build raises since you can‘t associate an unsaved record. create! takes an attributes hash and creates the associated record and its association in a transaction. [Jeremy Kemper]
      # Create a tagging to associate the post and tag.
  post.tags << Tag.find_by_name('old')
  post.tags.create! :name => 'general'

  # Would have been:
  post.taggings.create!(:tag => Tag.find_by_name('finally')
  transaction do
    post.taggings.create!(:tag => Tag.create!(:name => 'general'))
  end
  • Cache nil results for :included has_one associations also. 5787 [Michael Schoen]
  • Fixed a bug which would cause .save to fail after trying to access a empty has_one association on a unsaved record. [Tobias Lütke]
  • Nested classes are given table names prefixed by the singular form of the parent‘s table name. [Jeremy Kemper]
      Example: Invoice::Lineitem is given table name invoice_lineitems
  • Migrations: uniquely name multicolumn indexes so you don‘t have to. [Jeremy Kemper]
      # people_active_last_name_index, people_active_deactivated_at_index
  add_index    :people, [:active, :last_name]
  add_index    :people, [:active, :deactivated_at]
  remove_index :people, [:active, :last_name]
  remove_index :people, [:active, :deactivated_at]

    WARNING: backward-incompatibility. Multicolumn indexes created before this revision were named using the first column name only. Now they‘re uniquely named using all indexed columns.

    To remove an old multicolumn index, remove_index :table_name, :first_column

  • Fix for deep includes on the same association. [richcollins@gmail.com]
  • Tweak fixtures so they don‘t try to use a non-ActiveRecord class. [Kevin Clark]
  • Remove ActiveRecord::Base.reset since Dispatcher doesn‘t use it anymore. [Rick Olson]
  • PostgreSQL: autodetected sequences work correctly with multiple schemas. Rely on the schema search_path instead of explicitly qualifying the sequence name with its schema. 5280 [guy.naor@famundo.com]
  • Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
  • Cache nil results for has_one associations so multiple calls don‘t call the database. Closes 5757. [Michael Schoen]
  • Don‘t save has_one associations unnecessarily. 5735 [Jonathan Viney]
  • Refactor ActiveRecord::Base.reset_subclasses to reset, and add global observer resetting. [Rick Olson]
  • Formally deprecate the deprecated finders. [Michael Koziarski]
  • Formally deprecate rich associations. [Michael Koziarski]
  • Fixed that default timezones for new / initialize should uphold utc setting 5709 [daniluk@yahoo.com]
  • Fix announcement of very long migration names. 5722 [blake@near-time.com]
  • The exists? class method should treat a string argument as an id rather than as conditions. 5698 [jeremy@planetargon.com]
  • Fixed to_xml with :include misbehaviors when invoked on array of model instances 5690 [alexkwolfe@gmail.com]
  • Added support for conditions on Base.exists? 5689 [Josh Peek]. Examples:
      assert (Topic.exists?(:author_name => "David"))
        assert (Topic.exists?(:author_name => "Mary", :approved => true))
        assert (Topic.exists?(["parent_id = ?", 1]))
  • Schema dumper quotes date :default values. [Dave Thomas]
  • Calculate sum with SQL, not Enumerable on HasManyThrough Associations. [Dan Peterson]
  • Factor the attribute#{suffix} methods out of method_missing for easier extension. [Jeremy Kemper]
  • Patch sql injection vulnerability when using integer or float columns. [Jamis Buck]
  • Allow count through a has_many association to accept :include. [Dan Peterson]
  • create_table rdoc: suggest :id => false for habtm join tables. [Zed Shaw]
  • PostgreSQL: return array fields as strings. 4664 [Robby Russell]
  • SQLServer: added tests to ensure all database statements are closed, refactored identity_insert management code to use blocks, removed update/delete rowcount code out of execute and into update/delete, changed insert to go through execute method, removed unused quoting methods, disabled pessimistic locking tests as feature is currently unsupported, fixed RakeFile to load sqlserver specific tests whether running in ado or odbc mode, fixed support for recently added decimal types, added support for limits on integer types. 5670 [Tom Ward]
  • SQLServer: fix db:schema:dump case-sensitivity. 4684 [Will Rogers]
  • Oracle: BigDecimal support. 5667 [Michael Schoen]
  • Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. 5454 [robbat2@gentoo.org, work@ashleymoran.me.uk]
  • Firebird migrations support. 5337 [Ken Kunz <kennethkunz@gmail.com>]
  • PostgreSQL: create/drop as postgres user. 4790 [mail@matthewpainter.co.uk, mlaster@metavillage.com]
  • PostgreSQL: correctly quote the ’ in pk_and_sequence_for. 5462 [tietew@tietew.net]
  • PostgreSQL: correctly quote microseconds in timestamps. 5641 [rick@rickbradley.com]
  • Clearer has_one/belongs_to model names (account has_one :user). 5632 [matt@mattmargolis.net]
  • Oracle: use nonblocking queries if allow_concurrency is set, fix pessimistic locking, don‘t guess date vs. time by default (set OracleAdapter.emulate_dates = true for the old behavior), adapter cleanup. 5635 [Michael Schoen]
  • Fixed a few Oracle issues: Allows Oracle‘s odd date handling to still work consistently within to_xml, Passes test that hardcode insert statement by dropping the :id column, Updated RUNNING_UNIT_TESTS with Oracle instructions, Corrects method signature for exec 5294 [Michael Schoen]
  • Added :group to available options for finds done on associations 5516 [mike@michaeldewey.org]
  • Observers also watch subclasses created after they are declared. 5535 [daniels@pronto.com.au]
  • Removed deprecated timestamps_gmt class methods. [Jeremy Kemper]
  • rake build_mysql_database grants permissions to rails@localhost. 5501 [brianegge@yahoo.com]
  • PostgreSQL: support microsecond time resolution. 5492 [alex@msgpad.com]
  • Add AssociationCollection#sum since the method_missing invokation has been shadowed by Enumerable#sum.
  • Added find_or_initialize_by_X which works like find_or_create_by_X but doesn‘t save the newly instantiated record. [Sam Stephenson]
  • Row locking. Provide a locking clause with the :lock finder option or true for the default "FOR UPDATE". Use the lock! method to obtain a row lock on a single record (reloads the record with :lock => true). [Shugo Maeda]
      # Obtain an exclusive lock on person 1 so we can safely increment visits.
  Person.transaction do
    # select * from people where id=1 for update
    person = Person.find(1, :lock => true)
    person.visits += 1
    person.save!
  end
  • PostgreSQL: introduce allow_concurrency option which determines whether to use blocking or asynchronous execute. Adapters with blocking execute will deadlock Ruby threads. The default value is ActiveRecord::Base.allow_concurrency. [Jeremy Kemper]
  • Use a per-thread (rather than global) transaction mutex so you may execute concurrent transactions on separate connections. [Jeremy Kemper]
  • Change AR::Base#to_param to return a String instead of a Fixnum. Closes 5320. [Nicholas Seckar]
  • Use explicit delegation instead of method aliasing for AR::Base.to_param -> AR::Base.id. 5299 (skaes@web.de)
  • Refactored ActiveRecord::Base.to_xml to become a delegate for XmlSerializer, which restores sanity to the mega method. This refactoring also reinstates the opinions that type="string" is redundant and ugly and nil-differentiation is not a concern of serialization [David Heinemeier Hansson]
  • Added simple hash conditions to find that‘ll just convert hash to an AND-based condition string 5143 [Hampton Catlin]. Example:
      Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 }, :limit => 2)

…is the same as:

    Person.find(:all, :conditions => [ "last_name = ? and status = ?", "Catlin", 1 ], :limit => 2)

  This makes it easier to pass in the options from a form or otherwise outside.
  • Fixed issues with BLOB limits, charsets, and booleans for Firebird 5194, 5191, 5189 [kennethkunz@gmail.com]
  • Fixed usage of :limit and with_scope when the association in scope is a 1:m 5208 [alex@purefiction.net]
  • Fixed migration trouble with SQLite when NOT NULL is used in the new definition 5215 [greg@lapcominc.com]
  • Fixed problems with eager loading and counting on SQL Server 5212 [kajism@yahoo.com]
  • Fixed that count distinct should use the selected column even when using :include 5251 [anna@wota.jp]
  • Fixed that :includes merged from with_scope won‘t cause the same association to be loaded more than once if repetition occurs in the clauses 5253 [alex@purefiction.net]
  • Allow models to override to_xml. 4989 [Blair Zajac <blair@orcaware.com>]
  • PostgreSQL: don‘t ignore port when host is nil since it‘s often used to label the domain socket. 5247 [shimbo@is.naist.jp]
  • Records and arrays of records are bound as quoted ids. [Jeremy Kemper]
      Foo.find(:all, :conditions => ['bar_id IN (?)', bars])
  Foo.find(:first, :conditions => ['bar_id = ?', bar])
  • Fixed that Base.find :all, :conditions => [ "id IN (?)", collection ] would fail if collection was empty [David Heinemeier Hansson]
  • Add a list of regexes assert_queries skips in the ActiveRecord test suite. [Rick Olson]
  • Fix the has_and_belongs_to_many create doesn‘t populate the join for new records. Closes 3692 [Josh Susser]
  • Provide Association Extensions access to the instance that the association is being accessed from. Closes 4433 [Josh Susser]
  • Update OpenBase adaterp‘s maintainer‘s email address. Closes 5176. [Derrick Spell]
  • Add a quick note about :select and eagerly included associations. [Rick Olson]
  • Add docs for the :as option in has_one associations. Closes 5144 [cdcarter@gmail.com]
  • Fixed that has_many collections shouldn‘t load the entire association to do build or create [David Heinemeier Hansson]
  • Added :allow_nil option for aggregations 5091 [Ian White]
  • Fix Oracle boolean support and tests. Closes 5139. [Michael Schoen]
  • create! no longer blows up when no attributes are passed and a :create scope is in effect (e.g. foo.bars.create! failed whereas foo.bars.create!({}) didn‘t.) [Jeremy Kemper]
  • Call Inflector#demodulize on the class name when eagerly including an STI model. Closes 5077 [info@loobmedia.com]
  • Preserve MySQL boolean column defaults when changing a column in a migration. Closes 5015. [pdcawley@bofh.org.uk]
  • PostgreSQL: migrations support :limit with :integer columns by mapping limit < 4 to smallint, > 4 to bigint, and anything else to integer. 2900 [keegan@thebasement.org]
  • Dates and times interpret empty strings as nil rather than 2000-01-01. 4830 [kajism@yahoo.com]
  • Allow :uniq => true with has_many :through associations. [Jeremy Kemper]
  • Ensure that StringIO is always available for the Schema dumper. [Marcel Molina Jr.]
  • Allow AR::Base#to_xml to include methods too. Closes 4921. [johan@textdrive.com]
  • Remove duplicate fixture entry in comments.yml. Closes 4923. [Blair Zajac <blair@orcaware.com>]
  • When grouping, use the appropriate option key. [Marcel Molina Jr.]
  • Add support for FrontBase (www.frontbase.com/) with a new adapter thanks to the hard work of one Mike Laster. Closes 4093. [mlaster@metavillage.com]
  • Add warning about the proper way to validate the presence of a foreign key. Closes 4147. [Francois Beausoleil <francois.beausoleil@gmail.com>]
  • Fix syntax error in documentation. Closes 4679. [Mislav Marohnić]
  • Add Oracle support for CLOB inserts. Closes 4748. [schoenm@earthlink.net sandra.metz@duke.edu]
  • Various fixes for sqlserver_adapter (odbc statement finishing, ado schema dumper, drop index). Closes 4831. [kajism@yahoo.com]
  • Add support for :order option to with_scope. Closes 3887. [eric.daspet@survol.net]
  • Prettify output of schema_dumper by making things line up. Closes 4241 [Caio Chassot <caio@v2studio.com>]
  • Make build_postgresql_databases task make databases owned by the postgres user. Closes 4790. [mlaster@metavillage.com]
  • Sybase Adapter type conversion cleanup. Closes 4736. [dev@metacasa.net]
  • Fix bug where calculations with long alias names return null. [Rick Olson]
  • Raise error when trying to add to a has_many :through association. Use the Join Model instead. [Rick Olson]
      @post.tags << @tag                  # BAD
  @post.taggings.create(:tag => @tag) # GOOD
  • Allow all calculations to take the :include option, not just COUNT (closes 4840) [Rick Olson]
  • Add ActiveRecord::Errors#to_xml [Jamis Buck]
  • Properly quote index names in migrations (closes 4764) [John Long]
  • Fix the HasManyAssociation#count method so it uses the new ActiveRecord::Base#count syntax, while maintaining backwards compatibility. [Rick Olson]
  • Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson]
  • Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson]
  • Add :case_sensitive option to validates_uniqueness_of (closes 3090) [Rick Olson]
      class Account < ActiveRecord::Base
    validates_uniqueness_of :email, :case_sensitive => false
  end
  • Allow multiple association extensions with :extend option (closes 4666) [Josh Susser]
      class Account < ActiveRecord::Base
    has_many :people, :extend => [FindOrCreateByNameExtension, FindRecentExtension]
  end

*1.14.4* (August 8th, 2006)

  • Add warning about the proper way to validate the presence of a foreign key. 4147 [Francois Beausoleil <francois.beausoleil@gmail.com>]
  • Fix syntax error in documentation. 4679 [Mislav Marohnić]
  • Update inconsistent migrations documentation. 4683 [machomagna@gmail.com]

*1.14.3* (June 27th, 2006)

  • Fix announcement of very long migration names. 5722 [blake@near-time.com]
  • Update callbacks documentation. 3970 [Robby Russell <robby@planetargon.com>]
  • Properly quote index names in migrations (closes 4764) [John Long]
  • Ensure that Associations#include_eager_conditions? checks both scoped and explicit conditions [Rick Olson]
  • Associations#select_limited_ids_list adds the ORDER BY columns to the SELECT DISTINCT List for postgresql. [Rick Olson]

*1.14.2* (April 9th, 2006)

  • Fixed calculations for the Oracle Adapter (closes 4626) [Michael Schoen]

*1.14.1* (April 6th, 2006)

  • Fix type_name_with_module to handle type names that begin with ’::’. Closes 4614. [Nicholas Seckar]
  • Fixed that that multiparameter assignment doesn‘t work with aggregations (closes 4620) [Lars Pind]
  • Enable Limit/Offset in Calculations (closes 4558) [lmarlow]
  • Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes 4528) [Rick Olson]
  • Fixed HasManyAssociation#find bugs when :finder_sql is set 4600 [lagroue@free.fr]
  • Allow AR::Base#respond_to? to behave when @attributes is nil [Ryan Davis]
  • Support eager includes when going through a polymorphic has_many association. [Rick Olson]
  • Added support for eagerly including polymorphic has_one associations. (closes 4525) [Rick Olson]
      class Post < ActiveRecord::Base
    has_one :tagging, :as => :taggable
  end

  Post.find :all, :include => :tagging
  • Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick Olson]
  • Added support for going through a polymorphic has_many association: (closes 4401) [Rick Olson]
      class PhotoCollection < ActiveRecord::Base
    has_many :photos, :as => :photographic
    belongs_to :firm
  end

  class Firm < ActiveRecord::Base
    has_many :photo_collections
    has_many :photos, :through => :photo_collections
  end
  • Multiple fixes and optimizations in PostgreSQL adapter, allowing ruby-postgres gem to work properly. [ruben.nine@gmail.com]
  • Fixed that AssociationCollection#delete_all should work even if the records of the association are not loaded yet. [Florian Weber]
  • Changed those private ActiveRecord methods to take optional third argument :auto instead of nil for performance optimizations. (closes 4456) [Stefan]
  • Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument ‘scope’ (closes 4456) [Rick Olson]
  • DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [David Heinemeier Hansson]
  • Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes 4512) [David Heinemeier Hansson]
  • Do not implicitly mark recordss of has_many :through as readonly but do mark habtm records as readonly (eventually only on join tables without rich attributes). [Marcel Mollina Jr.]
  • Fixed broken OCIAdapter 4457 [Michael Schoen]

*1.14.0* (March 27th, 2006)

  • Replace ‘rescue Object’ with a finer grained rescue. Closes 4431. [Nicholas Seckar]
  • Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick Olson]
  • Add support for :include to with_scope [andrew@redlinesoftware.com]
  • Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 4390 [Michael Schoen]
  • Change periods (.) in table aliases to _‘s. Closes 4251 [jeff@ministrycentered.com]
  • Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes 4348 [Rick Olson]
  • Fixed issue that kept :select options from being scoped [Rick Olson]
  • Fixed db_schema_import when binary types are present 3101 [David Heinemeier Hansson]
  • Fixed that MySQL enums should always be returned as strings 3501 [David Heinemeier Hansson]
  • Change has_many :through to use the :source option to specify the source association. :class_name is now ignored. [Rick Olson]
      class Connection < ActiveRecord::Base
    belongs_to :user
    belongs_to :channel
  end

  class Channel < ActiveRecord::Base
    has_many :connections
    has_many :contacts, :through => :connections, :class_name => 'User' # OLD
    has_many :contacts, :through => :connections, :source => :user      # NEW
  end
  • Fixed DB2 adapter so nullable columns will be determines correctly now and quotes from column default values will be removed 4350 [contact@maik-schmidt.de]
  • Allow overriding of find parameters in scoped has_many :through calls [Rick Olson]

    In this example, :include => false disables the default eager association from loading. :select changes the standard select clause. :joins specifies a join that is added to the end of the has_many :through query.

      class Post < ActiveRecord::Base
    has_many :tags, :through => :taggings, :include => :tagging do
      def add_joins_and_select
        find :all, :select => 'tags.*, authors.id as author_id', :include => false,
          :joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
      end
    end
  end
  • Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [David Heinemeier Hansson]
  • Don‘t classify the has_one class when eager loading, it is already singular. Add tests. (closes 4117) [Jonathan Viney]
  • Quit ignoring default :include options in has_many :through calls [Mark James]
  • Allow has_many :through associations to find the source association by setting a custom class (closes 4307) [Jonathan Viney]
  • Eager Loading support added for has_many :through => :has_many associations (see below). [Rick Olson]
  • Allow has_many :through to work on has_many associations (closes 3864) [sco@scottraymond.net] Example:
      class Firm < ActiveRecord::Base
    has_many :clients
    has_many :invoices, :through => :clients
  end

  class Client < ActiveRecord::Base
    belongs_to :firm
    has_many   :invoices
  end

  class Invoice < ActiveRecord::Base
    belongs_to :client
  end
  • Raise error when trying to select many polymorphic objects with has_many :through or :include (closes 4226) [Josh Susser]
  • Fixed has_many :through to include :conditions set on the :through association. closes 4020 [Jonathan Viney]
  • Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes 4259) [andylien@gmail.com / Rick Olson]
  • SQL Server adapter gets some love 4298 [Ryan Tomayko]
  • Added OpenBase database adapter that builds on top of the www.spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported 3528 [derrickspell@cdmplus.com]
  • Rework table aliasing to account for truncated table aliases. Add smarter table aliasing when doing eager loading of STI associations. This allows you to use the association name in the order/where clause. [Jonathan Viney / Rick Olson] 4108 Example (SpecialComment is using STI):
      Author.find(:all, :include => { :posts => :special_comments }, :order => 'special_comments.body')
  • Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick Olson]
  • Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. 2090 [Michael Koziarski]
  • Remove broken attempts at handling columns with a default of ‘now()’ in the postgresql adapter. 2257 [Michael Koziarski]
  • Added connection#current_database that‘ll return of the current database (only works in MySQL, SQL Server, and Oracle so far — please help implement for the rest of the adapters) 3663 [Tom Ward]
  • Fixed that Migration#execute would have the table name prefix appended to its query 4110 [mark.imbriaco@pobox.com]
  • Make all tinyint(1) variants act like boolean in mysql (tinyint(1) unsigned, etc.) [Jamis Buck]
  • Use association‘s :conditions when eager loading. [Jeremy Evans] 4144
  • Alias the has_and_belongs_to_many join table on eager includes. 4106 [Jeremy Evans]

    This statement would normally error because the projects_developers table is joined twice, and therefore joined_on would be ambiguous.

      Developer.find(:all, :include => {:projects => :developers}, :conditions => 'join_project_developers.joined_on IS NOT NULL')
  • Oracle adapter gets some love 4230 [Michael Schoen]
      * Changes :text to CLOB rather than BLOB [Moses Hohman]
  * Fixes an issue with nil numeric length/scales (several)
  * Implements support for XMLTYPE columns [wilig / Kubo Takehiro]
  * Tweaks a unit test to get it all green again
  * Adds support for #current_database
  • Added Base.abstract_class? that marks which classes are not part of the Active Record hierarchy 3704 [Rick Olson]
      class CachedModel < ActiveRecord::Base
    self.abstract_class = true
  end

  class Post < CachedModel
  end

  CachedModel.abstract_class?
  => true

  Post.abstract_class?
  => false

  Post.base_class
  => Post

  Post.table_name
  => 'posts'
  • Allow :dependent options to be used with polymorphic joins. 3820 [Rick Olson]
      class Foo < ActiveRecord::Base
    has_many :attachments, :as => :attachable, :dependent => :delete_all
  end
  • Nicer error message on has_many :through when :through reflection can not be found. 4042 [court3nay]
  • Upgrade to Transaction::Simple 1.3 [Jamis Buck]
  • Catch FixtureClassNotFound when using instantiated fixtures on a fixture that has no ActiveRecord model [Rick Olson]
  • Allow ordering of calculated results and/or grouped fields in calculations [solo@gatelys.com]
  • Make ActiveRecord::Base#save! return true instead of nil on success. 4173 [johan@johansorensen.com]
  • Dynamically set allow_concurrency. 4044 [Stefan Kaes]
  • Added Base#to_xml that‘ll turn the current record into a XML representation [David Heinemeier Hansson]. Example:
      topic.to_xml

    …returns:

      <?xml version="1.0" encoding="UTF-8"?>
  <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <id type="integer">1</id>
    <approved type="boolean">false</approved>
    <replies-count type="integer">0</replies-count>
    <bonus-time type="datetime">2000-01-01 08:28:00</bonus-time>
    <written-on type="datetime">2003-07-16 09:28:00</written-on>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

    …and you can configure with:

      topic.to_xml(:skip_instruct => true, :except => [ :id, bonus_time, :written_on, replies_count ])

    …that‘ll return:

      <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <approved type="boolean">false</approved>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

    You can even do load first-level associations as part of the document:

      firm.to_xml :include => [ :account, :clients ]

    …that‘ll return something like:

      <?xml version="1.0" encoding="UTF-8"?>
  <firm>
    <id type="integer">1</id>
    <rating type="integer">1</rating>
    <name>37signals</name>
    <clients>
      <client>
        <rating type="integer">1</rating>
        <name>Summit</name>
      </client>
      <client>
        <rating type="integer">1</rating>
        <name>Microsoft</name>
      </client>
    </clients>
    <account>
      <id type="integer">1</id>
      <credit-limit type="integer">50</credit-limit>
    </account>
  </firm>
  • Allow :counter_cache to take a column name for custom counter cache columns [Jamis Buck]
  • Documentation fixes for :dependent [robby@planetargon.com]
  • Stop the MySQL adapter crashing when views are present. 3782 [Jonathan Viney]
  • Don‘t classify the belongs_to class, it is already singular 4117 [keithm@infused.org]
  • Allow set_fixture_class to take Classes instead of strings for a class in a module. Raise FixtureClassNotFound if a fixture can‘t load. [Rick Olson]
  • Fix quoting of inheritance column for STI eager loading 4098 [Jonathan Viney <jonathan@bluewire.net.nz>]
  • Added smarter table aliasing for eager associations for multiple self joins 3580 [Rick Olson]
      * The first time a table is referenced in a join, no alias is used.
  * After that, the parent class name and the reflection name are used.

      Tree.find(:all, :include => :children) # LEFT OUTER JOIN trees AS tree_children ...

  * Any additional join references get a numerical suffix like '_2', '_3', etc.
  • Fixed eager loading problems with single-table inheritance 3580 [Rick Olson]. Post.find(:all, :include => :special_comments) now returns all posts, and any special comments that the posts may have. And made STI work with has_many :through and polymorphic belongs_to.
  • Added cascading eager loading that allows for queries like Author.find(:all, :include=> { :posts=> :comments }), which will fetch all authors, their posts, and the comments belonging to those posts in a single query (using LEFT OUTER JOIN) 3913 [anna@wota.jp]. Examples:
      # cascaded in two levels
  >> Author.find(:all, :include=>{:posts=>:comments})
  => authors
       +- posts
            +- comments

  # cascaded in two levels and normal association
  >> Author.find(:all, :include=>[{:posts=>:comments}, :categorizations])
  => authors
       +- posts
            +- comments
       +- categorizations

  # cascaded in two levels with two has_many associations
  >> Author.find(:all, :include=>{:posts=>[:comments, :categorizations]})
  => authors
       +- posts
            +- comments
            +- categorizations

  # cascaded in three levels
  >> Company.find(:all, :include=>{:groups=>{:members=>{:favorites}}})
  => companies
       +- groups
            +- members
                 +- favorites
  • Make counter cache work when replacing an association 3245 [eugenol@gmail.com]
  • Make migrations verbose [Jamis Buck]
  • Make counter_cache work with polymorphic belongs_to [Jamis Buck]
  • Fixed that calling HasOneProxy#build_model repeatedly would cause saving to happen 4058 [anna@wota.jp]
  • Added Sybase database adapter that relies on the Sybase Open Client bindings (see raa.ruby-lang.org/project/sybase-ctlib) 3765 [John Sheets]. It‘s almost completely Active Record compliant (including migrations), but has the following caveats:
      * Does not support DATE SQL column types; use DATETIME instead.
  * Date columns on HABTM join tables are returned as String, not Time.
  * Insertions are potentially broken for :polymorphic join tables
  * BLOB column access not yet fully supported
  • Clear stale, cached connections left behind by defunct threads. [Jeremy Kemper]
  • CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Most AR usage is in single-threaded applications. [Jeremy Kemper]
  • Renamed the "oci" adapter to "oracle", but kept the old name as an alias 4017 [Michael Schoen]
  • Fixed that Base.save should always return false if the save didn‘t succeed, including if it has halted by before_save‘s 1861, 2477 [David Heinemeier Hansson]
  • Speed up class -> connection caching and stale connection verification. 3979 [Stefan Kaes]
  • Add set_fixture_class to allow the use of table name accessors with models which use set_table_name. [Kevin Clark]
  • Added that fixtures to placed in subdirectories of the main fixture files are also loaded 3937 [dblack@wobblini.net]
  • Define attribute query methods to avoid method_missing calls. 3677 [Jonathan Viney]
  • ActiveRecord::Base.remove_connection explicitly closes database connections and doesn‘t corrupt the connection cache. Introducing the disconnect! instance method for the PostgreSQL, MySQL, and SQL Server adapters; implementations for the others are welcome. 3591 [Simon Stapleton, Tom Ward]
  • Added support for nested scopes 3407 [anna@wota.jp]. Examples:
      Developer.with_scope(:find => { :conditions => "salary > 10000", :limit => 10 }) do
    Developer.find(:all)     # => SELECT * FROM developers WHERE (salary > 10000) LIMIT 10

    # inner rule is used. (all previous parameters are ignored)
    Developer.with_exclusive_scope(:find => { :conditions => "name = 'Jamis'" }) do
      Developer.find(:all)   # => SELECT * FROM developers WHERE (name = 'Jamis')
    end

    # parameters are merged
    Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
      Developer.find(:all)   # => SELECT * FROM developers WHERE (( salary > 10000 ) AND ( name = 'Jamis' )) LIMIT 10
    end
  end
  • Fixed db2 connection with empty user_name and auth options 3622 [phurley@gmail.com]
  • Fixed validates_length_of to work on UTF-8 strings by using characters instead of bytes 3699 [Masao Mutoh]
  • Fixed that reflections would bleed across class boundaries in single-table inheritance setups 3796 [Lars Pind]
  • Added calculations: Base.count, Base.average, Base.sum, Base.minimum, Base.maxmium, and the generic Base.calculate. All can be used with :group and :having. Calculations and statitics need no longer require custom SQL. 3958 [Rick Olson]. Examples:
      Person.average :age
  Person.minimum :age
  Person.maximum :age
  Person.sum :salary, :group => :last_name
  • Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) 3920 [Luke Redpath]
  • Reflections don‘t attempt to resolve module nesting of association classes. Simplify type computation. [Jeremy Kemper]
  • Improved the Oracle OCI Adapter with better performance for column reflection (from 3210), fixes to migrations (from 3476 and 3742), tweaks to unit tests (from 3610), and improved documentation (from 2446) 3879 [Aggregated by schoenm@earthlink.net]
  • Fixed that the schema_info table used by ActiveRecord::Schema.define should respect table pre- and suffixes 3834 [rubyonrails@atyp.de]
  • Added :select option to Base.count that‘ll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT 3839 [Stefan Kaes]
  • Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva]
  • Allow :include to be used with has_many :through associations 3611 [Michael Schoen]
  • PostgreSQL: smarter schema dumps using pk_and_sequence_for(table). 2920 [Blair Zajac]
  • SQLServer: more compatible limit/offset emulation. 3779 [Tom Ward]
  • Polymorphic join support for has_one associations (has_one :foo, :as => :bar) 3785 [Rick Olson]
  • PostgreSQL: correctly parse negative integer column defaults. 3776 [bellis@deepthought.org]
  • Fix problems with count when used with :include [Jeremy Hopple and Kevin Clark]
  • ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Lütke]
  • Using AssociationCollection#build with arrays of hashes should call build, not create [David Heinemeier Hansson]
  • Remove definition of reloadable? from ActiveRecord::Base to make way for new Reloadable code. [Nicholas Seckar]
  • Fixed schema handling for DB2 adapter that didn‘t work: an initial schema could be set, but it wasn‘t used when getting tables and indexes 3678 [Maik Schmidt]
  • Support the :column option for remove_index with the PostgreSQL adapter. 3661 [Shugo Maeda]
  • Add documentation for add_index and remove_index. 3600 [Manfred Stienstra <m.stienstra@fngtps.com>]
  • If the OCI library is not available, raise an exception indicating as much. 3593 [Michael Schoen]
  • Add explicit :order in finder tests as postgresql orders results differently by default. 3577. [Rick Olson]
  • Make dynamic finders honor additional passed in :conditions. 3569 [Oleg Pudeyev <pudeyo@rpi.edu>, Marcel Molina Jr.]
  • Show a meaningful error when the DB2 adapter cannot be loaded due to missing dependencies. [Nicholas Seckar]
  • Make .count work for has_many associations with multi line finder sql [Michael Schoen]
  • Add AR::Base.base_class for querying the ancestor AR::Base subclass [Jamis Buck]
  • Allow configuration of the column used for optimistic locking [wilsonb@gmail.com]
  • Don‘t hardcode ‘id’ in acts as list. [ror@philippeapril.com]
  • Fix date errors for SQLServer in association tests. 3406 [Kevin Clark]
  • Escape database name in MySQL adapter when creating and dropping databases. 3409 [anna@wota.jp]
  • Disambiguate table names for columns in validates_uniquness_of‘s WHERE clause. 3423 [alex.borovsky@gmail.com]
  • .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke]
  • Don‘t raise an exception when there are more keys than there are named bind variables when sanitizing conditions. [Marcel Molina Jr.]
  • Multiple enhancements and adjustments to DB2 adaptor. 3377 [contact@maik-schmidt.de]
  • Sanitize scoped conditions. [Marcel Molina Jr.]
  • Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [David Heinemeier Hansson]
  • Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [Tobias Lütke]
  • SchemaDumper now doesn‘t fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [Tobias Lütke]
  • Fixed that saving a model with multiple habtm associations would only save the first one. 3244 [yanowitz-rubyonrails@quantumfoam.org, Florian Weber]
  • Fix change_column to work with PostgreSQL 7.x and 8.x. 3141 [wejn@box.cz, Rick Olson, Scott Barron]
  • removed :piggyback in favor of just allowing :select on :through associations. [Tobias Lütke]
  • made method missing delegation to class methods on relation target work on :through associations. [Tobias Lütke]
  • made .find() work on :through relations. [Tobias Lütke]
  • Fix typo in association docs. 3296. [Blair Zajac]
  • Fixed :through relations when using STI inherited classes would use the inherited class‘s name as foreign key on the join model [Tobias Lütke]

*1.13.2* (December 13th, 2005)

  • Become part of Rails 1.0
  • MySQL: allow encoding option for mysql.rb driver. [Jeremy Kemper]
  • Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]. Example:
      class Post
    has_many :recent_comments, :class_name => "Comment", :limit => 10, :include => :author
  end

  post.recent_comments.find(:all) # Uses LIMIT 10 and includes authors
  post.recent_comments.find(:all, :limit => nil) # Uses no limit but include authors
  post.recent_comments.find(:all, :limit => nil, :include => nil) # Uses no limit and doesn't include authors
  • Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]
  • MySQL: fixes for the bundled mysql.rb driver. 3160 [Justin Forder]
  • SQLServer: fix obscure optimistic locking bug. 3068 [kajism@yahoo.com]
  • SQLServer: support uniqueidentifier columns. 2930 [keithm@infused.org]
  • SQLServer: cope with tables names qualified by owner. 3067 [jeff@ministrycentered.com]
  • SQLServer: cope with columns with "desc" in the name. 1950 [Ron Lusk, Ryan Tomayko]
  • SQLServer: cope with primary keys with "select" in the name. 3057 [rdifrango@captechventures.com]
  • Oracle: active? performs a select instead of a commit. 3133 [Michael Schoen]
  • MySQL: more robust test for nullified result hashes. 3124 [Stefan Kaes]
  • Reloading an instance refreshes its aggregations as well as its associations. 3024 [François Beausoleil]
  • Fixed that using :include together with :conditions array in Base.find would cause NoMethodError 2887 [Paul Hammmond]
  • PostgreSQL: more robust sequence name discovery. 3087 [Rick Olson]
  • Oracle: use syntax compatible with Oracle 8. 3131 [Michael Schoen]
  • MySQL: work around ruby-mysql/mysql-ruby inconsistency with mysql.stat. Eliminate usage of mysql.ping because it doesn‘t guarantee reconnect. Explicitly close and reopen the connection instead. [Jeremy Kemper]
  • Added preliminary support for polymorphic associations [David Heinemeier Hansson]
  • Added preliminary support for join models [David Heinemeier Hansson]
  • Allow validate_uniqueness_of to be scoped by more than just one column. 1559. [jeremy@jthopple.com, Marcel Molina Jr.]
  • Firebird: active? and reconnect! methods for handling stale connections. 428 [Ken Kunz <kennethkunz@gmail.com>]
  • Firebird: updated for FireRuby 0.4.0. 3009 [Ken Kunz <kennethkunz@gmail.com>]
  • MySQL and PostgreSQL: active? compatibility with the pure-Ruby driver. 428 [Jeremy Kemper]
  • Oracle: active? check pings the database rather than testing the last command status. 428 [Michael Schoen]
  • SQLServer: resolve column aliasing/quoting collision when using limit or offset in an eager find. 2974 [kajism@yahoo.com]
  • Reloading a model doesn‘t lose track of its connection. 2996 [junk@miriamtech.com, Jeremy Kemper]
  • Fixed bug where using update_attribute after pushing a record to a habtm association of the object caused duplicate rows in the join table. 2888 [colman@rominato.com, Florian Weber, Michael Schoen]
  • MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwise, the connection ‘loses’ its settings if it times out and is reconnected. 2978 [Shugo Maeda]
  • has_and_belongs_to_many: use JOIN instead of LEFT JOIN. [Jeremy Kemper]
  • MySQL: introduce :encoding option to specify the character set for client, connection, and results. Only available for MySQL 4.1 and later with the mysql-ruby driver. Do SHOW CHARACTER SET in mysql client to see available encodings. 2975 [Shugo Maeda]
  • Add tasks to create, drop and rebuild the MySQL and PostgreSQL test databases. [Marcel Molina Jr.]
  • Correct boolean handling in generated reader methods. 2945 [Don Park, Stefan Kaes]
  • Don‘t generate read methods for columns whose names are not valid ruby method names. 2946 [Stefan Kaes]
  • Document :force option to create_table. 2921 [Blair Zajac <blair@orcaware.com>]
  • Don‘t add the same conditions twice in has_one finder sql. 2916 [Jeremy Evans]
  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]
  • Introducing the Firebird adapter. Quote columns and use attribute_condition more consistently. Setup guide: wiki.rubyonrails.com/rails/pages/Firebird+Adapter 1874 [Ken Kunz <kennethkunz@gmail.com>]
  • SQLServer: active? and reconnect! methods for handling stale connections. 428 [kajism@yahoo.com, Tom Ward <tom@popdog.net>]
  • Associations handle case-equality more consistently: item.parts.is_a?(Array) and item.parts === Array. 1345 [MarkusQ@reality.com]
  • SQLServer: insert uses given primary key value if not nil rather than SELECT @@IDENTITY. 2866 [kajism@yahoo.com, Tom Ward <tom@popdog.net>]
  • Oracle: active? and reconnect! methods for handling stale connections. Optionally retry queries after reconnect. 428 [Michael Schoen <schoenm@earthlink.net>]
  • Correct documentation for Base.delete_all. 1568 [Newhydra]
  • Oracle: test case for column default parsing. 2788 [Michael Schoen <schoenm@earthlink.net>]
  • Update documentation for Migrations. 2861 [Tom Werner <tom@cube6media.com>]
  • When AbstractAdapter#log rescues an exception, attempt to detect and reconnect to an inactive database connection. Connection adapter must respond to the active? and reconnect! instance methods. Initial support for PostgreSQL, MySQL, and SQLite. Make certain that all statements which may need reconnection are performed within a logged block: for example, this means no avoiding log(sql, name) { } if @logger.nil? 428 [Jeremy Kemper]
  • Oracle: Much faster column reflection. 2848 [Michael Schoen <schoenm@earthlink.net>]
  • Base.reset_sequence_name analogous to reset_table_name (mostly useful for testing). Base.define_attr_method allows nil values. [Jeremy Kemper]
  • PostgreSQL: smarter sequence name defaults, stricter last_insert_id, warn on pk without sequence. [Jeremy Kemper]
  • PostgreSQL: correctly discover custom primary key sequences. 2594 [Blair Zajac <blair@orcaware.com>, meadow.nnick@gmail.com, Jeremy Kemper]
  • SQLServer: don‘t report limits for unsupported field types. 2835 [Ryan Tomayko]
  • Include the Enumerable module in ActiveRecord::Errors. [Rick Bradley <rick@rickbradley.com>]
  • Add :group option, correspond to GROUP BY, to the find method and to the has_many association. 2818 [rubyonrails@atyp.de]
  • Don‘t cast nil or empty strings to a dummy date. 2789 [Rick Bradley <rick@rickbradley.com>]
  • acts_as_list plays nicely with inheritance by remembering the class which declared it. 2811 [rephorm@rephorm.com]
  • Fix sqlite adaptor‘s detection of missing dbfile or database declaration. [Nicholas Seckar]
  • Fixed acts_as_list for definitions without an explicit :order 2803 [Jonathan Viney]
  • Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see 440) to ruby-mysql 0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now a part of the main driver; reapplied local change [2182]. Removed GC.start from Result.free. [tommy@tmtm.org, akuroda@gmail.com, Doug Fales <doug.fales@gmail.com>, Jeremy Kemper]
  • Correct handling of complex order clauses with SQL Server limit emulation. 2770 [Tom Ward <tom@popdog.net>, Matt B.]
  • Correct whitespace problem in Oracle default column value parsing. 2788 [rick@rickbradley.com]
  • Destroy associated has_and_belongs_to_many records after all before_destroy callbacks but before destroy. This allows you to act on the habtm association as you please while preserving referential integrity. 2065 [larrywilliams1@gmail.com, sam.kirchmeier@gmail.com, elliot@townx.org, Jeremy Kemper]
  • Deprecate the old, confusing :exclusively_dependent option in favor of :dependent => :delete_all. [Jeremy Kemper]
  • More compatible Oracle column reflection. 2771 [Ryan Davis <ryand-ruby@zenspider.com>, Michael Schoen <schoenm@earthlink.net>]

*1.13.0* (November 7th, 2005)

  • Fixed faulty regex in get_table_name method (SQLServerAdapter) 2639 [Ryan Tomayko]
  • Added :include as an option for association declarations [David Heinemeier Hansson]. Example:
      has_many :posts, :include => [ :author, :comments ]
  • Rename Base.constrain to Base.with_scope so it doesn‘t conflict with existing concept of database constraints. Make scoping more robust: uniform method => parameters, validated method names and supported finder parameters, raise exception on nested scopes. [Jeremy Kemper] Example:
      Comment.with_scope(:find => { :conditions => 'active=true' }, :create => { :post_id => 5 }) do
    # Find where name = ? and active=true
    Comment.find :all, :conditions => ['name = ?', name]
    # Create comment associated with :post_id
    Comment.create :body => "Hello world"
  end
  • Fixed that SQL Server should ignore :size declarations on anything but integer and string in the agnostic schema representation 2756 [Ryan Tomayko]
  • Added constrain scoping for creates using a hash of attributes bound to the :creation key [David Heinemeier Hansson]. Example:
      Comment.constrain(:creation => { :post_id => 5 }) do
    # Associated with :post_id
    Comment.create :body => "Hello world"
  end

    This is rarely used directly, but allows for find_or_create on associations. So you can do:

      # If the tag doesn't exist, a new one is created that's associated with the person
  person.tags.find_or_create_by_name("Summer")
  • Added find_or_create_by_X as a second type of dynamic finder that‘ll create the record if it doesn‘t already exist [David Heinemeier Hansson]. Example:
      # No 'Summer' tag exists
  Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")

  # Now the 'Summer' tag does exist
  Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
  • Added extension capabilities to has_many and has_and_belongs_to_many proxies [David Heinemeier Hansson]. Example:
      class Account < ActiveRecord::Base
    has_many :people do
      def find_or_create_by_name(name)
        first_name, *last_name = name.split
        last_name = last_name.join " "

        find_or_create_by_first_name_and_last_name(first_name, last_name)
      end
    end
  end

  person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson")
  person.first_name # => "David"
  person.last_name  # => "Heinemeier Hansson"

    Note that the anoymous module must be declared using brackets, not do/end (due to order of evaluation).

  • Omit internal dtproperties table from SQLServer table list. 2729 [Ryan Tomayko]
  • Quote column names in generated SQL. 2728 [Ryan Tomayko]
  • Correct the pure-Ruby MySQL 4.1.1 shim‘s version test. 2718 [Jeremy Kemper]
  • Add Model.create! to match existing model.save! method. When save! raises RecordInvalid, you can catch the exception, retrieve the invalid record (invalid_exception.record), and see its errors (invalid_exception.record.errors). [Jeremy Kemper]
  • Correct fixture behavior when table name pluralization is off. 2719 [Rick Bradley <rick@rickbradley.com>]
  • Changed :dbfile to :database for SQLite adapter for consistency (old key still works as an alias) 2644 [Dan Peterson]
  • Added migration support for Oracle 2647 [Michael Schoen]
  • Worked around that connection can‘t be reset if allow_concurrency is off. 2648 [Michael Schoen <schoenm@earthlink.net>]
  • Fixed SQL Server adapter to pass even more tests and do even better 2634 [Ryan Tomayko]
  • Fixed SQL Server adapter so it honors options[:conditions] when applying :limits 1978 [Tom Ward]
  • Added migration support to SQL Server adapter (please someone do the same for Oracle and DB2) 2625 [Tom Ward]
  • Use AR::Base.silence rather than AR::Base.logger.silence in fixtures to preserve Log4r compatibility. 2618 [dansketcher@gmail.com]
  • Constraints are cloned so they can‘t be inadvertently modified while they‘re

in effect. Added :readonly finder constraint. Calling an association collection‘s class method (Part.foobar via item.parts.foobar) constrains :readonly => false since the collection‘s :joins constraint would otherwise force it to true. [Jeremy Kemper <rails@bitsweat.net>]

  • Added :offset and :limit to the kinds of options that Base.constrain can use 2466 [duane.johnson@gmail.com]
  • Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general 2555 [Michael Schoen]
  • Added quoted_true and quoted_false methods and tables to db2_adapter and cleaned up tests for DB2 2493, 2624 [maik schmidt]

*1.12.2* (October 26th, 2005)

  • Allow symbols to rename columns when using SQLite adapter. 2531 [Kevin Clark]
  • Map Active Record time to SQL TIME. 2575, 2576 [Robby Russell <robby@planetargon.com>]
  • Clarify semantics of ActiveRecord::Base#respond_to? 2560 [Stefan Kaes]
  • Fixed Association#clear for associations which have not yet been accessed. 2524 [Patrick Lenz <patrick@lenz.sh>]
  • HABTM finders shouldn‘t return readonly records. 2525 [Patrick Lenz <patrick@lenz.sh>]
  • Make all tests runnable on their own. 2521. [Blair Zajac <blair@orcaware.com>]

*1.12.1* (October 19th, 2005)

  • Always parenthesize :conditions options so they may be safely combined with STI and constraints.
  • Correct PostgreSQL primary key sequence detection. 2507 [tmornini@infomania.com]
  • Added support for using limits in eager loads that involve has_many and has_and_belongs_to_many associations

*1.12.0* (October 16th, 2005)

  • Update/clean up documentation (rdoc)
  • PostgreSQL sequence support. Use set_sequence_name in your model class to specify its primary key sequence. 2292 [Rick Olson <technoweenie@gmail.com>, Robby Russell <robby@planetargon.com>]
  • Change default logging colors to work on both white and black backgrounds. [Sam Stephenson]
  • YAML fixtures support ordered hashes for fixtures with foreign key dependencies in the same table. 1896 [purestorm@ggnore.net]
  • :dependent now accepts :nullify option. Sets the foreign key of the related objects to NULL instead of deleting them. 2015 [Robby Russell <robby@planetargon.com>]
  • Introduce read-only records. If you call object.readonly! then it will mark the object as read-only and raise ReadOnlyRecord if you call object.save. object.readonly? reports whether the object is read-only. Passing :readonly => true to any finder method will mark returned records as read-only. The :joins option now implies :readonly, so if you use this option, saving the same record will now fail. Use find_by_sql to work around.
  • Avoid memleak in dev mode when using fcgi
  • Simplified .clear on active record associations by using the existing delete_records method. 1906 [Caleb <me@cpb.ca>]
  • Delegate access to a customized primary key to the conventional id method. 2444. [Blair Zajac <blair@orcaware.com>]
  • Fix errors caused by assigning a has-one or belongs-to property to itself
  • Add ActiveRecord::Base.schema_format setting which specifies how databases should be dumped [Sam Stephenson]
  • Update DB2 adapter. 2206. [contact@maik-schmidt.de]
  • Corrections to SQLServer native data types. 2267. [rails.20.clarry@spamgourmet.com]
  • Deprecated ActiveRecord::Base.threaded_connection in favor of ActiveRecord::Base.allow_concurrency.
  • Protect id attribute from mass assigment even when the primary key is set to something else. 2438. [Blair Zajac <blair@orcaware.com>]
  • Misc doc fixes (typos/grammar/etc.). 2430. [coffee2code]
  • Add test coverage for content_columns. 2432. [coffee2code]
  • Speed up for unthreaded environments. 2431. [Stefan Kaes]
  • Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. 2426. [Stefan Kaes]
  • Speed up the setting of table_name. 2428. [Stefan Kaes]
  • Optimize instantiation of STI subclass records. In partial fullfilment of 1236. [Stefan Kaes]
  • Fix typo of ‘constrains’ to ‘contraints’. 2069. [Michael Schuerig <michael@schuerig.de>]
  • Optimization refactoring for add_limit_offset!. In partial fullfilment of 1236. [Stefan Kaes]
  • Add ability to get all siblings, including the current child, with acts_as_tree. Recloses 2140. [Michael Schuerig <michael@schuerig.de>]
  • Add geometric type for postgresql adapter. 2233 [Andrew Kaspick]
  • Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of 1236. [Stefan Kaes]
  • Add convenience predicate methods on Column class. In partial fullfilment of 1236. [Stefan Kaes]
  • Raise errors when invalid hash keys are passed to ActiveRecord::Base.find. 2363 [Chad Fowler <chad@chadfowler.com>, Nicholas Seckar]
  • Added :force option to create_table that‘ll try to drop the table if it already exists before creating
  • Fix transactions so that calling return while inside a transaction will not leave an open transaction on the connection. [Nicholas Seckar]
  • Use foreign_key inflection uniformly. 2156 [Blair Zajac <blair@orcaware.com>]
  • model.association.clear should destroy associated objects if :dependent => true instead of nullifying their foreign keys. 2221 [joergd@pobox.com, ObieFernandez <obiefernandez@gmail.com>]
  • Returning false from before_destroy should cancel the action. 1829 [Jeremy Huffman]
  • Recognize PostgreSQL NOW() default as equivalent to CURRENT_TIMESTAMP or CURRENT_DATE, depending on the column‘s type. 2256 [mat <mat@absolight.fr>]
  • Extensive documentation for the abstract database adapter. 2250 [François Beausoleil <fbeausoleil@ftml.net>]
  • Clean up Fixtures.reset_sequences for PostgreSQL. Handle tables with no rows and models with custom primary keys. 2174, 2183 [jay@jay.fm, Blair Zajac <blair@orcaware.com>]
  • Improve error message when nil is assigned to an attr which validates_size_of within a range. 2022 [Manuel Holtgrewe <purestorm@ggnore.net>]
  • Make update_attribute use the same writer method that update_attributes uses.
 #2237 [trevor@protocool.com]
  • Make migrations honor table name prefixes and suffixes. 2298 [Jakob Skjerning, Marcel Molina Jr.]
  • Correct and optimize PostgreSQL bytea escaping. 1745, 1837 [dave@cherryville.org, ken@miriamtech.com, bellis@deepthought.org]
  • Fixtures should only reset a PostgreSQL sequence if it corresponds to an integer primary key named id. 1749 [chris@chrisbrinker.com]
  • Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior)
  • Added new symbol-driven approach to activating observers with Base#observers= [David Heinemeier Hansson]. Example:
      ActiveRecord::Base.observers = :cacher, :garbage_collector
  • Added AbstractAdapter#select_value and AbstractAdapter#select_values as convenience methods for selecting single values, instead of hashes, of the first column in a SELECT 2283 [solo@gatelys.com]
  • Wrap :conditions in parentheses to prevent problems with OR‘s 1871 [Jamis Buck]
  • Allow the postgresql adapter to work with the SchemaDumper. [Jamis Buck]
  • Add ActiveRecord::SchemaDumper for dumping a DB schema to a pure-ruby file, making it easier to consolidate large migration lists and port database schemas between databases. [Jamis Buck]
  • Fixed migrations for Windows when using more than 10 [David Naseby]
  • Fixed that the create_x method from belongs_to wouldn‘t save the association properly 2042 [Florian Weber]
  • Fixed saving a record with two unsaved belongs_to associations pointing to the same object 2023 [Tobias Lütke]
  • Improved migrations’ behavior when the schema_info table is empty. [Nicholas Seckar]
  • Fixed that Observers didn‘t observe sub-classes 627 [Florian Weber]
  • Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes 2222 [Marcel Molina Jr.]
  • Added check for RAILS_CONNECTION_ADAPTERS on startup and only load the connection adapters specified within if its present (available in Rails through config.connection_adapters using the new config) 1958 [skae]
  • Fixed various problems with has_and_belongs_to_many when using customer finder_sql 2094 [Florian Weber]
  • Added better exception error when unknown column types are used with migrations 1814 [François Beausoleil]
  • Fixed "connection lost" issue with the bundled Ruby/MySQL driver (would kill the app after 8 hours of inactivity) 2163, 428 [kajism@yahoo.com]
  • Fixed comparison of Active Record objects so two new objects are not equal 2099 [deberg]
  • Fixed that the SQL Server adapter would sometimes return DBI::Timestamp objects instead of Time 2127 [Tom Ward]
  • Added the instance methods root and ancestors on acts_as_tree and fixed siblings to not include the current node 2142, 2140 [coffee2code]
  • Fixed that Active Record would call SHOW FIELDS twice (or more) for the same model when the cached results were available 1947 [sd@notso.net]
  • Added log_level and use_silence parameter to ActiveRecord::Base.benchmark. The first controls at what level the benchmark statement will be logged (now as debug, instead of info) and the second that can be passed false to include all logging statements during the benchmark block/
  • Make sure the schema_info table is created before querying the current version 1903
  • Fixtures ignore table name prefix and suffix 1987 [Jakob Skjerning]
  • Add documentation for index_type argument to add_index method for migrations 2005 [Blaine]
  • Modify read_attribute to allow a symbol argument 2024 [Ken Kunz]
  • Make destroy return self 1913 [Sebastian Kanthak]
  • Fix typo in validations documentation 1938 [court3nay]
  • Make acts_as_list work for insert_at(1) 1966 [hensleyl@papermountain.org]
  • Fix typo in count_by_sql documentation 1969 [Alexey Verkhovsky]
  • Allow add_column and create_table to specify NOT NULL 1712 [emptysands@gmail.com]
  • Fix create_table so that id column is implicitly added [Rick Olson]
  • Default sequence names for Oracle changed to #{table_name}_seq, which is the most commonly used standard. In addition, a new method ActiveRecord::Base#set_sequence_name allows the developer to set the sequence name per model. This is a non-backwards-compatible change — anyone using the old-style "rails_sequence" will need to either create new sequences, or set: ActiveRecord::Base.set_sequence_name = "rails_sequence" 1798
  • OCIAdapter now properly handles synonyms, which are commonly used to separate out the schema owner from the application user 1798
  • Fixed the handling of camelCase columns names in Oracle 1798
  • Implemented for OCI the Rakefile tasks of :clone_structure_to_test, :db_structure_dump, and :purge_test_database, which enable Oracle folks to enjoy all the agile goodness of Rails for testing. Note that the current implementation is fairly limited — only tables and sequences are cloned, not constraints or indexes. A full clone in Oracle generally requires some manual effort, and is version-specific. Post 9i, Oracle recommends the use of the DBMS_METADATA package, though that approach requires editing of the physical characteristics generated 1798
  • Fixed the handling of multiple blob columns in Oracle if one or more of them are null 1798
  • Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections 1764 [Tobias Lütke]
      class Comment < AR:B
    def self.search(q)
      find(:all, :conditions => ["body = ?", q])
    end
  end

  class Post < AR:B
    has_many :comments
  end

  Post.find(1).comments.search('hi') # => SELECT * from comments WHERE post_id = 1 AND body = 'hi'

    NOTICE: This patch changes the underlying SQL generated by has_and_belongs_to_many queries. If your relying on that, such as by explicitly referencing the old t and j aliases, you‘ll need to update your code. Of course, you _shouldn‘t_ be relying on details like that no less than you should be diving in to touch private variables. But just in case you do, consider yourself noticed :)

  • Added migration support for SQLite (using temporary tables to simulate ALTER TABLE) 1771 [Sam Stephenson]
  • Remove extra definition of supports_migrations? from abstract_adaptor.rb [Nicholas Seckar]
  • Fix acts_as_list so that moving next-to-last item to the bottom does not result in duplicate item positions
  • Fixed incompatibility in DB2 adapter with the new limit/offset approach 1718 [Maik Schmidt]
  • Added :select option to find which can specify a different value than the default *, like find(:all, :select => "first_name, last_name"), if you either only want to select part of the columns or exclude columns otherwise included from a join 1338 [Stefan Kaes]

*1.11.1* (11 July, 2005)

  • Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError 1692 [Rick Olson]
  • Fixed that assume_bottom_position (in acts_as_list) could be called on items already last in the list and they would move one position away from the list 1648 [tyler@kianta.com]
  • Added ActiveRecord::Base.threaded_connections flag to turn off 1-connection per thread (required for thread safety). By default it‘s on, but WEBrick in Rails need it off 1685 [Sam Stephenson]
  • Correct reflected table name for singular associations. 1688 [court3nay]
  • Fixed optimistic locking with SQL Server 1660 [tom@popdog.net]
  • Added ActiveRecord::Migrator.migrate that can figure out whether to go up or down based on the target version and the current
  • Added better error message for "packets out of order" 1630 [court3nay]
  • Fixed first run of "rake migrate" on PostgreSQL by not expecting a return value on the id 1640

*1.11.0* (6 July, 2005)

  • Fixed that Yaml error message in fixtures hid the real error 1623 [Nicholas Seckar]
  • Changed logging of SQL statements to use the DEBUG level instead of INFO
  • Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases 1604 [Tobias Lütke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator.
  • Added callback hooks to association collections 1549 [Florian Weber]. Example:
      class Project
    has_and_belongs_to_many :developers, :before_add => :evaluate_velocity

    def evaluate_velocity(developer)
      ...
    end
  end

    ..raising an exception will cause the object not to be added (or removed, with before_remove).

  • Fixed Base.content_columns call for SQL Server adapter 1450 [DeLynn Berry]
  • Fixed Base#write_attribute to work with both symbols and strings 1190 [Paul Legato]
  • Fixed that has_and_belongs_to_many didn‘t respect single table inheritance types 1081 [Florian Weber]
  • Speed up ActiveRecord#method_missing for the common case (read_attribute).
  • Only notify observers on after_find and after_initialize if these methods are defined on the model. 1235 [Stefan Kaes]
  • Fixed that single-table inheritance sub-classes couldn‘t be used to limit the result set with eager loading 1215 [Chris McGrath]
  • Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on 1316 [raidel@onemail.at]
  • Added roots, root, and siblings to the batch of methods added by acts_as_tree 1541 [Michael Schuerig]
  • Added support for limit/offset with the MS SQL Server driver so that pagination will now work 1569 [DeLynn Berry]
  • Added support for ODBC connections to MS SQL Server so you can connect from a non-Windows machine 1569 [Mark Imbriaco/DeLynn Berry]
  • Fixed that multiparameter posts ignored attr_protected 1532 [alec+rails@veryclever.net]
  • Fixed problem with eager loading when using a has_and_belongs_to_many association using :association_foreign_key 1504 [flash@vanklinkenbergsoftware.nl]
  • Fixed Base#find to honor the documentation on how :joins work and make them consistent with Base#count 1405 [pritchie@gmail.com]. What used to be:
      Developer.find :all, :joins => 'developers_projects', :conditions => 'id=developer_id AND project_id=1'

    …should instead be:

      Developer.find(
    :all,
    :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
    :conditions => 'project_id=1'
  )
  • Fixed that validations didn‘t respecting custom setting for too_short, too_long messages 1437 [Marcel Molina Jr.]
  • Fixed that clear_association_cache doesn‘t delete new associations on new records (so you can safely place new records in the session with Action Pack without having new associations wiped) 1494 [cluon]
  • Fixed that calling Model.find([]) returns [] and doesn‘t throw an exception 1379
  • Fixed that adding a record to a has_and_belongs_to collection would always save it — now it only saves if its a new record 1203 [Alisdair McDiarmid]
  • Fixed saving of in-memory association structures to happen as a after_create/after_update callback instead of after_save — that way you can add new associations in after_create/after_update callbacks without getting them saved twice
  • Allow any Enumerable, not just Array, to work as bind variables 1344 [Jeremy Kemper]
  • Added actual database-changing behavior to collection assigment for has_many and has_and_belongs_to_many 1425 [Sebastian Kanthak]. Example:
      david.projects = [Project.find(1), Project.new("name" => "ActionWebSearch")]
  david.save

    If david.projects already contain the project with ID 1, this is left unchanged. Any other projects are dropped. And the new project is saved when david.save is called.

    Also included is a way to do assignments through IDs, which is perfect for checkbox updating, so you get to do:

      david.project_ids = [1, 5, 7]
  • Corrected typo in find SQL for has_and_belongs_to_many. 1312 [ben@bensinclair.com]
  • Fixed sanitized conditions for has_many finder method. 1281 [jackc@hylesanderson.com, pragdave, Tobias Lütke]
  • Comprehensive PostgreSQL schema support. Use the optional schema_search_path directive in database.yml to give a comma-separated list of schemas to search for your tables. This allows you, for example, to have tables in a shared schema without having to use a custom table name. See www.postgresql.org/docs/8.0/interactive/ddl-schemas.html to learn more. 827 [dave@cherryville.org]
  • Corrected @@configurations typo 1410 [david@ruppconsulting.com]
  • Return PostgreSQL columns in the order they were declared 1374 [perlguy@gmail.com]
  • Allow before/after update hooks to work on models using optimistic locking
  • Eager loading of dependent has_one associations won‘t delete the association 1212
  • Added a second parameter to the build and create method for has_one that controls whether the existing association should be replaced (which means nullifying its foreign key as well). By default this is true, but false can be passed to prevent it.
  • Using transactional fixtures now causes the data to be loaded only once.
  • Added fixture accessor methods that can be used when instantiated fixtures are disabled.
      fixtures :web_sites

  def test_something
    assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
  end
  • Added DoubleRenderError exception that‘ll be raised if render* is called twice 518 [Nicholas Seckar]
  • Fixed exceptions occuring after render has been called 1096 [Nicholas Seckar]
  • CHANGED: validates_presence_of now uses Errors#add_on_blank, which will make " " fail the validation where it didn‘t before 1309
  • Added Errors#add_on_blank which works like Errors#add_on_empty, but uses Object#blank? instead
  • Added the :if option to all validations that can either use a block or a method pointer to determine whether the validation should be run or not. 1324 [Duane Johnson/jhosteny]. Examples:

    Conditional validations such as the following are made possible:

      validates_numericality_of :income, :if => :employed?

    Conditional validations can also solve the salted login generator problem:

      validates_confirmation_of :password, :if => :new_password?

    Using blocks:

      validates_presence_of :username, :if => Proc.new { |user| user.signup_step > 1 }
  • Fixed use of construct_finder_sql when using :join 1288 [dwlt@dwlt.net]
  • Fixed that :delete_sql in has_and_belongs_to_many associations couldn‘t access record properties 1299 [Rick Olson]
  • Fixed that clone would break when an aggregate had the same name as one of its attributes 1307 [Jeremy Kemper]
  • Changed that destroying an object will only freeze the attributes hash, which keeps the object from having attributes changed (as that wouldn‘t make sense), but allows for the querying of associations after it has been destroyed.
  • Changed the callbacks such that observers are notified before the in-object callbacks are triggered. Without this change, it wasn‘t possible to act on the whole object in something like a before_destroy observer without having the objects own callbacks (like deleting associations) called first.
  • Added option for passing an array to the find_all version of the dynamic finders and have it evaluated as an IN fragment. Example:
      # SELECT * FROM topics WHERE title IN ('First', 'Second')
  Topic.find_all_by_title(["First", "Second"])
  • Added compatibility with camelCase column names for dynamic finders 533 [Dee Zsombor]
  • Fixed extraneous comma in count() function that made it not work with joins 1156 [Jarkko Laine/Dee Zsombor]
  • Fixed incompatibility with Base#find with an array of ids that would fail when using eager loading 1186 [Alisdair McDiarmid]
  • Fixed that validate_length_of lost :on option when :within was specified 1195 [jhosteny@mac.com]
  • Added encoding and min_messages options for PostgreSQL 1205 [Shugo Maeda]. Configuration example:
      development:
    adapter: postgresql
    database: rails_development
    host: localhost
    username: postgres
    password:
    encoding: UTF8
    min_messages: ERROR
  • Fixed acts_as_list where deleting an item that was removed from the list would ruin the positioning of other list items 1197 [Jamis Buck]
  • Added validates_exclusion_of as a negative of validates_inclusion_of
  • Optimized counting of has_many associations by setting the association to empty if the count is 0 so repeated calls doesn‘t trigger database calls

*1.10.1* (20th April, 2005)

  • Fixed frivilous database queries being triggered with eager loading on empty associations and other things
  • Fixed order of loading in eager associations
  • Fixed stray comma when using eager loading and ordering together from has_many associations 1143

*1.10.0* (19th April, 2005)

  • Added eager loading of associations as a way to solve the N+1 problem more gracefully without piggy-back queries. Example:
      for post in Post.find(:all, :limit => 100)
    puts "Post:            " + post.title
    puts "Written by:      " + post.author.name
    puts "Last comment on: " + post.comments.first.created_on
  end

    This used to generate 301 database queries if all 100 posts had both author and comments. It can now be written as:

      for post in Post.find(:all, :limit => 100, :include => [ :author, :comments ])

    …and the number of database queries needed is now 1.

  • Added new unified Base.find API and deprecated the use of find_first and find_all. See the documentation for Base.find. Examples:
      Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
  Person.find(1, 5, 6, :conditions => "administrator = 1", :order => "created_on DESC")
  Person.find(:first, :order => "created_on DESC", :offset => 5)
  Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
  Person.find(:all, :offset => 10, :limit => 10)
  • Added acts_as_nested_set 1000 [wschenk]. Introduction:
      This acts provides Nested Set functionality.  Nested Set is similiar to Tree, but with
  the added feature that you can select the children and all of it's descendants with
  a single query.  A good use case for this is a threaded post system, where you want
  to display every reply to a comment without multiple selects.
  • Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [Dave Thomas]
  • Fixed PostgreSQL usage of fixtures with regards to public schemas and table names with dots 962 [gnuman1@gmail.com]
  • Fixed that fixtures were being deleted in the same order as inserts causing FK errors 890 [andrew.john.peters@gmail.com]
  • Fixed loading of fixtures in to be in the right order (or PostgreSQL would bark) 1047 [stephenh@chase3000.com]
  • Fixed page caching for non-vhost applications living underneath the root 1004 [Ben Schumacher]
  • Fixes a problem with the SQL Adapter which was resulting in IDENTITY_INSERT not being set to ON when it should be 1104 [adelle]
  • Added the option to specify the acceptance string in validates_acceptance_of 1106 [caleb@aei-tech.com]
  • Added insert_at(position) to acts_as_list 1083 [DeLynnB]
  • Removed the default order by id on has_and_belongs_to_many queries as it could kill performance on large sets (you can still specify by hand with :order)
  • Fixed that Base.silence should restore the old logger level when done, not just set it to DEBUG 1084 [yon@milliped.com]
  • Fixed boolean saving on Oracle 1093 [mparrish@pearware.org]
  • Moved build_association and create_association for has_one and belongs_to out of deprecation as they work when the association is nil unlike association.build and association.create, which require the association to be already in place 864
  • Added rollbacks of transactions if they‘re active as the dispatcher is killed gracefully (TERM signal) 1054 [Leon Bredt]
  • Added quoting of column names for fixtures 997 [jcfischer@gmail.com]
  • Fixed counter_sql when no records exist in database for PostgreSQL (would give error, not 0) 1039 [Caleb Tennis]
  • Fixed that benchmarking times for rendering included db runtimes 987 [Stefan Kaes]
  • Fixed boolean queries for t/f fields in PostgreSQL 995 [dave@cherryville.org]
  • Added that model.items.delete(child) will delete the child, not just set the foreign key to nil, if the child is dependent on the model 978 [Jeremy Kemper]
  • Fixed auto-stamping of dates (created_on/updated_on) for PostgreSQL 985 [dave@cherryville.org]
  • Fixed Base.silence/benchmark to only log if a logger has been configured 986 [Stefan Kaes]
  • Added a join parameter as the third argument to Base.find_first and as the second to Base.count 426, 988 [Stefan Kaes]
  • Fixed bug in Base#hash method that would treat records with the same string-based id as different [Dave Thomas]
  • Renamed DateHelper#distance_of_time_in_words_to_now to DateHelper#time_ago_in_words (old method name is still available as a deprecated alias)

*1.9.1* (27th March, 2005)

  • Fixed that Active Record objects with float attribute could not be cloned 808
  • Fixed that MissingSourceFile‘s wasn‘t properly detected in production mode 925 [Nicholas Seckar]
  • Fixed that :counter_cache option would look for a line_items_count column for a LineItem object instead of lineitems_count
  • Fixed that AR exists?() would explode on postgresql if the passed id did not match the PK type 900 [Scott Barron]
  • Fixed the MS SQL adapter to work with the new limit/offset approach and with binary data (still suffering from 7KB limit, though) 901 [delynnb]

*1.9.0* (22th March, 2005)

  • Added adapter independent limit clause as a two-element array with the first being the limit, the second being the offset 795 [Sam Stephenson]. Example:
      Developer.find_all nil, 'id ASC', 5      # return the first five developers
  Developer.find_all nil, 'id ASC', [3, 8] # return three developers, starting from #8 and forward

    This doesn‘t yet work with the DB2 or MS SQL adapters. Patches to make that happen are encouraged.

  • Added alias_method :to_param, :id to Base, such that Active Record objects to be used as URL parameters in Action Pack automatically 812 [Nicholas Seckar/Sam Stephenson]
  • Improved the performance of the OCI8 adapter for Oracle 723 [pilx/gjenkins]
  • Added type conversion before saving a record, so string-based values like "10.0" aren‘t left for the database to convert 820 [dave@cherryville.org]
  • Added with additional settings for working with transactional fixtures and pre-loaded test databases 865 [mindel]
  • Fixed acts_as_list to trigger remove_from_list on destroy after the fact, not before, so a unique position can be maintained 871 [Alisdair McDiarmid]
  • Added the possibility of specifying fixtures in multiple calls 816 [kim@tinker.com]
  • Added Base.exists?(id) that‘ll return true if an object of the class with the given id exists 854 [stian@grytoyr.net]
  • Added optionally allow for nil or empty strings with validates_numericality_of 801 [Sebastian Kanthak]
  • Fixed problem with using slashes in validates_format_of regular expressions 801 [Sebastian Kanthak]
  • Fixed that SQLite3 exceptions are caught and reported properly 823 [yerejm]
  • Added that all types of after_find/after_initialized callbacks are triggered if the explicit implementation is present, not only the explicit implementation itself
  • Fixed that symbols can be used on attribute assignment, like page.emails.create(:subject => data.subject, :body => data.body)

*1.8.0* (7th March, 2005)

  • Added ActiveRecord::Base.colorize_logging to control whether to use colors in logs or not (on by default)
  • Added support for timestamp with time zone in PostgreSQL 560 [Scott Barron]
  • Added MultiparameterAssignmentErrors and AttributeAssignmentError exceptions 777 [demetrius]. Documentation:
     * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the
   +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+
   objects that should be inspected to determine which attributes triggered the errors.
 * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method.
   You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
  • Fixed that postgresql adapter would fails when reading bytea fields with null value 771 [rodrigo k]
  • Added transactional fixtures that uses rollback to undo changes to fixtures instead of DELETE/INSERT — it‘s much faster. See documentation under Fixtures 760 [Jeremy Kemper]
  • Added destruction of dependent objects in has_one associations when a new assignment happens 742 [mindel]. Example:
      class Account < ActiveRecord::Base
    has_one :credit_card, :dependent => true
  end
  class CreditCard < ActiveRecord::Base
    belongs_to :account
  end

  account.credit_card # => returns existing credit card, lets say id = 12
  account.credit_card = CreditCard.create("number" => "123")
  account.save # => CC with id = 12 is destroyed
  • Added validates_numericality_of 716 [Sebastian Kanthak/Chris McGrath]. Docuemntation:
      Validates whether the value of the specified attribute is numeric by trying to convert it to
  a float with Kernel.Float (if <tt>integer</tt> is false) or applying it to the regular expression
  <tt>/^[\+\-]?\d+$/</tt> (if <tt>integer</tt> is set to true).

    class Person < ActiveRecord::Base
      validates_numericality_of :value, :on => :create
    end

  Configuration options:
  * <tt>message</tt> - A custom error message (default is: "is not a number")
  * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
  * <tt>only_integer</tt> Specifies whether the value has to be an integer, e.g. an integral value (default is false)
  • Fixed that HasManyAssociation#count was using :finder_sql rather than :counter_sql if it was available 445 [Scott Barron]
  • Added better defaults for composed_of, so statements like composed_of :time_zone, :mapping => %w( time_zone time_zone ) can be written without the mapping part (it‘s now assumed)
  • Added MacroReflection#macro which will return a symbol describing the macro used (like :composed_of or :has_many) 718, 248 [james@slashetc.com]

*1.7.0* (24th February, 2005)

  • Changed the auto-timestamping feature to use ActiveRecord::Base.default_timezone instead of entertaining the parallel ActiveRecord::Base.timestamps_gmt method. The latter is now deprecated and will throw a warning on use (but still work) 710 [Jamis Buck]
  • Added a OCI8-based Oracle adapter that has been verified to work with Oracle 8 and 9 629 [Graham Jenkins]. Usage notes:
      1.  Key generation uses a sequence "rails_sequence" for all tables. (I couldn't find a simple
      and safe way of passing table-specific sequence information to the adapter.)
  2.  Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to
      resort to some hacks to get data converted to Date or Time in Ruby.
      If the column_name ends in _at (like created_at, updated_at) it's created as a Ruby Time. Else if the
      hours/minutes/seconds are 0, I make it a Ruby Date. Else it's a Ruby Time.
      This is nasty - but if you use Duck Typing you'll probably not care very much.
      In 9i it's tempting to map DATE to Date and TIMESTAMP to Time but I don't think that is
      valid - too many databases use DATE for both.
      Timezones and sub-second precision on timestamps are not supported.
  3.  Default values that are functions (such as "SYSDATE") are not supported. This is a
      restriction of the way active record supports default values.
  4.  Referential integrity constraints are not fully supported. Under at least
      some circumstances, active record appears to delete parent and child records out of
      sequence and out of transaction scope. (Or this may just be a problem of test setup.)

    The OCI8 driver can be retrieved from rubyforge.org/projects/ruby-oci8/

  • Added option :schema_order to the PostgreSQL adapter to support the use of multiple schemas per database 697 [YuriSchimke]
  • Optimized the SQL used to generate has_and_belongs_to_many queries by listing the join table first 693 [yerejm]
  • Fixed that when using validation macros with a custom message, if you happened to use single quotes in the message string you would get a parsing error 657 [tonka]
  • Fixed that Active Record would throw Broken Pipe errors with FCGI when the MySQL connection timed out instead of reconnecting 428 [Nicholas Seckar]
  • Added options to specify an SSL connection for MySQL. Define the following attributes in the connection config (config/database.yml in Rails) to use it: sslkey, sslcert, sslca, sslcapath, sslcipher. To use SSL with no client certs, just set :sslca = ’/dev/null’. dev.mysql.com/doc/mysql/en/secure-connections.html 604 [daniel@nightrunner.com]
  • Added automatic dropping/creating of test tables for running the unit tests on all databases 587 [adelle@bullet.net.au]
  • Fixed that find_by_* would fail when column names had numbers 670 [demetrius]
  • Fixed the SQL Server adapter on a bunch of issues 667 [DeLynn]
      1. Created a new columns method that is much cleaner.
  2. Corrected a problem with the select and select_all methods
     that didn't account for the LIMIT clause being passed into raw SQL statements.
  3. Implemented the string_to_time method in order to create proper instances of the time class.
  4. Added logic to the simplified_type method that allows the database to specify the scale of float data.
  5. Adjusted the quote_column_name to account for the fact that MS SQL is bothered by a forward slash in the data string.
  • Fixed that the dynamic finder like find_all_by_something_boolean(false) didn‘t work 649 [lmarlow]
  • Added validates_each that validates each specified attribute against a block 610 [Jeremy Kemper]. Example:
      class Person < ActiveRecord::Base
    validates_each :first_name, :last_name do |record, attr|
      record.errors.add attr, 'starts with z.' if attr[0] == ?z
    end
  end
  • Added :allow_nil as an explicit option for validates_length_of, so unless that‘s set to true having the attribute as nil will also return an error if a range is specified as :within 610 [Jeremy Kemper]
  • Added that validates_* now accept blocks to perform validations 618 [Tim Bates]. Example:
      class Person < ActiveRecord::Base
    validate { |person| person.errors.add("title", "will never be valid") if SHOULD_NEVER_BE_VALID }
  end
  • Addded validation for validate all the associated objects before declaring failure with validates_associated 618 [Tim Bates]
  • Added keyword-style approach to defining the custom relational bindings 545 [Jamis Buck]. Example:
      class Project < ActiveRecord::Base
    primary_key "sysid"
    table_name "XYZ_PROJECT"
    inheritance_column { original_inheritance_column + "_id" }
  end
  • Fixed Base#clone for use with PostgreSQL 565 [hanson@surgery.wisc.edu]

*1.6.0* (January 25th, 2005)

  • Added that has_many association build and create methods can take arrays of record data like Base#create and Base#build to build/create multiple records at once.
  • Added that Base#delete and Base#destroy both can take an array of ids to delete/destroy 336
  • Added the option of supplying an array of attributes to Base#create, so that multiple records can be created at once.
  • Added the option of supplying an array of ids and attributes to Base#update, so that multiple records can be updated at once (inspired by 526/Duane Johnson). Example
      people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
  Person.update(people.keys, people.values)
  • Added ActiveRecord::Base.timestamps_gmt that can be set to true to make the automated timestamping use GMT instead of local time 520 [Scott Baron]
  • Added that update_all calls sanitize_sql on its updates argument, so stuff like MyRecord.update_all([‘time = ?’, Time.now]) works 519 [notahat]
  • Fixed that the dynamic finders didn‘t treat nil as a "IS NULL" but rather "= NULL" case 515 [Demetrius]
  • Added bind-named arrays for interpolating a group of ids or strings in conditions 528 [Jeremy Kemper]
  • Added that has_and_belongs_to_many associations with additional attributes also can be created between unsaved objects and only committed to the database when Base#save is called on the associator 524 [Eric Anderson]
  • Fixed that records fetched with piggy-back attributes or through rich has_and_belongs_to_many associations couldn‘t be saved due to the extra attributes not part of the table 522 [Eric Anderson]
  • Added mass-assignment protection for the inheritance column — regardless of a custom column is used or not
  • Fixed that association proxies would fail === tests like PremiumSubscription === @account.subscription
  • Fixed that column aliases didn‘t work as expected with the new MySql411 driver 507 [Demetrius]
  • Fixed that find_all would produce invalid sql when called sequentialy 490 [Scott Baron]

*1.5.1* (January 18th, 2005)

  • Fixed that the belongs_to and has_one proxy would fail a test like ‘if project.manager’ — this unfortunately also means that you can‘t call methods like project.manager.build unless there already is a manager on the project 492 [Tim Bates]
  • Fixed that the Ruby/MySQL adapter wouldn‘t connect if the password was empty 503 [Pelle]

*1.5.0* (January 17th, 2005)

  • Fixed that unit tests for MySQL are now run as the "rails" user instead of root 455 [Eric Hodel]
  • Added validates_associated that enables validation of objects in an unsaved association 398 [Tim Bates]. Example:
      class Book < ActiveRecord::Base
    has_many :pages
    belongs_to :library

    validates_associated :pages, :library
  end
  • Added support for associating unsaved objects 402 [Tim Bates]. Rules that govern this addition:
      == Unsaved objects and associations

  You can manipulate objects and associations before they are saved to the database, but there is some special behaviour you should be
  aware of, mostly involving the saving of associated objects.

  === One-to-one associations

  * Assigning an object to a has_one association automatically saves that object, and the object being replaced (if there is one), in
    order to update their primary keys - except if the parent object is unsaved (new_record? == true).
  * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns false and the assignment
    is cancelled.
  * If you wish to assign an object to a has_one association without saving it, use the #association.build method (documented below).
  * Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does
    not save the parent either.

  === Collections

  * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object
    (the owner of the collection) is not yet stored in the database.
  * If saving any of the objects being added to a collection (via #push or similar) fails, then #push returns false.
  * You can add an object to a collection without automatically saving it by using the #collection.build method (documented below).
  * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved.
  • Added replace to associations, so you can do project.manager.replace(new_manager) or project.milestones.replace(new_milestones) 402 [Tim Bates]
  • Added build and create methods to has_one and belongs_to associations, so you can now do project.manager.build(attributes) 402 [Tim Bates]
  • Added that if a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last. 402 [Tim Bates]
  • Fixed that Base#== wouldn‘t work for multiple references to the same unsaved object 402 [Tim Bates]
  • Fixed binary support for PostgreSQL 444 [alex@byzantine.no]
  • Added a differenciation between AssociationCollection#size and -length. Now AssociationCollection#size returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn‘t been loaded and calling collection.size if it has. If it‘s more likely than not that the collection does have a size larger than zero and you need to fetch that collection afterwards, it‘ll take one less SELECT query if you use length.
  • Added Base#attributes that returns a hash of all the attributes with their names as keys and clones of their objects as values 433 [atyp.de]
  • Fixed that foreign keys named the same as the association would cause stack overflow 437 [Eric Anderson]
  • Fixed default scope of acts_as_list from "1" to "1 = 1", so it‘ll work in PostgreSQL (among other places) 427 [Alexey]
  • Added Base#reload that reloads the attributes of an object from the database 422 [Andreas Schwarz]
  • Added SQLite3 compatibility through the sqlite3-ruby adapter by Jamis Buck 381 [Jeremy Kemper]
  • Added support for the new protocol spoken by MySQL 4.1.1+ servers for the Ruby/MySQL adapter that ships with Rails 440 [Matt Mower]
  • Added that Observers can use the observes class method instead of overwriting self.observed_class().
      Before:
    class ListSweeper < ActiveRecord::Base
      def self.observed_class() [ List, Item ]
    end

  After:
    class ListSweeper < ActiveRecord::Base
      observes List, Item
    end
  • Fixed that conditions in has_many and has_and_belongs_to_many should be interpolated just like the finder_sql is
  • Fixed Base#update_attribute to be indifferent to whether a string or symbol is used to describe the name
  • Added Base#toggle(attribute) and Base#toggle!(attribute) that makes it easier to flip a switch or flag.
      Before: topic.update_attribute(:approved, !approved?)
  After : topic.toggle!(:approved)
  • Added Base#increment!(attribute) and Base#decrement!(attribute) that also saves the records. Example:
      page.views # => 1
  page.increment!(:views) # executes an UPDATE statement
  page.views # => 2

  page.increment(:views).increment!(:views)
  page.views # => 4
  • Added Base#increment(attribute) and Base#decrement(attribute) that encapsulates the += 1 and -= 1 patterns.

*1.14.2* (April 9th, 2005)

  • Fixed calculations for the Oracle Adapter (closes 4626) [Michael Schoen]

*1.14.1* (April 6th, 2006)

  • Fix type_name_with_module to handle type names that begin with ’::’. Closes 4614. [Nicholas Seckar]
  • Fixed that that multiparameter assignment doesn‘t work with aggregations (closes 4620) [Lars Pind]
  • Enable Limit/Offset in Calculations (closes 4558) [lmarlow]
  • Fixed that loading including associations returns all results if Load IDs For Limited Eager Loading returns none (closes 4528) [Rick Olson]
  • Fixed HasManyAssociation#find bugs when :finder_sql is set 4600 [lagroue@free.fr]
  • Allow AR::Base#respond_to? to behave when @attributes is nil [Ryan Davis]
  • Support eager includes when going through a polymorphic has_many association. [Rick Olson]
  • Added support for eagerly including polymorphic has_one associations. (closes 4525) [Rick Olson]
      class Post < ActiveRecord::Base
    has_one :tagging, :as => :taggable
  end

  Post.find :all, :include => :tagging
  • Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick Olson]
  • Added support for going through a polymorphic has_many association: (closes 4401) [Rick Olson]
      class PhotoCollection < ActiveRecord::Base
    has_many :photos, :as => :photographic
    belongs_to :firm
  end

  class Firm < ActiveRecord::Base
    has_many :photo_collections
    has_many :photos, :through => :photo_collections
  end
  • Multiple fixes and optimizations in PostgreSQL adapter, allowing ruby-postgres gem to work properly. [ruben.nine@gmail.com]
  • Fixed that AssociationCollection#delete_all should work even if the records of the association are not loaded yet. [Florian Weber]
  • Changed those private ActiveRecord methods to take optional third argument :auto instead of nil for performance optimizations. (closes 4456) [Stefan]
  • Private ActiveRecord methods add_limit!, add_joins!, and add_conditions! take an OPTIONAL third argument ‘scope’ (closes 4456) [Rick Olson]
  • DEPRECATED: Using additional attributes on has_and_belongs_to_many associations. Instead upgrade your association to be a real join model [David Heinemeier Hansson]
  • Fixed that records returned from has_and_belongs_to_many associations with additional attributes should be marked as read only (fixes 4512) [David Heinemeier Hansson]
  • Do not implicitly mark recordss of has_many :through as readonly but do mark habtm records as readonly (eventually only on join tables without rich attributes). [Marcel Mollina Jr.]
  • Fixed broken OCIAdapter 4457 [Michael Schoen]

*1.14.0* (March 27th, 2006)

  • Replace ‘rescue Object’ with a finer grained rescue. Closes 4431. [Nicholas Seckar]
  • Fixed eager loading so that an aliased table cannot clash with a has_and_belongs_to_many join table [Rick Olson]
  • Add support for :include to with_scope [andrew@redlinesoftware.com]
  • Support the use of public synonyms with the Oracle adapter; required ruby-oci8 v0.1.14 4390 [Michael Schoen]
  • Change periods (.) in table aliases to _‘s. Closes 4251 [jeff@ministrycentered.com]
  • Changed has_and_belongs_to_many join to INNER JOIN for Mysql 3.23.x. Closes 4348 [Rick Olson]
  • Fixed issue that kept :select options from being scoped [Rick Olson]
  • Fixed db_schema_import when binary types are present 3101 [David Heinemeier Hansson]
  • Fixed that MySQL enums should always be returned as strings 3501 [David Heinemeier Hansson]
  • Change has_many :through to use the :source option to specify the source association. :class_name is now ignored. [Rick Olson]
      class Connection < ActiveRecord::Base
    belongs_to :user
    belongs_to :channel
  end

  class Channel < ActiveRecord::Base
    has_many :connections
    has_many :contacts, :through => :connections, :class_name => 'User' # OLD
    has_many :contacts, :through => :connections, :source => :user      # NEW
  end
  • Fixed DB2 adapter so nullable columns will be determines correctly now and quotes from column default values will be removed 4350 [contact@maik-schmidt.de]
  • Allow overriding of find parameters in scoped has_many :through calls [Rick Olson]

    In this example, :include => false disables the default eager association from loading. :select changes the standard select clause. :joins specifies a join that is added to the end of the has_many :through query.

      class Post < ActiveRecord::Base
    has_many :tags, :through => :taggings, :include => :tagging do
      def add_joins_and_select
        find :all, :select => 'tags.*, authors.id as author_id', :include => false,
          :joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
      end
    end
  end
  • Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [David Heinemeier Hansson]
  • Don‘t classify the has_one class when eager loading, it is already singular. Add tests. (closes 4117) [Jonathan Viney]
  • Quit ignoring default :include options in has_many :through calls [Mark James]
  • Allow has_many :through associations to find the source association by setting a custom class (closes 4307) [Jonathan Viney]
  • Eager Loading support added for has_many :through => :has_many associations (see below). [Rick Olson]
  • Allow has_many :through to work on has_many associations (closes 3864) [sco@scottraymond.net] Example:
      class Firm < ActiveRecord::Base
    has_many :clients
    has_many :invoices, :through => :clients
  end

  class Client < ActiveRecord::Base
    belongs_to :firm
    has_many   :invoices
  end

  class Invoice < ActiveRecord::Base
    belongs_to :client
  end
  • Raise error when trying to select many polymorphic objects with has_many :through or :include (closes 4226) [Josh Susser]
  • Fixed has_many :through to include :conditions set on the :through association. closes 4020 [Jonathan Viney]
  • Fix that has_many :through honors the foreign key set by the belongs_to association in the join model (closes 4259) [andylien@gmail.com / Rick Olson]
  • SQL Server adapter gets some love 4298 [Ryan Tomayko]
  • Added OpenBase database adapter that builds on top of the www.spice-of-life.net/ruby-openbase/ driver. All functionality except LIMIT/OFFSET is supported 3528 [derrickspell@cdmplus.com]
  • Rework table aliasing to account for truncated table aliases. Add smarter table aliasing when doing eager loading of STI associations. This allows you to use the association name in the order/where clause. [Jonathan Viney / Rick Olson] 4108 Example (SpecialComment is using STI):
      Author.find(:all, :include => { :posts => :special_comments }, :order => 'special_comments.body')
  • Add AbstractAdapter#table_alias_for to create table aliases according to the rules of the current adapter. [Rick Olson]
  • Provide access to the underlying database connection through Adapter#raw_connection. Enables the use of db-specific methods without complicating the adapters. 2090 [Michael Koziarski]
  • Remove broken attempts at handling columns with a default of ‘now()’ in the postgresql adapter. 2257 [Michael Koziarski]
  • Added connection#current_database that‘ll return of the current database (only works in MySQL, SQL Server, and Oracle so far — please help implement for the rest of the adapters) 3663 [Tom Ward]
  • Fixed that Migration#execute would have the table name prefix appended to its query 4110 [mark.imbriaco@pobox.com]
  • Make all tinyint(1) variants act like boolean in mysql (tinyint(1) unsigned, etc.) [Jamis Buck]
  • Use association‘s :conditions when eager loading. [Jeremy Evans] 4144
  • Alias the has_and_belongs_to_many join table on eager includes. 4106 [Jeremy Evans]

    This statement would normally error because the projects_developers table is joined twice, and therefore joined_on would be ambiguous.

      Developer.find(:all, :include => {:projects => :developers}, :conditions => 'join_project_developers.joined_on IS NOT NULL')
  • Oracle adapter gets some love 4230 [Michael Schoen]
      * Changes :text to CLOB rather than BLOB [Moses Hohman]
  * Fixes an issue with nil numeric length/scales (several)
  * Implements support for XMLTYPE columns [wilig / Kubo Takehiro]
  * Tweaks a unit test to get it all green again
  * Adds support for #current_database
  • Added Base.abstract_class? that marks which classes are not part of the Active Record hierarchy 3704 [Rick Olson]
      class CachedModel < ActiveRecord::Base
    self.abstract_class = true
  end

  class Post < CachedModel
  end

  CachedModel.abstract_class?
  => true

  Post.abstract_class?
  => false

  Post.base_class
  => Post

  Post.table_name
  => 'posts'
  • Allow :dependent options to be used with polymorphic joins. 3820 [Rick Olson]
      class Foo < ActiveRecord::Base
    has_many :attachments, :as => :attachable, :dependent => :delete_all
  end
  • Nicer error message on has_many :through when :through reflection can not be found. 4042 [court3nay]
  • Upgrade to Transaction::Simple 1.3 [Jamis Buck]
  • Catch FixtureClassNotFound when using instantiated fixtures on a fixture that has no ActiveRecord model [Rick Olson]
  • Allow ordering of calculated results and/or grouped fields in calculations [solo@gatelys.com]
  • Make ActiveRecord::Base#save! return true instead of nil on success. 4173 [johan@johansorensen.com]
  • Dynamically set allow_concurrency. 4044 [Stefan Kaes]
  • Added Base#to_xml that‘ll turn the current record into a XML representation [David Heinemeier Hansson]. Example:
      topic.to_xml

    …returns:

      <?xml version="1.0" encoding="UTF-8"?>
  <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <id type="integer">1</id>
    <approved type="boolean">false</approved>
    <replies-count type="integer">0</replies-count>
    <bonus-time type="datetime">2000-01-01 08:28:00</bonus-time>
    <written-on type="datetime">2003-07-16 09:28:00</written-on>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

    …and you can configure with:

      topic.to_xml(:skip_instruct => true, :except => [ :id, bonus_time, :written_on, replies_count ])

    …that‘ll return:

      <topic>
    <title>The First Topic</title>
    <author-name>David</author-name>
    <approved type="boolean">false</approved>
    <content>Have a nice day</content>
    <author-email-address>david@loudthinking.com</author-email-address>
    <parent-id></parent-id>
    <last-read type="date">2004-04-15</last-read>
  </topic>

    You can even do load first-level associations as part of the document:

      firm.to_xml :include => [ :account, :clients ]

    …that‘ll return something like:

      <?xml version="1.0" encoding="UTF-8"?>
  <firm>
    <id type="integer">1</id>
    <rating type="integer">1</rating>
    <name>37signals</name>
    <clients>
      <client>
        <rating type="integer">1</rating>
        <name>Summit</name>
      </client>
      <client>
        <rating type="integer">1</rating>
        <name>Microsoft</name>
      </client>
    </clients>
    <account>
      <id type="integer">1</id>
      <credit-limit type="integer">50</credit-limit>
    </account>
  </firm>
  • Allow :counter_cache to take a column name for custom counter cache columns [Jamis Buck]
  • Documentation fixes for :dependent [robby@planetargon.com]
  • Stop the MySQL adapter crashing when views are present. 3782 [Jonathan Viney]
  • Don‘t classify the belongs_to class, it is already singular 4117 [keithm@infused.org]
  • Allow set_fixture_class to take Classes instead of strings for a class in a module. Raise FixtureClassNotFound if a fixture can‘t load. [Rick Olson]
  • Fix quoting of inheritance column for STI eager loading 4098 [Jonathan Viney <jonathan@bluewire.net.nz>]
  • Added smarter table aliasing for eager associations for multiple self joins 3580 [Rick Olson]
      * The first time a table is referenced in a join, no alias is used.
  * After that, the parent class name and the reflection name are used.

      Tree.find(:all, :include => :children) # LEFT OUTER JOIN trees AS tree_children ...

  * Any additional join references get a numerical suffix like '_2', '_3', etc.
  • Fixed eager loading problems with single-table inheritance 3580 [Rick Olson]. Post.find(:all, :include => :special_comments) now returns all posts, and any special comments that the posts may have. And made STI work with has_many :through and polymorphic belongs_to.
  • Added cascading eager loading that allows for queries like Author.find(:all, :include=> { :posts=> :comments }), which will fetch all authors, their posts, and the comments belonging to those posts in a single query (using LEFT OUTER JOIN) 3913 [anna@wota.jp]. Examples:
      # cascaded in two levels
  >> Author.find(:all, :include=>{:posts=>:comments})
  => authors
       +- posts
            +- comments

  # cascaded in two levels and normal association
  >> Author.find(:all, :include=>[{:posts=>:comments}, :categorizations])
  => authors
       +- posts
            +- comments
       +- categorizations

  # cascaded in two levels with two has_many associations
  >> Author.find(:all, :include=>{:posts=>[:comments, :categorizations]})
  => authors
       +- posts
            +- comments
            +- categorizations

  # cascaded in three levels
  >> Company.find(:all, :include=>{:groups=>{:members=>{:favorites}}})
  => companies
       +- groups
            +- members
                 +- favorites
  • Make counter cache work when replacing an association 3245 [eugenol@gmail.com]
  • Make migrations verbose [Jamis Buck]
  • Make counter_cache work with polymorphic belongs_to [Jamis Buck]
  • Fixed that calling HasOneProxy#build_model repeatedly would cause saving to happen 4058 [anna@wota.jp]
  • Added Sybase database adapter that relies on the Sybase Open Client bindings (see raa.ruby-lang.org/project/sybase-ctlib) 3765 [John Sheets]. It‘s almost completely Active Record compliant (including migrations), but has the following caveats:
      * Does not support DATE SQL column types; use DATETIME instead.
  * Date columns on HABTM join tables are returned as String, not Time.
  * Insertions are potentially broken for :polymorphic join tables
  * BLOB column access not yet fully supported
  • Clear stale, cached connections left behind by defunct threads. [Jeremy Kemper]
  • CHANGED DEFAULT: set ActiveRecord::Base.allow_concurrency to false. Most AR usage is in single-threaded applications. [Jeremy Kemper]
  • Renamed the "oci" adapter to "oracle", but kept the old name as an alias 4017 [Michael Schoen]
  • Fixed that Base.save should always return false if the save didn‘t succeed, including if it has halted by before_save‘s 1861, 2477 [David Heinemeier Hansson]
  • Speed up class -> connection caching and stale connection verification. 3979 [Stefan Kaes]
  • Add set_fixture_class to allow the use of table name accessors with models which use set_table_name. [Kevin Clark]
  • Added that fixtures to placed in subdirectories of the main fixture files are also loaded 3937 [dblack@wobblini.net]
  • Define attribute query methods to avoid method_missing calls. 3677 [Jonathan Viney]
  • ActiveRecord::Base.remove_connection explicitly closes database connections and doesn‘t corrupt the connection cache. Introducing the disconnect! instance method for the PostgreSQL, MySQL, and SQL Server adapters; implementations for the others are welcome. 3591 [Simon Stapleton, Tom Ward]
  • Added support for nested scopes 3407 [anna@wota.jp]. Examples:
      Developer.with_scope(:find => { :conditions => "salary > 10000", :limit => 10 }) do
    Developer.find(:all)     # => SELECT * FROM developers WHERE (salary > 10000) LIMIT 10

    # inner rule is used. (all previous parameters are ignored)
    Developer.with_exclusive_scope(:find => { :conditions => "name = 'Jamis'" }) do
      Developer.find(:all)   # => SELECT * FROM developers WHERE (name = 'Jamis')
    end

    # parameters are merged
    Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
      Developer.find(:all)   # => SELECT * FROM developers WHERE (( salary > 10000 ) AND ( name = 'Jamis' )) LIMIT 10
    end
  end
  • Fixed db2 connection with empty user_name and auth options 3622 [phurley@gmail.com]
  • Fixed validates_length_of to work on UTF-8 strings by using characters instead of bytes 3699 [Masao Mutoh]
  • Fixed that reflections would bleed across class boundaries in single-table inheritance setups 3796 [Lars Pind]
  • Added calculations: Base.count, Base.average, Base.sum, Base.minimum, Base.maxmium, and the generic Base.calculate. All can be used with :group and :having. Calculations and statitics need no longer require custom SQL. 3958 [Rick Olson]. Examples:
      Person.average :age
  Person.minimum :age
  Person.maximum :age
  Person.sum :salary, :group => :last_name
  • Renamed Errors#count to Errors#size but kept an alias for the old name (and included an alias for length too) 3920 [Luke Redpath]
  • Reflections don‘t attempt to resolve module nesting of association classes. Simplify type computation. [Jeremy Kemper]
  • Improved the Oracle OCI Adapter with better performance for column reflection (from 3210), fixes to migrations (from 3476 and 3742), tweaks to unit tests (from 3610), and improved documentation (from 2446) 3879 [Aggregated by schoenm@earthlink.net]
  • Fixed that the schema_info table used by ActiveRecord::Schema.define should respect table pre- and suffixes 3834 [rubyonrails@atyp.de]
  • Added :select option to Base.count that‘ll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT 3839 [Stefan Kaes]
  • Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva]
  • Allow :include to be used with has_many :through associations 3611 [Michael Schoen]
  • PostgreSQL: smarter schema dumps using pk_and_sequence_for(table). 2920 [Blair Zajac]
  • SQLServer: more compatible limit/offset emulation. 3779 [Tom Ward]
  • Polymorphic join support for has_one associations (has_one :foo, :as => :bar) 3785 [Rick Olson]
  • PostgreSQL: correctly parse negative integer column defaults. 3776 [bellis@deepthought.org]
  • Fix problems with count when used with :include [Jeremy Hopple and Kevin Clark]
  • ActiveRecord::RecordInvalid now states which validations failed in its default error message [Tobias Lütke]
  • Using AssociationCollection#build with arrays of hashes should call build, not create [David Heinemeier Hansson]
  • Remove definition of reloadable? from ActiveRecord::Base to make way for new Reloadable code. [Nicholas Seckar]
  • Fixed schema handling for DB2 adapter that didn‘t work: an initial schema could be set, but it wasn‘t used when getting tables and indexes 3678 [Maik Schmidt]
  • Support the :column option for remove_index with the PostgreSQL adapter. 3661 [Shugo Maeda]
  • Add documentation for add_index and remove_index. 3600 [Manfred Stienstra <m.stienstra@fngtps.com>]
  • If the OCI library is not available, raise an exception indicating as much. 3593 [Michael Schoen]
  • Add explicit :order in finder tests as postgresql orders results differently by default. 3577. [Rick Olson]
  • Make dynamic finders honor additional passed in :conditions. 3569 [Oleg Pudeyev <pudeyo@rpi.edu>, Marcel Molina Jr.]
  • Show a meaningful error when the DB2 adapter cannot be loaded due to missing dependencies. [Nicholas Seckar]
  • Make .count work for has_many associations with multi line finder sql [Michael Schoen]
  • Add AR::Base.base_class for querying the ancestor AR::Base subclass [Jamis Buck]
  • Allow configuration of the column used for optimistic locking [wilsonb@gmail.com]
  • Don‘t hardcode ‘id’ in acts as list. [ror@philippeapril.com]
  • Fix date errors for SQLServer in association tests. 3406 [Kevin Clark]
  • Escape database name in MySQL adapter when creating and dropping databases. 3409 [anna@wota.jp]
  • Disambiguate table names for columns in validates_uniquness_of‘s WHERE clause. 3423 [alex.borovsky@gmail.com]
  • .with_scope imposed create parameters now bypass attr_protected [Tobias Lütke]
  • Don‘t raise an exception when there are more keys than there are named bind variables when sanitizing conditions. [Marcel Molina Jr.]
  • Multiple enhancements and adjustments to DB2 adaptor. 3377 [contact@maik-schmidt.de]
  • Sanitize scoped conditions. [Marcel Molina Jr.]
  • Added option to Base.reflection_of_all_associations to specify a specific association to scope the call. For example Base.reflection_of_all_associations(:has_many) [David Heinemeier Hansson]
  • Added ActiveRecord::SchemaDumper.ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [Tobias Lütke]
  • SchemaDumper now doesn‘t fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [Tobias Lütke]
  • Fixed that saving a model with multiple habtm associations would only save the first one. 3244 [yanowitz-rubyonrails@quantumfoam.org, Florian Weber]
  • Fix change_column to work with PostgreSQL 7.x and 8.x. 3141 [wejn@box.cz, Rick Olson, Scott Barron]
  • removed :piggyback in favor of just allowing :select on :through associations. [Tobias Lütke]
  • made method missing delegation to class methods on relation target work on :through associations. [Tobias Lütke]
  • made .find() work on :through relations. [Tobias Lütke]
  • Fix typo in association docs. 3296. [Blair Zajac]
  • Fixed :through relations when using STI inherited classes would use the inherited class‘s name as foreign key on the join model [Tobias Lütke]

*1.13.2* (December 13th, 2005)

  • Become part of Rails 1.0
  • MySQL: allow encoding option for mysql.rb driver. [Jeremy Kemper]
  • Added option inheritance for find calls on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]. Example:
      class Post
    has_many :recent_comments, :class_name => "Comment", :limit => 10, :include => :author
  end

  post.recent_comments.find(:all) # Uses LIMIT 10 and includes authors
  post.recent_comments.find(:all, :limit => nil) # Uses no limit but include authors
  post.recent_comments.find(:all, :limit => nil, :include => nil) # Uses no limit and doesn't include authors
  • Added option to specify :group, :limit, :offset, and :select options from find on has_and_belongs_to_many and has_many assosociations [David Heinemeier Hansson]
  • MySQL: fixes for the bundled mysql.rb driver. 3160 [Justin Forder]
  • SQLServer: fix obscure optimistic locking bug. 3068 [kajism@yahoo.com]
  • SQLServer: support uniqueidentifier columns. 2930 [keithm@infused.org]
  • SQLServer: cope with tables names qualified by owner. 3067 [jeff@ministrycentered.com]
  • SQLServer: cope with columns with "desc" in the name. 1950 [Ron Lusk, Ryan Tomayko]
  • SQLServer: cope with primary keys with "select" in the name. 3057 [rdifrango@captechventures.com]
  • Oracle: active? performs a select instead of a commit. 3133 [Michael Schoen]
  • MySQL: more robust test for nullified result hashes. 3124 [Stefan Kaes]
  • Reloading an instance refreshes its aggregations as well as its associations. 3024 [François Beausoleil]
  • Fixed that using :include together with :conditions array in Base.find would cause NoMethodError 2887 [Paul Hammmond]
  • PostgreSQL: more robust sequence name discovery. 3087 [Rick Olson]
  • Oracle: use syntax compatible with Oracle 8. 3131 [Michael Schoen]
  • MySQL: work around ruby-mysql/mysql-ruby inconsistency with mysql.stat. Eliminate usage of mysql.ping because it doesn‘t guarantee reconnect. Explicitly close and reopen the connection instead. [Jeremy Kemper]
  • Added preliminary support for polymorphic associations [David Heinemeier Hansson]
  • Added preliminary support for join models [David Heinemeier Hansson]
  • Allow validate_uniqueness_of to be scoped by more than just one column. 1559. [jeremy@jthopple.com, Marcel Molina Jr.]
  • Firebird: active? and reconnect! methods for handling stale connections. 428 [Ken Kunz <kennethkunz@gmail.com>]
  • Firebird: updated for FireRuby 0.4.0. 3009 [Ken Kunz <kennethkunz@gmail.com>]
  • MySQL and PostgreSQL: active? compatibility with the pure-Ruby driver. 428 [Jeremy Kemper]
  • Oracle: active? check pings the database rather than testing the last command status. 428 [Michael Schoen]
  • SQLServer: resolve column aliasing/quoting collision when using limit or offset in an eager find. 2974 [kajism@yahoo.com]
  • Reloading a model doesn‘t lose track of its connection. 2996 [junk@miriamtech.com, Jeremy Kemper]
  • Fixed bug where using update_attribute after pushing a record to a habtm association of the object caused duplicate rows in the join table. 2888 [colman@rominato.com, Florian Weber, Michael Schoen]
  • MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwise, the connection ‘loses’ its settings if it times out and is reconnected. 2978 [Shugo Maeda]
  • has_and_belongs_to_many: use JOIN instead of LEFT JOIN. [Jeremy Kemper]
  • MySQL: introduce :encoding option to specify the character set for client, connection, and results. Only available for MySQL 4.1 and later with the mysql-ruby driver. Do SHOW CHARACTER SET in mysql client to see available encodings. 2975 [Shugo Maeda]
  • Add tasks to create, drop and rebuild the MySQL and PostgreSQL test databases. [Marcel Molina Jr.]
  • Correct boolean handling in generated reader methods. 2945 [Don Park, Stefan Kaes]
  • Don‘t generate read methods for columns whose names are not valid ruby method names. 2946 [Stefan Kaes]
  • Document :force option to create_table. 2921 [Blair Zajac <blair@orcaware.com>]
  • Don‘t add the same conditions twice in has_one finder sql. 2916 [Jeremy Evans]
  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]
  • Introducing the Firebird adapter. Quote columns and use attribute_condition more consistently. Setup guide: wiki.rubyonrails.com/rails/pages/Firebird+Adapter 1874 [Ken Kunz <kennethkunz@gmail.com>]
  • SQLServer: active? and reconnect! methods for handling stale connections. 428 [kajism@yahoo.com, Tom Ward <tom@popdog.net>]
  • Associations handle case-equality more consistently: item.parts.is_a?(Array) and item.parts === Array. 1345 [MarkusQ@reality.com]
  • SQLServer: insert uses given primary key value if not nil rather than SELECT @@IDENTITY. 2866 [kajism@yahoo.com, Tom Ward <tom@popdog.net>]
  • Oracle: active? and reconnect! methods for handling stale connections. Optionally retry queries after reconnect. 428 [Michael Schoen <schoenm@earthlink.net>]
  • Correct documentation for Base.delete_all. 1568 [Newhydra]
  • Oracle: test case for column default parsing. 2788 [Michael Schoen <schoenm@earthlink.net>]
  • Update documentation for Migrations. 2861 [Tom Werner <tom@cube6media.com>]
  • When AbstractAdapter#log rescues an exception, attempt to detect and reconnect to an inactive database connection. Connection adapter must respond to the active? and reconnect! instance methods. Initial support for PostgreSQL, MySQL, and SQLite. Make certain that all statements which may need reconnection are performed within a logged block: for example, this means no avoiding log(sql, name) { } if @logger.nil? 428 [Jeremy Kemper]
  • Oracle: Much faster column reflection. 2848 [Michael Schoen <schoenm@earthlink.net>]
  • Base.reset_sequence_name analogous to reset_table_name (mostly useful for testing). Base.define_attr_method allows nil values. [Jeremy Kemper]
  • PostgreSQL: smarter sequence name defaults, stricter last_insert_id, warn on pk without sequence. [Jeremy Kemper]
  • PostgreSQL: correctly discover custom primary key sequences. 2594 [Blair Zajac <blair@orcaware.com>, meadow.nnick@gmail.com, Jeremy Kemper]
  • SQLServer: don‘t report limits for unsupported field types. 2835 [Ryan Tomayko]
  • Include the Enumerable module in ActiveRecord::Errors. [Rick Bradley <rick@rickbradley.com>]
  • Add :group option, correspond to GROUP BY, to the find method and to the has_many association. 2818 [rubyonrails@atyp.de]
  • Don‘t cast nil or empty strings to a dummy date. 2789 [Rick Bradley <rick@rickbradley.com>]
  • acts_as_list plays nicely with inheritance by remembering the class which declared it. 2811 [rephorm@rephorm.com]
  • Fix sqlite adaptor‘s detection of missing dbfile or database declaration. [Nicholas Seckar]
  • Fixed acts_as_list for definitions without an explicit :order 2803 [Jonathan Viney]
  • Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see 440) to ruby-mysql 0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now a part of the main driver; reapplied local change [2182]. Removed GC.start from Result.free. [tommy@tmtm.org, akuroda@gmail.com, Doug Fales <doug.fales@gmail.com>, Jeremy Kemper]
  • Correct handling of complex order clauses with SQL Server limit emulation. 2770 [Tom Ward <tom@popdog.net>, Matt B.]
  • Correct whitespace problem in Oracle default column value parsing. 2788 [rick@rickbradley.com]
  • Destroy associated has_and_belongs_to_many records after all before_destroy callbacks but before destroy. This allows you to act on the habtm association as you please while preserving referential integrity. 2065 [larrywilliams1@gmail.com, sam.kirchmeier@gmail.com, elliot@townx.org, Jeremy Kemper]
  • Deprecate the old, confusing :exclusively_dependent option in favor of :dependent => :delete_all. [Jeremy Kemper]
  • More compatible Oracle column reflection. 2771 [Ryan Davis <ryand-ruby@zenspider.com>, Michael Schoen <schoenm@earthlink.net>]

*1.13.0* (November 7th, 2005)

  • Fixed faulty regex in get_table_name method (SQLServerAdapter) 2639 [Ryan Tomayko]
  • Added :include as an option for association declarations [David Heinemeier Hansson]. Example:
      has_many :posts, :include => [ :author, :comments ]
  • Rename Base.constrain to Base.with_scope so it doesn‘t conflict with existing concept of database constraints. Make scoping more robust: uniform method => parameters, validated method names and supported finder parameters, raise exception on nested scopes. [Jeremy Kemper] Example:
      Comment.with_scope(:find => { :conditions => 'active=true' }, :create => { :post_id => 5 }) do
    # Find where name = ? and active=true
    Comment.find :all, :conditions => ['name = ?', name]
    # Create comment associated with :post_id
    Comment.create :body => "Hello world"
  end
  • Fixed that SQL Server should ignore :size declarations on anything but integer and string in the agnostic schema representation 2756 [Ryan Tomayko]
  • Added constrain scoping for creates using a hash of attributes bound to the :creation key [David Heinemeier Hansson]. Example:
      Comment.constrain(:creation => { :post_id => 5 }) do
    # Associated with :post_id
    Comment.create :body => "Hello world"
  end

    This is rarely used directly, but allows for find_or_create on associations. So you can do:

      # If the tag doesn't exist, a new one is created that's associated with the person
  person.tags.find_or_create_by_name("Summer")
  • Added find_or_create_by_X as a second type of dynamic finder that‘ll create the record if it doesn‘t already exist [David Heinemeier Hansson]. Example:
      # No 'Summer' tag exists
  Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer")

  # Now the 'Summer' tag does exist
  Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer")
  • Added extension capabilities to has_many and has_and_belongs_to_many proxies [David Heinemeier Hansson]. Example:
      class Account < ActiveRecord::Base
    has_many :people do
      def find_or_create_by_name(name)
        first_name, *last_name = name.split
        last_name = last_name.join " "

        find_or_create_by_first_name_and_last_name(first_name, last_name)
      end
    end
  end

  person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson")
  person.first_name # => "David"
  person.last_name  # => "Heinemeier Hansson"

    Note that the anoymous module must be declared using brackets, not do/end (due to order of evaluation).

  • Omit internal dtproperties table from SQLServer table list. 2729 [Ryan Tomayko]
  • Quote column names in generated SQL. 2728 [Ryan Tomayko]
  • Correct the pure-Ruby MySQL 4.1.1 shim‘s version test. 2718 [Jeremy Kemper]
  • Add Model.create! to match existing model.save! method. When save! raises RecordInvalid, you can catch the exception, retrieve the invalid record (invalid_exception.record), and see its errors (invalid_exception.record.errors). [Jeremy Kemper]
  • Correct fixture behavior when table name pluralization is off. 2719 [Rick Bradley <rick@rickbradley.com>]
  • Changed :dbfile to :database for SQLite adapter for consistency (old key still works as an alias) 2644 [Dan Peterson]
  • Added migration support for Oracle 2647 [Michael Schoen]
  • Worked around that connection can‘t be reset if allow_concurrency is off. 2648 [Michael Schoen <schoenm@earthlink.net>]
  • Fixed SQL Server adapter to pass even more tests and do even better 2634 [Ryan Tomayko]
  • Fixed SQL Server adapter so it honors options[:conditions] when applying :limits 1978 [Tom Ward]
  • Added migration support to SQL Server adapter (please someone do the same for Oracle and DB2) 2625 [Tom Ward]
  • Use AR::Base.silence rather than AR::Base.logger.silence in fixtures to preserve Log4r compatibility. 2618 [dansketcher@gmail.com]
  • Constraints are cloned so they can‘t be inadvertently modified while they‘re

in effect. Added :readonly finder constraint. Calling an association collection‘s class method (Part.foobar via item.parts.foobar) constrains :readonly => false since the collection‘s :joins constraint would otherwise force it to true. [Jeremy Kemper <rails@bitsweat.net>]

  • Added :offset and :limit to the kinds of options that Base.constrain can use 2466 [duane.johnson@gmail.com]
  • Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general 2555 [Michael Schoen]
  • Added quoted_true and quoted_false methods and tables to db2_adapter and cleaned up tests for DB2 2493, 2624 [maik schmidt]

*1.12.2* (October 26th, 2005)

  • Allow symbols to rename columns when using SQLite adapter. 2531 [Kevin Clark]
  • Map Active Record time to SQL TIME. 2575, 2576 [Robby Russell <robby@planetargon.com>]
  • Clarify semantics of ActiveRecord::Base#respond_to? 2560 [Stefan Kaes]
  • Fixed Association#clear for associations which have not yet been accessed. 2524 [Patrick Lenz <patrick@lenz.sh>]
  • HABTM finders shouldn‘t return readonly records. 2525 [Patrick Lenz <patrick@lenz.sh>]
  • Make all tests runnable on their own. 2521. [Blair Zajac <blair@orcaware.com>]

*1.12.1* (October 19th, 2005)

  • Always parenthesize :conditions options so they may be safely combined with STI and constraints.
  • Correct PostgreSQL primary key sequence detection. 2507 [tmornini@infomania.com]
  • Added support for using limits in eager loads that involve has_many and has_and_belongs_to_many associations

*1.12.0* (October 16th, 2005)

  • Update/clean up documentation (rdoc)
  • PostgreSQL sequence support. Use set_sequence_name in your model class to specify its primary key sequence. 2292 [Rick Olson <technoweenie@gmail.com>, Robby Russell <robby@planetargon.com>]
  • Change default logging colors to work on both white and black backgrounds. [Sam Stephenson]
  • YAML fixtures support ordered hashes for fixtures with foreign key dependencies in the same table. 1896 [purestorm@ggnore.net]
  • :dependent now accepts :nullify option. Sets the foreign key of the related objects to NULL instead of deleting them. 2015 [Robby Russell <robby@planetargon.com>]
  • Introduce read-only records. If you call object.readonly! then it will mark the object as read-only and raise ReadOnlyRecord if you call object.save. object.readonly? reports whether the object is read-only. Passing :readonly => true to any finder method will mark returned records as read-only. The :joins option now implies :readonly, so if you use this option, saving the same record will now fail. Use find_by_sql to work around.
  • Avoid memleak in dev mode when using fcgi
  • Simplified .clear on active record associations by using the existing delete_records method. 1906 [Caleb <me@cpb.ca>]
  • Delegate access to a customized primary key to the conventional id method. 2444. [Blair Zajac <blair@orcaware.com>]
  • Fix errors caused by assigning a has-one or belongs-to property to itself
  • Add ActiveRecord::Base.schema_format setting which specifies how databases should be dumped [Sam Stephenson]
  • Update DB2 adapter. 2206. [contact@maik-schmidt.de]
  • Corrections to SQLServer native data types. 2267. [rails.20.clarry@spamgourmet.com]
  • Deprecated ActiveRecord::Base.threaded_connection in favor of ActiveRecord::Base.allow_concurrency.
  • Protect id attribute from mass assigment even when the primary key is set to something else. 2438. [Blair Zajac <blair@orcaware.com>]
  • Misc doc fixes (typos/grammar/etc.). 2430. [coffee2code]
  • Add test coverage for content_columns. 2432. [coffee2code]
  • Speed up for unthreaded environments. 2431. [Stefan Kaes]
  • Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. 2426. [Stefan Kaes]
  • Speed up the setting of table_name. 2428. [Stefan Kaes]
  • Optimize instantiation of STI subclass records. In partial fullfilment of 1236. [Stefan Kaes]
  • Fix typo of ‘constrains’ to ‘contraints’. 2069. [Michael Schuerig <michael@schuerig.de>]
  • Optimization refactoring for add_limit_offset!. In partial fullfilment of 1236. [Stefan Kaes]
  • Add ability to get all siblings, including the current child, with acts_as_tree. Recloses 2140. [Michael Schuerig <michael@schuerig.de>]
  • Add geometric type for postgresql adapter. 2233 [Andrew Kaspick]
  • Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of 1236. [Stefan Kaes]
  • Add convenience predicate methods on Column class. In partial fullfilment of 1236. [Stefan Kaes]
  • Raise errors when invalid hash keys are passed to ActiveRecord::Base.find. 2363 [Chad Fowler <chad@chadfowler.com>, Nicholas Seckar]
  • Added :force option to create_table that‘ll try to drop the table if it already exists before creating
  • Fix transactions so that calling return while inside a transaction will not leave an open transaction on the connection. [Nicholas Seckar]
  • Use foreign_key inflection uniformly. 2156 [Blair Zajac <blair@orcaware.com>]
  • model.association.clear should destroy associated objects if :dependent => true instead of nullifying their foreign keys. 2221 [joergd@pobox.com, ObieFernandez <obiefernandez@gmail.com>]
  • Returning false from before_destroy should cancel the action. 1829 [Jeremy Huffman]
  • Recognize PostgreSQL NOW() default as equivalent to CURRENT_TIMESTAMP or CURRENT_DATE, depending on the column‘s type. 2256 [mat <mat@absolight.fr>]
  • Extensive documentation for the abstract database adapter. 2250 [François Beausoleil <fbeausoleil@ftml.net>]
  • Clean up Fixtures.reset_sequences for PostgreSQL. Handle tables with no rows and models with custom primary keys. 2174, 2183 [jay@jay.fm, Blair Zajac <blair@orcaware.com>]
  • Improve error message when nil is assigned to an attr which validates_size_of within a range. 2022 [Manuel Holtgrewe <purestorm@ggnore.net>]
  • Make update_attribute use the same writer method that update_attributes uses.
 #2237 [trevor@protocool.com]
  • Make migrations honor table name prefixes and suffixes. 2298 [Jakob Skjerning, Marcel Molina Jr.]
  • Correct and optimize PostgreSQL bytea escaping. 1745, 1837 [dave@cherryville.org, ken@miriamtech.com, bellis@deepthought.org]
  • Fixtures should only reset a PostgreSQL sequence if it corresponds to an integer primary key named id. 1749 [chris@chrisbrinker.com]
  • Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior)
  • Added new symbol-driven approach to activating observers with Base#observers= [David Heinemeier Hansson]. Example:
      ActiveRecord::Base.observers = :cacher, :garbage_collector
  • Added AbstractAdapter#select_value and AbstractAdapter#select_values as convenience methods for selecting single values, instead of hashes, of the first column in a SELECT 2283 [solo@gatelys.com]
  • Wrap :conditions in parentheses to prevent problems with OR‘s 1871 [Jamis Buck]
  • Allow the postgresql adapter to work with the SchemaDumper. [Jamis Buck]
  • Add ActiveRecord::SchemaDumper for dumping a DB schema to a pure-ruby file, making it easier to consolidate large migration lists and port database schemas between databases. [Jamis Buck]
  • Fixed migrations for Windows when using more than 10 [David Naseby]
  • Fixed that the create_x method from belongs_to wouldn‘t save the association properly 2042 [Florian Weber]
  • Fixed saving a record with two unsaved belongs_to associations pointing to the same object 2023 [Tobias Lütke]
  • Improved migrations’ behavior when the schema_info table is empty. [Nicholas Seckar]
  • Fixed that Observers didn‘t observe sub-classes 627 [Florian Weber]
  • Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes 2222 [Marcel Molina Jr.]
  • Added check for RAILS_CONNECTION_ADAPTERS on startup and only load the connection adapters specified within if its present (available in Rails through config.connection_adapters using the new config) 1958 [skae]
  • Fixed various problems with has_and_belongs_to_many when using customer finder_sql 2094 [Florian Weber]
  • Added better exception error when unknown column types are used with migrations 1814 [François Beausoleil]
  • Fixed "connection lost" issue with the bundled Ruby/MySQL driver (would kill the app after 8 hours of inactivity) 2163, 428 [kajism@yahoo.com]
  • Fixed comparison of Active Record objects so two new objects are not equal 2099 [deberg]
  • Fixed that the SQL Server adapter would sometimes return DBI::Timestamp objects instead of Time 2127 [Tom Ward]
  • Added the instance methods root and ancestors on acts_as_tree and fixed siblings to not include the current node 2142, 2140 [coffee2code]
  • Fixed that Active Record would call SHOW FIELDS twice (or more) for the same model when the cached results were available 1947 [sd@notso.net]
  • Added log_level and use_silence parameter to ActiveRecord::Base.benchmark. The first controls at what level the benchmark statement will be logged (now as debug, instead of info) and the second that can be passed false to include all logging statements during the benchmark block/
  • Make sure the schema_info table is created before querying the current version 1903
  • Fixtures ignore table name prefix and suffix 1987 [Jakob Skjerning]
  • Add documentation for index_type argument to add_index method for migrations 2005 [Blaine]
  • Modify read_attribute to allow a symbol argument 2024 [Ken Kunz]
  • Make destroy return self 1913 [Sebastian Kanthak]
  • Fix typo in validations documentation 1938 [court3nay]
  • Make acts_as_list work for insert_at(1) 1966 [hensleyl@papermountain.org]
  • Fix typo in count_by_sql documentation 1969 [Alexey Verkhovsky]
  • Allow add_column and create_table to specify NOT NULL 1712 [emptysands@gmail.com]
  • Fix create_table so that id column is implicitly added [Rick Olson]
  • Default sequence names for Oracle changed to #{table_name}_seq, which is the most commonly used standard. In addition, a new method ActiveRecord::Base#set_sequence_name allows the developer to set the sequence name per model. This is a non-backwards-compatible change — anyone using the old-style "rails_sequence" will need to either create new sequences, or set: ActiveRecord::Base.set_sequence_name = "rails_sequence" 1798
  • OCIAdapter now properly handles synonyms, which are commonly used to separate out the schema owner from the application user 1798
  • Fixed the handling of camelCase columns names in Oracle 1798
  • Implemented for OCI the Rakefile tasks of :clone_structure_to_test, :db_structure_dump, and :purge_test_database, which enable Oracle folks to enjoy all the agile goodness of Rails for testing. Note that the current implementation is fairly limited — only tables and sequences are cloned, not constraints or indexes. A full clone in Oracle generally requires some manual effort, and is version-specific. Post 9i, Oracle recommends the use of the DBMS_METADATA package, though that approach requires editing of the physical characteristics generated 1798
  • Fixed the handling of multiple blob columns in Oracle if one or more of them are null 1798
  • Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections 1764 [Tobias Lütke]
      class Comment < AR:B
    def self.search(q)
      find(:all, :conditions => ["body = ?", q])
    end
  end

  class Post < AR:B
    has_many :comments
  end

  Post.find(1).comments.search('hi') # => SELECT * from comments WHERE post_id = 1 AND body = 'hi'

    NOTICE: This patch changes the underlying SQL generated by has_and_belongs_to_many queries. If your relying on that, such as by explicitly referencing the old t and j aliases, you‘ll need to update your code. Of course, you _shouldn‘t_ be relying on details like that no less than you should be diving in to touch private variables. But just in case you do, consider yourself noticed :)

  • Added migration support for SQLite (using temporary tables to simulate ALTER TABLE) 1771 [Sam Stephenson]
  • Remove extra definition of supports_migrations? from abstract_adaptor.rb [Nicholas Seckar]
  • Fix acts_as_list so that moving next-to-last item to the bottom does not result in duplicate item positions
  • Fixed incompatibility in DB2 adapter with the new limit/offset approach 1718 [Maik Schmidt]
  • Added :select option to find which can specify a different value than the default *, like find(:all, :select => "first_name, last_name"), if you either only want to select part of the columns or exclude columns otherwise included from a join 1338 [Stefan Kaes]

*1.11.1* (11 July, 2005)

  • Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError 1692 [Rick Olson]
  • Fixed that assume_bottom_position (in acts_as_list) could be called on items already last in the list and they would move one position away from the list 1648 [tyler@kianta.com]
  • Added ActiveRecord::Base.threaded_connections flag to turn off 1-connection per thread (required for thread safety). By default it‘s on, but WEBrick in Rails need it off 1685 [Sam Stephenson]
  • Correct reflected table name for singular associations. 1688 [court3nay]
  • Fixed optimistic locking with SQL Server 1660 [tom@popdog.net]
  • Added ActiveRecord::Migrator.migrate that can figure out whether to go up or down based on the target version and the current
  • Added better error message for "packets out of order" 1630 [court3nay]
  • Fixed first run of "rake migrate" on PostgreSQL by not expecting a return value on the id 1640

*1.11.0* (6 July, 2005)

  • Fixed that Yaml error message in fixtures hid the real error 1623 [Nicholas Seckar]
  • Changed logging of SQL statements to use the DEBUG level instead of INFO
  • Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases 1604 [Tobias Lütke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator.
  • Added callback hooks to association collections 1549 [Florian Weber]. Example:
      class Project
    has_and_belongs_to_many :developers, :before_add => :evaluate_velocity

    def evaluate_velocity(developer)
      ...
    end
  end

    ..raising an exception will cause the object not to be added (or removed, with before_remove).

  • Fixed Base.content_columns call for SQL Server adapter 1450 [DeLynn Berry]
  • Fixed Base#write_attribute to work with both symbols and strings 1190 [Paul Legato]
  • Fixed that has_and_belongs_to_many didn‘t respect single table inheritance types 1081 [Florian Weber]
  • Speed up ActiveRecord#method_missing for the common case (read_attribute).
  • Only notify observers on after_find and after_initialize if these methods are defined on the model. 1235 [Stefan Kaes]
  • Fixed that single-table inheritance sub-classes couldn‘t be used to limit the result set with eager loading 1215 [Chris McGrath]
  • Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on 1316 [raidel@onemail.at]
  • Added roots, root, and siblings to the batch of methods added by acts_as_tree 1541 [Michael Schuerig]
  • Added support for limit/offset with the MS SQL Server driver so that pagination will now work 1569 [DeLynn Berry]
  • Added support for ODBC connections to MS SQL Server so you can connect from a non-Windows machine 1569 [Mark Imbriaco/DeLynn Berry]
  • Fixed that multiparameter posts ignored attr_protected 1532 [alec+rails@veryclever.net]
  • Fixed problem with eager loading when using a has_and_belongs_to_many association using :association_foreign_key 1504 [flash@vanklinkenbergsoftware.nl]
  • Fixed Base#find to honor the documentation on how :joins work and make them consistent with Base#count 1405 [pritchie@gmail.com]. What used to be:
      Developer.find :all, :joins => 'developers_projects', :conditions => 'id=developer_id AND project_id=1'

    …should instead be:

      Developer.find(
    :all,
    :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
    :conditions => 'project_id=1'
  )
  • Fixed that validations didn‘t respecting custom setting for too_short, too_long messages 1437 [Marcel Molina Jr.]
  • Fixed that clear_association_cache doesn‘t delete new associations on new records (so you can safely place new records in the session with Action Pack without having new associations wiped) 1494 [cluon]
  • Fixed that calling Model.find([]) returns [] and doesn‘t throw an exception 1379
  • Fixed that adding a record to a has_and_belongs_to collection would always save it — now it only saves if its a new record 1203 [Alisdair McDiarmid]
  • Fixed saving of in-memory association structures to happen as a after_create/after_update callback instead of after_save — that way you can add new associations in after_create/after_update callbacks without getting them saved twice
  • Allow any Enumerable, not just Array, to work as bind variables 1344 [Jeremy Kemper]
  • Added actual database-changing behavior to collection assigment for has_many and has_and_belongs_to_many 1425 [Sebastian Kanthak]. Example:
      david.projects = [Project.find(1), Project.new("name" => "ActionWebSearch")]
  david.save

    If david.projects already contain the project with ID 1, this is left unchanged. Any other projects are dropped. And the new project is saved when david.save is called.

    Also included is a way to do assignments through IDs, which is perfect for checkbox updating, so you get to do:

      david.project_ids = [1, 5, 7]
  • Corrected typo in find SQL for has_and_belongs_to_many. 1312 [ben@bensinclair.com]
  • Fixed sanitized conditions for has_many finder method. 1281 [jackc@hylesanderson.com, pragdave, Tobias Lütke]
  • Comprehensive PostgreSQL schema support. Use the optional schema_search_path directive in database.yml to give a comma-separated list of schemas to search for your tables. This allows you, for example, to have tables in a shared schema without having to use a custom table name. See www.postgresql.org/docs/8.0/interactive/ddl-schemas.html to learn more. 827 [dave@cherryville.org]
  • Corrected @@configurations typo 1410 [david@ruppconsulting.com]
  • Return PostgreSQL columns in the order they were declared 1374 [perlguy@gmail.com]
  • Allow before/after update hooks to work on models using optimistic locking
  • Eager loading of dependent has_one associations won‘t delete the association 1212
  • Added a second parameter to the build and create method for has_one that controls whether the existing association should be replaced (which means nullifying its foreign key as well). By default this is true, but false can be passed to prevent it.
  • Using transactional fixtures now causes the data to be loaded only once.
  • Added fixture accessor methods that can be used when instantiated fixtures are disabled.
      fixtures :web_sites

  def test_something
    assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
  end
  • Added DoubleRenderError exception that‘ll be raised if render* is called twice 518 [Nicholas Seckar]
  • Fixed exceptions occuring after render has been called 1096 [Nicholas Seckar]
  • CHANGED: validates_presence_of now uses Errors#add_on_blank, which will make " " fail the validation where it didn‘t before 1309
  • Added Errors#add_on_blank which works like Errors#add_on_empty, but uses Object#blank? instead
  • Added the :if option to all validations that can either use a block or a method pointer to determine whether the validation should be run or not. 1324 [Duane Johnson/jhosteny]. Examples:

    Conditional validations such as the following are made possible:

      validates_numericality_of :income, :if => :employed?

    Conditional validations can also solve the salted login generator problem:

      validates_confirmation_of :password, :if => :new_password?

    Using blocks:

      validates_presence_of :username, :if => Proc.new { |user| user.signup_step > 1 }
  • Fixed use of construct_finder_sql when using :join 1288 [dwlt@dwlt.net]
  • Fixed that :delete_sql in has_and_belongs_to_many associations couldn‘t access record properties 1299 [Rick Olson]
  • Fixed that clone would break when an aggregate had the same name as one of its attributes 1307 [Jeremy Kemper]
  • Changed that destroying an object will only freeze the attributes hash, which keeps the object from having attributes changed (as that wouldn‘t make sense), but allows for the querying of associations after it has been destroyed.
  • Changed the callbacks such that observers are notified before the in-object callbacks are triggered. Without this change, it wasn‘t possible to act on the whole object in something like a before_destroy observer without having the objects own callbacks (like deleting associations) called first.
  • Added option for passing an array to the find_all version of the dynamic finders and have it evaluated as an IN fragment. Example:
      # SELECT * FROM topics WHERE title IN ('First', 'Second')
  Topic.find_all_by_title(["First", "Second"])
  • Added compatibility with camelCase column names for dynamic finders 533 [Dee Zsombor]
  • Fixed extraneous comma in count() function that made it not work with joins 1156 [Jarkko Laine/Dee Zsombor]
  • Fixed incompatibility with Base#find with an array of ids that would fail when using eager loading 1186 [Alisdair McDiarmid]
  • Fixed that validate_length_of lost :on option when :within was specified 1195 [jhosteny@mac.com]
  • Added encoding and min_messages options for PostgreSQL 1205 [Shugo Maeda]. Configuration example:
      development:
    adapter: postgresql
    database: rails_development
    host: localhost
    username: postgres
    password:
    encoding: UTF8
    min_messages: ERROR
  • Fixed acts_as_list where deleting an item that was removed from the list would ruin the positioning of other list items 1197 [Jamis Buck]
  • Added validates_exclusion_of as a negative of validates_inclusion_of
  • Optimized counting of has_many associations by setting the association to empty if the count is 0 so repeated calls doesn‘t trigger database calls

*1.10.1* (20th April, 2005)

  • Fixed frivilous database queries being triggered with eager loading on empty associations and other things
  • Fixed order of loading in eager associations
  • Fixed stray comma when using eager loading and ordering together from has_many associations 1143

*1.10.0* (19th April, 2005)

  • Added eager loading of associations as a way to solve the N+1 problem more gracefully without piggy-back queries. Example:
      for post in Post.find(:all, :limit => 100)
    puts "Post:            " + post.title
    puts "Written by:      " + post.author.name
    puts "Last comment on: " + post.comments.first.created_on
  end

    This used to generate 301 database queries if all 100 posts had both author and comments. It can now be written as:

      for post in Post.find(:all, :limit => 100, :include => [ :author, :comments ])

    …and the number of database queries needed is now 1.

  • Added new unified Base.find API and deprecated the use of find_first and find_all. See the documentation for Base.find. Examples:
      Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
  Person.find(1, 5, 6, :conditions => "administrator = 1", :order => "created_on DESC")
  Person.find(:first, :order => "created_on DESC", :offset => 5)
  Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
  Person.find(:all, :offset => 10, :limit => 10)
  • Added acts_as_nested_set 1000 [wschenk]. Introduction:
      This acts provides Nested Set functionality.  Nested Set is similiar to Tree, but with
  the added feature that you can select the children and all of it's descendants with
  a single query.  A good use case for this is a threaded post system, where you want
  to display every reply to a comment without multiple selects.
  • Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [Dave Thomas]
  • Fixed PostgreSQL usage of fixtures with regards to public schemas and table names with dots 962 [gnuman1@gmail.com]
  • Fixed that fixtures were being deleted in the same order as inserts causing FK errors 890 [andrew.john.peters@gmail.com]
  • Fixed loading of fixtures in to be in the right order (or PostgreSQL would bark) 1047 [stephenh@chase3000.com]
  • Fixed page caching for non-vhost applications living underneath the root 1004 [Ben Schumacher]
  • Fixes a problem with the SQL Adapter which was resulting in IDENTITY_INSERT not being set to ON when it should be 1104 [adelle]
  • Added the option to specify the acceptance string in validates_acceptance_of 1106 [caleb@aei-tech.com]
  • Added insert_at(position) to acts_as_list 1083 [DeLynnB]
  • Removed the default order by id on has_and_belongs_to_many queries as it could kill performance on large sets (you can still specify by hand with :order)
  • Fixed that Base.silence should restore the old logger level when done, not just set it to DEBUG 1084 [yon@milliped.com]
  • Fixed boolean saving on Oracle 1093 [mparrish@pearware.org]
  • Moved build_association and create_association for has_one and belongs_to out of deprecation as they work when the association is nil unlike association.build and association.create, which require the association to be already in place 864
  • Added rollbacks of transactions if they‘re active as the dispatcher is killed gracefully (TERM signal) 1054 [Leon Bredt]
  • Added quoting of column names for fixtures 997 [jcfischer@gmail.com]
  • Fixed counter_sql when no records exist in database for PostgreSQL (would give error, not 0) 1039 [Caleb Tennis]
  • Fixed that benchmarking times for rendering included db runtimes 987 [Stefan Kaes]
  • Fixed boolean queries for t/f fields in PostgreSQL 995 [dave@cherryville.org]
  • Added that model.items.delete(child) will delete the child, not just set the foreign key to nil, if the child is dependent on the model 978 [Jeremy Kemper]
  • Fixed auto-stamping of dates (created_on/updated_on) for PostgreSQL 985 [dave@cherryville.org]
  • Fixed Base.silence/benchmark to only log if a logger has been configured 986 [Stefan Kaes]
  • Added a join parameter as the third argument to Base.find_first and as the second to Base.count 426, 988 [Stefan Kaes]
  • Fixed bug in Base#hash method that would treat records with the same string-based id as different [Dave Thomas]
  • Renamed DateHelper#distance_of_time_in_words_to_now to DateHelper#time_ago_in_words (old method name is still available as a deprecated alias)

*1.9.1* (27th March, 2005)

  • Fixed that Active Record objects with float attribute could not be cloned 808
  • Fixed that MissingSourceFile‘s wasn‘t properly detected in production mode 925 [Nicholas Seckar]
  • Fixed that :counter_cache option would look for a line_items_count column for a LineItem object instead of lineitems_count
  • Fixed that AR exists?() would explode on postgresql if the passed id did not match the PK type 900 [Scott Barron]
  • Fixed the MS SQL adapter to work with the new limit/offset approach and with binary data (still suffering from 7KB limit, though) 901 [delynnb]

*1.9.0* (22th March, 2005)

  • Added adapter independent limit clause as a two-element array with the first being the limit, the second being the offset 795 [Sam Stephenson]. Example:
      Developer.find_all nil, 'id ASC', 5      # return the first five developers
  Developer.find_all nil, 'id ASC', [3, 8] # return three developers, starting from #8 and forward

    This doesn‘t yet work with the DB2 or MS SQL adapters. Patches to make that happen are encouraged.

  • Added alias_method :to_param, :id to Base, such that Active Record objects to be used as URL parameters in Action Pack automatically 812 [Nicholas Seckar/Sam Stephenson]
  • Improved the performance of the OCI8 adapter for Oracle 723 [pilx/gjenkins]
  • Added type conversion before saving a record, so string-based values like "10.0" aren‘t left for the database to convert 820 [dave@cherryville.org]
  • Added with additional settings for working with transactional fixtures and pre-loaded test databases 865 [mindel]
  • Fixed acts_as_list to trigger remove_from_list on destroy after the fact, not before, so a unique position can be maintained 871 [Alisdair McDiarmid]
  • Added the possibility of specifying fixtures in multiple calls 816 [kim@tinker.com]
  • Added Base.exists?(id) that‘ll return true if an object of the class with the given id exists 854 [stian@grytoyr.net]
  • Added optionally allow for nil or empty strings with validates_numericality_of 801 [Sebastian Kanthak]
  • Fixed problem with using slashes in validates_format_of regular expressions 801 [Sebastian Kanthak]
  • Fixed that SQLite3 exceptions are caught and reported properly 823 [yerejm]
  • Added that all types of after_find/after_initialized callbacks are triggered if the explicit implementation is present, not only the explicit implementation itself
  • Fixed that symbols can be used on attribute assignment, like page.emails.create(:subject => data.subject, :body => data.body)

*1.8.0* (7th March, 2005)

  • Added ActiveRecord::Base.colorize_logging to control whether to use colors in logs or not (on by default)
  • Added support for timestamp with time zone in PostgreSQL 560 [Scott Barron]
  • Added MultiparameterAssignmentErrors and AttributeAssignmentError exceptions 777 [demetrius]. Documentation:
     * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the
   +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+
   objects that should be inspected to determine which attributes triggered the errors.
 * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method.
   You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
  • Fixed that postgresql adapter would fails when reading bytea fields with null value 771 [rodrigo k]
  • Added transactional fixtures that uses rollback to undo changes to fixtures instead of DELETE/INSERT — it‘s much faster. See documentation under Fixtures 760 [Jeremy Kemper]
  • Added destruction of dependent objects in has_one associations when a new assignment happens 742 [mindel]. Example:
      class Account < ActiveRecord::Base
    has_one :credit_card, :dependent => true
  end
  class CreditCard < ActiveRecord::Base
    belongs_to :account
  end

  account.credit_card # => returns existing credit card, lets say id = 12
  account.credit_card = CreditCard.create("number" => "123")
  account.save # => CC with id = 12 is destroyed
  • Added validates_numericality_of 716 [Sebastian Kanthak/Chris McGrath]. Docuemntation:
      Validates whether the value of the specified attribute is numeric by trying to convert it to
  a float with Kernel.Float (if <tt>integer</tt> is false) or applying it to the regular expression
  <tt>/^[\+\-]?\d+$/</tt> (if <tt>integer</tt> is set to true).

    class Person < ActiveRecord::Base
      validates_numericality_of :value, :on => :create
    end

  Configuration options:
  * <tt>message</tt> - A custom error message (default is: "is not a number")
  * <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
  * <tt>only_integer</tt> Specifies whether the value has to be an integer, e.g. an integral value (default is false)
  • Fixed that HasManyAssociation#count was using :finder_sql rather than :counter_sql if it was available 445 [Scott Barron]
  • Added better defaults for composed_of, so statements like composed_of :time_zone, :mapping => %w( time_zone time_zone ) can be written without the mapping part (it‘s now assumed)
  • Added MacroReflection#macro which will return a symbol describing the macro used (like :composed_of or :has_many) 718, 248 [james@slashetc.com]

*1.7.0* (24th February, 2005)

  • Changed the auto-timestamping feature to use ActiveRecord::Base.default_timezone instead of entertaining the parallel ActiveRecord::Base.timestamps_gmt method. The latter is now deprecated and will throw a warning on use (but still work) 710 [Jamis Buck]
  • Added a OCI8-based Oracle adapter that has been verified to work with Oracle 8 and 9 629 [Graham Jenkins]. Usage notes:
      1.  Key generation uses a sequence "rails_sequence" for all tables. (I couldn't find a simple
      and safe way of passing table-specific sequence information to the adapter.)
  2.  Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to
      resort to some hacks to get data converted to Date or Time in Ruby.
      If the column_name ends in _at (like created_at, updated_at) it's created as a Ruby Time. Else if the
      hours/minutes/seconds are 0, I make it a Ruby Date. Else it's a Ruby Time.
      This is nasty - but if you use Duck Typing you'll probably not care very much.
      In 9i it's tempting to map DATE to Date and TIMESTAMP to Time but I don't think that is
      valid - too many databases use DATE for both.
      Timezones and sub-second precision on timestamps are not supported.
  3.  Default values that are functions (such as "SYSDATE") are not supported. This is a
      restriction of the way active record supports default values.
  4.  Referential integrity constraints are not fully supported. Under at least
      some circumstances, active record appears to delete parent and child records out of
      sequence and out of transaction scope. (Or this may just be a problem of test setup.)

    The OCI8 driver can be retrieved from rubyforge.org/projects/ruby-oci8/

  • Added option :schema_order to the PostgreSQL adapter to support the use of multiple schemas per database 697 [YuriSchimke]
  • Optimized the SQL used to generate has_and_belongs_to_many queries by listing the join table first 693 [yerejm]
  • Fixed that when using validation macros with a custom message, if you happened to use single quotes in the message string you would get a parsing error 657 [tonka]
  • Fixed that Active Record would throw Broken Pipe errors with FCGI when the MySQL connection timed out instead of reconnecting 428 [Nicholas Seckar]
  • Added options to specify an SSL connection for MySQL. Define the following attributes in the connection config (config/database.yml in Rails) to use it: sslkey, sslcert, sslca, sslcapath, sslcipher. To use SSL with no client certs, just set :sslca = ’/dev/null’. dev.mysql.com/doc/mysql/en/secure-connections.html 604 [daniel@nightrunner.com]
  • Added automatic dropping/creating of test tables for running the unit tests on all databases 587 [adelle@bullet.net.au]
  • Fixed that find_by_* would fail when column names had numbers 670 [demetrius]
  • Fixed the SQL Server adapter on a bunch of issues 667 [DeLynn]
      1. Created a new columns method that is much cleaner.
  2. Corrected a problem with the select and select_all methods
     that didn't account for the LIMIT clause being passed into raw SQL statements.
  3. Implemented the string_to_time method in order to create proper instances of the time class.
  4. Added logic to the simplified_type method that allows the database to specify the scale of float data.
  5. Adjusted the quote_column_name to account for the fact that MS SQL is bothered by a forward slash in the data string.
  • Fixed that the dynamic finder like find_all_by_something_boolean(false) didn‘t work 649 [lmarlow]
  • Added validates_each that validates each specified attribute against a block 610 [Jeremy Kemper]. Example:
      class Person < ActiveRecord::Base
    validates_each :first_name, :last_name do |record, attr|
      record.errors.add attr, 'starts with z.' if attr[0] == ?z
    end
  end
  • Added :allow_nil as an explicit option for validates_length_of, so unless that‘s set to true having the attribute as nil will also return an error if a range is specified as :within 610 [Jeremy Kemper]
  • Added that validates_* now accept blocks to perform validations 618 [Tim Bates]. Example:
      class Person < ActiveRecord::Base
    validate { |person| person.errors.add("title", "will never be valid") if SHOULD_NEVER_BE_VALID }
  end
  • Addded validation for validate all the associated objects before declaring failure with validates_associated 618 [Tim Bates]
  • Added keyword-style approach to defining the custom relational bindings 545 [Jamis Buck]. Example:
      class Project < ActiveRecord::Base
    primary_key "sysid"
    table_name "XYZ_PROJECT"
    inheritance_column { original_inheritance_column + "_id" }
  end
  • Fixed Base#clone for use with PostgreSQL 565 [hanson@surgery.wisc.edu]

*1.6.0* (January 25th, 2005)

  • Added that has_many association build and create methods can take arrays of record data like Base#create and Base#build to build/create multiple records at once.
  • Added that Base#delete and Base#destroy both can take an array of ids to delete/destroy 336
  • Added the option of supplying an array of attributes to Base#create, so that multiple records can be created at once.
  • Added the option of supplying an array of ids and attributes to Base#update, so that multiple records can be updated at once (inspired by 526/Duane Johnson). Example
      people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
  Person.update(people.keys, people.values)
  • Added ActiveRecord::Base.timestamps_gmt that can be set to true to make the automated timestamping use GMT instead of local time 520 [Scott Baron]
  • Added that update_all calls sanitize_sql on its updates argument, so stuff like MyRecord.update_all([‘time = ?’, Time.now]) works 519 [notahat]
  • Fixed that the dynamic finders didn‘t treat nil as a "IS NULL" but rather "= NULL" case 515 [Demetrius]
  • Added bind-named arrays for interpolating a group of ids or strings in conditions 528 [Jeremy Kemper]
  • Added that has_and_belongs_to_many associations with additional attributes also can be created between unsaved objects and only committed to the database when Base#save is called on the associator 524 [Eric Anderson]
  • Fixed that records fetched with piggy-back attributes or through rich has_and_belongs_to_many associations couldn‘t be saved due to the extra attributes not part of the table 522 [Eric Anderson]
  • Added mass-assignment protection for the inheritance column — regardless of a custom column is used or not
  • Fixed that association proxies would fail === tests like PremiumSubscription === @account.subscription
  • Fixed that column aliases didn‘t work as expected with the new MySql411 driver 507 [Demetrius]
  • Fixed that find_all would produce invalid sql when called sequentialy 490 [Scott Baron]

*1.5.1* (January 18th, 2005)

  • Fixed that the belongs_to and has_one proxy would fail a test like ‘if project.manager’ — this unfortunately also means that you can‘t call methods like project.manager.build unless there already is a manager on the project 492 [Tim Bates]
  • Fixed that the Ruby/MySQL adapter wouldn‘t connect if the password was empty 503 [Pelle]

*1.5.0* (January 17th, 2005)

  • Fixed that unit tests for MySQL are now run as the "rails" user instead of root 455 [Eric Hodel]
  • Added validates_associated that enables validation of objects in an unsaved association 398 [Tim Bates]. Example:
      class Book < ActiveRecord::Base
    has_many :pages
    belongs_to :library

    validates_associated :pages, :library
  end
  • Added support for associating unsaved objects 402 [Tim Bates]. Rules that govern this addition:
      == Unsaved objects and associations

  You can manipulate objects and associations before they are saved to the database, but there is some special behaviour you should be
  aware of, mostly involving the saving of associated objects.

  === One-to-one associations

  * Assigning an object to a has_one association automatically saves that object, and the object being replaced (if there is one), in
    order to update their primary keys - except if the parent object is unsaved (new_record? == true).
  * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns false and the assignment
    is cancelled.
  * If you wish to assign an object to a has_one association without saving it, use the #association.build method (documented below).
  * Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does
    not save the parent either.

  === Collections

  * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object
    (the owner of the collection) is not yet stored in the database.
  * If saving any of the objects being added to a collection (via #push or similar) fails, then #push returns false.
  * You can add an object to a collection without automatically saving it by using the #collection.build method (documented below).
  * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved.
  • Added replace to associations, so you can do project.manager.replace(new_manager) or project.milestones.replace(new_milestones) 402 [Tim Bates]
  • Added build and create methods to has_one and belongs_to associations, so you can now do project.manager.build(attributes) 402 [Tim Bates]
  • Added that if a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last. 402 [Tim Bates]
  • Fixed that Base#== wouldn‘t work for multiple references to the same unsaved object 402 [Tim Bates]
  • Fixed binary support for PostgreSQL 444 [alex@byzantine.no]
  • Added a differenciation between AssociationCollection#size and -length. Now AssociationCollection#size returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn‘t been loaded and calling collection.size if it has. If it‘s more likely than not that the collection does have a size larger than zero and you need to fetch that collection afterwards, it‘ll take one less SELECT query if you use length.
  • Added Base#attributes that returns a hash of all the attributes with their names as keys and clones of their objects as values 433 [atyp.de]
  • Fixed that foreign keys named the same as the association would cause stack overflow 437 [Eric Anderson]
  • Fixed default scope of acts_as_list from "1" to "1 = 1", so it‘ll work in PostgreSQL (among other places) 427 [Alexey]
  • Added Base#reload that reloads the attributes of an object from the database 422 [Andreas Schwarz]
  • Added SQLite3 compatibility through the sqlite3-ruby adapter by Jamis Buck 381 [Jeremy Kemper]
  • Added support for the new protocol spoken by MySQL 4.1.1+ servers for the Ruby/MySQL adapter that ships with Rails 440 [Matt Mower]
  • Added that Observers can use the observes class method instead of overwriting self.observed_class().
      Before:
    class ListSweeper < ActiveRecord::Base
      def self.observed_class() [ List, Item ]
    end

  After:
    class ListSweeper < ActiveRecord::Base
      observes List, Item
    end
  • Fixed that conditions in has_many and has_and_belongs_to_many should be interpolated just like the finder_sql is
  • Fixed Base#update_attribute to be indifferent to whether a string or symbol is used to describe the name
  • Added Base#toggle(attribute) and Base#toggle!(attribute) that makes it easier to flip a switch or flag.
      Before: topic.update_attribute(:approved, !approved?)
  After : topic.toggle!(:approved)
  • Added Base#increment!(attribute) and Base#decrement!(attribute) that also saves the records. Example:
      page.views # => 1
  page.increment!(:views) # executes an UPDATE statement
  page.views # => 2

  page.increment(:views).increment!(:views)
  page.views # => 4
  • Added Base#increment(attribute) and Base#decrement(attribute) that encapsulates the += 1 and -= 1 patterns.

*1.4.0* (January 4th, 2005)

  • Added automated optimistic locking if the field lock_version is present. Each update to the record increments the lock_version column and the locking facilities ensure that records instantiated twice will let the last one saved raise a StaleObjectError if the first was also updated. Example:
      p1 = Person.find(1)
  p2 = Person.find(1)

  p1.first_name = "Michael"
  p1.save

  p2.first_name = "should fail"
  p2.save # Raises a ActiveRecord::StaleObjectError

    You‘re then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.

    384 [Michael Koziarski]

  • Added dynamic attribute-based finders as a cleaner way of getting objects by simple queries without turning to SQL. They work by appending the name of an attribute to find_by_, so you get finders like Person.find_by_user_name, Payment.find_by_transaction_id. So instead of writing Person.find_first(["user_name = ?", user_name]), you just do Person.find_by_user_name(user_name).

    It‘s also possible to use multiple attributes in the same find by separating them with "and", so you get finders like Person.find_by_user_name_and_password or even Payment.find_by_purchaser_and_state_and_country. So instead of writing Person.find_first(["user_name = ? AND password = ?", user_name, password]), you just do Person.find_by_user_name_and_password(user_name, password).

    While primarily a construct for easier find_firsts, it can also be used as a construct for find_all by using calls like Payment.find_all_by_amount(50) that is turned into Payment.find_all(["amount = ?", 50]). This is something not as equally useful, though, as it‘s not possible to specify the order in which the objects are returned.

  • Added block-style for callbacks 332 [Jeremy Kemper].
      Before:
    before_destroy(Proc.new{ |record| Person.destroy_all "firm_id = #{record.id}" })

  After:
    before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" }
  • Added :counter_cache option to acts_as_tree that works just like the one you can define on belongs_to 371 [Josh Peek]
  • Added Base.default_timezone accessor that determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database. This is set to :local by default.
  • Added the possibility for adapters to overwrite add_limit! to implement a different limiting scheme than "LIMIT X" used by MySQL, PostgreSQL, and SQLite.
  • Added the possibility of having objects with acts_as_list created before their scope is available or…
  • Added a db2 adapter that only depends on the Ruby/DB2 bindings (raa.ruby-lang.org/project/ruby-db2/) 386 [Maik Schmidt]
  • Added the final touches to the Microsoft SQL Server adapter by Joey Gibson that makes it suitable for actual use 394 [DeLynn Barry]
  • Added that Base#find takes an optional options hash, including :conditions. Base#find_on_conditions deprecated in favor of find with :conditions 407 [Jeremy Kemper]
  • Added HasManyAssociation#count that works like Base#count 413 [intinig]
  • Fixed handling of binary content in blobs and similar fields for Ruby/MySQL and SQLite 409 [xal]
  • Fixed a bug in the Ruby/MySQL that caused binary content to be escaped badly and come back mangled 405 [Tobias Lütke]
  • Fixed that the const_missing autoload assumes the requested constant is set by require_association and calls const_get to retrieve it. If require_association did not set the constant then const_get will call const_missing, resulting in an infinite loop 380 [Jeremy Kemper]
  • Fixed broken transactions that were actually only running object-level and not db level transactions [andreas]
  • Fixed that validates_uniqueness_of used ‘id’ instead of defined primary key 406
  • Fixed that the overwritten respond_to? method didn‘t take two parameters like the original 391
  • Fixed quoting in validates_format_of that would allow some rules to pass regardless of input 390 [Dmitry V. Sabanin]

*1.3.0* (December 23, 2004)

  • Added a require_association hook on const_missing that makes it possible to use any model class without requiring it first. This makes STI look like:
      before:
    require_association 'person'
    class Employee < Person
    end

  after:
    class Employee < Person
    end

    This also reduces the usefulness of Controller.model in Action Pack to currently only being for documentation purposes.

  • Added that Base.update_all and Base.delete_all return an integer of the number of affected rows 341
  • Added scope option to validation_uniqueness 349 [Kent Sibilev]
  • Added respondence to *_before_type_cast for all attributes to return their string-state before they were type casted by the column type. This is helpful for getting "100,000" back on a integer-based validation where the value would normally be "100".
  • Added allow_nil options to validates_inclusion_of so that validation is only triggered if the attribute is not nil [what-a-day]
  • Added work-around for PostgreSQL and the problem of getting fixtures to be created from id 1 on each test case. This only works for auto-incrementing primary keys called "id" for now 359 [Scott Baron]
  • Added Base#clear_association_cache to empty all the cached associations 347 [Tobias Lütke]
  • Added more informative exceptions in establish_connection 356 [Jeremy Kemper]
  • Added Base#update_attributes that‘ll accept a hash of attributes and save the record (returning true if it passed validation, false otherwise).
      Before:
    person.attributes = @params["person"]
    person.save

  Now:
    person.update_attributes(@params["person"])
  • Added Base.destroy and Base.delete to remove records without holding a reference to them first.
  • Added that query benchmarking will only happen if its going to be logged anyway 344
  • Added higher_item and lower_item as public methods for acts_as_list 342 [Tobias Lütke]
  • Fixed that options[:counter_sql] was overwritten with interpolated sql rather than original sql 355 [Jeremy Kemper]
  • Fixed that overriding an attribute‘s accessor would be disregarded by add_on_empty and add_on_boundary_breaking because they simply used the attributes[] hash instead of checking for @base.respond_to?(attr.to_s). [Marten]
  • Fixed that Base.table_name would expect a parameter when used in has_and_belongs_to_many joins [Anna Lissa Cruz]
  • Fixed that nested transactions now work by letting the outer most transaction have the responsibilty of starting and rolling back the transaction. If any of the inner transactions swallow the exception raised, though, the transaction will not be rolled back. So always let the transaction bubble up even when you‘ve dealt with local issues. Closes 231 and 340.
  • Fixed validates_{confirmation,acceptance}_of to only happen when the virtual attributes are not nil 348 [dpiddy@gmail.com]
  • Changed the interface on AbstractAdapter to require that adapters return the number of affected rows on delete and update operations.
  • Fixed the automated timestamping feature when running under Rails’ development environment that resets the inheritable attributes on each request.

*1.2.0*

  • Added Base.validates_inclusion_of that validates whether the value of the specified attribute is available in a particular enumerable object. [what-a-day]
      class Person < ActiveRecord::Base
    validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!"
    validates_inclusion_of :age, :in=>0..99
  end
  • Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom. [Tobias Lütke] Example:
      class TodoItem < ActiveRecord::Base
    acts_as_list :scope => :todo_list_id
    belongs_to :todo_list
  end
  • Added acts_as_tree that can decorates an existing class with a many to many relationship with itself. Perfect for categories in categories and the likes. [Tobias Lütke]
  • Added that Active Records will automatically record creation and/or update timestamps of database objects if fields of the names created_at/created_on or updated_at/updated_on are present. [Tobias Lütke]
  • Added Base.default_error_messages as a hash of all the error messages used in the validates_*_of so they can be changed in one place [Tobias Lütke]
  • Added automatic transaction block around AssociationCollection.<<, AssociationCollection.delete, and AssociationCollection.destroy_all
  • Fixed that Base#find will return an array if given an array — regardless of the number of elements 270 [Marten]
  • Fixed that has_and_belongs_to_many would generate bad sql when naming conventions differed from using vanilla "id" everywhere [RedTerror]
  • Added a better exception for when a type column is used in a table without the intention of triggering single-table inheritance. Example:
      ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'bad_class!'.
  This error is raised because the column 'type' is reserved for storing the class in case of inheritance.
  Please rename this column if you didn't intend it to be used for storing the inheritance class or
  overwrite Company.inheritance_column to use another column for that information.
  • Added that single-table inheritance will only kick in if the inheritance_column (by default "type") is present. Otherwise, inheritance won‘t have any magic side effects.
  • Added the possibility of marking fields as being in error without adding a message (using nil) to it that‘ll get displayed wth full_messages 208 [mjobin]
  • Fixed Base.errors to be indifferent as to whether strings or symbols are used. Examples:
      Before:
    errors.add(:name, "must be shorter") if name.size > 10
    errors.on(:name)  # => "must be shorter"
    errors.on("name") # => nil

  After:
    errors.add(:name, "must be shorter") if name.size > 10
    errors.on(:name)  # => "must be shorter"
    errors.on("name") # => "must be shorter"
  • Added Base.validates_format_of that Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided. [Marcel Molina Jr.]
      class Person < ActiveRecord::Base
    validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/, :on => :create
  end
  • Added Base.validates_length_of that delegates to add_on_boundary_breaking 312 [Tobias Lütke]. Example:
      Validates that the specified attribute matches the length restrictions supplied in either:

    - configuration[:minimum]
    - configuration[:maximum]
    - configuration[:is]
    - configuration[:within] (aka. configuration[:in])

  Only one option can be used at a time.

    class Person < ActiveRecord::Base
      validates_length_of :first_name, :maximum=>30
      validates_length_of :last_name, :maximum=>30, :message=>"less than %d if you don't mind"
      validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
      validates_length_of :fav_bra_size, :minimum=>1, :too_short=>"please enter at least %d character"
      validates_length_of :smurf_leader, :is=>4, :message=>"papa is spelled with %d characters... don't play me."
    end
  • Added Base.validate_presence as an alternative to implementing validate and doing errors.add_on_empty yourself.
  • Added Base.validates_uniqueness_of that alidates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named "davidhh".
      class Person < ActiveRecord::Base
    validates_uniqueness_of :user_name
  end

    When the record is created, a check is performed to make sure that no record exist in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

  • Added Base.validates_confirmation_of that encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:
       Model:
     class Person < ActiveRecord::Base
       validates_confirmation_of :password
     end

   View:
     <%= password_field "person", "password" %>
     <%= password_field "person", "password_confirmation" %>

 The person has to already have a password attribute (a column in the people table), but the password_confirmation is virtual.
 It exists only as an in-memory variable for validating the password. This check is performed both on create and update.
  • Added Base.validates_acceptance_of that encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
     class Person < ActiveRecord::Base
   validates_acceptance_of :terms_of_service
 end

    The terms_of_service attribute is entirely virtual. No database column is needed. This check is performed both on create and update.

    NOTE: The agreement is considered valid if it‘s set to the string "1". This makes it easy to relate it to an HTML checkbox.

  • Added validation macros to make the stackable just like the lifecycle callbacks. Examples:
      class Person < ActiveRecord::Base
    validate { |record| record.errors.add("name", "too short") unless name.size > 10 }
    validate { |record| record.errors.add("name", "too long")  unless name.size < 20 }
    validate_on_create :validate_password

    private
      def validate_password
        errors.add("password", "too short") unless password.size > 6
      end
  end
  • Added the option for sanitizing find_by_sql and the offset parts in regular finds [Sam Stephenson]. Examples:
      Project.find_all ["category = ?", category_name], "created ASC", ["? OFFSET ?", 15, 20]
  Post.find_by_sql ["SELECT * FROM posts WHERE author = ? AND created > ?", author_id, start_date]
  • Fixed value quoting in all generated SQL statements, so that integers are not surrounded in quotes and that all sanitation are happening through the database‘s own quoting routine. This should hopefully make it lots easier for new adapters that doesn‘t accept ‘1’ for integer columns.
  • Fixed has_and_belongs_to_many guessing of foreign key so that keys are generated correctly for models like SomeVerySpecialClient [Florian Weber]
  • Added counter_sql option for has_many associations [Jeremy Kemper]. Documentation:
      <tt>:counter_sql</tt> - specify a complete SQL statement to fetch the size of the association. If +:finder_sql+ is
  specified but +:counter_sql+, +:counter_sql+ will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM.
  • Fixed that methods wrapped in callbacks still return their original result 260 [Jeremy Kemper]
  • Fixed the Inflector to handle the movie/movies pair correctly 261 [Scott Baron]
  • Added named bind-style variable interpolation 281 [Michael Koziarski]. Example:
      Person.find(["id = :id and first_name = :first_name", { :id => 5, :first_name = "bob' or 1=1" }])
  • Added bind-style variable interpolation for the condition arrays that uses the adapter‘s quote method [Michael Koziarski]

    Before:

      find_first([ "user_name = '%s' AND password = '%s'", user_name, password ])]
  find_first([ "firm_id = %s", firm_id ])] # unsafe!

    After:

      find_first([ "user_name = ? AND password = ?", user_name, password ])]
  find_first([ "firm_id = ?", firm_id ])]
  • Added CSV format for fixtures 272 [what-a-day]. (See the new and expanded documentation on fixtures for more information)
  • Fixed fixtures using primary key fields called something else than "id" [dave]
  • Added proper handling of time fields that are turned into Time objects with the dummy date of 2000/1/1 [HariSeldon]
  • Added reverse order of deleting fixtures, so referential keys can be maintained 247 [Tim Bates]
  • Added relative path search for sqlite dbfiles in database.yml (if RAILS_ROOT is defined) 233 [Jeremy Kemper]
  • Added option to establish_connection where you‘ll be able to leave out the parameter to have it use the RAILS_ENV environment variable
  • Fixed problems with primary keys and postgresql sequences (230) [Tim Bates]
  • Added reloading for associations under cached environments like FastCGI and mod_ruby. This makes it possible to use those environments for development. This is turned on by default, but can be turned off with ActiveRecord::Base.reload_dependencies = false in production environments.

    NOTE: This will only have an effect if you let the associations manage the requiring of model classes. All libraries loaded through require will be "forever" cached. You can, however, use ActiveRecord::Base.load_or_require("library") to get this behavior outside of the auto-loading associations.

  • Added ERB capabilities to the fixture files for dynamic fixture generation. You don‘t need to do anything, just include ERB blocks like:
      david:
    id: 1
    name: David

  jamis:
    id: 2
    name: Jamis

  <% for digit in 3..10 %>
  dev_<%= digit %>:
    id: <%= digit %>
    name: fixture_<%= digit %>
  <% end %>
  • Changed the yaml fixture searcher to look in the root of the fixtures directory, so when you before could have something like:
      fixtures/developers/fixtures.yaml
  fixtures/accounts/fixtures.yaml

    …you now need to do:

      fixtures/developers.yaml
  fixtures/accounts.yaml
  • Changed the fixture format from:
      name: david
  data:
   id: 1
   name: David Heinemeier Hansson
   birthday: 1979-10-15
   profession: Systems development
  ---
  name: steve
  data:
   id: 2
   name: Steve Ross Kellock
   birthday: 1974-09-27
   profession: guy with keyboard

    …to:

      david:
   id: 1
   name: David Heinemeier Hansson
   birthday: 1979-10-15
   profession: Systems development

  steve:
   id: 2
   name: Steve Ross Kellock
   birthday: 1974-09-27
   profession: guy with keyboard

    The change is NOT backwards compatible. Fixtures written in the old YAML style needs to be rewritten!

  • All associations will now attempt to require the classes that they associate to. Relieving the need for most explicit ‘require’ statements.

*1.1.0* (34)

  • Added automatic fixture setup and instance variable availability. Fixtures can also be automatically instantiated in instance variables relating to their names using the following style:
      class FixturesTest < Test::Unit::TestCase
    fixtures :developers # you can add more with comma separation

    def test_developers
      assert_equal 3, @developers.size # the container for all the fixtures is automatically set
      assert_kind_of Developer, @david # works like @developers["david"].find
      assert_equal "David Heinemeier Hansson", @david.name
    end
  end
  • Added HasAndBelongsToManyAssociation#push_with_attributes(object, join_attributes) that can create associations in the join table with additional attributes. This is really useful when you have information that‘s only relevant to the join itself, such as a "added_on" column for an association between post and category. The added attributes will automatically be injected into objects retrieved through the association similar to the piggy-back approach:
      post.categories.push_with_attributes(category, :added_on => Date.today)
  post.categories.first.added_on # => Date.today

    NOTE: The categories table doesn‘t have a added_on column, it‘s the categories_post join table that does!

  • Fixed that :exclusively_dependent and :dependent can‘t be activated at the same time on has_many associations [Jeremy Kemper]
  • Fixed that database passwords couldn‘t be all numeric [Jeremy Kemper]
  • Fixed that calling id would create the instance variable for new_records preventing them from being saved correctly [Jeremy Kemper]
  • Added sanitization feature to HasManyAssociation#find_all so it works just like Base.find_all [Sam Stephenson/Jeremy Kemper]
  • Added that you can pass overlapping ids to find without getting duplicated records back [Jeremy Kemper]
  • Added that Base.benchmark returns the result of the block [Jeremy Kemper]
  • Fixed problem with unit tests on Windows with SQLite [paterno]
  • Fixed that quotes would break regular non-yaml fixtures [Dmitry Sabanin/daft]
  • Fixed fixtures on windows with line endings cause problems under unix / mac [Tobias Lütke]
  • Added HasAndBelongsToManyAssociation#find(id) that‘ll search inside the collection and find the object or record with that id
  • Added :conditions option to has_and_belongs_to_many that works just like the one on all the other associations
  • Added AssociationCollection#clear to remove all associations from has_many and has_and_belongs_to_many associations without destroying the records [geech]
  • Added type-checking and remove in 1-instead-of-N sql statements to AssociationCollection#delete [geech]
  • Added a return of self to AssociationCollection#<< so appending can be chained, like project << Milestone.create << Milestone.create [geech]
  • Added Base#hash and Base#eql? which means that all of the equality using features of array and other containers now works:
      [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
  • Added :uniq as an option to has_and_belongs_to_many which will automatically ensure that AssociateCollection#uniq is called before pulling records out of the association. This is especially useful for three-way (and above) has_and_belongs_to_many associations.
  • Added AssociateCollection#uniq which is especially useful for has_and_belongs_to_many associations that can include duplicates, which is common on associations that also use metadata. Usage: post.categories.uniq
  • Fixed respond_to? to use a subclass specific hash instead of an Active Record-wide one
  • Fixed has_and_belongs_to_many to treat associations between classes in modules properly [Florian Weber]
  • Added a NoMethod exception to be raised when query and writer methods are called for attributes that doesn‘t exist [geech]
  • Added a more robust version of Fixtures that throws meaningful errors when on formatting issues [geech]
  • Added Base#transaction as a compliment to Base.transaction for prettier use in instance methods [geech]
  • Improved the speed of respond_to? by placing the dynamic methods lookup table in a hash [geech]
  • Added that any additional fields added to the join table in a has_and_belongs_to_many association will be placed as attributes when pulling records out through has_and_belongs_to_many associations. This is helpful when have information about the association itself that you want available on retrival.
  • Added better loading exception catching and RubyGems retries to the database adapters [alexeyv]
  • Fixed bug with per-model transactions [daniel]
  • Fixed Base#transaction so that it returns the result of the last expression in the transaction block [alexeyv]
  • Added Fixture#find to find the record corresponding to the fixture id. The record class name is guessed by using Inflector#classify (also new) on the fixture directory name.
      Before: Document.find(@documents["first"]["id"])
  After : @documents["first"].find
  • Fixed that the table name part of column names ("TABLE.COLUMN") wasn‘t removed properly [Andreas Schwarz]
  • Fixed a bug with Base#size when a finder_sql was used that didn‘t capitalize SELECT and FROM [geech]
  • Fixed quoting problems on SQLite by adding quote_string to the AbstractAdapter that can be overwritten by the concrete adapters for a call to the dbm. [Andreas Schwarz]
  • Removed RubyGems backup strategy for requiring SQLite-adapter — if people want to use gems, they‘re already doing it with AR.

*1.0.0 (35)*

  • Added OO-style associations methods [Florian Weber]. Examples:
      Project#milestones_count       => Project#milestones.size
  Project#build_to_milestones    => Project#milestones.build
  Project#create_for_milestones  => Project#milestones.create
  Project#find_in_milestones     => Project#milestones.find
  Project#find_all_in_milestones => Project#milestones.find_all
  • Added serialize as a new class method to control when text attributes should be YAMLized or not. This means that automated serialization of hashes, arrays, and so on WILL NO LONGER HAPPEN (10). You need to do something like this:
      class User < ActiveRecord::Base
    serialize :settings
  end

    This will assume that settings is a text column and will now YAMLize any object put in that attribute. You can also specify an optional :class_name option that‘ll raise an exception if a serialized object is retrieved as a descendant of a class not in the hierarchy. Example:

      class User < ActiveRecord::Base
    serialize :settings, :class_name => "Hash"
  end

  user = User.create("settings" => %w( one two three ))
  User.find(user.id).settings # => raises SerializationTypeMismatch
  • Added the option to connect to a different database for one model at a time. Just call establish_connection on the class you want to have connected to another database than Base. This will automatically also connect decendents of that class to the different database [Renald Buter].
  • Added transactional protection for Base#save. Validations can now check for values knowing that it happens in a transaction and callbacks can raise exceptions knowing that the save will be rolled back. [Suggested by Alexey Verkhovsky]
  • Added column name quoting so reserved words, such as "references", can be used as column names [Ryan Platte]
  • Added the possibility to chain the return of what happened inside a logged block [geech]:
      This now works:
    log { ... }.map { ... }

  Instead of doing:
    result = []
    log { result = ... }
    result.map { ... }
  • Added "socket" option for the MySQL adapter, so you can change it to something else than "/tmp/mysql.sock" [Anna Lissa Cruz]
  • Added respond_to? answers for all the attribute methods. So if Person has a name attribute retrieved from the table schema, person.respond_to? "name" will return true.
  • Added Base.benchmark which can be used to aggregate logging and benchmark, so you can measure and represent multiple statements in a single block. Usage (hides all the SQL calls for the individual actions and calculates total runtime for them all):
      Project.benchmark("Creating project") do
    project = Project.create("name" => "stuff")
    project.create_manager("name" => "David")
    project.milestones << Milestone.find_all
  end
  • Added logging of invalid SQL statements [Daniel Von Fange]
  • Added alias Errors#[] for Errors#on, so you can now say person.errors["name"] to retrieve the errors for name [Andreas Schwarz]
  • Added RubyGems require attempt if sqlite-ruby is not available through regular methods.
  • Added compatibility with 2.x series of sqlite-ruby drivers. [Jamis Buck]
  • Added type safety for association assignments, so a ActiveRecord::AssociationTypeMismatch will be raised if you attempt to assign an object that‘s not of the associated class. This cures the problem with nil giving id = 4 and fixnums giving id = 1 on mistaken association assignments. [Reported by Andreas Schwarz]
  • Added the option to keep many fixtures in one single YAML document [what-a-day]
  • Added the class method "inheritance_column" that can be overwritten to return the name of an alternative column than "type" for storing the type for inheritance hierarchies. [Dave Steinberg]
  • Added [] and []= as an alternative way to access attributes when the regular methods have been overwritten [Dave Steinberg]
  • Added the option to observer more than one class at the time by specifying observed_class as an array
  • Added auto-id propagation support for tables with arbitrary primary keys that have autogenerated sequences associated with them on PostgreSQL. [Dave Steinberg]
  • Changed that integer and floats set to "" through attributes= remain as NULL. This was especially a problem for scaffolding and postgresql. (49)
  • Changed the MySQL Adapter to rely on MySQL for its defaults for socket, host, and port [Andreas Schwarz]
  • Changed ActionControllerError to decent from StandardError instead of Exception. It can now be caught by a generic rescue.
  • Changed class inheritable attributes to not use eval [Caio Chassot]
  • Changed Errors#add to now use "invalid" as the default message instead of true, which means full_messages work with those [Marcel Molina Jr.]
  • Fixed spelling on Base#add_on_boundry_breaking to Base#add_on_boundary_breaking (old naming still works) [Marcel Molina Jr.]
  • Fixed that entries in the has_and_belongs_to_many join table didn‘t get removed when an associated object was destroyed.
  • Fixed unnecessary calls to SET AUTOCOMMIT=0/1 for MySQL adapter [Andreas Schwarz]
  • Fixed PostgreSQL defaults are now handled gracefully [Dave Steinberg]
  • Fixed increment/decrement_counter are now atomic updates [Andreas Schwarz]
  • Fixed the problems the Inflector had turning Attachment into attuchments and Cases into Casis [radsaq/Florian Gross]
  • Fixed that cloned records would point attribute references on the parent object [Andreas Schwarz]
  • Fixed SQL for type call on inheritance hierarchies [Caio Chassot]
  • Fixed bug with typed inheritance [Florian Weber]
  • Fixed a bug where has_many collection_count wouldn‘t use the conditions specified for that association

*0.9.5*

  • Expanded the table_name guessing rules immensely [Florian Green]. Documentation:
      Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
  directly from ActiveRecord. So if the hierarchy looks like: Reply < Message < ActiveRecord, then Message is used
  to guess the table name from even when called on Reply. The guessing rules are as follows:
  * Class name ends in "x", "ch" or "ss": "es" is appended, so a Search class becomes a searches table.
  * Class name ends in "y" preceded by a consonant or "qu": The "y" is replaced with "ies",
    so a Category class becomes a categories table.
  * Class name ends in "fe": The "fe" is replaced with "ves", so a Wife class becomes a wives table.
  * Class name ends in "lf" or "rf": The "f" is replaced with "ves", so a Half class becomes a halves table.
  * Class name ends in "person": The "person" is replaced with "people", so a Salesperson class becomes a salespeople table.
  * Class name ends in "man": The "man" is replaced with "men", so a Spokesman class becomes a spokesmen table.
  * Class name ends in "sis": The "i" is replaced with an "e", so a Basis class becomes a bases table.
  * Class name ends in "tum" or "ium": The "um" is replaced with an "a", so a Datum class becomes a data table.
  * Class name ends in "child": The "child" is replaced with "children", so a NodeChild class becomes a node_children table.
  * Class name ends in an "s": No additional characters are added or removed.
  * Class name doesn't end in "s": An "s" is appended, so a Comment class becomes a comments table.
  * Class name with word compositions: Compositions are underscored, so CreditCard class becomes a credit_cards table.
  Additionally, the class-level table_name_prefix is prepended to the table_name and the table_name_suffix is appended.
  So if you have "myapp_" as a prefix, the table name guess for an Account class becomes "myapp_accounts".

  You can also overwrite this class method to allow for unguessable links, such as a Mouse class with a link to a
  "mice" table. Example:

    class Mouse < ActiveRecord::Base
       def self.table_name() "mice" end
    end

    This conversion is now done through an external class called Inflector residing in lib/active_record/support/inflector.rb.

  • Added find_all_in_collection to has_many defined collections. Works like this:
      class Firm < ActiveRecord::Base
    has_many :clients
  end

  firm.id # => 1
  firm.find_all_in_clients "revenue > 1000" # SELECT * FROM clients WHERE firm_id = 1 AND revenue > 1000

    [Requested by Dave Thomas]

  • Fixed finders for inheritance hierarchies deeper than one level [Florian Weber]
  • Added add_on_boundry_breaking to errors to accompany add_on_empty as a default validation method. It‘s used like this:
      class Person < ActiveRecord::Base
    protected
      def validation
        errors.add_on_boundry_breaking "password", 3..20
      end
  end

    This will add an error to the tune of "is too short (minimum is 3 characters)" or "is too long (minimum is 20 characters)" if the password is outside the boundry. The messages can be changed by passing a third and forth parameter as message strings.

  • Implemented a clone method that works properly with AR. It returns a clone of the record that hasn‘t been assigned an id yet and is treated as a new record.
  • Allow for domain sockets in PostgreSQL by not assuming localhost when no host is specified [Scott Barron]
  • Fixed that bignums are saved properly instead of attempted to be YAMLized [Andreas Schwartz]
  • Fixed a bug in the GEM where the rdoc options weren‘t being passed according to spec [Chad Fowler]
  • Fixed a bug with the exclusively_dependent option for has_many

*0.9.4*

  • Correctly guesses the primary key when the class is inside a module [Dave Steinberg].
  • Added [] and []= as alternatives to read_attribute and write_attribute [Dave Steinberg]
  • has_and_belongs_to_many now accepts an :order key to determine in which order the collection is returned [radsaq].
  • The ids passed to find and find_on_conditions are now automatically sanitized.
  • Added escaping of plings in YAML content.
  • Multi-parameter assigns where all the parameters are empty will now be set to nil instead of a new instance of their class.
  • Proper type within an inheritance hierarchy is now ensured already at object initialization (instead of first at create)

*0.9.3*

  • Fixed bug with using a different primary key name together with has_and_belongs_to_many [Investigation by Scott]
  • Added :exclusively_dependent option to the has_many association macro. The doc reads:
      If set to true all the associated object are deleted in one SQL statement without having their
  before_destroy callback run. This should only be used on associations that depend solely on
  this class and don't need to do any clean-up in before_destroy. The upside is that it's much
  faster, especially if there's a counter_cache involved.
  • Added :port key to connection options, so the PostgreSQL and MySQL adapters can connect to a database server running on another port than the default.
  • Converted the new natural singleton methods that prevented AR objects from being saved by PStore (and hence be placed in a Rails session) to a module. [Florian Weber]
  • Fixed the use of floats (was broken since 0.9.0+)
  • Fixed PostgreSQL adapter so default values are displayed properly when used in conjunction with Action Pack scaffolding.
  • Fixed booleans support for PostgreSQL (use real true/false on boolean fields instead of 0/1 on tinyints) [radsaq]

*0.9.2*

  • Added static method for instantly updating a record
  • Treat decimal and numeric as Ruby floats [Andreas Schwartz]
  • Treat chars as Ruby strings (fixes problem for Action Pack form helpers too)
  • Removed debugging output accidently left in (which would screw web applications)

*0.9.1*

  • Added MIT license
  • Added natural object-style assignment for has_and_belongs_to_many associations. Consider the following model:
      class Event < ActiveRecord::Base
    has_one_and_belongs_to_many :sponsors
  end

  class Sponsor < ActiveRecord::Base
    has_one_and_belongs_to_many :sponsors
  end

    Earlier, you‘d have to use synthetic methods for creating associations between two objects of the above class:

      roskilde_festival.add_to_sponsors(carlsberg)
  roskilde_festival.remove_from_sponsors(carlsberg)

  nike.add_to_events(world_cup)
  nike.remove_from_events(world_cup)

    Now you can use regular array-styled methods:

      roskilde_festival.sponsors << carlsberg
  roskilde_festival.sponsors.delete(carlsberg)

  nike.events << world_cup
  nike.events.delete(world_cup)
  • Added delete method for has_many associations. Using this will nullify an association between the has_many and the belonging object by setting the foreign key to null. Consider this model:
      class Post < ActiveRecord::Base
    has_many :comments
  end

  class Comment < ActiveRecord::Base
    belongs_to :post
  end

    You could do something like:

      funny_comment.has_post? # => true
  announcement.comments.delete(funny_comment)
  funny_comment.has_post? # => false

*0.9.0*

  • Active Record is now thread safe! (So you can use it with Cerise and WEBrick applications) [Implementation idea by Michael Neumann, debugging assistance by Jamis Buck]
  • Improved performance by roughly 400% on a basic test case of pulling 100 records and querying one attribute. This brings the tax for using Active Record instead of "riding on the metal" (using MySQL-ruby C-driver directly) down to ~50%. Done by doing lazy type conversions and caching column information on the class-level.
  • Added callback objects and procs as options for implementing the target for callback macros.
  • Added "counter_cache" option to belongs_to that automates the usage of increment_counter and decrement_counter. Consider:
      class Post < ActiveRecord::Base
    has_many :comments
  end

  class Comment < ActiveRecord::Base
    belongs_to :post
  end

    Iterating over 100 posts like this:

      <% for post in @posts %>
    <%= post.title %> has <%= post.comments_count %> comments
  <% end %>

    Will generate 100 SQL count queries — one for each call to post.comments_count. If you instead add a "comments_count" int column to the posts table and rewrite the comments association macro with:

      class Comment < ActiveRecord::Base
    belongs_to :post, :counter_cache => true
  end

    Those 100 SQL count queries will be reduced to zero. Beware that counter caching is only appropriate for objects that begin life with the object it‘s specified to belong with and is destroyed like that as well. Typically objects where you would also specify :dependent => true. If your objects switch from one belonging to another (like a post that can be move from one category to another), you‘ll have to manage the counter yourself.

  • Added natural object-style assignment for has_one and belongs_to associations. Consider the following model:
      class Project < ActiveRecord::Base
    has_one :manager
  end

  class Manager < ActiveRecord::Base
    belongs_to :project
  end

    Earlier, assignments would work like following regardless of which way the assignment told the best story:

      active_record.manager_id = david.id

    Now you can do it either from the belonging side:

      david.project = active_record

    …or from the having side:

      active_record.manager = david

    If the assignment happens from the having side, the assigned object is automatically saved. So in the example above, the project_id attribute on david would be set to the id of active_record, then david would be saved.

  • Added natural object-style assignment for has_many associations [Florian Weber]. Consider the following model:
      class Project < ActiveRecord::Base
    has_many :milestones
  end

  class Milestone < ActiveRecord::Base
    belongs_to :project
  end

    Earlier, assignments would work like following regardless of which way the assignment told the best story:

      deadline.project_id = active_record.id

    Now you can do it either from the belonging side:

      deadline.project = active_record

    …or from the having side:

      active_record.milestones << deadline

    The milestone is automatically saved with the new foreign key.

  • API CHANGE: Attributes for text (or blob or similar) columns will now have unknown classes stored using YAML instead of using to_s. (Known classes that won‘t be yamelized are: String, NilClass, TrueClass, FalseClass, Fixnum, Date, and Time). Likewise, data pulled out of text-based attributes will be attempted converged using Yaml if they have the "— " header. This was primarily done to be enable the storage of hashes and arrays without wrapping them in aggregations, so now you can do:
      user = User.find(1)
  user.preferences = { "background" => "black", "display" => large }
  user.save

  User.find(1).preferences # => { "background" => "black", "display" => large }

    Please note that this method should only be used when you don‘t care about representing the object in proper columns in the database. A money object consisting of an amount and a currency is still a much better fit for a value object done through aggregations than this new option.

  • POSSIBLE CODE BREAKAGE: As a consequence of the lazy type conversions, it‘s a bad idea to reference the @attributes hash directly (it always was, but now it‘s paramount that you don‘t). If you do, you won‘t get the type conversion. So to implement new accessors for existing attributes, use read_attribute(attr_name) and write_attribute(attr_name, value) instead. Like this:
      class Song < ActiveRecord::Base
    # Uses an integer of seconds to hold the length of the song

    def length=(minutes)
      write_attribute("length", minutes * 60)
    end

    def length
      read_attribute("length") / 60
    end
  end

    The clever kid will notice that this opens a door to sidestep the automated type conversion by using @attributes directly. This is not recommended as read/write_attribute may be granted additional responsibilities in the future, but if you think you know what you‘re doing and aren‘t afraid of future consequences, this is an option.

  • Applied a few minor bug fixes reported by Daniel Von Fange.

*0.8.4*

Reflection

  • Added ActiveRecord::Reflection with a bunch of methods and classes for reflecting in aggregations and associations.
  • Added Base.columns and Base.content_columns which returns arrays of column description (type, default, etc) objects.
  • Added Base#attribute_names which returns an array of names for the attributes available on the object.
  • Added Base#column_for_attribute(name) which returns the column description object for the named attribute.

Misc

  • Added multi-parameter assignment:
      # Instantiate objects for all attribute classes that needs more than one constructor parameter. This is done
  # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
  # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
  # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
  # parenteses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float,
  # s for String, and a for Array.

    This is incredibly useful for assigning dates from HTML drop-downs of month, year, and day.

  • Fixed bug with custom primary key column name and Base.find on multiple parameters.
  • Fixed bug with dependent option on has_one associations if there was no associated object.

*0.8.3*

Transactions

  • Added transactional protection for destroy (important for the new :dependent option) [Suggested by Carl Youngblood]
  • Fixed so transactions are ignored on MyISAM tables for MySQL (use InnoDB to get transactions)
  • Changed transactions so only exceptions will cause a rollback, not returned false.

Mapping

  • Added support for non-integer primary keys [Aredridel/earlier work by Michael Neumann]
      User.find "jdoe"
  Product.find "PDKEY-INT-12"
  • Added option to specify naming method for primary key column. ActiveRecord::Base.primary_key_prefix_type can either be set to nil, :table_name, or :table_name_with_underscore. :table_name will assume that Product class has a primary key of "productid" and :table_name_with_underscore will assume "product_id". The default nil will just give "id".
  • Added an overwriteable primary_key method that‘ll instruct AR to the name of the id column [Aredridele/earlier work by Guan Yang]
      class Project < ActiveRecord::Base
    def self.primary_key() "project_id" end
  end
  • Fixed that Active Records can safely associate inside and out of modules.
      class MyApplication::Account < ActiveRecord::Base
    has_many :clients # will look for MyApplication::Client
    has_many :interests, :class_name => "Business::Interest" # will look for Business::Interest
  end
  • Fixed that Active Records can safely live inside modules [Aredridel]
      class MyApplication::Account < ActiveRecord::Base
  end

Misc

  • Added freeze call to value object assignments to ensure they remain immutable [Spotted by Gavin Sinclair]
  • Changed interface for specifying observed class in observers. Was OBSERVED_CLASS constant, now is observed_class() class method. This is more consistant with things like self.table_name(). Works like this:
      class AuditObserver < ActiveRecord::Observer
    def self.observed_class() Account end
    def after_update(account)
      AuditTrail.new(account, "UPDATED")
    end
  end

    [Suggested by Gavin Sinclair]

  • Create new Active Record objects by setting the attributes through a block. Like this:
      person = Person.new do |p|
    p.name = 'Freddy'
    p.age  = 19
  end

    [Suggested by Gavin Sinclair]

*0.8.2*

  • Added inheritable callback queues that can ensure that certain callback methods or inline fragments are run throughout the entire inheritance hierarchy. Regardless of whether a descendant overwrites the callback method:
      class Topic < ActiveRecord::Base
    before_destroy :destroy_author, 'puts "I'm an inline fragment"'
  end

    Learn more in classes/ActiveRecord/Callbacks.html

  • Added :dependent option to has_many and has_one, which will automatically destroy associated objects when the holder is destroyed:
      class Album < ActiveRecord::Base
    has_many :tracks, :dependent => true
  end

    All the associated tracks are destroyed when the album is.

  • Added Base.create as a factory that‘ll create, save, and return a new object in one step.
  • Automatically convert strings in config hashes to symbols for the _connection methods. This allows you to pass the argument hashes directly from yaml. (Luke)
  • Fixed the install.rb to include simple.rb [Spotted by Kevin Bullock]
  • Modified block syntax to better follow our code standards outlined in www.rubyonrails.org/CodingStandards

*0.8.1*

  • Added object-level transactions [Austin Ziegler]
  • Changed adapter-specific connection methods to use centralized ActiveRecord::Base.establish_connection, which is parametized through a config hash with symbol keys instead of a regular parameter list. This will allow for database connections to be opened in a more generic fashion. (Luke)

    NOTE: This requires all *_connections to be updated! Read more in: ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000081

  • Fixed SQLite adapter so objects fetched from has_and_belongs_to_many have proper attributes (t.name is now name). [Spotted by Garrett Rooney]
  • Fixed SQLite adapter so dates are returned as Date objects, not Time objects [Spotted by Gavin Sinclair]
  • Fixed requirement of date class, so date conversions are succesful regardless of whether you manually require date or not.

*0.8.0*

  • Added transactions
  • Changed Base.find to also accept either a list (1, 5, 6) or an array of ids ([5, 7]) as parameter and then return an array of objects instead of just an object
  • Fixed method has_collection? for has_and_belongs_to_many macro to behave as a collection, not an association
  • Fixed SQLite adapter so empty or nil values in columns of datetime, date, or time type aren‘t treated as current time [Spotted by Gavin Sinclair]

*0.7.6*

  • Fixed the install.rb to create the lib/active_record/support directory [Spotted by Gavin Sinclair]
  • Fixed that has_association? would always return true [Daniel Von Fange]


File: README

README

Path: | vendor/rails/actionpack/README
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Action Pack — On rails from request to response

Action Pack splits the response to a web request into a controller part (performing the logic) and a view part (rendering a template). This two-step approach is known as an action, which will normally create, read, update, or delete (CRUD for short) some sort of model part (often backed by a database) before choosing either to render a template or redirecting to another action.

Action Pack implements these actions as public methods on Action Controllers and uses Action Views to implement the template rendering. Action Controllers are then responsible for handling all the actions relating to a certain part of an application. This grouping usually consists of actions for lists and for CRUDs revolving around a single (or a few) model objects. So ContactsController would be responsible for listing contacts, creating, deleting, and updating contacts. A WeblogController could be responsible for both posts and comments.

Action View templates are written using embedded Ruby in tags mingled in with the HTML. To avoid cluttering the templates with code, a bunch of helper classes provide common behavior for forms, dates, and strings. And it‘s easy to add specific helpers to keep the separation as the application evolves.

Note: Some of the features, such as scaffolding and form building, are tied to ActiveRecord (an object-relational mapping package), but that doesn‘t mean that Action Pack depends on Active Record. Action Pack is an independent package that can be used with any sort of backend (Instiki, which is based on an older version of Action Pack, used Madeleine for example). Read more about the role Action Pack can play when used together with Active Record on www.rubyonrails.org.

A short rundown of the major features:

  • Actions grouped in controller as methods instead of separate command objects and can therefore share helper methods
      CustomersController < ActionController::Base
    def show
      @customer = find_customer
    end

    def update
      @customer = find_customer
      @customer.attributes = params[:customer]
      @customer.save ?
        redirect_to(:action => "show") :
        render(:action => "edit")
    end

    private
      def find_customer() Customer.find(params[:id]) end
  end

    Learn more

  • Embedded Ruby for templates (no new "easy" template language)
      <% for post in @posts %>
    Title: <%= post.title %>
  <% end %>

  All post titles: <%= @posts.collect{ |p| p.title }.join ", " %>

  <% unless @person.is_client? %>
    Not for clients to see...
  <% end %>

    Learn more

  • Builder-based templates (great for XML content, like RSS)
      xml.rss("version" => "2.0") do
    xml.channel do
      xml.title(@feed_title)
      xml.link(@url)
      xml.description "Basecamp: Recent items"
      xml.language "en-us"
      xml.ttl "40"

      for item in @recent_items
        xml.item do
          xml.title(item_title(item))
          xml.description(item_description(item))
          xml.pubDate(item_pubDate(item))
          xml.guid(@recent_items.url(item))
          xml.link(@recent_items.url(item))
        end
      end
    end
  end

    Learn more

  • Filters for pre and post processing of the response (as methods, procs, and classes)
      class WeblogController < ActionController::Base
    before_filter :authenticate, :cache, :audit
    after_filter { |c| c.response.body = Gzip::compress(c.response.body) }
    after_filter LocalizeFilter

    def index
      # Before this action is run, the user will be authenticated, the cache
      # will be examined to see if a valid copy of the results already
      # exists, and the action will be logged for auditing.

      # After this action has run, the output will first be localized then
      # compressed to minimize bandwidth usage
    end

    private
      def authenticate
        # Implement the filter with full access to both request and response
      end
  end

    Learn more

  • Helpers for forms, dates, action links, and text
      <%= text_field "post", "title", "size" => 30 %>
  <%= html_date_select(Date.today) %>
  <%= link_to "New post", :controller => "post", :action => "new" %>
  <%= truncate(post.title, :length => 25) %>

    Learn more

  • Layout sharing for template reuse (think simple version of Struts Tiles)
      class WeblogController < ActionController::Base
    layout "weblog_layout"

    def hello_world
    end
  end

  Layout file (called weblog_layout):
    <html><body><%= yield %></body></html>

  Template for hello_world action:
    <h1>Hello world</h1>

  Result of running hello_world action:
    <html><body><h1>Hello world</h1></body></html>

    Learn more

  • Routing makes pretty urls incredibly easy
      map.connect 'clients/:client_name/:project_name/:controller/:action'

  Accessing /clients/37signals/basecamp/project/dash calls ProjectController#dash with
  { "client_name" => "37signals", "project_name" => "basecamp" } in params[:params]

  From that URL, you can rewrite the redirect in a number of ways:

  redirect_to(:action => "edit") =>
    /clients/37signals/basecamp/project/dash

  redirect_to(:client_name => "nextangle", :project_name => "rails") =>
    /clients/nextangle/rails/project/dash

    Learn more

  • Javascript and Ajax integration
      link_to_function "Greeting", "alert('Hello world!')"
  link_to_remote "Delete this post", :update => "posts",
                 :url => { :action => "destroy", :id => post.id }

    Learn more

  • Easy testing of both controller and rendered template through ActionController::TestCase
      class LoginControllerTest < ActionController::TestCase
    def test_failing_authenticate
      process :authenticate, :user_name => "nop", :password => ""
      assert flash.has_key?(:alert)
      assert_redirected_to :action => "index"
    end
  end

    Learn more

  • Automated benchmarking and integrated logging
      Processing WeblogController#index (for 127.0.0.1 at Fri May 28 00:41:55)
  Parameters: {"action"=>"index", "controller"=>"weblog"}
  Rendering weblog/index (200 OK)
  Completed in 0.029281 (34 reqs/sec)

  If Active Record is used as the model, you'll have the database debugging
  as well:

  Processing PostsController#create (for 127.0.0.1 at Sat Jun 19 14:04:23)
  Params: {"controller"=>"posts", "action"=>"create",
           "post"=>{"title"=>"this is good"} }
  SQL (0.000627) INSERT INTO posts (title) VALUES('this is good')
  Redirected to http://example.com/posts/5
  Completed in 0.221764 (4 reqs/sec) | DB: 0.059920 (27%)

  You specify a logger through a class method, such as:

  ActionController::Base.logger = Logger.new("Application Log")
  ActionController::Base.logger = Log4r::Logger.new("Application Log")
  • Caching at three levels of granularity (page, action, fragment)
      class WeblogController < ActionController::Base
    caches_page :show
    caches_action :account

    def show
      # the output of the method will be cached as
      # ActionController::Base.page_cache_directory + "/weblog/show/n.html"
      # and the web server will pick it up without even hitting Rails
    end

    def account
      # the output of the method will be cached in the fragment store
      # but Rails is hit to retrieve it, so filters are run
    end

    def update
      List.update(params[:list][:id], params[:list])
      expire_page   :action => "show", :id => params[:list][:id]
      expire_action :action => "account"
      redirect_to   :action => "show", :id => params[:list][:id]
    end
  end

    Learn more

  • Powerful debugging mechanism for local requests
      All exceptions raised on actions performed on the request of a local user
  will be presented with a tailored debugging screen that includes exception
  message, stack trace, request parameters, session contents, and the
  half-finished response.

    Learn more

  • Scaffolding for Active Record model objects
      class AccountController < ActionController::Base
    scaffold :account
  end

  The AccountController now has the full CRUD range of actions and default
  templates: list, show, destroy, new, create, edit, update

    Learn more

  • Form building for Active Record model objects
      The post object has a title (varchar), content (text), and
  written_on (date)

  <%= form "post" %>

  ...will generate something like (the selects will have more options, of
  course):

  <form action="create" method="POST">
    <p>
      <b>Title:</b><br/>
      <input type="text" name="post[title]" value="<%= @post.title %>" />
    </p>
    <p>
      <b>Content:</b><br/>
      <textarea name="post[content]"><%= @post.title %></textarea>
    </p>
    <p>
      <b>Written on:</b><br/>
      <select name='post[written_on(3i)]'><option>18</option></select>
      <select name='post[written_on(2i)]'><option value='7'>July</option></select>
      <select name='post[written_on(1i)]'><option>2004</option></select>
    </p>

    <input type="submit" value="Create">
  </form>

  This form generates a params[:post] array that can be used directly in a save action:

  class WeblogController < ActionController::Base
    def create
      post = Post.create(params[:post])
      redirect_to :action => "show", :id => post.id
    end
  end

    Learn more

  • Runs on top of WEBrick, Mongrel, CGI, FCGI, and mod_ruby

Simple example (from outside of Rails)

This example will implement a simple weblog system using inline templates and an Active Record model. So let‘s build that WeblogController with just a few methods:

  require 'action_controller'
  require 'post'

  class WeblogController < ActionController::Base
    layout "weblog/layout"

    def index
      @posts = Post.find(:all)
    end

    def show
      @post = Post.find(params[:id])
    end

    def new
      @post = Post.new
    end

    def create
      @post = Post.create(params[:post])
      redirect_to :action => "show", :id => @post.id
    end
  end

  WeblogController::Base.view_paths = [ File.dirname(__FILE__) ]
  WeblogController.process_cgi if $0 == __FILE__

The last two lines are responsible for telling ActionController where the template files are located and actually running the controller on a new request from the web-server (like to be Apache).

And the templates look like this:

  weblog/layout.html.erb:
    <html><body>
    <%= yield %>
    </body></html>

  weblog/index.html.erb:
    <% for post in @posts %>
      <p><%= link_to(post.title, :action => "show", :id => post.id) %></p>
    <% end %>

  weblog/show.html.erb:
    <p>
      <b><%= @post.title %></b><br/>
      <b><%= @post.content %></b>
    </p>

  weblog/new.html.erb:
    <%= form "post" %>

This simple setup will list all the posts in the system on the index page, which is called by accessing /weblog/. It uses the form builder for the Active Record model to make the new screen, which in turn hands everything over to the create action (that‘s the default target for the form builder when given a new model). After creating the post, it‘ll redirect to the show page using an URL such as /weblog/5 (where 5 is the id of the post).

Download

The latest version of Action Pack can be found at

  • rubyforge.org/project/showfiles.php?group_id=249

Documentation can be found at

  • api.rubyonrails.com

Installation

You can install Action Pack with the following command.

  % [sudo] ruby install.rb

from its distribution directory.

License

Action Pack is released under the MIT license.

Support

The Action Pack homepage is www.rubyonrails.org. You can find the Action Pack RubyForge page at rubyforge.org/projects/actionpack. And as Jim from Rake says:

   Feel free to submit commits or feature requests.  If you send a patch,
   remember to update the corresponding unit tests.  If fact, I prefer
   new feature to be submitted in the form of new unit tests.


Module: ActionController::Assertions

Module | ActionController::Assertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb vendor/rails/actionpack/lib/action_controller/assertions/tag_assertions.rb

Classes and Modules

Module ActionController::Assertions::DomAssertions
Module ActionController::Assertions::ModelAssertions
Module ActionController::Assertions::ResponseAssertions
Module ActionController::Assertions::RoutingAssertions
Module ActionController::Assertions::SelectorAssertions
Module ActionController::Assertions::TagAssertions

Constants

NO_STRIP = %w{pre script style textarea}


Module: ActionController::Assertions::DomAssertions

Module | ActionController::Assertions::DomAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb

Methods

assert_dom_equal assert_dom_not_equal

Public Instance methods

assert_dom_equal(expected, actual, message = "")

Test two HTML strings for equivalency (e.g., identical up to reordering of attributes)

Examples

  # assert that the referenced method generates the appropriate HTML string
  assert_dom_equal '<a href="http://www.example.com">Apples</a>', link_to("Apples", "http://www.example.com")

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb, line 11
11:       def assert_dom_equal(expected, actual, message = "")
12:         clean_backtrace do
13:           expected_dom = HTML::Document.new(expected).root
14:           actual_dom   = HTML::Document.new(actual).root
15:           full_message = build_message(message, "<?> expected to be == to\n<?>.", expected_dom.to_s, actual_dom.to_s)
16:
17:           assert_block(full_message) { expected_dom == actual_dom }
18:         end
19:       end
assert_dom_not_equal(expected, actual, message = "")

The negated form of assert_dom_equivalent.

Examples

  # assert that the referenced method does not generate the specified HTML string
  assert_dom_not_equal '<a href="http://www.example.com">Apples</a>', link_to("Oranges", "http://www.example.com")

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb, line 28
28:       def assert_dom_not_equal(expected, actual, message = "")
29:         clean_backtrace do
30:           expected_dom = HTML::Document.new(expected).root
31:           actual_dom   = HTML::Document.new(actual).root
32:           full_message = build_message(message, "<?> expected to be != to\n<?>.", expected_dom.to_s, actual_dom.to_s)
33:
34:           assert_block(full_message) { expected_dom != actual_dom }
35:         end
36:       end


Module: ActionController::Assertions::ModelAssertions

Module | ActionController::Assertions::ModelAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb

Methods

assert_valid

Public Instance methods

assert_valid(record)

Ensures that the passed record is valid by Active Record standards and returns any error messages if it is not.

Examples

  # assert that a newly created record is valid
  model = Model.new
  assert_valid(model)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb, line 13
13:       def assert_valid(record)
14:         ::ActiveSupport::Deprecation.warn("assert_valid is deprecated. Use assert record.valid? instead", caller)
15:         clean_backtrace do
16:           assert record.valid?, record.errors.full_messages.join("\n")
17:         end
18:       end


Module: ActionController::Assertions::ResponseAssertions

Module | ActionController::Assertions::ResponseAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb

A small suite of assertions that test responses from Rails applications.

Methods

assert_redirected_to assert_response assert_template

Public Instance methods

assert_redirected_to(options = {}, message=nil)

Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that assert_redirected_to(:controller => "weblog") will also match the redirection of redirect_to(:controller => "weblog", :action => "show") and so on.

Examples

  # assert that the redirection was to the "index" action on the WeblogController
  assert_redirected_to :controller => "weblog", :action => "index"

  # assert that the redirection was to the named route login_url
  assert_redirected_to login_url

  # assert that the redirection was to the url for @customer
  assert_redirected_to @customer

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb, line 59
59:       def assert_redirected_to(options = {}, message=nil)
60:         clean_backtrace do
61:           assert_response(:redirect, message)
62:           return true if options == @response.redirected_to
63:
64:           # Support partial arguments for hash redirections
65:           if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
66:             return true if options.all? {|(key, value)| @response.redirected_to[key] == value}
67:           end
68:
69:           redirected_to_after_normalisation = normalize_argument_to_redirection(@response.redirected_to)
70:           options_after_normalisation       = normalize_argument_to_redirection(options)
71:
72:           if redirected_to_after_normalisation != options_after_normalisation
73:             flunk "Expected response to be a redirect to <#{options_after_normalisation}> but was a redirect to <#{redirected_to_after_normalisation}>"
74:           end
75:         end
76:       end
assert_response(type, message = nil)

Asserts that the response is one of the following types:

  • :success - Status code was 200
  • :redirect - Status code was in the 300-399 range
  • :missing - Status code was 404
  • :error - Status code was in the 500-599 range

You can also pass an explicit status number like assert_response(501) or its symbolic equivalent assert_response(:not_implemented). See ActionController::StatusCodes for a full list.

Examples

  # assert that the response was a redirection
  assert_response :redirect

  # assert that the response code was status code 401 (unauthorized)
  assert_response 401

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb, line 24
24:       def assert_response(type, message = nil)
25:         clean_backtrace do
26:           if [ :success, :missing, :redirect, :error ].include?(type) && @response.send("#{type}?")
27:             assert_block("") { true } # to count the assertion
28:           elsif type.is_a?(Fixnum) && @response.response_code == type
29:             assert_block("") { true } # to count the assertion
30:           elsif type.is_a?(Symbol) && @response.response_code == ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[type]
31:             assert_block("") { true } # to count the assertion
32:           else
33:             if @response.error?
34:               exception = @response.template.instance_variable_get(:@exception)
35:               exception_message = exception && exception.message
36:               assert_block(build_message(message, "Expected response to be a <?>, but was <?>\n<?>", type, @response.response_code, exception_message.to_s)) { false }
37:             else
38:               assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
39:             end
40:           end
41:         end
42:       end
assert_template(options = {}, message = nil)

Asserts that the request was rendered with the appropriate template file or partials

Examples

  # assert that the "new" view template was rendered
  assert_template "new"

  # assert that the "_customer" partial was rendered twice
  assert_template :partial => '_customer', :count => 2

  # assert that no partials were rendered
  assert_template :partial => false

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb, line 91
 91:       def assert_template(options = {}, message = nil)
 92:         clean_backtrace do
 93:           case options
 94:            when NilClass, String
 95:             rendered = @response.rendered[:template].to_s
 96:             msg = build_message(message,
 97:                     "expecting <?> but rendering with <?>",
 98:                     options, rendered)
 99:             assert_block(msg) do
100:               if options.nil?
101:                 @response.rendered[:template].blank?
102:               else
103:                 rendered.to_s.match(options)
104:               end
105:             end
106:           when Hash
107:             if expected_partial = options[:partial]
108:               partials = @response.rendered[:partials]
109:               if expected_count = options[:count]
110:                 found = partials.detect { |p, _| p.to_s.match(expected_partial) }
111:                 actual_count = found.nil? ? 0 : found.second
112:                 msg = build_message(message,
113:                         "expecting ? to be rendered ? time(s) but rendered ? time(s)",
114:                          expected_partial, expected_count, actual_count)
115:                 assert(actual_count == expected_count.to_i, msg)
116:               else
117:                 msg = build_message(message,
118:                         "expecting partial <?> but action rendered <?>",
119:                         options[:partial], partials.keys)
120:                 assert(partials.keys.any? { |p| p.to_s.match(expected_partial) }, msg)
121:               end
122:             else
123:               assert @response.rendered[:partials].empty?,
124:                 "Expected no partials to be rendered"
125:             end
126:           end
127:         end
128:       end


Module: ActionController::Assertions::RoutingAssertions

Module | ActionController::Assertions::RoutingAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb

Suite of assertions to test routes generated by Rails and the handling of requests made to them.

Methods

assert_generates assert_recognizes assert_routing

Public Instance methods

assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)

Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.

The defaults parameter is unused.

Examples

  # Asserts that the default action is generated for a route with no action
  assert_generates "/items", :controller => "items", :action => "index"

  # Tests that the list action is properly routed
  assert_generates "/items/list", :controller => "items", :action => "list"

  # Tests the generation of a route with a parameter
  assert_generates "/items/list/1", { :controller => "items", :action => "list", :id => "1" }

  # Asserts that the generated route gives us our custom route
  assert_generates "changesets/12", { :controller => 'scm', :action => 'show_diff', :revision => "12" }

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb, line 80
80:       def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
81:         clean_backtrace do
82:           expected_path = "/#{expected_path}" unless expected_path[0] == ?/
83:           # Load routes.rb if it hasn't been loaded.
84:           ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
85:
86:           generated_path, extra_keys = ActionController::Routing::Routes.generate_extras(options, defaults)
87:           found_extras = options.reject {|k, v| ! extra_keys.include? k}
88:
89:           msg = build_message(message, "found extras <?>, not <?>", found_extras, extras)
90:           assert_block(msg) { found_extras == extras }
91:
92:           msg = build_message(message, "The generated path <?> did not match <?>", generated_path,
93:               expected_path)
94:           assert_block(msg) { expected_path == generated_path }
95:         end
96:       end
assert_recognizes(expected_options, path, extras={}, message=nil)

Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.

Pass a hash in the second argument (path) to specify the request method. This is useful for routes requiring a specific HTTP method. The hash should contain a :path with the incoming request path and a :method containing the required HTTP verb.

  # assert that POSTing to /items will call the create action on ItemsController
  assert_recognizes {:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post}

You can also pass in extras with a hash containing URL parameters that would normally be in the query string. This can be used to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the extras argument, appending the query string on the path directly will not work. For example:

  # assert that a path of '/items/list/1?view=print' returns the correct options
  assert_recognizes {:controller => 'items', :action => 'list', :id => '1', :view => 'print'}, 'items/list/1', { :view => "print" }

The message parameter allows you to pass in an error message that is displayed upon failure.

Examples

  # Check the default route (i.e., the index action)
  assert_recognizes {:controller => 'items', :action => 'index'}, 'items'

  # Test a specific action
  assert_recognizes {:controller => 'items', :action => 'list'}, 'items/list'

  # Test an action with a parameter
  assert_recognizes {:controller => 'items', :action => 'destroy', :id => '1'}, 'items/destroy/1'

  # Test a custom route
  assert_recognizes {:controller => 'items', :action => 'show', :id => '1'}, 'view/item1'

  # Check a Simply RESTful generated route
  assert_recognizes list_items_url, 'items/list'

[Source]

    # File vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb, line 39
39:       def assert_recognizes(expected_options, path, extras={}, message=nil)
40:         if path.is_a? Hash
41:           request_method = path[:method]
42:           path           = path[:path]
43:         else
44:           request_method = nil
45:         end
46:
47:         clean_backtrace do
48:           ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
49:           request = recognized_request_for(path, request_method)
50:
51:           expected_options = expected_options.clone
52:           extras.each_key { |key| expected_options.delete key } unless extras.nil?
53:
54:           expected_options.stringify_keys!
55:           routing_diff = expected_options.diff(request.path_parameters)
56:           msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>",
57:               request.path_parameters, expected_options, expected_options.diff(request.path_parameters))
58:           assert_block(msg) { request.path_parameters == expected_options }
59:         end
60:       end
assert_routing(path, options, defaults={}, extras={}, message=nil)

Asserts that path and options match both ways; in other words, it verifies that path generates options and then that options generates path. This essentially combines assert_recognizes and assert_generates into one step.

The extras hash allows you to specify options that would normally be provided as a query string to the action. The message parameter allows you to specify a custom error message to display upon failure.

Examples

 # Assert a basic route: a controller with the default action (index)
 assert_routing '/home', :controller => 'home', :action => 'index'

 # Test a route generated with a specific controller, action, and parameter (id)
 assert_routing '/entries/show/23', :controller => 'entries', :action => 'show', id => 23

 # Assert a basic route (controller + default action), with an error message if it fails
 assert_routing '/store', { :controller => 'store', :action => 'index' }, {}, {}, 'Route for store index not generated properly'

 # Tests a route, providing a defaults hash
 assert_routing 'controller/action/9', {:id => "9", :item => "square"}, {:controller => "controller", :action => "action"}, {}, {:item => "square"}

 # Tests a route with a HTTP method
 assert_routing { :method => 'put', :path => '/product/321' }, { :controller => "product", :action => "update", :id => "321" }

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb, line 120
120:       def assert_routing(path, options, defaults={}, extras={}, message=nil)
121:         assert_recognizes(options, path, extras, message)
122:
123:         controller, default_controller = options[:controller], defaults[:controller]
124:         if controller && controller.include?(?/) && default_controller && default_controller.include?(?/)
125:           options[:controller] = "/#{controller}"
126:         end
127:
128:         assert_generates(path.is_a?(Hash) ? path[:path] : path, options, defaults, extras, message)
129:       end


Module: ActionController::Assertions::SelectorAssertions

Module | ActionController::Assertions::SelectorAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb

Adds the assert_select method for use in Rails functional test cases, which can be used to make assertions on the response HTML of a controller action. You can also call assert_select within another assert_select to make assertions on elements selected by the enclosing assertion.

Use css_select to select elements without making an assertions, either from the response HTML or elements selected by the enclosing assertion.

In addition to HTML responses, you can make the following assertions:

  • assert_select_rjs - Assertions on HTML content of RJS update and insertion operations.
  • assert_select_encoded - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
  • assert_select_email - Assertions on the HTML body of an e-mail.

Also see HTML::Selector to learn how to use selectors.

Methods

assert_select assert_select_email assert_select_encoded assert_select_rjs css_select response_from_page_or_rjs unescape_rjs

Constants

RJS_PATTERN_HTML | = | "\"((\\\\\"|[^\"])*)\""
RJS_ANY_ID | = | "\"([^\"])*\""
RJS_STATEMENTS | = | { :chained_replace => "\\$\\(#{RJS_ANY_ID}\\)\\.replace\\(#{RJS_PATTERN_HTML}\\)", :chained_replace_html => "\\$\\(#{RJS_ANY_ID}\\)\\.update\\(#{RJS_PATTERN_HTML}\\)", :replace_html => "Element\\.update\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)", :replace => "Element\\.replace\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)"
RJS_INSERTIONS | = | ["top", "bottom", "before", "after"]
RJS_PATTERN_UNICODE_ESCAPED_CHAR | = | /\\u([0-9a-zA-Z]{4})/

Public Instance methods

assert_select(selector, equality?, message?)
assert_select(element, selector, equality?, message?)

An assertion that selects elements and makes one or more equality tests.

If the first argument is an element, selects all matching elements starting from (and including) that element and all its children in depth-first order.

If no element if specified, calling assert_select selects from the response HTML unless assert_select is called from within an assert_select block.

When called with a block assert_select passes an array of selected elements to the block. Calling assert_select from the block, with no element specified, runs the assertion on the complete set of elements selected by the enclosing assertion. Alternatively the array may be iterated through so that assert_select can be called separately for each element.

Example

If the response contains two ordered lists, each with four list elements then:

  assert_select "ol" do |elements|
    elements.each do |element|
      assert_select element, "li", 4
    end
  end

will pass, as will:

  assert_select "ol" do
    assert_select "li", 8
  end

The selector may be a CSS selector expression (String), an expression with substitution values, or an HTML::Selector object.

Equality Tests

The equality test may be one of the following:

  • true - Assertion is true if at least one element selected.
  • false - Assertion is true if no element selected.
  • String/Regexp - Assertion is true if the text value of at least one element matches the string or regular expression.
  • Integer - Assertion is true if exactly that number of elements are selected.
  • Range - Assertion is true if the number of selected elements fit the range.

If no equality test specified, the assertion is true if at least one element selected.

To perform more than one equality tests, use a hash with the following keys:

  • :text - Narrow the selection to elements that have this text value (string or regexp).
  • :html - Narrow the selection to elements that have this HTML content (string or regexp).
  • :count - Assertion is true if the number of selected elements is equal to this value.
  • :minimum - Assertion is true if the number of selected elements is at least this value.
  • :maximum - Assertion is true if the number of selected elements is at most this value.

If the method is called with a block, once all equality tests are evaluated the block is called with an array of all matched elements.

Examples

  # At least one form element
  assert_select "form"

  # Form element includes four input fields
  assert_select "form input", 4

  # Page title is "Welcome"
  assert_select "title", "Welcome"

  # Page title is "Welcome" and there is only one title element
  assert_select "title", {:count=>1, :text=>"Welcome"},
      "Wrong title or more than one title element"

  # Page contains no forms
  assert_select "form", false, "This page must contain no forms"

  # Test the content and style
  assert_select "body div.header ul.menu"

  # Use substitution values
  assert_select "ol>li#?", /item-\d+/

  # All input fields in the form have a name
  assert_select "form input" do
    assert_select "[name=?]", /.+/  # Not empty
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 195
195:       def assert_select(*args, &block)
196:         # Start with optional element followed by mandatory selector.
197:         arg = args.shift
198:
199:         if arg.is_a?(HTML::Node)
200:           # First argument is a node (tag or text, but also HTML root),
201:           # so we know what we're selecting from.
202:           root = arg
203:           arg = args.shift
204:         elsif arg == nil
205:           # This usually happens when passing a node/element that
206:           # happens to be nil.
207:           raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
208:         elsif @selected
209:           root = HTML::Node.new(nil)
210:           root.children.concat @selected
211:         else
212:           # Otherwise just operate on the response document.
213:           root = response_from_page_or_rjs
214:         end
215:
216:         # First or second argument is the selector: string and we pass
217:         # all remaining arguments. Array and we pass the argument. Also
218:         # accepts selector itself.
219:         case arg
220:           when String
221:             selector = HTML::Selector.new(arg, args)
222:           when Array
223:             selector = HTML::Selector.new(*arg)
224:           when HTML::Selector
225:             selector = arg
226:           else raise ArgumentError, "Expecting a selector as the first argument"
227:         end
228:
229:         # Next argument is used for equality tests.
230:         equals = {}
231:         case arg = args.shift
232:           when Hash
233:             equals = arg
234:           when String, Regexp
235:             equals[:text] = arg
236:           when Integer
237:             equals[:count] = arg
238:           when Range
239:             equals[:minimum] = arg.begin
240:             equals[:maximum] = arg.end
241:           when FalseClass
242:             equals[:count] = 0
243:           when NilClass, TrueClass
244:             equals[:minimum] = 1
245:           else raise ArgumentError, "I don't understand what you're trying to match"
246:         end
247:
248:         # By default we're looking for at least one match.
249:         if equals[:count]
250:           equals[:minimum] = equals[:maximum] = equals[:count]
251:         else
252:           equals[:minimum] = 1 unless equals[:minimum]
253:         end
254:
255:         # Last argument is the message we use if the assertion fails.
256:         message = args.shift
257:         #- message = "No match made with selector #{selector.inspect}" unless message
258:         if args.shift
259:           raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type"
260:         end
261:
262:         matches = selector.select(root)
263:         # If text/html, narrow down to those elements that match it.
264:         content_mismatch = nil
265:         if match_with = equals[:text]
266:           matches.delete_if do |match|
267:             text = ""
268:             text.force_encoding(match_with.encoding) if text.respond_to?(:force_encoding)
269:             stack = match.children.reverse
270:             while node = stack.pop
271:               if node.tag?
272:                 stack.concat node.children.reverse
273:               else
274:                 content = node.content
275:                 content.force_encoding(match_with.encoding) if content.respond_to?(:force_encoding)
276:                 text << content
277:               end
278:             end
279:             text.strip! unless NO_STRIP.include?(match.name)
280:             unless match_with.is_a?(Regexp) ? (text =~ match_with) : (text == match_with.to_s)
281:               content_mismatch ||= build_message(message, "<?> expected but was\n<?>.", match_with, text)
282:               true
283:             end
284:           end
285:         elsif match_with = equals[:html]
286:           matches.delete_if do |match|
287:             html = match.children.map(&:to_s).join
288:             html.strip! unless NO_STRIP.include?(match.name)
289:             unless match_with.is_a?(Regexp) ? (html =~ match_with) : (html == match_with.to_s)
290:               content_mismatch ||= build_message(message, "<?> expected but was\n<?>.", match_with, html)
291:               true
292:             end
293:           end
294:         end
295:         # Expecting foo found bar element only if found zero, not if
296:         # found one but expecting two.
297:         message ||= content_mismatch if matches.empty?
298:         # Test minimum/maximum occurrence.
299:         min, max = equals[:minimum], equals[:maximum]
300:         message = message || %(Expected #{count_description(min, max)} matching "#{selector.to_s}", found #{matches.size}.)
301:         assert matches.size >= min, message if min
302:         assert matches.size <= max, message if max
303:
304:         # If a block is given call that block. Set @selected to allow
305:         # nested assert_select, which can be nested several levels deep.
306:         if block_given? && !matches.empty?
307:           begin
308:             in_scope, @selected = @selected, matches
309:             yield matches
310:           ensure
311:             @selected = in_scope
312:           end
313:         end
314:
315:         # Returns all matches elements.
316:         matches
317:       end
assert_select_email { }

Extracts the body of an email and runs nested assertions on it.

You must enable deliveries for this assertion to work, use:

  ActionMailer::Base.perform_deliveries = true

Examples

 assert_select_email do
   assert_select "h1", "Email alert"
 end

 assert_select_email do
   items = assert_select "ol>li"
   items.each do
      # Work with items here...
   end
 end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 557
557:       def assert_select_email(&block)
558:         deliveries = ActionMailer::Base.deliveries
559:         assert !deliveries.empty?, "No e-mail in delivery list"
560:
561:         for delivery in deliveries
562:           for part in delivery.parts
563:             if part["Content-Type"].to_s =~ /^text\/html\W/
564:               root = HTML::Document.new(part.body).root
565:               assert_select root, ":root", &block
566:             end
567:           end
568:         end
569:       end
assert_select_encoded(element?) { |elements| ... }

Extracts the content of an element, treats it as encoded HTML and runs nested assertion on it.

You typically call this method within another assertion to operate on all currently selected elements. You can also pass an element or array of elements.

The content of each element is un-encoded, and wrapped in the root element encoded. It then calls the block with all un-encoded elements.

Examples

  # Selects all bold tags from within the title of an ATOM feed's entries (perhaps to nab a section name prefix)
  assert_select_feed :atom, 1.0 do
    # Select each entry item and then the title item
    assert_select "entry>title" do
      # Run assertions on the encoded title elements
      assert_select_encoded do
        assert_select "b"
      end
    end
  end

  # Selects all paragraph tags from within the description of an RSS feed
  assert_select_feed :rss, 2.0 do
    # Select description element of each feed item.
    assert_select "channel>item>description" do
      # Run assertions on the encoded elements.
      assert_select_encoded do
        assert_select "p"
      end
    end
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 503
503:       def assert_select_encoded(element = nil, &block)
504:         case element
505:           when Array
506:             elements = element
507:           when HTML::Node
508:             elements = [element]
509:           when nil
510:             unless elements = @selected
511:               raise ArgumentError, "First argument is optional, but must be called from a nested assert_select"
512:             end
513:           else
514:             raise ArgumentError, "Argument is optional, and may be node or array of nodes"
515:         end
516:
517:         fix_content = lambda do |node|
518:           # Gets around a bug in the Rails 1.1 HTML parser.
519:           node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { CGI.escapeHTML($1) }
520:         end
521:
522:         selected = elements.map do |element|
523:           text = element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
524:           root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root
525:           css_select(root, "encoded:root", &block)[0]
526:         end
527:
528:         begin
529:           old_selected, @selected = @selected, selected
530:           assert_select ":root", &block
531:         ensure
532:           @selected = old_selected
533:         end
534:       end
assert_select_rjs(id?) { |elements| ... }
assert_select_rjs(statement, id?) { |elements| ... }
assert_select_rjs(:insert, position, id?) { |elements| ... }

Selects content from the RJS response.

Narrowing down

With no arguments, asserts that one or more elements are updated or inserted by RJS statements.

Use the id argument to narrow down the assertion to only statements that update or insert an element with that identifier.

Use the first argument to narrow down assertions to only statements of that type. Possible values are :replace, :replace_html, :show, :hide, :toggle, :remove and :insert_html.

Use the argument :insert followed by an insertion position to narrow down the assertion to only statements that insert elements in that position. Possible values are :top, :bottom, :before and :after.

Using the :remove statement, you will be able to pass a block, but it will be ignored as there is no HTML passed for this statement.

Using blocks

Without a block, assert_select_rjs merely asserts that the response contains one or more RJS statements that replace or update content.

With a block, assert_select_rjs also selects all elements used in these statements and passes them to the block. Nested assertions are supported.

Calling assert_select_rjs with no arguments and using nested asserts asserts that the HTML content is returned by one or more RJS statements. Using assert_select directly makes the same assertion on the content, but without distinguishing whether the content is returned in an HTML or JavaScript.

Examples

  # Replacing the element foo.
  # page.replace 'foo', ...
  assert_select_rjs :replace, "foo"

  # Replacing with the chained RJS proxy.
  # page[:foo].replace ...
  assert_select_rjs :chained_replace, 'foo'

  # Inserting into the element bar, top position.
  assert_select_rjs :insert, :top, "bar"

  # Remove the element bar
  assert_select_rjs :remove, "bar"

  # Changing the element foo, with an image.
  assert_select_rjs "foo" do
    assert_select "img[src=/images/logo.gif""
  end

  # RJS inserts or updates a list with four items.
  assert_select_rjs do
    assert_select "ol>li", 4
  end

  # The same, but shorter.
  assert_select "ol>li", 4

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 402
402:       def assert_select_rjs(*args, &block)
403:         rjs_type = args.first.is_a?(Symbol) ? args.shift : nil
404:         id       = args.first.is_a?(String) ? args.shift : nil
405:
406:         # If the first argument is a symbol, it's the type of RJS statement we're looking
407:         # for (update, replace, insertion, etc). Otherwise, we're looking for just about
408:         # any RJS statement.
409:         if rjs_type
410:           if rjs_type == :insert
411:             position  = args.shift
412:             id = args.shift
413:             insertion = "insert_#{position}".to_sym
414:             raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion]
415:             statement = "(#{RJS_STATEMENTS[insertion]})"
416:           else
417:             raise ArgumentError, "Unknown RJS statement type #{rjs_type}" unless RJS_STATEMENTS[rjs_type]
418:             statement = "(#{RJS_STATEMENTS[rjs_type]})"
419:           end
420:         else
421:           statement = "#{RJS_STATEMENTS[:any]}"
422:         end
423:
424:         # Next argument we're looking for is the element identifier. If missing, we pick
425:         # any element, otherwise we replace it in the statement.
426:         pattern = Regexp.new(
427:           id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement
428:         )
429:
430:         # Duplicate the body since the next step involves destroying it.
431:         matches = nil
432:         case rjs_type
433:           when :remove, :show, :hide, :toggle
434:             matches = @response.body.match(pattern)
435:           else
436:             @response.body.gsub(pattern) do |match|
437:               html = unescape_rjs(match)
438:               matches ||= []
439:               matches.concat HTML::Document.new(html).root.children.select { |n| n.tag? }
440:               ""
441:             end
442:         end
443:
444:         if matches
445:           assert_block("") { true } # to count the assertion
446:           if block_given? && !([:remove, :show, :hide, :toggle].include? rjs_type)
447:             begin
448:               in_scope, @selected = @selected, matches
449:               yield matches
450:             ensure
451:               @selected = in_scope
452:             end
453:           end
454:           matches
455:         else
456:           # RJS statement not found.
457:           case rjs_type
458:             when :remove, :show, :hide, :toggle
459:               flunk_message = "No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered."
460:             else
461:               flunk_message = "No RJS statement that replaces or inserts HTML content."
462:           end
463:           flunk args.shift || flunk_message
464:         end
465:       end
css_select(selector) => array
css_select(element, selector) => array

Select and return all matching elements.

If called with a single argument, uses that argument as a selector to match all elements of the current page. Returns an empty array if no match is found.

If called with two arguments, uses the first argument as the base element and the second argument as the selector. Attempts to match the base element and any of its children. Returns an empty array if no match is found.

The selector may be a CSS selector expression (String), an expression with substitution values (Array) or an HTML::Selector object.

Examples

  # Selects all div tags
  divs = css_select("div")

  # Selects all paragraph tags and does something interesting
  pars = css_select("p")
  pars.each do |par|
    # Do something fun with paragraphs here...
  end

  # Selects all list items in unordered lists
  items = css_select("ul>li")

  # Selects all form tags and then all inputs inside the form
  forms = css_select("form")
  forms.each do |form|
    inputs = css_select(form, "input")
    ...
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 65
 65:       def css_select(*args)
 66:         # See assert_select to understand what's going on here.
 67:         arg = args.shift
 68:
 69:         if arg.is_a?(HTML::Node)
 70:           root = arg
 71:           arg = args.shift
 72:         elsif arg == nil
 73:           raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
 74:         elsif @selected
 75:           matches = []
 76:
 77:           @selected.each do |selected|
 78:             subset = css_select(selected, HTML::Selector.new(arg.dup, args.dup))
 79:             subset.each do |match|
 80:               matches << match unless matches.any? { |m| m.equal?(match) }
 81:             end
 82:           end
 83:
 84:           return matches
 85:         else
 86:           root = response_from_page_or_rjs
 87:         end
 88:
 89:         case arg
 90:           when String
 91:             selector = HTML::Selector.new(arg, args)
 92:           when Array
 93:             selector = HTML::Selector.new(*arg)
 94:           when HTML::Selector
 95:             selector = arg
 96:           else raise ArgumentError, "Expecting a selector as the first argument"
 97:         end
 98:
 99:         selector.select(root)
100:       end

Protected Instance methods

response_from_page_or_rjs()

assert_select and css_select call this to obtain the content in the HTML page, or from all the RJS statements, depending on the type of response.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 595
595:         def response_from_page_or_rjs()
596:           content_type = @response.content_type
597:
598:           if content_type && Mime::JS =~ content_type
599:             body = @response.body.dup
600:             root = HTML::Node.new(nil)
601:
602:             while true
603:               next if body.sub!(RJS_STATEMENTS[:any]) do |match|
604:                 html = unescape_rjs(match)
605:                 matches = HTML::Document.new(html).root.children.select { |n| n.tag? }
606:                 root.children.concat matches
607:                 ""
608:               end
609:               break
610:             end
611:
612:             root
613:           else
614:             html_document.root
615:           end
616:         end
unescape_rjs(rjs_string)

Unescapes a RJS string.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb, line 619
619:         def unescape_rjs(rjs_string)
620:           # RJS encodes double quotes and line breaks.
621:           unescaped= rjs_string.gsub('\"', '"')
622:           unescaped.gsub!(/\\\//, '/')
623:           unescaped.gsub!('\n', "\n")
624:           unescaped.gsub!('\076', '>')
625:           unescaped.gsub!('\074', '<')
626:           # RJS encodes non-ascii characters.
627:           unescaped.gsub!(RJS_PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')}
628:           unescaped
629:         end


Module: ActionController::Assertions::TagAssertions

Module | ActionController::Assertions::TagAssertions
In: | vendor/rails/actionpack/lib/action_controller/assertions/tag_assertions.rb

Pair of assertions to testing elements in the HTML output of the response.

Methods

assert_no_tag assert_tag

Public Instance methods

assert_no_tag(*opts)

Identical to assert_tag, but asserts that a matching tag does not exist. (See assert_tag for a full discussion of the syntax.)

Examples

  # Assert that there is not a "div" containing a "p"
  assert_no_tag :tag => "div", :descendant => { :tag => "p" }

  # Assert that an unordered list is empty
  assert_no_tag :tag => "ul", :descendant => { :tag => "li" }

  # Assert that there is not a "p" tag with between 1 to 3 "img" tags
  # as immediate children
  assert_no_tag :tag => "p",
             :children => { :count => 1..3, :only => { :tag => "img" } }

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/tag_assertions.rb, line 118
118:       def assert_no_tag(*opts)
119:         clean_backtrace do
120:           opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first
121:           tag = find_tag(opts)
122:           assert !tag, "expected no tag, but found tag matching #{opts.inspect} in:\n#{@response.body.inspect}"
123:         end
124:       end
assert_tag(*opts)

Asserts that there is a tag/node/element in the body of the response that meets all of the given conditions. The conditions parameter must be a hash of any of the following keys (all are optional):

  • :tag: the node type must match the corresponding value
  • :attributes: a hash. The node‘s attributes must match the corresponding values in the hash.
  • :parent: a hash. The node‘s parent must match the corresponding hash.
  • :child: a hash. At least one of the node‘s immediate children must meet the criteria described by the hash.
  • :ancestor: a hash. At least one of the node‘s ancestors must meet the criteria described by the hash.
  • :descendant: a hash. At least one of the node‘s descendants must meet the criteria described by the hash.
  • :sibling: a hash. At least one of the node‘s siblings must meet the criteria described by the hash.
  • :after: a hash. The node must be after any sibling meeting the criteria described by the hash, and at least one sibling must match.
  • :before: a hash. The node must be before any sibling meeting the criteria described by the hash, and at least one sibling must match.
  • :children: a hash, for counting children of a node. Accepts the keys:
    • :count: either a number or a range which must equal (or include) the number of children that match.
    • :less_than: the number of matching children must be less than this number.
    • :greater_than: the number of matching children must be greater than this number.
    • :only: another hash consisting of the keys to use to match on the children, and only matching children will be counted.
  • :content: the textual content of the node must match the given value. This will not match HTML tags in the body of a tag—only text.

Conditions are matched using the following algorithm:

  • if the condition is a string, it must be a substring of the value.
  • if the condition is a regexp, it must match the value.
  • if the condition is a number, the value must match number.to_s.
  • if the condition is true, the value must not be nil.
  • if the condition is false or nil, the value must be nil.

Examples

  # Assert that there is a "span" tag
  assert_tag :tag => "span"

  # Assert that there is a "span" tag with id="x"
  assert_tag :tag => "span", :attributes => { :id => "x" }

  # Assert that there is a "span" tag using the short-hand
  assert_tag :span

  # Assert that there is a "span" tag with id="x" using the short-hand
  assert_tag :span, :attributes => { :id => "x" }

  # Assert that there is a "span" inside of a "div"
  assert_tag :tag => "span", :parent => { :tag => "div" }

  # Assert that there is a "span" somewhere inside a table
  assert_tag :tag => "span", :ancestor => { :tag => "table" }

  # Assert that there is a "span" with at least one "em" child
  assert_tag :tag => "span", :child => { :tag => "em" }

  # Assert that there is a "span" containing a (possibly nested)
  # "strong" tag.
  assert_tag :tag => "span", :descendant => { :tag => "strong" }

  # Assert that there is a "span" containing between 2 and 4 "em" tags
  # as immediate children
  assert_tag :tag => "span",
             :children => { :count => 2..4, :only => { :tag => "em" } }

  # Get funky: assert that there is a "div", with an "ul" ancestor
  # and an "li" parent (with "class" = "enum"), and containing a
  # "span" descendant that contains text matching /hello world/
  assert_tag :tag => "div",
             :ancestor => { :tag => "ul" },
             :parent => { :tag => "li",
                          :attributes => { :class => "enum" } },
             :descendant => { :tag => "span",
                              :child => /hello world/ }

Please note: assert_tag and assert_no_tag only work with well-formed XHTML. They recognize a few tags as implicitly self-closing (like br and hr and such) but will not work correctly with tags that allow optional closing tags (p, li, td). You must explicitly close all of your tags to use these assertions.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/assertions/tag_assertions.rb, line 96
 96:       def assert_tag(*opts)
 97:         clean_backtrace do
 98:           opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first
 99:           tag = find_tag(opts)
100:           assert tag, "expected tag, but no tag found matching #{opts.inspect} in:\n#{@response.body.inspect}"
101:         end
102:       end


Class: ActionController::Base

Class | ActionController::Base
In: | vendor/rails/actionpack/lib/action_controller/base.rb
Parent: | Object

Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either render a template or redirect to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.

A sample controller could look like this:

  class GuestBookController < ActionController::Base
    def index
      @entries = Entry.find(:all)
    end

    def sign
      Entry.create(params[:entry])
      redirect_to :action => "index"
    end
  end

Actions, by default, render a template in the app/views directory corresponding to the name of the controller and action after executing code in the action. For example, the index action of the GuestBookController would render the template app/views/guestbook/index.erb by default after populating the @entries instance variable.

Unlike index, the sign action will not render a template. After performing its main purpose (creating a new entry in the guest book), it initiates a redirect instead. This redirect works by returning an external "302 Moved" HTTP response that takes the user to the index action.

The index and sign represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect. Most actions are variations of these themes.

Requests

Requests are processed by the Action Controller framework by extracting the value of the "action" key in the request parameters. This value should hold the name of the action to be performed. Once the action has been identified, the remaining request parameters, the session (if one is available), and the full request with all the HTTP headers are made available to the action through instance variables. Then the action is performed.

The full request object is available with the request accessor and is primarily used to query for HTTP headers. These queries are made by accessing the environment hash, like this:

  def server_ip
    location = request.env["SERVER_ADDR"]
    render :text => "This server hosted at #{location}"
  end

Parameters

All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method which returns a hash. For example, an action that was performed through /weblog/list?category=All&limit=5 will include { "category" => "All", "limit" => 5 } in params.

It‘s also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:

  <input type="text" name="post[name]" value="david">
  <input type="text" name="post[address]" value="hyacintvej">

A request stemming from a form holding these inputs will include {
"post" => { "name" => "david",
"address" => "hyacintvej" } }. If the address
input had been named "post[address][street]", the params would
have included { "post" => { "address" => {
"street" => "hyacintvej" } } }. There‘s
no limit to the depth of the nesting.

Sessions

Sessions allows you to store objects in between requests. This is useful for objects that are not yet ready to be persisted, such as a Signup object constructed in a multi-paged process, or objects that don‘t change much and are needed all the time, such as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it‘s likely they could be changed unknowingly. It‘s usually too much work to keep it all synchronized — something databases already excel at.

You can place objects in the session by using the session method, which accesses a hash:

  session[:person] = Person.authenticate(user_name, password)

And retrieved again through the same hash:

  Hello #{session[:person]}

For removing objects from the session, you can either assign a single key to nil:

  # removes :person from session
  session[:person] = nil

or you can remove the entire session with reset_session.

Sessions are stored by default in a browser cookie that‘s cryptographically signed, but unencrypted. This prevents the user from tampering with the session but also allows him to see its contents.

Do not put secret information in cookie-based sessions!

Other options for session storage are:

  • ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and, unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
      config.action_controller.session_store = :active_record_store

    in your config/environment.rb and run rake db:sessions:create.

  • MemCacheStore - Sessions are stored as entries in your memcached cache. Set the session store type in config/environment.rb:
      config.action_controller.session_store = :mem_cache_store

    This assumes that memcached has been installed and configured properly. See the MemCacheStore docs for more information.

Responses

Each action results in a response, which holds the headers and document to be sent to the user‘s browser. The actual response object is generated automatically through the use of renders and redirects and requires no user intervention.

Renders

Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering of a template. Included in the Action Pack is the Action View, which enables rendering of ERb templates. It‘s automatically configured. The controller passes objects to the view by assigning instance variables:

  def show
    @post = Post.find(params[:id])
  end

Which are then automatically available to the view:

  Title: <%= @post.title %>

You don‘t have to rely on the automated rendering. Especially actions that could result in the rendering of different templates will use the manual rendering methods:

  def search
    @results = Search.find(params[:query])
    case @results
      when 0 then render :action => "no_results"
      when 1 then render :action => "show"
      when 2..10 then render :action => "show_many"
    end
  end

Read more about writing ERb and Builder templates in classes/ActionView/Base.html.

Redirects

Redirects are used to move from one action to another. For example, after a create action, which stores a blog entry to a database, we might like to show the user the new entry. Because we‘re following good DRY principles (Don‘t Repeat Yourself), we‘re going to reuse (and redirect to) a show action that we‘ll assume has already been created. The code might look like this:

  def create
    @entry = Entry.new(params[:entry])
    if @entry.save
      # The entry was saved correctly, redirect to show
      redirect_to :action => 'show', :id => @entry.id
    else
      # things didn't go so well, do something else
    end
  end

In this case, after saving our new entry to the database, the user is redirected to the show method which is then executed.

Calling multiple redirects or renders

An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:

  def do_something
    redirect_to :action => "elsewhere"
    render :action => "overthere" # raises DoubleRenderError
  end

If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.

  def do_something
    redirect_to(:action => "elsewhere") and return if monkeys.nil?
    render :action => "overthere" # won't be called if monkeys is nil
  end

Methods

append_view_path append_view_path call controller_class_name controller_class_name controller_name controller_name controller_path controller_path default_url_options expires_in expires_now filter_parameter_logging fresh_when head hidden_actions hide_action prepend_view_path prepend_view_path redirect_to redirect_to_full_url render render_to_string reset_session send_response session_enabled? stale? url_for view_paths view_paths view_paths= view_paths=

Included Modules

StatusCodes

Constants

DEFAULT_RENDER_STATUS_CODE = "200 OK"

Attributes

action_name [RW] Returns the name of the action this controller is processing.

Public Class methods

append_view_path(path)

Adds a view_path to the end of the view_paths array. If the current class has no view paths, copy them from the superclass. This change will be visible for all future requests.

  ArticleController.append_view_path("views/default")
  ArticleController.append_view_path(["views/default", "views/custom"])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 455
455:       def append_view_path(path)
456:         @view_paths = superclass.view_paths.dup if @view_paths.nil?
457:         @view_paths.push(*path)
458:       end
call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 382
382:       def call(env)
383:         # HACK: For global rescue to have access to the original request and response
384:         request = env["action_controller.rescue.request"] ||= Request.new(env)
385:         response = env["action_controller.rescue.response"] ||= Response.new
386:         process(request, response)
387:       end
controller_class_name()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 395
395:       def controller_class_name
396:         @controller_class_name ||= name.demodulize
397:       end
controller_name()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "neat".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 400
400:       def controller_name
401:         @controller_name ||= controller_class_name.sub(/Controller$/, '').underscore
402:       end
controller_path()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 405
405:       def controller_path
406:         @controller_path ||= name.gsub(/Controller$/, '').underscore
407:       end
filter_parameter_logging(*filter_words) {|key, value| ...}

Replace sensitive parameter data from the request log. Filters parameters that have any of the arguments as a substring. Looks in all subhashes of the param hash for keys to filter. If a block is given, each key and value of the parameter hash and all subhashes is passed to it, the value or key can be replaced using String#replace or similar method.

Examples:

  filter_parameter_logging
  => Does nothing, just slows the logging process down

  filter_parameter_logging :password
  => replaces the value to all keys matching /password/i with "[FILTERED]"

  filter_parameter_logging :foo, "bar"
  => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

  filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i }
  => reverses the value to all keys matching /secret/i

  filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i }
  => reverses the value to all keys matching /secret/i, and
     replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 483
483:       def filter_parameter_logging(*filter_words, &block)
484:         parameter_filter = Regexp.new(filter_words.collect{ |s| s.to_s }.join('|'), true) if filter_words.length > 0
485:
486:         define_method(:filter_parameters) do |unfiltered_parameters|
487:           filtered_parameters = {}
488:
489:           unfiltered_parameters.each do |key, value|
490:             if key =~ parameter_filter
491:               filtered_parameters[key] = '[FILTERED]'
492:             elsif value.is_a?(Hash)
493:               filtered_parameters[key] = filter_parameters(value)
494:             elsif block_given?
495:               key = key.dup
496:               value = value.dup if value
497:               yield key, value
498:               filtered_parameters[key] = value
499:             else
500:               filtered_parameters[key] = value
501:             end
502:           end
503:
504:           filtered_parameters
505:         end
506:         protected :filter_parameters
507:       end
hidden_actions()

Return an array containing the names of public methods that have been marked hidden from the action processor. By default, all methods defined in ActionController::Base and included modules are hidden. More methods can be hidden using hide_actions.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 412
412:       def hidden_actions
413:         read_inheritable_attribute(:hidden_actions) || write_inheritable_attribute(:hidden_actions, [])
414:       end
hide_action(*names)

Hide each of the given methods from being callable as actions.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 417
417:       def hide_action(*names)
418:         write_inheritable_attribute(:hidden_actions, hidden_actions | names.map { |name| name.to_s })
419:       end
prepend_view_path(path)

Adds a view_path to the front of the view_paths array. If the current class has no view paths, copy them from the superclass. This change will be visible for all future requests.

  ArticleController.prepend_view_path("views/default")
  ArticleController.prepend_view_path(["views/default", "views/custom"])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 443
443:       def prepend_view_path(path)
444:         @view_paths = superclass.view_paths.dup if !defined?(@view_paths) || @view_paths.nil?
445:         @view_paths.unshift(*path)
446:       end
view_paths()

View load paths determine the bases from which template references can be made. So a call to render("test/template") will be looked up in the view load paths array and the closest match will be returned.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 424
424:       def view_paths
425:         if defined? @view_paths
426:           @view_paths
427:         else
428:           superclass.view_paths
429:         end
430:       end
view_paths=(value)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 432
432:       def view_paths=(value)
433:         @view_paths = ActionView::Base.process_view_paths(value) if value
434:       end

Public Instance methods

append_view_path(path)

Adds a view_path to the end of the view_paths array. This change affects the current request only.

  self.append_view_path("views/default")
  self.append_view_path(["views/default", "views/custom"])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 677
677:       def append_view_path(path)
678:         @template.view_paths.push(*path)
679:       end
controller_class_name()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 632
632:       def controller_class_name
633:         self.class.controller_class_name
634:       end
controller_name()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "neat".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 637
637:       def controller_name
638:         self.class.controller_name
639:       end
controller_path()

Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 642
642:       def controller_path
643:         self.class.controller_path
644:       end
prepend_view_path(path)

Adds a view_path to the front of the view_paths array. This change affects the current request only.

  self.prepend_view_path("views/default")
  self.prepend_view_path(["views/default", "views/custom"])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 667
667:       def prepend_view_path(path)
668:         @template.view_paths.unshift(*path)
669:       end
send_response()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 530
530:       def send_response
531:         response.prepare!
532:         response
533:       end
session_enabled?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 646
646:       def session_enabled?
647:         ActiveSupport::Deprecation.warn("Sessions are now lazy loaded. So if you don't access them, consider them disabled.", caller)
648:       end
url_for(options = {})

Returns a URL that has been rewritten according to the options hash and the defined routes. (For doing a complete redirect, use redirect_to).

url_for is used to:

All keys given to url_for are forwarded to the Route module, save for the following:

  • :anchor - Specifies the anchor name to be appended to the path. For example, url_for :controller => ‘posts’, :action => ‘show’, :id => 10, :anchor => ‘comments‘ will produce "/posts/show/10#comments".
  • :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (false by default).
  • :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this is currently not recommended since it breaks caching.
  • :host - Overrides the default (current) host if provided.
  • :protocol - Overrides the default (current) protocol if provided.
  • :port - Optionally specify the port to connect to.
  • :user - Inline HTTP authentication (only plucked out if :password is also present).
  • :password - Inline HTTP authentication (only plucked out if :user is also present).
  • :skip_relative_url_root - If true, the url is not constructed using the relative_url_root of the request so the path will include the web server relative installation directory.

The URL is generated from the remaining keys in the hash. A URL contains two key parts: the <base> and a query string. Routes composes a query string as the key/value pairs not included in the <base>.

The default Routes setup supports a typical Rails path of "controller/action/id" where action and id are optional, with action defaulting to ‘index’ when not given. Here are some typical url_for statements and their corresponding URLs:

  url_for :controller => 'posts', :action => 'recent'                # => 'proto://host.com/posts/recent'
  url_for :controller => 'posts', :action => 'index'                 # => 'proto://host.com/posts'
  url_for :controller => 'posts', :action => 'index', :port=>'8033'  # => 'proto://host.com:8033/posts'
  url_for :controller => 'posts', :action => 'show', :id => 10       # => 'proto://host.com/posts/show/10'
  url_for :controller => 'posts', :user => 'd', :password => '123'   # => 'proto://d:123@host.com/posts'

When generating a new URL, missing values may be filled in from the current request‘s parameters. For example, url_for :action => ‘some_action‘ will retain the current controller, as expected. This behavior extends to other parameters, including :controller, :id, and any other parameters that are placed into a Route‘s path. The URL helpers such as url_for have a limited form of memory: when generating a new URL, they can look for missing values in the current request‘s parameters. Routes attempts to guess when a value should and should not be taken from the defaults. There are a few simple rules on how this is performed:

  • If the controller name begins with a slash no defaults are used:
      url_for :controller => '/home'

    In particular, a leading slash ensures no namespace is assumed. Thus, while url_for :controller => ‘users‘ may resolve to Admin::UsersController if the current controller lives under that module, url_for :controller => ’/users‘ ensures you link to ::UsersController no matter what.

  • If the controller changes, the action will default to index unless provided

The final rule is applied while the URL is being generated and is best illustrated by an example. Let us consider the route given by map.connect ‘people/:last/:first/:action’, :action => ‘bio’, :controller => ‘people‘.

Suppose that the current URL is "people/hh/david/contacts". Let‘s consider a few different cases of URLs which are generated from this page.

  • url_for :action => ‘bio‘ — During the generation of this URL, default values will be used for the first and

last components, and the action shall change. The generated URL will be, "people/hh/david/bio".

  • url_for :first => ‘davids-little-brother‘ This generates the URL ‘people/hh/davids-little-brother’ — note that this URL leaves out the assumed action of ‘bio’.

However, you might ask why the action from the current request, ‘contacts’, isn‘t carried over into the new URL. The answer has to do with the order in which the parameters appear in the generated path. In a nutshell, since the value that appears in the slot for :first is not equal to default value for :first we stop using defaults. On its own, this rule can account for much of the typical Rails URL behavior. Although a convenience, defaults can occasionally get in your way. In some cases a default persists longer than desired. The default may be cleared by adding :name => nil to url_for‘s options. This is often required when writing form helpers, since the defaults in play may vary greatly depending upon where the helper is used from. The following line will redirect to PostController‘s default action, regardless of the page it is displayed on:

  url_for :controller => 'posts', :action => nil

If you explicitly want to create a URL that‘s almost the same as the current URL, you can do so using the :overwrite_params options. Say for your posts you have different views for showing and printing them. Then, in the show view, you get the URL for the print view like this

  url_for :overwrite_params => { :action => 'print' }

This takes the current URL as is and only exchanges the action. In contrast, url_for :action => ‘print‘ would have slashed-off the path components after the changed action.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 619
619:       def url_for(options = {})
620:         options ||= {}
621:         case options
622:           when String
623:             options
624:           when Hash
625:             @url.rewrite(rewrite_options(options))
626:           else
627:             polymorphic_url(options)
628:         end
629:       end
view_paths()

View load paths for controller.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 653
653:       def view_paths
654:         @template.view_paths
655:       end
view_paths=(value)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 657
657:       def view_paths=(value)
658:         @template.view_paths = ActionView::Base.process_view_paths(value)
659:       end

Protected Instance methods

default_url_options(options = nil)

Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in the form of a hash, just like the one you would use for url_for directly. Example:

  def default_url_options(options)
    { :project => @project.active? ? @project.url_name : "unknown" }
  end

As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set by this method.

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1063
1063:       def default_url_options(options = nil)
1064:       end
expires_in(seconds, options = {})

Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a "private" instruction, so that intermediate caches shouldn‘t cache the response.

Examples:

  expires_in 20.minutes
  expires_in 3.hours, :public => true
  expires in 3.hours, 'max-stale' => 5.hours, :public => true

This method will overwrite an existing Cache-Control header. See www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1207
1207:       def expires_in(seconds, options = {}) #:doc:
1208:         cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
1209:
1210:         cache_control << "max-age=#{seconds}"
1211:         cache_control.delete("no-cache")
1212:         if options[:public]
1213:           cache_control.delete("private")
1214:           cache_control << "public"
1215:         else
1216:           cache_control << "private"
1217:         end
1218:
1219:         # This allows for additional headers to be passed through like 'max-stale' => 5.hours
1220:         cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
1221:
1222:         response.headers["Cache-Control"] = cache_control.join(', ')
1223:       end
expires_now(

Sets a HTTP 1.1 Cache-Control header of "no-cache" so no caching should occur by the browser or intermediate caches (like caching proxy servers).

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1227
1227:       def expires_now #:doc:
1228:         response.headers["Cache-Control"] = "no-cache"
1229:       end
fresh_when(options)

Sets the etag, last_modified, or both on the response and renders a "304 Not Modified" response if the request is already fresh.

Parameters:

  • :etag
  • :last_modified
  • :public By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).

Example:

  def show
    @article = Article.find(params[:id])
    fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
  end

This will render the show template if the request isn‘t sending a matching etag or If-Modified-Since header and just a "304 Not Modified" response if there‘s a match.

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1178
1178:       def fresh_when(options)
1179:         options.assert_valid_keys(:etag, :last_modified, :public)
1180:
1181:         response.etag          = options[:etag]          if options[:etag]
1182:         response.last_modified = options[:last_modified] if options[:last_modified]
1183:
1184:         if options[:public]
1185:           cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
1186:           cache_control.delete("private")
1187:           cache_control.delete("no-cache")
1188:           cache_control << "public"
1189:           response.headers["Cache-Control"] = cache_control.join(', ')
1190:         end
1191:
1192:         if request.fresh?(response)
1193:           head :not_modified
1194:         end
1195:       end
head(*args)

Return a response that has no content (merely headers). The options argument is interpreted to be a hash of header names and values. This allows you to easily return a response that consists only of significant headers:

  head :created, :location => person_path(@person)

It can also be used to return exceptional conditions:

  return head(:method_not_allowed) unless request.post?
  return head(:bad_request) unless valid_request?
  render

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1005
1005:       def head(*args)
1006:         if args.length > 2
1007:           raise ArgumentError, "too many arguments to head"
1008:         elsif args.empty?
1009:           raise ArgumentError, "too few arguments to head"
1010:         end
1011:         options = args.extract_options!
1012:         status = interpret_status(args.shift || options.delete(:status) || :ok)
1013:
1014:         options.each do |key, value|
1015:           headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s
1016:         end
1017:
1018:         render :nothing => true, :status => status
1019:       end
redirect_to(options = {}, response_status = {})

Redirects the browser to the target specified in options. This parameter can take one of three forms:

  • Hash - The URL will be generated by calling url_for with the options.
  • Record - The URL will be generated by calling url_for with the options, which will reference a named URL for that record.
  • String starting with protocol:// (like http://) - Is passed straight through as the target for redirection.
  • String not containing a protocol - The current protocol and host is prepended to the string.
  • :back - Back to the page that issued the request. Useful for forms that are triggered from multiple places. Short-hand for redirect_to(request.env["HTTP_REFERER"])

Examples:

  redirect_to :action => "show", :id => 5
  redirect_to post
  redirect_to "http://www.rubyonrails.org"
  redirect_to "/images/screenshot.jpg"
  redirect_to articles_url
  redirect_to :back

The redirection happens as a "302 Moved" header unless otherwise specified.

Examples:

  redirect_to post_url(@post), :status=>:found
  redirect_to :action=>'atom', :status=>:moved_permanently
  redirect_to post_url(@post), :status=>301
  redirect_to :action=>'atom', :status=>302

When using redirect_to :back, if there is no referrer, RedirectBackError will be raised. You may specify some fallback behavior for this case by rescuing RedirectBackError.

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1094
1094:       def redirect_to(options = {}, response_status = {}) #:doc:
1095:         raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
1096:
1097:         if options.is_a?(Hash) && options[:status]
1098:           status = options.delete(:status)
1099:         elsif response_status[:status]
1100:           status = response_status[:status]
1101:         else
1102:           status = 302
1103:         end
1104:
1105:         response.redirected_to = options
1106:
1107:         case options
1108:           # The scheme name consist of a letter followed by any combination of
1109:           # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
1110:           # characters; and is terminated by a colon (":").
1111:           when %r{^\w[\w\d+.-]*:.*}
1112:             redirect_to_full_url(options, status)
1113:           when String
1114:             redirect_to_full_url(request.protocol + request.host_with_port + options, status)
1115:           when :back
1116:             if referer = request.headers["Referer"]
1117:               redirect_to(referer, :status=>status)
1118:             else
1119:               raise RedirectBackError
1120:             end
1121:           else
1122:             redirect_to_full_url(url_for(options), status)
1123:         end
1124:       end
redirect_to_full_url(url, status)

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1126
1126:       def redirect_to_full_url(url, status)
1127:         raise DoubleRenderError if performed?
1128:         logger.info("Redirected to #{url}") if logger && logger.info?
1129:         response.redirect(url, interpret_status(status))
1130:         @performed_redirect = true
1131:       end
render(options = nil, extra_options = {}, &block)

Renders the content that will be returned to the browser as the response body.

Rendering an action

Action rendering is the most common form and the type used automatically by Action Controller when nothing else is specified. By default, actions are rendered within the current layout (if one exists).

  # Renders the template for the action "goal" within the current controller
  render :action => "goal"

  # Renders the template for the action "short_goal" within the current controller,
  # but without the current active layout
  render :action => "short_goal", :layout => false

  # Renders the template for the action "long_goal" within the current controller,
  # but with a custom layout
  render :action => "long_goal", :layout => "spectacular"

Rendering partials

Partial rendering in a controller is most commonly used together with Ajax calls that only update one or a few elements on a page without reloading. Rendering of partials from the controller makes it possible to use the same partial template in both the full-page rendering (by calling it from within the template) and when sub-page updates happen (from the controller action responding to Ajax calls). By default, the current layout is not used.

  # Renders the same partial with a local variable.
  render :partial => "person", :locals => { :name => "david" }

  # Renders the partial, making @new_person available through
  # the local variable 'person'
  render :partial => "person", :object => @new_person

  # Renders a collection of the same partial by making each element
  # of @winners available through the local variable "person" as it
  # builds the complete response.
  render :partial => "person", :collection => @winners

  # Renders a collection of partials but with a custom local variable name
  render :partial => "admin_person", :collection => @winners, :as => :person

  # Renders the same collection of partials, but also renders the
  # person_divider partial between each person partial.
  render :partial => "person", :collection => @winners, :spacer_template => "person_divider"

  # Renders a collection of partials located in a view subfolder
  # outside of our current controller.  In this example we will be
  # rendering app/views/shared/_note.r(html|xml)  Inside the partial
  # each element of @new_notes is available as the local var "note".
  render :partial => "shared/note", :collection => @new_notes

  # Renders the partial with a status code of 500 (internal error).
  render :partial => "broken", :status => 500

Note that the partial filename must also be a valid Ruby variable name, so e.g. 2005 and register-user are invalid.

Automatic etagging

Rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. No etag header will be inserted if it‘s already set.

Rendering a template

Template rendering works just like action rendering except that it takes a path relative to the template root. The current layout is automatically applied.

  # Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
  render :template => "weblog/show"

  # Renders the template with a local variable
  render :template => "weblog/show", :locals => {:customer => Customer.new}

Rendering a file

File rendering works just like action rendering except that it takes a filesystem path. By default, the path is assumed to be absolute, and the current layout is not applied.

  # Renders the template located at the absolute filesystem path
  render :file => "/path/to/some/template.erb"
  render :file => "c:/path/to/some/template.erb"

  # Renders a template within the current layout, and with a 404 status code
  render :file => "/path/to/some/template.erb", :layout => true, :status => 404
  render :file => "c:/path/to/some/template.erb", :layout => true, :status => 404

Rendering text

Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text rendering is not done within the active layout.

  # Renders the clear text "hello world" with status code 200
  render :text => "hello world!"

  # Renders the clear text "Explosion!"  with status code 500
  render :text => "Explosion!", :status => 500

  # Renders the clear text "Hi there!" within the current active layout (if one exists)
  render :text => "Hi there!", :layout => true

  # Renders the clear text "Hi there!" within the layout
  # placed in "app/views/layouts/special.r(html|xml)"
  render :text => "Hi there!", :layout => "special"

Streaming data and/or controlling the page generation

The :text option can also accept a Proc object, which can be used to:

  1. stream on-the-fly generated data to the browser. Note that you should use the methods provided by ActionController::Steaming instead if you want to stream a buffer or a file.
  2. manually control the page generation. This should generally be avoided, as it violates the separation between code and content, and because almost everything that can be done with this method can also be done more cleanly using one of the other rendering methods, most notably templates.

Two arguments are passed to the proc, a response object and an output object. The response object is equivalent to the return value of the ActionController::Base#response method, and can be used to control various things in the HTTP response, such as setting the Content-Type header. The output object is an writable IO-like object, so one can call write and flush on it.

The following example demonstrates how one can stream a large amount of on-the-fly generated data to the browser:

  # Streams about 180 MB of generated data to the browser.
  render :text => proc { |response, output|
    10_000_000.times do |i|
      output.write("This is line #{i}\n")
      output.flush
    end
  }

Another example:

  # Renders "Hello from code!"
  render :text => proc { |response, output| output.write("Hello from code!") }

Rendering XML

Rendering XML sets the content type to application/xml.

  # Renders '<name>David</name>'
  render :xml => {:name => "David"}.to_xml

It‘s not necessary to call to_xml on the object you want to render, since render will automatically do that for you:

  # Also renders '<name>David</name>'
  render :xml => {:name => "David"}

Rendering JSON

Rendering JSON sets the content type to application/json and optionally wraps the JSON in a callback. It is expected that the response will be parsed (or eval‘d) for use as a data structure.

  # Renders '{"name": "David"}'
  render :json => {:name => "David"}.to_json

It‘s not necessary to call to_json on the object you want to render, since render will automatically do that for you:

  # Also renders '{"name": "David"}'
  render :json => {:name => "David"}

Sometimes the result isn‘t handled directly by a script (such as when the request comes from a SCRIPT tag), so the :callback option is provided for these cases.

  # Renders 'show({"name": "David"})'
  render :json => {:name => "David"}.to_json, :callback => 'show'

Rendering an inline template

Rendering of an inline template works as a cross between text and action rendering where the source for the template is supplied inline, like text, but its interpreted with ERb or Builder, like action. By default, ERb is used for rendering and the current layout is not used.

  # Renders "hello, hello, hello, again"
  render :inline => "<%= 'hello, ' * 3 + 'again' %>"

  # Renders "<p>Good seeing you!</p>" using Builder
  render :inline => "xml.p { 'Good seeing you!' }", :type => :builder

  # Renders "hello david"
  render :inline => "<%= 'hello ' + name %>", :locals => { :name => "david" }

Rendering inline JavaScriptGenerator page updates

In addition to rendering JavaScriptGenerator page updates with Ajax in RJS templates (see ActionView::Base for details), you can also pass the :update parameter to render, along with a block, to render page updates inline.

  render :update do |page|
    page.replace_html  'user_list', :partial => 'user', :collection => @users
    page.visual_effect :highlight, 'user_list'
  end

Rendering vanilla JavaScript

In addition to using RJS with render :update, you can also just render vanilla JavaScript with :js.

  # Renders "alert('hello')" and sets the mime type to text/javascript
  render :js => "alert('hello')"

Rendering with status and location headers

All renders take the :status and :location options and turn them into headers. They can even be used together:

  render :xml => post.to_xml, :status => :created, :location => post_url(post)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 891
891:       def render(options = nil, extra_options = {}, &block) #:doc:
892:         raise DoubleRenderError, "Can only render or redirect once per action" if performed?
893:
894:         validate_render_arguments(options, extra_options, block_given?)
895:
896:         if options.nil?
897:           options = { :template => default_template, :layout => true }
898:         elsif options == :update
899:           options = extra_options.merge({ :update => true })
900:         elsif options.is_a?(String) || options.is_a?(Symbol)
901:           case options.to_s.index('/')
902:           when 0
903:             extra_options[:file] = options
904:           when nil
905:             extra_options[:action] = options
906:           else
907:             extra_options[:template] = options
908:           end
909:
910:           options = extra_options
911:         elsif !options.is_a?(Hash)
912:           extra_options[:partial] = options
913:           options = extra_options
914:         end
915:
916:         layout = pick_layout(options)
917:         response.layout = layout.path_without_format_and_extension if layout
918:         logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
919:
920:         if content_type = options[:content_type]
921:           response.content_type = content_type.to_s
922:         end
923:
924:         if location = options[:location]
925:           response.headers["Location"] = url_for(location)
926:         end
927:
928:         if options.has_key?(:text)
929:           text = layout ? @template.render(options.merge(:text => options[:text], :layout => layout)) : options[:text]
930:           render_for_text(text, options[:status])
931:
932:         else
933:           if file = options[:file]
934:             render_for_file(file, options[:status], layout, options[:locals] || {})
935:
936:           elsif template = options[:template]
937:             render_for_file(template, options[:status], layout, options[:locals] || {})
938:
939:           elsif inline = options[:inline]
940:             render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
941:
942:           elsif action_name = options[:action]
943:             render_for_file(default_template(action_name.to_s), options[:status], layout)
944:
945:           elsif xml = options[:xml]
946:             response.content_type ||= Mime::XML
947:             render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options[:status])
948:
949:           elsif js = options[:js]
950:             response.content_type ||= Mime::JS
951:             render_for_text(js, options[:status])
952:
953:           elsif json = options[:json]
954:             json = json.to_json unless json.is_a?(String)
955:             json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
956:             response.content_type ||= Mime::JSON
957:             render_for_text(json, options[:status])
958:
959:           elsif options[:partial]
960:             options[:partial] = default_template_name if options[:partial] == true
961:             if layout
962:               render_for_text(@template.render(:text => @template.render(options), :layout => layout), options[:status])
963:             else
964:               render_for_text(@template.render(options), options[:status])
965:             end
966:
967:           elsif options[:update]
968:             @template.send(:_evaluate_assigns_and_ivars)
969:
970:             generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
971:             response.content_type = Mime::JS
972:             render_for_text(generator.to_s, options[:status])
973:
974:           elsif options[:nothing]
975:             render_for_text(nil, options[:status])
976:
977:           else
978:             render_for_file(default_template, options[:status], layout)
979:           end
980:         end
981:       end
render_to_string(options = nil, &block)

Renders according to the same rules as render, but returns the result in a string instead of sending it as the response body to the browser.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/base.rb, line 985
985:       def render_to_string(options = nil, &block) #:doc:
986:         render(options, &block)
987:       ensure
988:         response.content_type = nil
989:         erase_render_results
990:         reset_variables_added_to_assigns
991:       end
reset_session(

Resets the session by clearing out all the objects stored within and initializing a new session object.

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1232
1232:       def reset_session #:doc:
1233:         request.reset_session
1234:         @_session = request.session
1235:       end
stale?(options)

Sets the etag and/or last_modified on the response and checks it against the client request. If the request doesn‘t match the options provided, the request is considered stale and should be generated from scratch. Otherwise, it‘s fresh and we don‘t need to generate anything and a reply of "304 Not Modified" is sent.

Parameters:

  • :etag
  • :last_modified
  • :public By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).

Example:

  def show
    @article = Article.find(params[:id])

    if stale?(:etag => @article, :last_modified => @article.created_at.utc)
      @statistics = @article.really_expensive_call
      respond_to do |format|
        # all the supported formats
      end
    end
  end

[Source]

      # File vendor/rails/actionpack/lib/action_controller/base.rb, line 1155
1155:       def stale?(options)
1156:         fresh_when(options)
1157:         !request.fresh?(response)
1158:       end


Module: ActionController::Benchmarking::ClassMethods

Module | ActionController::Benchmarking::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/benchmarking.rb

Methods

benchmark silence

Public Instance methods

benchmark(title, log_level = Logger::DEBUG, use_silence = true) {|| ...}

Log and benchmark the workings of a single block and silence whatever logging that may have happened inside it (unless use_silence is set to false).

The benchmark is only recorded if the current level of the logger matches the log_level, which makes it easy to include benchmarking statements in production software that will remain inexpensive because the benchmark will only be conducted if the log level is low enough.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/benchmarking.rb, line 23
23:       def benchmark(title, log_level = Logger::DEBUG, use_silence = true)
24:         if logger && logger.level == log_level
25:           result = nil
26:           ms = Benchmark.ms { result = use_silence ? silence { yield } : yield }
27:           logger.add(log_level, "#{title} (#{('%.1f' % ms)}ms)")
28:           result
29:         else
30:           yield
31:         end
32:       end
silence() {|| ...}

Silences the logger for the duration of the block.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/benchmarking.rb, line 35
35:       def silence
36:         old_logger_level, logger.level = logger.level, Logger::ERROR if logger
37:         yield
38:       ensure
39:         logger.level = old_logger_level if logger
40:       end


Class: ActionController::CGIHandler

Class | ActionController::CGIHandler
In: | vendor/rails/actionpack/lib/action_controller/cgi_process.rb
Parent: | Object

Methods

dispatch_cgi

Classes and Modules

Module ActionController::CGIHandler::ProperStream

Public Class methods

dispatch_cgi(app, cgi, out = $stdout)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_process.rb, line 21
21:     def self.dispatch_cgi(app, cgi, out = $stdout)
22:       env = cgi.__send__(:env_table)
23:       env.delete "HTTP_CONTENT_LENGTH"
24:
25:       cgi.stdinput.extend ProperStream
26:
27:       env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
28:
29:       env.update({
30:         "rack.version" => [0,1],
31:         "rack.input" => cgi.stdinput,
32:         "rack.errors" => $stderr,
33:         "rack.multithread" => false,
34:         "rack.multiprocess" => true,
35:         "rack.run_once" => false,
36:         "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
37:       })
38:
39:       env["QUERY_STRING"] ||= ""
40:       env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
41:       env["REQUEST_PATH"] ||= "/"
42:       env.delete "PATH_INFO" if env["PATH_INFO"] == ""
43:
44:       status, headers, body = app.call(env)
45:       begin
46:         out.binmode if out.respond_to?(:binmode)
47:         out.sync = false if out.respond_to?(:sync=)
48:
49:         headers['Status'] = status.to_s
50:
51:         if headers.include?('Set-Cookie')
52:           headers['cookie'] = headers.delete('Set-Cookie').split("\n")
53:         end
54:
55:         out.write(cgi.header(headers))
56:
57:         body.each { |part|
58:           out.write part
59:           out.flush if out.respond_to?(:flush)
60:         }
61:       ensure
62:         body.close if body.respond_to?(:close)
63:       end
64:     end


Module: ActionController::CGIHandler::ProperStream

Module | ActionController::CGIHandler::ProperStream
In: | vendor/rails/actionpack/lib/action_controller/cgi_process.rb

Methods

each read

Public Instance methods

each() {|line| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_process.rb, line 6
 6:       def each
 7:         while line = gets
 8:           yield line
 9:         end
10:       end
read(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_process.rb, line 12
12:       def read(*args)
13:         if args.empty?
14:           super || ""
15:         else
16:           super
17:         end
18:       end


Module: ActionController::Caching

Module | ActionController::Caching
In: | vendor/rails/actionpack/lib/action_controller/caching/actions.rb vendor/rails/actionpack/lib/action_controller/caching/fragments.rb vendor/rails/actionpack/lib/action_controller/caching/pages.rb vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb vendor/rails/actionpack/lib/action_controller/caching.rb

Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls around for subsequent requests. Action Controller affords you three approaches in varying levels of granularity: Page, Action, Fragment.

You can read more about each approach and the sweeping assistance by clicking the modules below.

Note: To turn off all caching and sweeping, set Base.perform_caching = false.

Caching stores

All the caching stores from ActiveSupport::Cache is available to be used as backends for Action Controller caching. This setting only affects action and fragment caching as page caching is always written to disk.

Configuration examples (MemoryStore is the default):

  ActionController::Base.cache_store = :memory_store
  ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
  ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
  ActionController::Base.cache_store = :mem_cache_store, "localhost"
  ActionController::Base.cache_store = MyOwnStore.new("parameter")

Methods

cache cache_configured? cache_store=

Included Modules

Pages Actions Fragments Sweeping

Classes and Modules

Module ActionController::Caching::Actions
Module ActionController::Caching::Fragments
Module ActionController::Caching::Pages
Module ActionController::Caching::Sweeping

Public Class methods

cache_configured?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching.rb, line 49
49:         def self.cache_configured?
50:           perform_caching && cache_store
51:         end
cache_store=(store_option)

Defines the storage option for cached fragments

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching.rb, line 39
39:         def self.cache_store=(store_option)
40:           @@cache_store = ActiveSupport::Cache.lookup_store(store_option)
41:         end

Protected Instance methods

cache(key, options = {}) {|| ...}

Convenience accessor

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching.rb, line 57
57:       def cache(key, options = {}, &block)
58:         if cache_configured?
59:           cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
60:         else
61:           yield
62:         end
63:       end


Module: ActionController::Caching::Actions

Module | ActionController::Caching::Actions
In: | vendor/rails/actionpack/lib/action_controller/caching/actions.rb

Action caching is similar to page caching by the fact that the entire output of the response is cached, but unlike page caching, every request still goes through the Action Pack. The key benefit of this is that filters are run before the cache is served, which allows for authentication and other restrictions on whether someone is allowed to see the cache. Example:

  class ListsController < ApplicationController
    before_filter :authenticate, :except => :public
    caches_page   :public
    caches_action :index, :show, :feed
  end

In this example, the public action doesn‘t require authentication, so it‘s possible to use the faster page caching method. But both the show and feed action are to be shielded behind the authenticate filter, so we need to implement those as action caches.

Action caching internally uses the fragment caching and an around filter to do the job. The fragment cache is named according to both the current host and the path. So a page that is accessed at david.somewhere.com/lists/show/1 will result in a fragment named "david.somewhere.com/lists/show/1". This allows the cacher to differentiate between "david.somewhere.com/lists/" and "jamis.somewhere.com/lists/" — which is a helpful way of assisting the subdomain-as-account-key pattern.

Different representations of the same resource, e.g. david.somewhere.com/lists and david.somewhere.com/lists.xml are treated like separate requests and so are cached separately. Keep in mind when expiring an action cache that :action => ‘lists‘ is not the same as :action => ‘list’, :format => :xml.

You can set modify the default action cache path by passing a :cache_path option. This will be passed directly to ActionCachePath.path_for. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance.

And you can also use :if (or :unless) to pass a Proc that specifies when the action should be cached.

Finally, if you are using memcached, you can also pass :expires_in.

  class ListsController < ApplicationController
    before_filter :authenticate, :except => :public
    caches_page   :public
    caches_action :index, :if => Proc.new { |c| !c.request.format.json? } # cache if is not a JSON request
    caches_action :show, :cache_path => { :project => 1 }, :expires_in => 1.hour
    caches_action :feed, :cache_path => Proc.new { |controller|
      controller.params[:user_id] ?
        controller.send(:user_list_url, controller.params[:user_id], controller.params[:id]) :
        controller.send(:list_url, controller.params[:id]) }
  end

If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information.

Methods

expire_action

Classes and Modules

Module ActionController::Caching::Actions::ClassMethods
Class ActionController::Caching::Actions::ActionCachePath

Protected Instance methods

expire_action(options = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/actions.rb, line 69
69:         def expire_action(options = {})
70:           return unless cache_configured?
71:
72:           if options[:action].is_a?(Array)
73:             options[:action].dup.each do |action|
74:               expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false))
75:             end
76:           else
77:             expire_fragment(ActionCachePath.path_for(self, options, false))
78:           end
79:         end


Class: ActionController::Caching::Actions::ActionCachePath

Class | ActionController::Caching::Actions::ActionCachePath
In: | vendor/rails/actionpack/lib/action_controller/caching/actions.rb
Parent: | Object

Methods

new path_for

Attributes

extension | [R]
path | [R]

Public Class methods

new(controller, options = {}, infer_extension = true)

When true, infer_extension will look up the cache path extension from the request‘s path & format. This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/caching/actions.rb, line 140
140:         def initialize(controller, options = {}, infer_extension = true)
141:           if infer_extension
142:             extract_extension(controller.request)
143:             options = options.reverse_merge(:format => @extension) if options.is_a?(Hash)
144:           end
145:
146:           path = controller.url_for(options).split('://').last
147:           normalize!(path)
148:           add_extension!(path, @extension)
149:           @path = URI.unescape(path)
150:         end
path_for(controller, options, infer_extension = true)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/caching/actions.rb, line 132
132:           def path_for(controller, options, infer_extension = true)
133:             new(controller, options, infer_extension).path
134:           end


Module: ActionController::Caching::Actions::ClassMethods

Module | ActionController::Caching::Actions::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/caching/actions.rb

Methods

caches_action

Public Instance methods

caches_action(*actions)

Declares that actions should be cached. See ActionController::Caching::Actions for details.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/actions.rb, line 58
58:         def caches_action(*actions)
59:           return unless cache_configured?
60:           options = actions.extract_options!
61:           filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) }
62:
63:           cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options)
64:           around_filter(cache_filter, filter_options)
65:         end


Module: ActionController::Caching::Fragments

Module | ActionController::Caching::Fragments
In: | vendor/rails/actionpack/lib/action_controller/caching/fragments.rb

Fragment caching is used for caching various blocks within templates without caching the entire action as a whole. This is useful when certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple parties. The caching is done using the cache helper available in the Action View. A template with caching might look something like:

  <b>Hello <%= @name %></b>
  <% cache do %>
    All the topics in the system:
    <%= render :partial => "topic", :collection => Topic.find(:all) %>
  <% end %>

This cache will bind to the name of the action that called it, so if this code was part of the view for the topics/list action, you would be able to invalidate it using expire_fragment(:controller => "topics", :action => "list").

This default behavior is of limited use if you need to cache multiple fragments per action or if the action itself is cached using caches_action, so we also have the option to qualify the name of the cached fragment with something like:

  <% cache(:action => "list", :action_suffix => "all_topics") do %>

That would result in a name such as "/topics/list/all_topics", avoiding conflicts with the action cache and with any fragments that use a different suffix. Note that the URL doesn‘t have to really exist or be callable - the url_for system is just used to generate unique cache names that we can refer to when we need to expire the cache.

The expiration call for this example is:

  expire_fragment(:controller => "topics", :action => "list", :action_suffix => "all_topics")

Methods

expire_fragment fragment_cache_key fragment_exist? read_fragment write_fragment

Public Instance methods

expire_fragment(key, options = nil)

Removes fragments from the cache.

key can take one of three forms:

  • String - This would normally take the form of a path, like "pages/45/notes".
  • Hash - Treated as an implicit call to url_for, like {:controller => "pages", :action => "notes", :id => 45}
  • Regexp - Will remove any fragment that matches, so %r{pages/\d*/notes} might remove all notes. Make sure you don‘t use anchors in the regex (^ or $) because the actual filename matched looks like ./cache/filename/path.cache. Note: Regexp expiration is only supported on caches that can iterate over all keys (unlike memcached).

options is passed through to the cache store‘s delete method (or delete_matched, for Regexp keys.)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/caching/fragments.rb, line 103
103:       def expire_fragment(key, options = nil)
104:         return unless cache_configured?
105:
106:         key = key.is_a?(Regexp) ? key : fragment_cache_key(key)
107:
108:         if key.is_a?(Regexp)
109:           self.class.benchmark "Expired fragments matching: #{key.source}" do
110:             cache_store.delete_matched(key, options)
111:           end
112:         else
113:           self.class.benchmark "Expired fragment: #{key}" do
114:             cache_store.delete(key, options)
115:           end
116:         end
117:       end
fragment_cache_key(key)

Given a key (as described in expire_fragment), returns a key suitable for use in reading, writing, or expiring a cached fragment. If the key is a hash, the generated key is the return value of url_for on that hash (without the protocol). All keys are prefixed with "views/" and uses ActiveSupport::Cache.expand_cache_key for the expansion.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/fragments.rb, line 33
33:       def fragment_cache_key(key)
34:         ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
35:       end
fragment_exist?(key, options = nil)

Check if a cached fragment from the location signified by key exists (see expire_fragment for acceptable formats)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/fragments.rb, line 76
76:       def fragment_exist?(key, options = nil)
77:         return unless cache_configured?
78:
79:         key = fragment_cache_key(key)
80:
81:         self.class.benchmark "Cached fragment exists?: #{key}" do
82:           cache_store.exist?(key, options)
83:         end
84:       end
read_fragment(key, options = nil)

Reads a cached fragment from the location signified by key (see expire_fragment for acceptable formats)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/fragments.rb, line 65
65:       def read_fragment(key, options = nil)
66:         return unless cache_configured?
67:
68:         key = fragment_cache_key(key)
69:
70:         self.class.benchmark "Cached fragment hit: #{key}" do
71:           cache_store.read(key, options)
72:         end
73:       end
write_fragment(key, content, options = nil)

Writes content to the location signified by key (see expire_fragment for acceptable formats)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/fragments.rb, line 52
52:       def write_fragment(key, content, options = nil)
53:         return content unless cache_configured?
54:
55:         key = fragment_cache_key(key)
56:
57:         self.class.benchmark "Cached fragment miss: #{key}" do
58:           cache_store.write(key, content, options)
59:         end
60:
61:         content
62:       end


Module: ActionController::Caching::Pages

Module | ActionController::Caching::Pages
In: | vendor/rails/actionpack/lib/action_controller/caching/pages.rb

Page caching is an approach to caching where the entire action output of is stored as a HTML file that the web server can serve without going through Action Pack. This is the fastest way to cache your content as opposed to going dynamically through the process of generating the content. Unfortunately, this incredible speed-up is only available to stateless pages where all visitors are treated the same. Content management systems — including weblogs and wikis — have many pages that are a great fit for this approach, but account-based systems where people log in and manipulate their own data are often less likely candidates.

Specifying which actions to cache is done through the caches_page class method:

  class WeblogController < ActionController::Base
    caches_page :show, :new
  end

This will generate cache files such as weblog/show/5.html and weblog/new.html, which match the URLs used to trigger the dynamic generation. This is how the web server is able pick up a cache file when it exists and otherwise let the request pass on to Action Pack to generate it.

Expiration of the cache is handled by deleting the cached file, which results in a lazy regeneration approach where the cache is not restored before another hit is made against it. The API for doing so mimics the options from url_for and friends:

  class WeblogController < ActionController::Base
    def update
      List.update(params[:list][:id], params[:list])
      expire_page :action => "show", :id => params[:list][:id]
      redirect_to :action => "show", :id => params[:list][:id]
    end
  end

Additionally, you can expire caches using Sweepers that act on changes in the model to determine when a cache is supposed to be expired.

Methods

cache_page expire_page

Classes and Modules

Module ActionController::Caching::Pages::ClassMethods

Public Instance methods

cache_page(content = nil, options = nil)

Manually cache the content in the key determined by options. If no content is provided, the contents of response.body is used If no options are provided, the requested url is used. Example:

  cache_page "I'm the cached content", :controller => "lists", :action => "show"

[Source]

     # File vendor/rails/actionpack/lib/action_controller/caching/pages.rb, line 131
131:       def cache_page(content = nil, options = nil)
132:         return unless perform_caching && caching_allowed
133:
134:         path = case options
135:           when Hash
136:             url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))
137:           when String
138:             options
139:           else
140:             request.path
141:         end
142:
143:         self.class.cache_page(content || response.body, path)
144:       end
expire_page(options = {})

Expires the page that was cached with the options as a key. Example:

  expire_page :controller => "lists", :action => "show"

[Source]

     # File vendor/rails/actionpack/lib/action_controller/caching/pages.rb, line 112
112:       def expire_page(options = {})
113:         return unless perform_caching
114:
115:         if options.is_a?(Hash)
116:           if options[:action].is_a?(Array)
117:             options[:action].dup.each do |action|
118:               self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :action => action)))
119:             end
120:           else
121:             self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true)))
122:           end
123:         else
124:           self.class.expire_page(options)
125:         end
126:       end


Module: ActionController::Caching::Pages::ClassMethods

Module | ActionController::Caching::Pages::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/caching/pages.rb

Methods

cache_page caches_page expire_page

Public Instance methods

cache_page(content, path)

Manually cache the content in the key determined by path. Example:

  cache_page "I'm the cached content", "/lists/show"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/pages.rb, line 73
73:         def cache_page(content, path)
74:           return unless perform_caching
75:
76:           benchmark "Cached page: #{page_cache_file(path)}" do
77:             FileUtils.makedirs(File.dirname(page_cache_path(path)))
78:             File.open(page_cache_path(path), "wb+") { |f| f.write(content) }
79:           end
80:         end
caches_page(*actions)

Caches the actions using the page-caching approach that‘ll store the cache in a path within the page_cache_directory that matches the triggering url.

Usage:

  # cache the index action
  caches_page :index

  # cache the index action except for JSON requests
  caches_page :index, :if => Proc.new { |c| !c.request.format.json? }

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/pages.rb, line 92
92:         def caches_page(*actions)
93:           return unless perform_caching
94:           options = actions.extract_options!
95:           after_filter({:only => actions}.merge(options)) { |c| c.cache_page }
96:         end
expire_page(path)

Expires the page that was cached with the path as a key. Example:

  expire_page "/lists/show"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/caching/pages.rb, line 63
63:         def expire_page(path)
64:           return unless perform_caching
65:
66:           benchmark "Expired page: #{page_cache_file(path)}" do
67:             File.delete(page_cache_path(path)) if File.exist?(page_cache_path(path))
68:           end
69:         end


Module: ActionController::Caching::Sweeping

Module | ActionController::Caching::Sweeping
In: | vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb

Sweepers are the terminators of the caching world and responsible for expiring caches when model objects change. They do this by being half-observers, half-filters and implementing callbacks for both roles. A Sweeper example:

  class ListSweeper < ActionController::Caching::Sweeper
    observe List, Item

    def after_save(record)
      list = record.is_a?(List) ? record : record.list
      expire_page(:controller => "lists", :action => %w( show public feed ), :id => list.id)
      expire_action(:controller => "lists", :action => "all")
      list.shares.each { |share| expire_page(:controller => "lists", :action => "show", :id => share.url_key) }
    end
  end

The sweeper is assigned in the controllers that wish to have its job performed using the cache_sweeper class method:

  class ListsController < ApplicationController
    caches_action :index, :show, :public, :feed
    cache_sweeper :list_sweeper, :only => [ :edit, :destroy, :share ]
  end

In the example above, four actions are cached and three actions are responsible for expiring those caches.

You can also name an explicit class in the declaration of a sweeper, which is needed if the sweeper is in a module:

  class ListsController < ApplicationController
    caches_action :index, :show, :public, :feed
    cache_sweeper OpenBar::Sweeper, :only => [ :edit, :destroy, :share ]
  end


Module: ActionController::CgiExt

Module | ActionController::CgiExt
In: | vendor/rails/actionpack/lib/action_controller/cgi_ext/stdinput.rb

Classes and Modules

Module ActionController::CgiExt::Stdinput


Module: ActionController::CgiExt::Stdinput

Module | ActionController::CgiExt::Stdinput
In: | vendor/rails/actionpack/lib/action_controller/cgi_ext/stdinput.rb

Publicize the CGI‘s internal input stream so we can lazy-read request.body. Make it writable so we don‘t have to play $stdin games.

Methods

included initialize_with_stdinput

Public Class methods

included(base)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/stdinput.rb, line 8
 8:       def self.included(base)
 9:         base.class_eval do
10:           remove_method :stdinput
11:           attr_accessor :stdinput
12:         end
13:
14:         base.alias_method_chain :initialize, :stdinput
15:       end

Public Instance methods

initialize_with_stdinput(type = nil, stdinput = $stdin)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/stdinput.rb, line 17
17:       def initialize_with_stdinput(type = nil, stdinput = $stdin)
18:         @stdinput = stdinput
19:         @stdinput.set_encoding(Encoding::BINARY) if @stdinput.respond_to?(:set_encoding)
20:         initialize_without_stdinput(type || 'query')
21:       end


Module: ActionController::Cookies

Module | ActionController::Cookies
In: | vendor/rails/actionpack/lib/action_controller/cookies.rb

Cookies are read and written through ActionController#cookies.

The cookies being read are the ones received along with the request, the cookies being written will be sent out with the response. Reading a cookie does not get the cookie object itself back, just the value it holds.

Examples for writing:

  # Sets a simple session cookie.
  cookies[:user_name] = "david"

  # Sets a cookie that expires in 1 hour.
  cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }

Examples for reading:

  cookies[:user_name] # => "david"
  cookies.size        # => 2

Example for deleting:

  cookies.delete :user_name

Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:

 cookies[:key] = {
   :value => 'a yummy cookie',
   :expires => 1.year.from_now,
   :domain => 'domain.com'
 }

 cookies.delete(:key, :domain => 'domain.com')

The option symbols for setting cookies are:

  • :value - The cookie‘s value or list of values (as an array).
  • :path - The path for which this cookie applies. Defaults to the root of the application.
  • :domain - The domain for which this cookie applies.
  • :expires - The time at which this cookie expires, as a Time object.
  • :secure - Whether this cookie is a only transmitted to HTTPS servers. Default is false.
  • :httponly - Whether this cookie is accessible via scripting or only HTTP. Defaults to false.

Methods

cookies included

Public Class methods

included(base)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cookies.rb, line 47
47:     def self.included(base)
48:       base.helper_method :cookies
49:     end

Protected Instance methods

cookies()

Returns the cookie container, which operates as described above.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cookies.rb, line 53
53:       def cookies
54:         CookieJar.new(self)
55:       end


Class: ActionController::Dispatcher

Class | ActionController::Dispatcher
In: | vendor/rails/actionpack/lib/action_controller/dispatcher.rb
Parent: | Object

Dispatches requests to the appropriate controller and takes care of reloading the app after each request when Dependencies.load? is true.

Methods

_call call cleanup_application define_dispatcher_callbacks dispatch dispatch dispatch_cgi flush_logger new reload_application run_prepare_callbacks to_prepare

Included Modules

ActiveSupport::Callbacks

Public Class methods

cleanup_application()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 62
62:       def cleanup_application
63:         # Cleanup the application before processing the current request.
64:         ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
65:         ActiveSupport::Dependencies.clear
66:         ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
67:       end
define_dispatcher_callbacks(cache_classes)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 6
 6:       def define_dispatcher_callbacks(cache_classes)
 7:         unless cache_classes
 8:           unless self.middleware.include?(Reloader)
 9:             self.middleware.insert_after(Failsafe, Reloader)
10:           end
11:
12:           ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
13:         end
14:
15:         if defined?(ActiveRecord)
16:           to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
17:         end
18:
19:         after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
20:
21:         to_prepare do
22:           I18n.reload!
23:         end
24:       end
dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)

DEPRECATE: Remove CGI support

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 27
27:       def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
28:         new(output).dispatch_cgi(cgi, session_options)
29:       end
new(output = $stdout, request = nil, response = nil)

DEPRECATE: Remove arguments, since they are only used by CGI

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 80
80:     def initialize(output = $stdout, request = nil, response = nil)
81:       @output = output
82:       @app = @@middleware.build(lambda { |env| self.dup._call(env) })
83:     end
reload_application()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 55
55:       def reload_application
56:         # Run prepare callbacks before every request in development mode
57:         run_prepare_callbacks
58:
59:         Routing::Routes.reload
60:       end
run_prepare_callbacks()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 45
45:       def run_prepare_callbacks
46:         if defined?(Rails) && Rails.logger
47:           logger = Rails.logger
48:         else
49:           logger = Logger.new($stderr)
50:         end
51:
52:         new(logger).send :run_callbacks, :prepare_dispatch
53:       end
to_prepare(identifier = nil, &block)

Add a preparation callback. Preparation callbacks are run before every request in development mode, and before the first request in production mode.

An optional identifier may be supplied for the callback. If provided, to_prepare may be called again with the same identifier to replace the existing callback. Passing an identifier is a suggested practice if the code adding a preparation block may be reloaded.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 39
39:       def to_prepare(identifier = nil, &block)
40:         @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
41:         callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
42:         @prepare_dispatch_callbacks.replace_or_append!(callback)
43:       end

Public Instance methods

_call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 109
109:     def _call(env)
110:       @env = env
111:       dispatch
112:     end
call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 105
105:     def call(env)
106:       @app.call(env)
107:     end
dispatch()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 85
85:     def dispatch
86:       begin
87:         run_callbacks :before_dispatch
88:         Routing::Routes.call(@env)
89:       rescue Exception => exception
90:         if controller ||= (::ApplicationController rescue Base)
91:           controller.call_with_exception(@env, exception).to_a
92:         else
93:           raise exception
94:         end
95:       ensure
96:         run_callbacks :after_dispatch, :enumerator => :reverse_each
97:       end
98:     end
dispatch_cgi(cgi, session_options)

DEPRECATE: Remove CGI support

[Source]

     # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 101
101:     def dispatch_cgi(cgi, session_options)
102:       CGIHandler.dispatch_cgi(self, cgi, @output)
103:     end
flush_logger()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 114
114:     def flush_logger
115:       Base.logger.flush
116:     end


Class: ActionController::Failsafe

Class | ActionController::Failsafe
In: | vendor/rails/actionpack/lib/action_controller/failsafe.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/failsafe.rb, line 6
6:     def initialize(app)
7:       @app = app
8:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/failsafe.rb, line 10
10:     def call(env)
11:       @app.call(env)
12:     rescue Exception => exception
13:       # Reraise exception in test environment
14:       if env["rack.test"]
15:         raise exception
16:       else
17:         failsafe_response(exception)
18:       end
19:     end


Module: ActionController::Filters::ClassMethods

Module | ActionController::Filters::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/filters.rb

Filters enable controllers to run shared pre- and post-processing code for its actions. These filters can be used to do authentication, caching, or auditing before the intended action is performed. Or to do localization or output compression after the action has been performed. Filters have access to the request, response, and all the instance variables set by other filters in the chain or by the action (in the case of after filters).

Filter inheritance

Controller inheritance hierarchies share filters downwards, but subclasses can also add or skip filters without affecting the superclass. For example:

  class BankController < ActionController::Base
    before_filter :audit

    private
      def audit
        # record the action and parameters in an audit log
      end
  end

  class VaultController < BankController
    before_filter :verify_credentials

    private
      def verify_credentials
        # make sure the user is allowed into the vault
      end
  end

Now any actions performed on the BankController will have the audit method called before. On the VaultController, first the audit method is called, then the verify_credentials method. If the audit method renders or redirects, then verify_credentials and the intended action are never called.

Filter types

A filter can take one of three forms: method reference (symbol), external class, or inline method (proc). The first is the most common and works by referencing a protected or private method somewhere in the inheritance hierarchy of the controller by use of a symbol. In the bank example above, both BankController and VaultController use this form.

Using an external class makes for more easily reused generic filters, such as output compression. External filter classes are implemented by having a static filter method on any class and then passing this class to the filter method. Example:

  class OutputCompressionFilter
    def self.filter(controller)
      controller.response.body = compress(controller.response.body)
    end
  end

  class NewspaperController < ActionController::Base
    after_filter OutputCompressionFilter
  end

The filter method is passed the controller instance and is hence granted access to all aspects of the controller and can manipulate them as it sees fit.

The inline method (using a proc) can be used to quickly do something small that doesn‘t require a lot of explanation. Or just as a quick test. It works like this:

  class WeblogController < ActionController::Base
    before_filter { |controller| head(400) if controller.params["stop_action"] }
  end

As you can see, the block expects to be passed the controller after it has assigned the request to the internal variables. This means that the block has access to both the request and response objects complete with convenience methods for params, session, template, and assigns. Note: The inline method doesn‘t strictly have to be a block; any object that responds to call and returns 1 or -1 on arity will do (such as a Proc or an Method object).

Please note that around_filters function a little differently than the normal before and after filters with regard to filter types. Please see the section dedicated to around_filters below.

Filter chain ordering

Using before_filter and after_filter appends the specified filters to the existing chain. That‘s usually just fine, but some times you care more about the order in which the filters are executed. When that‘s the case, you can use prepend_before_filter and prepend_after_filter. Filters added by these methods will be put at the beginning of their respective chain and executed before the rest. For example:

  class ShoppingController < ActionController::Base
    before_filter :verify_open_shop

  class CheckoutController < ShoppingController
    prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock

The filter chain for the CheckoutController is now :ensure_items_in_cart, :ensure_items_in_stock, :verify_open_shop. So if either of the ensure filters renders or redirects, we‘ll never get around to see if the shop is open or not.

You may pass multiple filter arguments of each type as well as a filter block. If a block is given, it is treated as the last argument.

Around filters

Around filters wrap an action, executing code both before and after. They may be declared as method references, blocks, or objects responding to filter or to both before and after.

To use a method as an around_filter, pass a symbol naming the Ruby method. Yield (or block.call) within the method to run the action.

  around_filter :catch_exceptions

  private
    def catch_exceptions
      yield
    rescue => exception
      logger.debug "Caught exception! #{exception}"
      raise
    end

To use a block as an around_filter, pass a block taking as args both the controller and the action block. You can‘t call yield directly from an around_filter block; explicitly call the action block instead:

  around_filter do |controller, action|
    logger.debug "before #{controller.action_name}"
    action.call
    logger.debug "after #{controller.action_name}"
  end

To use a filter object with around_filter, pass an object responding to :filter or both :before and :after. With a filter method, yield to the block as above:

  around_filter BenchmarkingFilter

  class BenchmarkingFilter
    def self.filter(controller, &block)
      Benchmark.measure(&block)
    end
  end

With before and after methods:

  around_filter Authorizer.new

  class Authorizer
    # This will run before the action. Redirecting aborts the action.
    def before(controller)
      unless user.authorized?
        redirect_to(login_url)
      end
    end

    # This will run after the action if and only if before did not render or redirect.
    def after(controller)
    end
  end

If the filter has before and after methods, the before method will be called before the action. If before renders or redirects, the filter chain is halted and after will not be run. See Filter Chain Halting below for an example.

Filter chain skipping

Declaring a filter on a base class conveniently applies to its subclasses, but sometimes a subclass should skip some of its superclass’ filters:

  class ApplicationController < ActionController::Base
    before_filter :authenticate
    around_filter :catch_exceptions
  end

  class WeblogController < ApplicationController
    # Will run the :authenticate and :catch_exceptions filters.
  end

  class SignupController < ApplicationController
    # Skip :authenticate, run :catch_exceptions.
    skip_before_filter :authenticate
  end

  class ProjectsController < ApplicationController
    # Skip :catch_exceptions, run :authenticate.
    skip_filter :catch_exceptions
  end

  class ClientsController < ApplicationController
    # Skip :catch_exceptions and :authenticate unless action is index.
    skip_filter :catch_exceptions, :authenticate, :except => :index
  end

Filter conditions

Filters may be limited to specific actions by declaring the actions to include or exclude. Both options accept single actions (:only => :index) or arrays of actions (:except => [:foo, :bar]).

  class Journal < ActionController::Base
    # Require authentication for edit and delete.
    before_filter :authorize, :only => [:edit, :delete]

    # Passing options to a filter with a block.
    around_filter(:except => :index) do |controller, action_block|
      results = Profiler.run(&action_block)
      controller.response.sub! "</body>", "#{results}</body>"
    end

    private
      def authorize
        # Redirect to login unless authenticated.
      end
  end

Filter Chain Halting

before_filter and around_filter may halt the request before a controller action is run. This is useful, for example, to deny access to unauthenticated users or to redirect from HTTP to HTTPS. Simply call render or redirect. After filters will not be executed if the filter chain is halted.

Around filters halt the request unless the action block is called. Given these filters

  after_filter :after
  around_filter :around
  before_filter :before

The filter chain will look like:

  ...
  .      #   .  #around (code before yield)
  .  .       #   .  .  #before (actual filter code is run)
  .  .  .       #   .  .  .  execute controller action
  .  .  .  /
  .  .  ...
  .  .  /
  .  #around (code after yield)
  . /
  #after (actual filter code is run, unless the around filter does not yield)

If around returns before yielding, after will still not be run. The before filter and controller action will not be run. If before renders or redirects, the second half of around and will still run but after and the action will not. If around fails to yield, after will not be run.

Methods

after_filter append_after_filter append_around_filter append_before_filter around_filter before_filter filter_chain prepend_after_filter prepend_around_filter prepend_before_filter skip_after_filter skip_before_filter skip_filter

Public Instance methods

after_filter(*filters, &block)

Alias for append_after_filter

append_after_filter(*filters, &block)

The passed filters will be appended to the array of filters that run after actions on this controller are performed.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 498
498:       def append_after_filter(*filters, &block)
499:         filter_chain.append_filter_to_chain(filters, :after, &block)
500:       end
append_around_filter(*filters, &block)

If you append_around_filter A.new, B.new, the filter chain looks like

  B#before
    A#before
      # run the action
    A#after
  B#after

With around filters which yield to the action block, before and after are the code before and after the yield.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 521
521:       def append_around_filter(*filters, &block)
522:         filter_chain.append_filter_to_chain(filters, :around, &block)
523:       end
append_before_filter(*filters, &block)

The passed filters will be appended to the filter_chain and will execute before the action on this controller is performed.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 483
483:       def append_before_filter(*filters, &block)
484:         filter_chain.append_filter_to_chain(filters, :before, &block)
485:       end
around_filter(*filters, &block)

Alias for append_around_filter

before_filter(*filters, &block)

Alias for append_before_filter

filter_chain()

Returns an array of Filter objects for this controller.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 573
573:       def filter_chain
574:         if chain = read_inheritable_attribute('filter_chain')
575:           return chain
576:         else
577:           write_inheritable_attribute('filter_chain', FilterChain.new)
578:           return filter_chain
579:         end
580:       end
prepend_after_filter(*filters, &block)

The passed filters will be prepended to the array of filters that run after actions on this controller are performed.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 504
504:       def prepend_after_filter(*filters, &block)
505:         filter_chain.prepend_filter_to_chain(filters, :after, &block)
506:       end
prepend_around_filter(*filters, &block)

If you prepend_around_filter A.new, B.new, the filter chain looks like:

  A#before
    B#before
      # run the action
    B#after
  A#after

With around filters which yield to the action block, before and after are the code before and after the yield.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 535
535:       def prepend_around_filter(*filters, &block)
536:         filter_chain.prepend_filter_to_chain(filters, :around, &block)
537:       end
prepend_before_filter(*filters, &block)

The passed filters will be prepended to the filter_chain and will execute before the action on this controller is performed.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 489
489:       def prepend_before_filter(*filters, &block)
490:         filter_chain.prepend_filter_to_chain(filters, :before, &block)
491:       end
skip_after_filter(*filters)

Removes the specified filters from the after filter chain. Note that this only works for skipping method-reference filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out of many sub-controllers need a different hierarchy.

You can control the actions to skip the filter for with the :only and :except options, just like when you apply the filters.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 558
558:       def skip_after_filter(*filters)
559:         filter_chain.skip_filter_in_chain(*filters, &:after?)
560:       end
skip_before_filter(*filters)

Removes the specified filters from the before filter chain. Note that this only works for skipping method-reference filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out of many sub-controllers need a different hierarchy.

You can control the actions to skip the filter for with the :only and :except options, just like when you apply the filters.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 548
548:       def skip_before_filter(*filters)
549:         filter_chain.skip_filter_in_chain(*filters, &:before?)
550:       end
skip_filter(*filters)

Removes the specified filters from the filter chain. This only works for method reference (symbol) filters, not procs. This method is different from skip_after_filter and skip_before_filter in that it will match any before, after or yielding around filter.

You can control the actions to skip the filter for with the :only and :except options, just like when you apply the filters.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/filters.rb, line 568
568:       def skip_filter(*filters)
569:         filter_chain.skip_filter_in_chain(*filters)
570:       end


Module: ActionController::Flash

Module | ActionController::Flash
In: | vendor/rails/actionpack/lib/action_controller/flash.rb

The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create action that sets flash[:notice] = "Successfully created" before redirecting to a display action that can then expose the flash to its template. Actually, that exposure is automatically done. Example:

  class PostsController < ActionController::Base
    def create
      # save post
      flash[:notice] = "Successfully created post"
      redirect_to posts_path(@post)
    end

    def show
      # doesn't need to assign the flash notice to the template, that's done automatically
    end
  end

  show.html.erb
    <% if flash[:notice] %>
      <div class="notice"><%= flash[:notice] %></div>
    <% end %>

This example just places a string in the flash, but you can put any object in there. And of course, you can put as many as you like at a time too. Just remember: They‘ll be gone by the time the next action has been performed.

See docs on the FlashHash class for more details about the flash.

Methods

included

Included Modules

InstanceMethods

Classes and Modules

Class ActionController::Flash::FlashHash

Public Class methods

included(base)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/flash.rb, line 29
29:     def self.included(base)
30:       base.class_eval do
31:         include InstanceMethods
32:         alias_method_chain :perform_action, :flash
33:         alias_method_chain :reset_session,  :flash
34:       end
35:     end


Class: ActionController::Flash::FlashHash

Class | ActionController::Flash::FlashHash
In: | vendor/rails/actionpack/lib/action_controller/flash.rb
Parent: | Hash

Methods

discard keep now

External Aliases

update -> merge!

Public Instance methods

discard(k = nil)

Marks the entire flash or a single flash entry to be discarded by the end of the current action:

    flash.discard              # discard the entire flash at the end of the current action
    flash.discard(:warning)    # discard only the "warning" entry at the end of the current action

[Source]

     # File vendor/rails/actionpack/lib/action_controller/flash.rb, line 102
102:       def discard(k = nil)
103:         use(k)
104:       end
keep(k = nil)

Keeps either the entire current flash or a specific flash entry available for the next action:

   flash.keep            # keeps the entire flash
   flash.keep(:notice)   # keeps only the "notice" entry, the rest of the flash is discarded

[Source]

    # File vendor/rails/actionpack/lib/action_controller/flash.rb, line 94
94:       def keep(k = nil)
95:         use(k, false)
96:       end
now()

Sets a flash that will not be available to the next action, only to the current.

    flash.now[:message] = "Hello current action"

This method enables you to use the flash as a central messaging system in your app. When you need to pass an object to the next action, you use the standard flash assign ([]=). When you need to pass an object to the current action, you use now, and your object will vanish when the current action is done.

Entries set via now are accessed the same way as standard entries: flash[‘my-key’].

[Source]

    # File vendor/rails/actionpack/lib/action_controller/flash.rb, line 86
86:       def now
87:         FlashNow.new(self)
88:       end


Module: ActionController::Helpers::ClassMethods

Module | ActionController::Helpers::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/helpers.rb

The Rails framework provides a large number of helpers for working with assets, dates, forms, numbers and Active Record objects, to name a few. These helpers are available to all templates by default.

In addition to using the standard template helpers provided in the Rails framework, creating custom helpers to extract complicated logic or reusable functionality is strongly encouraged. By default, the controller will include a helper whose name matches that of the controller, e.g., MyController will automatically include MyHelper.

Additional helpers can be specified using the helper class method in ActionController::Base or any controller which inherits from it.

Examples

The to_s method from the Time class can be wrapped in a helper method to display a custom message if the Time object is blank:

  module FormattedTimeHelper
    def format_time(time, format=:long, blank_message="&nbsp;")
      time.blank? ? blank_message : time.to_s(format)
    end
  end

FormattedTimeHelper can now be included in a controller, using the helper class method:

  class EventsController < ActionController::Base
    helper FormattedTimeHelper
    def index
      @events = Event.find(:all)
    end
  end

Then, in any view rendered by EventController, the format_time method can be called:

  <% @events.each do |event| -%>
    <p>
      <% format_time(event.time, :short, "N/A") %> | <%= event.name %>
    </p>
  <% end -%>

Finally, assuming we have two event instances, one which has a time and one which does not, the output might look like this:

  23 Aug 11:30 | Carolina Railhawks Soccer Match
  N/A | Carolina Railhaws Training Workshop

Methods

helper helper_attr helper_method helpers

Public Instance methods

helper(*args, &block)

The helper class method can take a series of helper module names, a block, or both.

  • *args: One or more modules, strings or symbols, or the special symbol :all.
  • &block: A block defining helper methods.

Examples

When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file and include the module in the template class. The second form illustrates how to include custom helpers when working with namespaced controllers, or other cases where the file containing the helper definition is not in one of Rails’ standard load paths:

  helper :foo             # => requires 'foo_helper' and includes FooHelper
  helper 'resources/foo'  # => requires 'resources/foo_helper' and includes Resources::FooHelper

When the argument is a module it will be included directly in the template class.

  helper FooHelper # => includes FooHelper

When the argument is the symbol :all, the controller will include all helpers beneath ActionController::Base.helpers_dir (defaults to app/helpers/**/*.rb under RAILS_ROOT).

  helper :all

Additionally, the helper class method can receive and evaluate a block, making the methods defined available to the template.

  # One line
  helper { def hello() "Hello, world!" end }
  # Multi-line
  helper do
    def foo(bar)
      "#{bar} is the very best"
    end
  end

Finally, all the above styles can be mixed together, and the helper method can be invoked with a mix of symbols, strings, modules and blocks.

  helper(:three, BlindHelper) { def mice() 'mice' end }

[Source]

     # File vendor/rails/actionpack/lib/action_controller/helpers.rb, line 114
114:       def helper(*args, &block)
115:         args.flatten.each do |arg|
116:           case arg
117:             when Module
118:               add_template_helper(arg)
119:             when :all
120:               helper(all_application_helpers)
121:             when String, Symbol
122:               file_name  = arg.to_s.underscore + '_helper'
123:               class_name = file_name.camelize
124:
125:               begin
126:                 require_dependency(file_name)
127:               rescue LoadError => load_error
128:                 requiree = / -- (.*?)(\.rb)?$/.match(load_error.message).to_a[1]
129:                 if requiree == file_name
130:                   msg = "Missing helper file helpers/#{file_name}.rb"
131:                   raise LoadError.new(msg).copy_blame!(load_error)
132:                 else
133:                   raise
134:                 end
135:               end
136:
137:               add_template_helper(class_name.constantize)
138:             else
139:               raise ArgumentError, "helper expects String, Symbol, or Module argument (was: #{args.inspect})"
140:           end
141:         end
142:
143:         # Evaluate block in template class if given.
144:         master_helper_module.module_eval(&block) if block_given?
145:       end
helper_attr(*attrs)

Declares helper accessors for controller attributes. For example, the following adds new name and name= instance methods to a controller and makes them available to the view:

  helper_attr :name
  attr_accessor :name

[Source]

     # File vendor/rails/actionpack/lib/action_controller/helpers.rb, line 179
179:       def helper_attr(*attrs)
180:         attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
181:       end
helper_method(*methods)

Declare a controller method as a helper. For example, the following makes the current_user controller method available to the view:

  class ApplicationController < ActionController::Base
    helper_method :current_user, :logged_in?

    def current_user
      @current_user ||= User.find_by_id(session[:user])
    end

     def logged_in?
       current_user != nil
     end
  end

In a view:

 <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>

[Source]

     # File vendor/rails/actionpack/lib/action_controller/helpers.rb, line 163
163:       def helper_method(*methods)
164:         methods.flatten.each do |method|
165:           master_helper_module.module_eval "def \#{method}(*args, &block)                    # def current_user(*args, &block)\ncontroller.send(%(\#{method}), *args, &block)  #   controller.send(%(current_user), *args, &block)\nend                                             # end\n"
166:         end
167:       end
helpers()

Provides a proxy to access helpers methods from outside the view.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/helpers.rb, line 184
184:       def helpers
185:         unless @helper_proxy
186:           @helper_proxy = ActionView::Base.new
187:           @helper_proxy.extend master_helper_module
188:         else
189:           @helper_proxy
190:         end
191:       end


Module: ActionController::Http

Module | ActionController::Http
In: | vendor/rails/actionpack/lib/action_controller/headers.rb

Classes and Modules

Class ActionController::Http::Headers


Class: ActionController::Http::Headers

Class | ActionController::Http::Headers
In: | vendor/rails/actionpack/lib/action_controller/headers.rb
Parent: | ::Hash

Methods

[] new

Public Class methods

new(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/headers.rb, line 8
 8:       def initialize(*args)
 9:          if args.size == 1 && args[0].is_a?(Hash)
10:            super()
11:            update(args[0])
12:          else
13:            super
14:          end
15:        end

Public Instance methods

[](header_name)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/headers.rb, line 17
17:       def [](header_name)
18:         if include?(header_name)
19:           super
20:         else
21:           super(env_name(header_name))
22:         end
23:       end


Module: ActionController::HttpAuthentication

Module | ActionController::HttpAuthentication
In: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb

Classes and Modules

Module ActionController::HttpAuthentication::Basic
Module ActionController::HttpAuthentication::Digest


Module: ActionController::HttpAuthentication::Basic

Module | ActionController::HttpAuthentication::Basic
In: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb

Makes it dead easy to do HTTP Basic authentication.

Simple Basic example:

  class PostsController < ApplicationController
    USER_NAME, PASSWORD = "dhh", "secret"

    before_filter :authenticate, :except => [ :index ]

    def index
      render :text => "Everyone can see me!"
    end

    def edit
      render :text => "I'm only accessible if you know the password"
    end

    private
      def authenticate
        authenticate_or_request_with_http_basic do |user_name, password|
          user_name == USER_NAME && password == PASSWORD
        end
      end
  end

Here is a more advanced Basic example where only Atom feeds and the XML API is protected by HTTP authentication, the regular HTML interface is protected by a session approach:

  class ApplicationController < ActionController::Base
    before_filter :set_account, :authenticate

    protected
      def set_account
        @account = Account.find_by_url_name(request.subdomains.first)
      end

      def authenticate
        case request.format
        when Mime::XML, Mime::ATOM
          if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
            @current_user = user
          else
            request_http_basic_authentication
          end
        else
          if session_authenticated?
            @current_user = @account.users.find(session[:authenticated][:user_id])
          else
            redirect_to(login_url) and return false
          end
        end
      end
  end

In your integration tests, you can do something like this:

  def test_access_granted_from_xml
    get(
      "/notes/1.xml", nil,
      :authorization => ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
    )

    assert_equal 200, status
  end

Simple Digest example:

  require 'digest/md5'
  class PostsController < ApplicationController
    REALM = "SuperSecret"
    USERS = {"dhh" => "secret", #plain text password
             "dap" => Digest:MD5::hexdigest(["dap",REALM,"secret"].join(":"))  #ha1 digest password

    before_filter :authenticate, :except => [:index]

    def index
      render :text => "Everyone can see me!"
    end

    def edit
      render :text => "I'm only accessible if you know the password"
    end

    private
      def authenticate
        authenticate_or_request_with_http_digest(REALM) do |username|
          USERS[username]
        end
      end
  end

NOTE: The authenticate_or_request_with_http_digest block must return the user‘s password or the ha1 digest hash so the framework can appropriately

      hash to check the user's credentials. Returning +nil+ will cause authentication to fail.
      Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
      the password file or database is compromised, the attacker would be able to use the ha1 hash to
      authenticate as the user at this +realm+, but would not have the user's password to try using at
      other sites.

On shared hosts, Apache sometimes doesn‘t pass authentication headers to FCGI instances. If your environment matches this description and you cannot authenticate, try this rule in your Apache setup:

  RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]

Methods

authenticate authentication_request authorization decode_credentials encode_credentials user_name_and_password

Classes and Modules

Module ActionController::HttpAuthentication::Basic::ControllerMethods

Public Instance methods

authenticate(controller, &login_procedure)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 124
124:       def authenticate(controller, &login_procedure)
125:         unless authorization(controller.request).blank?
126:           login_procedure.call(*user_name_and_password(controller.request))
127:         end
128:       end
authentication_request(controller, realm)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 149
149:       def authentication_request(controller, realm)
150:         controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
151:         controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
152:       end
authorization(request)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 134
134:       def authorization(request)
135:         request.env['HTTP_AUTHORIZATION']   ||
136:         request.env['X-HTTP_AUTHORIZATION'] ||
137:         request.env['X_HTTP_AUTHORIZATION'] ||
138:         request.env['REDIRECT_X_HTTP_AUTHORIZATION']
139:       end
decode_credentials(request)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 141
141:       def decode_credentials(request)
142:         ActiveSupport::Base64.decode64(authorization(request).split.last || '')
143:       end
encode_credentials(user_name, password)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 145
145:       def encode_credentials(user_name, password)
146:         "Basic #{ActiveSupport::Base64.encode64("#{user_name}:#{password}")}"
147:       end
user_name_and_password(request)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 130
130:       def user_name_and_password(request)
131:         decode_credentials(request).split(/:/, 2)
132:       end


Module: ActionController::HttpAuthentication::Basic::ControllerMethods

Module | ActionController::HttpAuthentication::Basic::ControllerMethods
In: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb

Methods

authenticate_or_request_with_http_basic authenticate_with_http_basic request_http_basic_authentication

Public Instance methods

authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 111
111:         def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
112:           authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
113:         end
authenticate_with_http_basic(&login_procedure)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 115
115:         def authenticate_with_http_basic(&login_procedure)
116:           HttpAuthentication::Basic.authenticate(self, &login_procedure)
117:         end
request_http_basic_authentication(realm = "Application")

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 119
119:         def request_http_basic_authentication(realm = "Application")
120:           HttpAuthentication::Basic.authentication_request(self, realm)
121:         end


Module: ActionController::HttpAuthentication::Digest

Module | ActionController::HttpAuthentication::Digest
In: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb

Methods

authenticate authentication_header authentication_request authorization decode_credentials decode_credentials_header encode_credentials expected_response ha1 nonce opaque secret_key validate_digest_response validate_nonce

Classes and Modules

Module ActionController::HttpAuthentication::Digest::ControllerMethods

Public Instance methods

authenticate(controller, realm, &password_procedure)

Returns false on a valid response, true otherwise

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 175
175:       def authenticate(controller, realm, &password_procedure)
176:         authorization(controller.request) && validate_digest_response(controller.request, realm, &password_procedure)
177:       end
authentication_header(controller, realm)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 233
233:       def authentication_header(controller, realm)
234:         controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
235:       end
authentication_request(controller, realm, message = nil)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 237
237:       def authentication_request(controller, realm, message = nil)
238:         message ||= "HTTP Digest: Access denied.\n"
239:         authentication_header(controller, realm)
240:         controller.__send__ :render, :text => message, :status => :unauthorized
241:       end
authorization(request)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 179
179:       def authorization(request)
180:         request.env['HTTP_AUTHORIZATION']   ||
181:         request.env['X-HTTP_AUTHORIZATION'] ||
182:         request.env['X_HTTP_AUTHORIZATION'] ||
183:         request.env['REDIRECT_X_HTTP_AUTHORIZATION']
184:       end
decode_credentials(header)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 225
225:       def decode_credentials(header)
226:         header.to_s.gsub(/^Digest\s+/,'').split(',').inject({}) do |hash, pair|
227:           key, value = pair.split('=', 2)
228:           hash[key.strip.to_sym] = value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')
229:           hash
230:         end
231:       end
decode_credentials_header(request)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 221
221:       def decode_credentials_header(request)
222:         decode_credentials(authorization(request))
223:       end
encode_credentials(http_method, credentials, password, password_is_ha1)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 216
216:       def encode_credentials(http_method, credentials, password, password_is_ha1)
217:         credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
218:         "Digest " + credentials.sort_by {|x| x[0].to_s }.inject([]) {|a, v| a << "#{v[0]}='#{v[1]}'" }.join(', ')
219:       end
expected_response(http_method, uri, credentials, password, password_is_ha1=true)

Returns the expected response for a request of http_method to uri with the decoded credentials and the expected password Optional parameter +password_is_ha1+ is set to true by default, since best practice is to store ha1 digest instead of a plain-text password.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 206
206:       def expected_response(http_method, uri, credentials, password, password_is_ha1=true)
207:         ha1 = password_is_ha1 ? password : ha1(credentials, password)
208:         ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(':'))
209:         ::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(':'))
210:       end
ha1(credentials, password)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 212
212:       def ha1(credentials, password)
213:         ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(':'))
214:       end
nonce(time = Time.now)

Uses an MD5 digest based on time to generate a value to be used only once.

A server-specified data string which should be uniquely generated each time a 401 response is made. It is recommended that this string be base64 or hexadecimal data. Specifically, since the string is passed in the header lines as a quoted string, the double-quote character is not allowed.

The contents of the nonce are implementation dependent. The quality of the implementation depends on a good choice. A nonce might, for example, be constructed as the base 64 encoding of

> time-stamp H(time-stamp ":" ETag ":" private-key)

where time-stamp is a server-generated time or other non-repeating value, ETag is the value of the HTTP ETag header associated with the requested entity, and private-key is data known only to the server. With a nonce of this form a server would recalculate the hash portion after receiving the client authentication header and reject the request if it did not match the nonce from that header or if the time-stamp value is not recent enough. In this way the server can limit the time of the nonce‘s validity. The inclusion of the ETag prevents a replay request for an updated version of the resource. (Note: including the IP address of the client in the nonce would appear to offer the server the ability to limit the reuse of the nonce to the same client that originally got it. However, that would break proxy farms, where requests from a single user often go through different proxies in the farm. Also, IP address spoofing is not that hard.)

An implementation might choose not to accept a previously used nonce or a previously used digest, in order to protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for POST or PUT requests and a time-stamp for GET requests. For more details on the issues involved see Section 4 of this document.

The nonce is opaque to the client. Composed of Time, and hash of Time with secret key from the Rails session secret generated upon creation of project. Ensures the time cannot be modifed by client.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 275
275:       def nonce(time = Time.now)
276:         t = time.to_i
277:         hashed = [t, secret_key]
278:         digest = ::Digest::MD5.hexdigest(hashed.join(":"))
279:         Base64.encode64("#{t}:#{digest}").gsub("\n", '')
280:       end
opaque()

Opaque based on random generation - but changing each request?

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 293
293:       def opaque()
294:         ::Digest::MD5.hexdigest(secret_key)
295:       end
secret_key()

Set in /initializers/session_store.rb, and loaded even if sessions are not in use.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 298
298:       def secret_key
299:         ActionController::Base.session_options[:secret]
300:       end
validate_digest_response(request, realm, &password_procedure)

Raises error unless the request credentials response value matches the expected value. First try the password as a ha1 digest password. If this fails, then try it as a plain text password.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 189
189:       def validate_digest_response(request, realm, &password_procedure)
190:         credentials = decode_credentials_header(request)
191:         valid_nonce = validate_nonce(request, credentials[:nonce])
192:
193:         if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque]
194:           password = password_procedure.call(credentials[:username])
195:
196:          [true, false].any? do |password_is_ha1|
197:            expected = expected_response(request.env['REQUEST_METHOD'], request.env['REQUEST_URI'], credentials, password, password_is_ha1)
198:            expected == credentials[:response]
199:          end
200:         end
201:       end
validate_nonce(request, value, seconds_to_timeout=5*60)

Might want a shorter timeout depending on whether the request is a PUT or POST, and if client is browser or web service. Can be much shorter if the Stale directive is implemented. This would allow a user to use new nonce without prompting user again for their username and password.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 287
287:       def validate_nonce(request, value, seconds_to_timeout=5*60)
288:         t = Base64.decode64(value).split(":").first.to_i
289:         nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
290:       end


Module: ActionController::HttpAuthentication::Digest::ControllerMethods

Module | ActionController::HttpAuthentication::Digest::ControllerMethods
In: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb

Methods

authenticate_or_request_with_http_digest authenticate_with_http_digest request_http_digest_authentication

Public Instance methods

authenticate_or_request_with_http_digest(realm = "Application", &password_procedure)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 159
159:         def authenticate_or_request_with_http_digest(realm = "Application", &password_procedure)
160:           authenticate_with_http_digest(realm, &password_procedure) || request_http_digest_authentication(realm)
161:         end
authenticate_with_http_digest(realm = "Application", &password_procedure)

Authenticate with HTTP Digest, returns true or false

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 164
164:         def authenticate_with_http_digest(realm = "Application", &password_procedure)
165:           HttpAuthentication::Digest.authenticate(self, realm, &password_procedure)
166:         end
request_http_digest_authentication(realm = "Application", message = nil)

Render output including the HTTP Digest authentication header

[Source]

     # File vendor/rails/actionpack/lib/action_controller/http_authentication.rb, line 169
169:         def request_http_digest_authentication(realm = "Application", message = nil)
170:           HttpAuthentication::Digest.authentication_request(self, realm, message)
171:         end


Module: ActionController::Integration::Runner

Module | ActionController::Integration::Runner
In: | vendor/rails/actionpack/lib/action_controller/integration.rb

Methods

method_missing open_session reset!

Public Instance methods

method_missing(sym, *args, &block)

Delegate unhandled messages to the current session instance.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 553
553:       def method_missing(sym, *args, &block)
554:         reset! unless @integration_session
555:         returning @integration_session.__send__(sym, *args, &block) do
556:           copy_session_variables!
557:         end
558:       end
open_session(application = nil) {|session if block_given?| ...}

Open a new session instance. If a block is given, the new session is yielded to the block before being returned.

  session = open_session do |sess|
    sess.extend(CustomAssertions)
  end

By default, a single session is automatically created for you, but you can use this method to open multiple sessions that ought to be tested simultaneously.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 516
516:       def open_session(application = nil)
517:         session = Integration::Session.new(application)
518:
519:         # delegate the fixture accessors back to the test instance
520:         extras = Module.new { attr_accessor :delegate, :test_result }
521:         if self.class.respond_to?(:fixture_table_names)
522:           self.class.fixture_table_names.each do |table_name|
523:             name = table_name.tr(".", "_")
524:             next unless respond_to?(name)
525:             extras.__send__(:define_method, name) { |*args|
526:               delegate.send(name, *args)
527:             }
528:           end
529:         end
530:
531:         # delegate add_assertion to the test case
532:         extras.__send__(:define_method, :add_assertion) {
533:           test_result.add_assertion
534:         }
535:         session.extend(extras)
536:         session.delegate = self
537:         session.test_result = @_result
538:
539:         yield session if block_given?
540:         session
541:       end
reset!()

Reset the current session. This is useful for testing multiple sessions in a single test case.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 490
490:       def reset!
491:         @integration_session = open_session
492:       end


Class: ActionController::Integration::Session

Class | ActionController::Integration::Session
In: | vendor/rails/actionpack/lib/action_controller/integration.rb
Parent: | Object

An integration Session instance represents a set of requests and responses performed sequentially by some virtual user. Becase you can instantiate multiple sessions and run them side-by-side, you can also mimic (to some limited extent) multiple simultaneous users interacting with your system.

Typically, you will instantiate a new session using IntegrationTest#open_session, rather than instantiating Integration::Session directly.

Methods

delete delete_via_redirect follow_redirect! get get_via_redirect head host! https! https? new post post_via_redirect put put_via_redirect redirect? request_via_redirect reset! url_for xhr xml_http_request

Included Modules

Test::Unit::Assertions
ActionController::TestCase::Assertions
ActionController::TestProcess

Classes and Modules

Class ActionController::Integration::Session::MultiPartNeededException

Attributes

accept | [RW] | The Accept header to send.
application | [RW] | Rack application to use
body | [R] | The body of the last request.
controller | [R] | A reference to the controller instance used by the last request.
cookies | [R] | A map of the cookies returned by the last response, and which will be sent with the next request.
headers | [R] | A map of the headers returned by the last response.
host | [RW] | The hostname used in the last request.
path | [R] | The URI of the last request.
remote_addr | [RW] | The remote_addr used in the last request.
request | [R] | A reference to the request instance used by the last request.
request_count | [RW] | A running counter of the number of requests processed.
response | [R] | A reference to the response instance used by the last request.
status | [R] | The integer HTTP status code of the last request.
status_message | [R] | The status message that accompanied the status code of the last request.

Public Class methods

new(app = nil)

Create and initialize a new Session instance.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 67
67:       def initialize(app = nil)
68:         @application = app || ActionController::Dispatcher.new
69:         reset!
70:       end

Public Instance methods

delete(path, parameters = nil, headers = nil)

Performs a DELETE request with the given parameters. See get() for more details.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 213
213:       def delete(path, parameters = nil, headers = nil)
214:         process :delete, path, parameters, headers
215:       end
delete_via_redirect(path, parameters = nil, headers = nil)

Performs a DELETE request, following any subsequent redirect. See request_via_redirect for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 166
166:       def delete_via_redirect(path, parameters = nil, headers = nil)
167:         request_via_redirect(:delete, path, parameters, headers)
168:       end
follow_redirect!()

Follow a single redirect response. If the last response was not a redirect, an exception will be raised. Otherwise, the redirect is performed on the location header.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 130
130:       def follow_redirect!
131:         raise "not a redirect! #{@status} #{@status_message}" unless redirect?
132:         get(interpret_uri(headers['location']))
133:         status
134:       end
get(path, parameters = nil, headers = nil)

Performs a GET request with the given parameters.

  • path: The URI (as a String) on which you want to perform a GET request.
  • parameters: The HTTP parameters that you want to pass. This may be nil, a Hash, or a String that is appropriately encoded (application/x-www-form-urlencoded or multipart/form-data).
  • headers: Additional HTTP headers to pass, as a Hash. The keys will automatically be upcased, with the prefix ‘HTTP_’ added if needed.

This method returns an Response object, which one can use to inspect the details of the response. Furthermore, if this method was called from an ActionController::IntegrationTest object, then that object‘s @response instance variable will point to the same response object.

You can also perform POST, PUT, DELETE, and HEAD requests with post, put, delete, and head.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 195
195:       def get(path, parameters = nil, headers = nil)
196:         process :get, path, parameters, headers
197:       end
get_via_redirect(path, parameters = nil, headers = nil)

Performs a GET request, following any subsequent redirect. See request_via_redirect for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 148
148:       def get_via_redirect(path, parameters = nil, headers = nil)
149:         request_via_redirect(:get, path, parameters, headers)
150:       end
head(path, parameters = nil, headers = nil)

Performs a HEAD request with the given parameters. See get() for more details.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 219
219:       def head(path, parameters = nil, headers = nil)
220:         process :head, path, parameters, headers
221:       end
host!(name)

Set the host name to use in the next request.

  session.host! "www.example.com"

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 123
123:       def host!(name)
124:         @host = name
125:       end
https!(flag = true)

Specify whether or not the session should mimic a secure HTTPS request.

  session.https!
  session.https!(false)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 107
107:       def https!(flag = true)
108:         @https = flag
109:       end
https?()

Return true if the session is mimicking a secure HTTPS request.

  if session.https?
    ...
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 116
116:       def https?
117:         @https
118:       end
post(path, parameters = nil, headers = nil)

Performs a POST request with the given parameters. See get() for more details.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 201
201:       def post(path, parameters = nil, headers = nil)
202:         process :post, path, parameters, headers
203:       end
post_via_redirect(path, parameters = nil, headers = nil)

Performs a POST request, following any subsequent redirect. See request_via_redirect for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 154
154:       def post_via_redirect(path, parameters = nil, headers = nil)
155:         request_via_redirect(:post, path, parameters, headers)
156:       end
put(path, parameters = nil, headers = nil)

Performs a PUT request with the given parameters. See get() for more details.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 207
207:       def put(path, parameters = nil, headers = nil)
208:         process :put, path, parameters, headers
209:       end
put_via_redirect(path, parameters = nil, headers = nil)

Performs a PUT request, following any subsequent redirect. See request_via_redirect for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 160
160:       def put_via_redirect(path, parameters = nil, headers = nil)
161:         request_via_redirect(:put, path, parameters, headers)
162:       end
redirect?()

Returns true if the last response was a redirect.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 171
171:       def redirect?
172:         status/100 == 3
173:       end
request_via_redirect(http_method, path, parameters = nil, headers = nil)

Performs a request using the specified method, following any subsequent redirect. Note that the redirects are followed until the response is not a redirect—this means you may run into an infinite loop if your redirect loops back to itself.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 140
140:       def request_via_redirect(http_method, path, parameters = nil, headers = nil)
141:         send(http_method, path, parameters, headers)
142:         follow_redirect! while redirect?
143:         status
144:       end
reset!()

Resets the instance. This can be used to reset the state information in an existing session instance, so it can be used from a clean-slate condition.

  session.reset!

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 77
 77:       def reset!
 78:         @status = @path = @headers = nil
 79:         @result = @status_message = nil
 80:         @https = false
 81:         @cookies = {}
 82:         @controller = @request = @response = nil
 83:         @request_count = 0
 84:
 85:         self.host        = "www.example.com"
 86:         self.remote_addr = "127.0.0.1"
 87:         self.accept      = "text/xml,application/xml,application/xhtml+xml," +
 88:                            "text/html;q=0.9,text/plain;q=0.8,image/png," +
 89:                            "*/*;q=0.5"
 90:
 91:         unless defined? @named_routes_configured
 92:           # install the named routes in this session instance.
 93:           klass = class << self; self; end
 94:           Routing::Routes.install_helpers(klass)
 95:
 96:           # the helpers are made protected by default--we make them public for
 97:           # easier access during testing and troubleshooting.
 98:           klass.module_eval { public *Routing::Routes.named_routes.helpers }
 99:           @named_routes_configured = true
100:         end
101:       end
url_for(options)

Returns the URL for the given options, according to the rules specified in the application‘s routes.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 240
240:       def url_for(options)
241:         controller ?
242:           controller.url_for(options) :
243:           generic_url_rewriter.rewrite(options)
244:       end
xhr(request_method, path, parameters = nil, headers = nil)

Alias for xml_http_request

xml_http_request(request_method, path, parameters = nil, headers = nil)

Performs an XMLHttpRequest request with the given parameters, mirroring a request from the Prototype library.

The request_method is :get, :post, :put, :delete or :head; the parameters are nil, a hash, or a url-encoded or multipart string; the headers are a hash. Keys are automatically upcased and prefixed with ‘HTTP_’ if not already.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/integration.rb, line 230
230:       def xml_http_request(request_method, path, parameters = nil, headers = nil)
231:         headers ||= {}
232:         headers['X-Requested-With'] = 'XMLHttpRequest'
233:         headers['Accept'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
234:         process(request_method, path, parameters, headers)
235:       end


Class: ActionController::Integration::Session::MultiPartNeededException

Class | ActionController::Integration::Session::MultiPartNeededException
In: | vendor/rails/actionpack/lib/action_controller/integration.rb
Parent: | Exception


Class: ActionController::IntegrationTest

Class | ActionController::IntegrationTest
In: | vendor/rails/actionpack/lib/action_controller/integration.rb
Parent: | ActiveSupport::TestCase

An IntegrationTest is one that spans multiple controllers and actions, tying them all together to ensure they work together as expected. It tests more completely than either unit or functional tests do, exercising the entire stack, from the dispatcher to the database.

At its simplest, you simply extend IntegrationTest and write your tests using the get/post methods:

  require "#{File.dirname(__FILE__)}/test_helper"

  class ExampleTest < ActionController::IntegrationTest
    fixtures :people

    def test_login
      # get the login page
      get "/login"
      assert_equal 200, status

      # post the login and follow through to the home page
      post "/login", :username => people(:jamis).username,
        :password => people(:jamis).password
      follow_redirect!
      assert_equal 200, status
      assert_equal "/home", path
    end
  end

However, you can also have multiple session instances open per test, and even extend those instances with assertions and methods to create a very powerful testing DSL that is specific for your application. You can even reference any named routes you happen to have defined!

  require "#{File.dirname(__FILE__)}/test_helper"

  class AdvancedTest < ActionController::IntegrationTest
    fixtures :people, :rooms

    def test_login_and_speak
      jamis, david = login(:jamis), login(:david)
      room = rooms(:office)

      jamis.enter(room)
      jamis.speak(room, "anybody home?")

      david.enter(room)
      david.speak(room, "hello!")
    end

    private

      module CustomAssertions
        def enter(room)
          # reference a named route, for maximum internal consistency!
          get(room_url(:id => room.id))
          assert(...)
          ...
        end

        def speak(room, message)
          xml_http_request "/say/#{room.id}", :message => message
          assert(...)
          ...
        end
      end

      def login(who)
        open_session do |sess|
          sess.extend(CustomAssertions)
          who = people(who)
          sess.post "/login", :username => who.username,
            :password => who.password
          assert(...)
        end
      end
  end

Included Modules

Integration::Runner


Module: ActionController::Layout::ClassMethods

Module | ActionController::Layout::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/layout.rb

Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in repeated setups. The inclusion pattern has pages that look like this:

  <%= render "shared/header" %>
  Hello World
  <%= render "shared/footer" %>

This approach is a decent way of keeping common structures isolated from the changing content, but it‘s verbose and if you ever want to change the structure of these two includes, you‘ll have to change all the templates.

With layouts, you can flip it around and have the common structure know where to insert changing content. This means that the header and footer are only mentioned in one place, like this:

  // The header part of this layout
  <%= yield %>
  // The footer part of this layout

And then you have content pages that look like this:

   hello world

At rendering time, the content page is computed and then inserted in the layout, like this:

  // The header part of this layout
  hello world
  // The footer part of this layout

NOTE: The old notation for rendering the view from a layout was to expose the magic @content_for_layout instance variable. The preferred notation now is to use yield, as documented above.

Accessing shared variables

Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with references that won‘t materialize before rendering time:

  <h1><%= @page_title %></h1>
  <%= yield %>

…and content pages that fulfill these references at rendering time:

   <% @page_title = "Welcome" %>
   Off-world colonies offers you a chance to start a new life

The result after rendering is:

  <h1>Welcome</h1>
  Off-world colonies offers you a chance to start a new life

Automatic layout assignment

If there is a template in app/views/layouts/ with the same name as the current controller then it will be automatically set as that controller‘s layout unless explicitly told otherwise. Say you have a WeblogController, for example. If a template named app/views/layouts/weblog.erb or app/views/layouts/weblog.builder exists then it will be automatically set as the layout for your WeblogController. You can create a layout with the name application.erb or application.builder and this will be set as the default controller if there is no layout with the same name as the current controller and there is no layout explicitly assigned with the layout method. Nested controllers use the same folder structure for automatic layout. assignment. So an Admin::WeblogController will look for a template named app/views/layouts/admin/weblog.erb. Setting a layout explicitly will always override the automatic behaviour for the controller where the layout is set. Explicitly setting the layout in a parent class, though, will not override the child class‘s layout assignment if the child class has a layout with the same name.

Inheritance for layouts

Layouts are shared downwards in the inheritance hierarchy, but not upwards. Examples:

  class BankController < ActionController::Base
    layout "bank_standard"

  class InformationController < BankController

  class VaultController < BankController
    layout :access_level_layout

  class EmployeeController < BankController
    layout nil

The InformationController uses "bank_standard" inherited from the BankController, the VaultController overwrites and picks the layout dynamically, and the EmployeeController doesn‘t want to use a layout at all.

Types of layouts

Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can be done either by specifying a method reference as a symbol or using an inline method (as a proc).

The method reference is the preferred approach to variable layouts and is used like this:

  class WeblogController < ActionController::Base
    layout :writers_and_readers

    def index
      # fetching posts
    end

    private
      def writers_and_readers
        logged_in? ? "writer_layout" : "reader_layout"
      end

Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing is logged in or not.

If you want to use an inline method, such as a proc, do something like this:

  class WeblogController < ActionController::Base
    layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }

Of course, the most common way of specifying a layout is still just as a plain template name:

  class WeblogController < ActionController::Base
    layout "weblog_standard"

If no directory is specified for the template name, the template will by default be looked for in app/views/layouts/. Otherwise, it will be looked up relative to the template root.

Conditional layouts

If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The :only and :except options can be passed to the layout call. For example:

  class WeblogController < ActionController::Base
    layout "weblog_standard", :except => :rss

    # ...

  end

This will assign "weblog_standard" as the WeblogController‘s layout except for the rss action, which will not wrap a layout around the rendered view.

Both the :only and :except condition can accept an arbitrary number of method references, so #:except => [ :rss, :text_only ] is valid, as is :except => :rss.

Using a different layout in the action render call

If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above. Sometimes you‘ll have exceptions where one action wants to use a different layout than the rest of the controller. You can do this by passing a :layout option to the render call. For example:

  class WeblogController < ActionController::Base
    layout "weblog_standard"

    def help
      render :action => "help", :layout => "help"
    end
  end

This will render the help action with the "help" layout instead of the controller-wide "weblog_standard" layout.

Methods

layout

Public Instance methods

layout(template_name, conditions = {}, auto = false)

If a layout is specified, all rendered actions will have their result rendered when the layout yields. This layout can itself depend on instance variables assigned during action performance and have access to them as any normal template would.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/layout.rb, line 165
165:       def layout(template_name, conditions = {}, auto = false)
166:         add_layout_conditions(conditions)
167:         write_inheritable_attribute(:layout, template_name)
168:         write_inheritable_attribute(:auto_layout, auto)
169:       end


Class: ActionController::MiddlewareStack

Class | ActionController::MiddlewareStack
In: | vendor/rails/actionpack/lib/action_controller/middleware_stack.rb
Parent: | Array

Methods

active build insert insert_after insert_before new swap use

Classes and Modules

Class ActionController::MiddlewareStack::Middleware

Public Class methods

new(*args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 83
83:     def initialize(*args, &block)
84:       super(*args)
85:       block.call(self) if block_given?
86:     end

Public Instance methods

active()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 111
111:     def active
112:       find_all { |middleware| middleware.active? }
113:     end
build(app)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 115
115:     def build(app)
116:       active.reverse.inject(app) { |a, e| e.build(a) }
117:     end
insert(index, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 88
88:     def insert(index, *args, &block)
89:       index = self.index(index) unless index.is_a?(Integer)
90:       middleware = Middleware.new(*args, &block)
91:       super(index, middleware)
92:     end
insert_after(index, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 96
96:     def insert_after(index, *args, &block)
97:       index = self.index(index) unless index.is_a?(Integer)
98:       insert(index + 1, *args, &block)
99:     end
insert_before(index, *args, &block)

Alias for insert

swap(target, *args, &block)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 101
101:     def swap(target, *args, &block)
102:       insert_before(target, *args, &block)
103:       delete(target)
104:     end
use(*args, &block)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 106
106:     def use(*args, &block)
107:       middleware = Middleware.new(*args, &block)
108:       push(middleware)
109:     end


Class: ActionController::MiddlewareStack::Middleware

Class | ActionController::MiddlewareStack::Middleware
In: | vendor/rails/actionpack/lib/action_controller/middleware_stack.rb
Parent: | Object

Methods

== active? build inspect klass new new

Attributes

args | [R]
block | [R]

Public Class methods

new(klass, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 14
14:       def initialize(klass, *args, &block)
15:         @klass = klass
16:
17:         options = args.extract_options!
18:         if options.has_key?(:if)
19:           @conditional = options.delete(:if)
20:         else
21:           @conditional = true
22:         end
23:         args << options unless options.empty?
24:
25:         @args = args
26:         @block = block
27:       end
new(klass, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 4
 4:       def self.new(klass, *args, &block)
 5:         if klass.is_a?(self)
 6:           klass
 7:         else
 8:           super
 9:         end
10:       end

Public Instance methods

==(middleware)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 51
51:       def ==(middleware)
52:         case middleware
53:         when Middleware
54:           klass == middleware.klass
55:         when Class
56:           klass == middleware
57:         else
58:           klass == middleware.to_s.constantize
59:         end
60:       end
active?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 41
41:       def active?
42:         return false unless klass
43:
44:         if @conditional.respond_to?(:call)
45:           @conditional.call
46:         else
47:           @conditional
48:         end
49:       end
build(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 68
68:       def build(app)
69:         if block
70:           klass.new(app, *build_args, &block)
71:         else
72:           klass.new(app, *build_args)
73:         end
74:       end
inspect()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 62
62:       def inspect
63:         str = klass.to_s
64:         args.each { |arg| str += ", #{arg.inspect}" }
65:         str
66:       end
klass()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/middleware_stack.rb, line 29
29:       def klass
30:         if @klass.respond_to?(:call)
31:           @klass.call
32:         elsif @klass.is_a?(Class)
33:           @klass
34:         else
35:           @klass.to_s.constantize
36:         end
37:       rescue NameError
38:         @klass
39:       end


Module: ActionController::MimeResponds::InstanceMethods

Module | ActionController::MimeResponds::InstanceMethods
In: | vendor/rails/actionpack/lib/action_controller/mime_responds.rb

Methods

respond_to

Public Instance methods

respond_to(*types, &block)

Without web-service support, an action which collects the data for displaying a list of people might look something like this:

  def index
    @people = Person.find(:all)
  end

Here‘s the same action, with web-service support baked in:

  def index
    @people = Person.find(:all)

    respond_to do |format|
      format.html
      format.xml { render :xml => @people.to_xml }
    end
  end

What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.)

Supposing you have an action that adds a new person, optionally creating their company (by name) if it does not already exist, without web-services, it might look like this:

  def create
    @company = Company.find_or_create_by_name(params[:company][:name])
    @person  = @company.people.create(params[:person])

    redirect_to(person_list_url)
  end

Here‘s the same action, with web-service support baked in:

  def create
    company  = params[:person].delete(:company)
    @company = Company.find_or_create_by_name(company[:name])
    @person  = @company.people.create(params[:person])

    respond_to do |format|
      format.html { redirect_to(person_list_url) }
      format.js
      format.xml  { render :xml => @person.to_xml(:include => @company) }
    end
  end

If the client wants HTML, we just redirect them back to the person list. If they want Javascript (format.js), then it is an RJS request and we render the RJS template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person‘s company in the rendered XML, so you get something like this:

  <person>
    <id>...</id>
    ...
    <company>
      <id>...</id>
      <name>...</name>
      ...
    </company>
  </person>

Note, however, the extra bit at the top of that action:

  company  = params[:person].delete(:company)
  @company = Company.find_or_create_by_name(company[:name])

This is because the incoming XML document (if a web-service request is in process) can only contain a single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):

  person[name]=...&person[company][name]=...&...

And, like this (xml-encoded):

  <person>
    <name>...</name>
    <company>
      <name>...</name>
    </company>
  </person>

In other words, we make the request so that it operates on a single entity‘s person. Then, in the action, we extract the company data from the request, find or create the company, and then create the new person with the remaining data.

Note that you can define your own XML parameter parser which would allow you to describe multiple entities in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow and accept Rails’ defaults, life will be much easier.

If you need to use a MIME type which isn‘t supported by default, you can register your own handlers in environment.rb as follows.

  Mime::Type.register "image/jpg", :jpg

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_responds.rb, line 102
102:       def respond_to(*types, &block)
103:         raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
104:         block ||= lambda { |responder| types.each { |type| responder.send(type) } }
105:         responder = Responder.new(self)
106:         block.call(responder)
107:         responder.respond
108:       end


Class: ActionController::ParamsParser

Class | ActionController::ParamsParser
In: | vendor/rails/actionpack/lib/action_controller/params_parser.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/params_parser.rb, line 6
6:     def initialize(app)
7:       @app = app
8:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/params_parser.rb, line 10
10:     def call(env)
11:       if params = parse_formatted_parameters(env)
12:         env["action_controller.request.request_parameters"] = params
13:       end
14:
15:       @app.call(env)
16:     end


Class: ActionController::PerformanceTest

Class | ActionController::PerformanceTest
In: | vendor/rails/actionpack/lib/action_controller/performance_test.rb
Parent: | ActionController::IntegrationTest

An integration test that runs a code profiler on your test methods. Profiling output for combinations of each test method, measurement, and output format are written to your tmp/performance directory.

By default, process_time is measured and both flat and graph_html output formats are written, so you‘ll have two output files per test method.

Included Modules

ActiveSupport::Testing::Performance ActiveSupport::Testing::Default


Module: ActionController::PolymorphicRoutes

Module | ActionController::PolymorphicRoutes
In: | vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb

Polymorphic URL helpers are methods for smart resolution to a named route call when given an Active Record model instance. They are to be used in combination with ActionController::Resources.

These methods are useful when you want to generate correct URL or path to a RESTful resource without having to know the exact type of the record in question.

Nested resources and/or namespaces are also supported, as illustrated in the example:

  polymorphic_url([:admin, @article, @comment])

results in:

  admin_article_comment_url(@article, @comment)

Usage within the framework

Polymorphic URL helpers are used in a number of places throughout the Rails framework:

  • url_for, so you can use it with a record as the argument, e.g. url_for(@article);
  • ActionView::Helpers::FormHelper uses polymorphic_path, so you can write form_for(@article) without having to specify :url parameter for the form action;
  • redirect_to (which, in fact, uses url_for) so you can write redirect_to(post) in your controllers;
  • ActionView::Helpers::AtomFeedHelper, so you don‘t have to explicitly specify URLs for feed entries.

Prefixed polymorphic helpers

In addition to polymorphic_url and polymorphic_path methods, a number of prefixed helpers are available as a shorthand to :action => "…" in options. Those are:

  • edit_polymorphic_url, edit_polymorphic_path
  • new_polymorphic_url, new_polymorphic_path

Example usage:

  edit_polymorphic_path(@post)              # => "/posts/1/edit"
  polymorphic_path(@post, :format => :pdf)  # => "/posts/1.pdf"

Methods

formatted_polymorphic_path formatted_polymorphic_url polymorphic_path polymorphic_url

Public Instance methods

formatted_polymorphic_path(record_or_hash, options = {})

[Source]

     # File vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb, line 142
142:     def formatted_polymorphic_path(record_or_hash, options = {})
143:       ActiveSupport::Deprecation.warn("formatted_polymorphic_path has been deprecated. Please pass :format to the polymorphic_path method instead", caller)
144:       options[:format] = record_or_hash.pop if record_or_hash === Array
145:       polymorphic_url(record_or_hash, options.merge(:routing_type => :path))
146:     end
formatted_polymorphic_url(record_or_hash, options = {})

[Source]

     # File vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb, line 136
136:     def formatted_polymorphic_url(record_or_hash, options = {})
137:       ActiveSupport::Deprecation.warn("formatted_polymorphic_url has been deprecated. Please pass :format to the polymorphic_url method instead", caller)
138:       options[:format] = record_or_hash.pop if Array === record_or_hash
139:       polymorphic_url(record_or_hash, options)
140:     end
polymorphic_path(record_or_hash_or_array, options = {})

Returns the path component of a URL for the given record. It uses polymorphic_url with :routing_type => :path.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb, line 114
114:     def polymorphic_path(record_or_hash_or_array, options = {})
115:       options[:routing_type] = :path
116:       polymorphic_url(record_or_hash_or_array, options)
117:     end
polymorphic_url(record_or_hash_or_array, options = {})

Constructs a call to a named RESTful route for the given record and returns the resulting URL string. For example:

  # calls post_url(post)
  polymorphic_url(post) # => "http://example.com/posts/1"
  polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
  polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
  polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"

Options

  • :action - Specifies the action prefix for the named route: :new or :edit. Default is no prefix.
  • :routing_type - Allowed values are :path or :url. Default is :url.

Examples

  # an Article record
  polymorphic_url(record)  # same as article_url(record)

  # a Comment record
  polymorphic_url(record)  # same as comment_url(record)

  # it recognizes new records and maps to the collection
  record = Comment.new
  polymorphic_url(record)  # same as comments_url()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb, line 73
 73:     def polymorphic_url(record_or_hash_or_array, options = {})
 74:       if record_or_hash_or_array.kind_of?(Array)
 75:         record_or_hash_or_array = record_or_hash_or_array.compact
 76:         record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1
 77:       end
 78:
 79:       record    = extract_record(record_or_hash_or_array)
 80:       namespace = extract_namespace(record_or_hash_or_array)
 81:
 82:       args = case record_or_hash_or_array
 83:         when Hash;  [ record_or_hash_or_array ]
 84:         when Array; record_or_hash_or_array.dup
 85:         else        [ record_or_hash_or_array ]
 86:       end
 87:
 88:       inflection =
 89:         case
 90:         when options[:action].to_s == "new"
 91:           args.pop
 92:           :singular
 93:         when record.respond_to?(:new_record?) && record.new_record?
 94:           args.pop
 95:           :plural
 96:         else
 97:           :singular
 98:         end
 99:
100:       args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
101:
102:       named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
103:
104:       url_options = options.except(:action, :routing_type)
105:       unless url_options.empty?
106:         args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
107:       end
108:
109:       __send__(named_route, *args)
110:     end


Module: ActionController::RecordIdentifier

Module | ActionController::RecordIdentifier
In: | vendor/rails/actionpack/lib/action_controller/record_identifier.rb

The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to a higher logical level. Example:

  # routes
  map.resources :posts

  # view
  <% div_for(post) do %>     <div id="post_45" class="post">
    <%= post.body %>           What a wonderful world!
  <% end %>                  </div>

  # controller
  def destroy
    post = Post.find(params[:id])
    post.destroy

    respond_to do |format|
      format.html { redirect_to(post) } # Calls polymorphic_url(post) which in turn calls post_url(post)
      format.js do
        # Calls: new Effect.fade('post_45');
        render(:update) { |page| page[post].visual_effect(:fade) }
      end
    end
  end

As the example above shows, you can stop caring to a large extent what the actual id of the post is. You just know that one is being assigned and that the subsequent calls in redirect_to and the RJS expect that same naming convention and allows you to write less code if you follow it.

Methods

dom_class dom_id partial_path plural_class_name singular_class_name

Constants

JOIN | = | '_'.freeze
NEW | = | 'new'.freeze

Public Instance methods

dom_class(record_or_class, prefix = nil)

The DOM class convention is to use the singular form of an object or class. Examples:

  dom_class(post)   # => "post"
  dom_class(Person) # => "person"

If you need to address multiple instances of the same class in the same view, you can prefix the dom_class:

  dom_class(post, :edit)   # => "edit_post"
  dom_class(Person, :edit) # => "edit_person"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/record_identifier.rb, line 61
61:     def dom_class(record_or_class, prefix = nil)
62:       singular = singular_class_name(record_or_class)
63:       prefix ? "#{prefix}#{JOIN}#{singular}" : singular
64:     end
dom_id(record, prefix = nil)

The DOM id convention is to use the singular form of an object or class with the id following an underscore. If no id is found, prefix with "new_" instead. Examples:

  dom_id(Post.find(45))       # => "post_45"
  dom_id(Post.new)            # => "new_post"

If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:

  dom_id(Post.find(45), :edit) # => "edit_post_45"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/record_identifier.rb, line 75
75:     def dom_id(record, prefix = nil)
76:       if record_id = record.id
77:         "#{dom_class(record, prefix)}#{JOIN}#{record_id}"
78:       else
79:         dom_class(record, prefix || NEW)
80:       end
81:     end
partial_path(record_or_class, controller_path = nil)

Returns plural/singular for a record or class. Example:

  partial_path(post)                   # => "posts/post"
  partial_path(Person)                 # => "people/person"
  partial_path(Person, "admin/games")  # => "admin/people/person"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/record_identifier.rb, line 42
42:     def partial_path(record_or_class, controller_path = nil)
43:       name = model_name_from_record_or_class(record_or_class)
44:
45:       if controller_path && controller_path.include?("/")
46:         "#{File.dirname(controller_path)}/#{name.partial_path}"
47:       else
48:         name.partial_path
49:       end
50:     end
plural_class_name(record_or_class)

Returns the plural class name of a record or class. Examples:

  plural_class_name(post)             # => "posts"
  plural_class_name(Highrise::Person) # => "highrise_people"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/record_identifier.rb, line 87
87:     def plural_class_name(record_or_class)
88:       model_name_from_record_or_class(record_or_class).plural
89:     end
singular_class_name(record_or_class)

Returns the singular class name of a record or class. Examples:

  singular_class_name(post)             # => "post"
  singular_class_name(Highrise::Person) # => "highrise_person"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/record_identifier.rb, line 95
95:     def singular_class_name(record_or_class)
96:       model_name_from_record_or_class(record_or_class).singular
97:     end


Class: ActionController::Reloader

Class | ActionController::Reloader
In: | vendor/rails/actionpack/lib/action_controller/reloader.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/reloader.rb, line 3
3:     def initialize(app)
4:       @app = app
5:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/reloader.rb, line 7
 7:     def call(env)
 8:       Dispatcher.reload_application
 9:       @app.call(env)
10:     ensure
11:       Dispatcher.cleanup_application
12:     end


Class: ActionController::Request

Class | ActionController::Request
In: | vendor/rails/actionpack/lib/action_controller/request.rb
Parent: | Rack::Request

Methods

GET POST accepts body cache_format content_length content_type delete? domain etag_matches? form_data? format format= fresh? get? head? headers host host_with_port if_modified_since if_none_match key? method not_modified? parameters params path path_parameters port port_string post? protocol put? query_parameters query_string raw_host_with_port raw_post remote_ip request_method request_parameters request_uri reset_session server_port server_software session session_options session_options= ssl? standard_port subdomains symbolized_path_parameters template_format url xhr? xml_http_request?

Constants

HTTP_METHODS | = | %w(get head put post delete options)
HTTP_METHOD_LOOKUP | = | HTTP_METHODS.inject({}) { |h, m| h[m] = h[m.upcase] = m.to_sym;
TRUSTED_PROXIES | = | /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i | Which IP addresses are "trusted proxies" that can be stripped from the right-hand-side of X-Forwarded-For

Public Instance methods

GET()

Override Rack‘s GET method to support indifferent access

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 422
422:     def GET
423:       @env["action_controller.request.query_parameters"] ||= normalize_parameters(super)
424:     end
POST()

Override Rack‘s POST method to support indifferent access

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 428
428:     def POST
429:       @env["action_controller.request.request_parameters"] ||= normalize_parameters(super)
430:     end
accepts()

Returns the accepted MIME type for the request.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 99
 99:     def accepts
100:       @accepts ||= begin
101:         header = @env['HTTP_ACCEPT'].to_s.strip
102:
103:         if header.empty?
104:           [content_type, Mime::ALL].compact
105:         else
106:           Mime::Type.parse(header)
107:         end
108:       end
109:     end
body()

The request body is an IO input stream. If the RAW_POST_DATA environment variable is already set, wrap it in a StringIO.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 408
408:     def body
409:       if raw_post = @env['RAW_POST_DATA']
410:         raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
411:         StringIO.new(raw_post)
412:       else
413:         @env['rack.input']
414:       end
415:     end
cache_format()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 195
195:     def cache_format
196:       parameters[:format]
197:     end
content_length()

Returns the content length of the request as an integer.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 80
80:     def content_length
81:       super.to_i
82:     end
content_type()

The MIME type of the HTTP request, such as Mime::XML.

For backward compatibility, the post \format is extracted from the X-Post-Data-Format HTTP header if present.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 88
88:     def content_type
89:       @content_type ||= begin
90:         if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/
91:           Mime::Type.lookup($1.strip.downcase)
92:         else
93:           nil
94:         end
95:       end
96:     end
delete?()

Is this a DELETE request? Equivalent to request.method == :delete.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 62
62:     def delete?
63:       request_method == :delete
64:     end
domain(tld_length = 1)

Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify a different tld_length, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 316
316:     def domain(tld_length = 1)
317:       return nil unless named_host?(host)
318:
319:       host.split('.').last(1 + tld_length).join('.')
320:     end
etag_matches?(etag)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 125
125:     def etag_matches?(etag)
126:       if_none_match && if_none_match == etag
127:     end
form_data?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 417
417:     def form_data?
418:       FORM_DATA_MEDIA_TYPES.include?(content_type.to_s)
419:     end
format()

Returns the Mime type for the \format used in the request.

  GET /posts/5.xml   | request.format => Mime::XML
  GET /posts/5.xhtml | request.format => Mime::HTML
  GET /posts/5       | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of <tt>ActionController::Base.use_accept_header</tt>

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 150
150:     def format
151:       @format ||=
152:         if parameters[:format]
153:           Mime::Type.lookup_by_extension(parameters[:format])
154:         elsif ActionController::Base.use_accept_header
155:           accepts.first
156:         elsif xhr?
157:           Mime::Type.lookup_by_extension("js")
158:         else
159:           Mime::Type.lookup_by_extension("html")
160:         end
161:     end
format=(extension)

Sets the \format by string extension, which can be used to force custom formats that are not controlled by the extension.

  class ApplicationController < ActionController::Base
    before_filter :adjust_format_for_iphone

    private
      def adjust_format_for_iphone
        request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
      end
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 175
175:     def format=(extension)
176:       parameters[:format] = extension.to_s
177:       @format = Mime::Type.lookup_by_extension(parameters[:format])
178:     end
fresh?(response)

Check response freshness (Last-Modified and ETag) against request If-Modified-Since and If-None-Match conditions. If both headers are supplied, both must match, or the request is not considered fresh.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 132
132:     def fresh?(response)
133:       case
134:       when if_modified_since && if_none_match
135:         not_modified?(response.last_modified) && etag_matches?(response.etag)
136:       when if_modified_since
137:         not_modified?(response.last_modified)
138:       when if_none_match
139:         etag_matches?(response.etag)
140:       else
141:         false
142:       end
143:     end
get?()

Is this a GET (or HEAD) request? Equivalent to request.method == :get.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 47
47:     def get?
48:       method == :get
49:     end
head?()

Is this a HEAD request? Since request.method sees HEAD as :get, this \method checks the actual HTTP \method directly.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 68
68:     def head?
69:       request_method == :head
70:     end
headers()

Provides access to the request‘s HTTP headers, for example:

  request.headers["Content-Type"] # => "text/plain"

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 75
75:     def headers
76:       @headers ||= ActionController::Http::Headers.new(@env)
77:     end
host()

Returns the host for this request, such as example.com.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 281
281:     def host
282:       raw_host_with_port.sub(/:\d+$/, '')
283:     end
host_with_port()

Returns a \host:\port string for this request, such as "example.com" or "example.com:8080".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 287
287:     def host_with_port
288:       "#{host}#{port_string}"
289:     end
if_modified_since()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 111
111:     def if_modified_since
112:       if since = env['HTTP_IF_MODIFIED_SINCE']
113:         Time.rfc2822(since) rescue nil
114:       end
115:     end
if_none_match()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 117
117:     def if_none_match
118:       env['HTTP_IF_NONE_MATCH']
119:     end
key?(key)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 24
24:     def key?(key)
25:       @env.key?(key)
26:     end
method()

Returns the HTTP request \method used for action processing as a lowercase symbol, such as :post. (Unlike request_method, this method returns :get for a HEAD request because the two are functionally equivalent from the application‘s perspective.)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 42
42:     def method
43:       request_method == :head ? :get : request_method
44:     end
not_modified?(modified_at)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 121
121:     def not_modified?(modified_at)
122:       if_modified_since && modified_at && if_modified_since >= modified_at
123:     end
parameters()

Returns both GET and POST \parameters in a single hash.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 381
381:     def parameters
382:       @parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
383:     end
params()

Alias for parameters

path()

Returns the interpreted \path to requested resource after all the installation directory of this application was taken into account.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 364
364:     def path
365:       path = request_uri.to_s[/\A[^\?]*/]
366:       path.sub!(/\A#{ActionController::Base.relative_url_root}/, '')
367:       path
368:     end
path_parameters()

Returns a hash with the \parameters used to form the \path of the request. Returned hash keys are strings:

  {'action' => 'my_action', 'controller' => 'my_controller'}

See symbolized_path_parameters for symbolized keys.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 402
402:     def path_parameters
403:       @env["rack.routing_args"] ||= {}
404:     end
port()

Returns the port number of this request as an integer.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 292
292:     def port
293:       if raw_host_with_port =~ /:(\d+)$/
294:         $1.to_i
295:       else
296:         standard_port
297:       end
298:     end
port_string()

Returns a \port suffix like ":8080" if the \port number of this request is not the default HTTP \port 80 or HTTPS \port 443.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 310
310:     def port_string
311:       port == standard_port ? '' : ":#{port}"
312:     end
post?()

Is this a POST request? Equivalent to request.method == :post.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 52
52:     def post?
53:       request_method == :post
54:     end
protocol()

Returns ‘https://’ if this is an SSL request and ‘http://’ otherwise.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 262
262:     def protocol
263:       ssl? ? 'https://' : 'http://'
264:     end
put?()

Is this a PUT request? Equivalent to request.method == :put.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 57
57:     def put?
58:       request_method == :put
59:     end
query_parameters()

Alias for GET

query_string()

Returns the query string, accounting for server idiosyncrasies.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 333
333:     def query_string
334:       @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].split('?', 2)[1] || '')
335:     end
raw_host_with_port()

Returns the \host for this request, such as "example.com".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 272
272:     def raw_host_with_port
273:       if forwarded = env["HTTP_X_FORWARDED_HOST"]
274:         forwarded.split(/,\s?/).last
275:       else
276:         env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}"
277:       end
278:     end
raw_post()

Read the request \body. This is useful for web services that need to work with raw requests directly.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 372
372:     def raw_post
373:       unless @env.include? 'RAW_POST_DATA'
374:         @env['RAW_POST_DATA'] = body.read(@env['CONTENT_LENGTH'].to_i)
375:         body.rewind if body.respond_to?(:rewind)
376:       end
377:       @env['RAW_POST_DATA']
378:     end
remote_ip()

Determines originating IP address. REMOTE_ADDR is the standard but will fail if the user is behind a proxy. HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by proxies so check for these if REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma- delimited list in the case of multiple chained proxies; the last address which is not trusted is the originating IP.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 217
217:     def remote_ip
218:       remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].scan(/[^,\s]+/)
219:
220:       unless remote_addr_list.blank?
221:         not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES}
222:         return not_trusted_addrs.first unless not_trusted_addrs.empty?
223:       end
224:       remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',')
225:
226:       if @env.include? 'HTTP_CLIENT_IP'
227:         if ActionController::Base.ip_spoofing_check && remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP'])
228:           # We don't know which came from the proxy, and which from the user
229:           raise ActionControllerError.new("IP spoofing attack?!\nHTTP_CLIENT_IP=\#{@env['HTTP_CLIENT_IP'].inspect}\nHTTP_X_FORWARDED_FOR=\#{@env['HTTP_X_FORWARDED_FOR'].inspect}\n")
230:         end
231:
232:         return @env['HTTP_CLIENT_IP']
233:       end
234:
235:       if remote_ips
236:         while remote_ips.size > 1 && TRUSTED_PROXIES =~ remote_ips.last.strip
237:           remote_ips.pop
238:         end
239:
240:         return remote_ips.last.strip
241:       end
242:
243:       @env['REMOTE_ADDR']
244:     end
request_method()

Returns the true HTTP request \method as a lowercase symbol, such as :get. If the request \method is not listed in the HTTP_METHODS constant above, an UnknownHttpMethod exception is raised.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request.rb, line 34
34:     def request_method
35:       @request_method ||= HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
36:     end
request_parameters()

Alias for POST

request_uri()

Returns the request URI, accounting for server idiosyncrasies. WEBrick includes the full URL. IIS leaves REQUEST_URI blank.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 339
339:     def request_uri
340:       if uri = @env['REQUEST_URI']
341:         # Remove domain, which webrick puts into the request_uri.
342:         (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri
343:       else
344:         # Construct IIS missing REQUEST_URI from SCRIPT_NAME and PATH_INFO.
345:         uri = @env['PATH_INFO'].to_s
346:
347:         if script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$})
348:           uri = uri.sub(/#{script_filename}\//, '')
349:         end
350:
351:         env_qs = @env['QUERY_STRING'].to_s
352:         uri += "?#{env_qs}" unless env_qs.empty?
353:
354:         if uri.blank?
355:           @env.delete('REQUEST_URI')
356:         else
357:           @env['REQUEST_URI'] = uri
358:         end
359:       end
360:     end
reset_session()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 445
445:     def reset_session
446:       @env['rack.session.options'].delete(:id)
447:       @env['rack.session'] = {}
448:     end
server_port()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 458
458:     def server_port
459:       @env['SERVER_PORT'].to_i
460:     end
server_software()

Returns the lowercase name of the HTTP server software.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 252
252:     def server_software
253:       (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil
254:     end
session()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 437
437:     def session
438:       @env['rack.session'] ||= {}
439:     end
session_options()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 450
450:     def session_options
451:       @env['rack.session.options'] ||= {}
452:     end
session_options=(options)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 454
454:     def session_options=(options)
455:       @env['rack.session.options'] = options
456:     end
ssl?()

Is this an SSL request?

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 267
267:     def ssl?
268:       @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
269:     end
standard_port()

Returns the standard \port number for this request‘s protocol.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 301
301:     def standard_port
302:       case protocol
303:         when 'https://' then 443
304:         else 80
305:       end
306:     end
subdomains(tld_length = 1)

Returns all the \subdomains as an array, so ["dev", "www"] would be returned for "dev.www.rubyonrails.org". You can specify a different tld_length, such as 2 to catch ["www"] instead of ["www", "rubyonrails"] in "www.rubyonrails.co.uk".

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 326
326:     def subdomains(tld_length = 1)
327:       return [] unless named_host?(host)
328:       parts = host.split('.')
329:       parts[0..-(tld_length+2)]
330:     end
symbolized_path_parameters()

The same as path_parameters with explicitly symbolized keys.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 392
392:     def symbolized_path_parameters
393:       @symbolized_path_parameters ||= path_parameters.symbolize_keys
394:     end
template_format()

Returns a symbolized version of the :format parameter of the request. If no \format is given it returns :jsfor Ajax requests and :html otherwise.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 183
183:     def template_format
184:       parameter_format = parameters[:format]
185:
186:       if parameter_format
187:         parameter_format
188:       elsif xhr?
189:         :js
190:       else
191:         :html
192:       end
193:     end
url()

Returns the complete URL used for this request.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 257
257:     def url
258:       protocol + host_with_port + request_uri
259:     end
xhr?()

Alias for xml_http_request?

xml_http_request?()

Returns true if the request‘s "X-Requested-With" header contains "XMLHttpRequest". (The Prototype Javascript library sends this header with every Ajax request.)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request.rb, line 202
202:     def xml_http_request?
203:       !(@env['HTTP_X_REQUESTED_WITH'] !~ /XMLHttpRequest/i)
204:     end


Module: ActionController::RequestForgeryProtection

Module | ActionController::RequestForgeryProtection
In: | vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb

Methods

form_authenticity_token included protect_against_forgery? verifiable_request_format? verified_request? verify_authenticity_token

Classes and Modules

Module ActionController::RequestForgeryProtection::ClassMethods

Public Class methods

included(base)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 6
 6:     def self.included(base)
 7:       base.class_eval do
 8:         helper_method :form_authenticity_token
 9:         helper_method :protect_against_forgery?
10:       end
11:       base.extend(ClassMethods)
12:     end

Protected Instance methods

form_authenticity_token()

Sets the token value for the current session. Pass a :secret option in protect_from_forgery to add a custom salt to the hash.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 100
100:       def form_authenticity_token
101:         session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
102:       end
protect_against_forgery?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 104
104:       def protect_against_forgery?
105:         allow_forgery_protection && request_forgery_protection_token
106:       end
verifiable_request_format?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 94
94:       def verifiable_request_format?
95:         !request.content_type.nil? && request.content_type.verify_request?
96:       end
verified_request?()

Returns true or false if a request is verified. Checks:

  • is the format restricted? By default, only HTML and AJAX requests are checked.
  • is it a GET request? Gets should be safe and idempotent
  • Does the form_authenticity_token match the given token value from the params?

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 87
87:       def verified_request?
88:         !protect_against_forgery?     ||
89:           request.method == :get      ||
90:           !verifiable_request_format? ||
91:           form_authenticity_token == params[request_forgery_protection_token]
92:       end
verify_authenticity_token()

The actual before_filter that is used. Modify this to change how you handle unverified requests.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 78
78:       def verify_authenticity_token
79:         verified_request? || raise(ActionController::InvalidAuthenticityToken)
80:       end


Module: ActionController::RequestForgeryProtection::ClassMethods

Module | ActionController::RequestForgeryProtection::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb

Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current web application, not a forged link from another site, is done by embedding a token based on a random string stored in the session (which an attacker wouldn‘t know) in all forms and Ajax requests generated by Rails and then verifying the authenticity of that token in the controller. Only HTML/JavaScript requests are checked, so this will not protect your XML API (presumably you‘ll have a different authentication scheme there anyway). Also, GET requests are not protected as these should be idempotent anyway.

This is turned on with the protect_from_forgery method, which will check the token and raise an ActionController::InvalidAuthenticityToken if it doesn‘t match what was expected. You can customize the error message in production by editing public/422.html. A call to this method in ApplicationController is generated by default in post-Rails 2.0 applications.

The token parameter is named authenticity_token by default. If you are generating an HTML form manually (without the use of Rails’ form_for, form_tag or other helpers), you have to include a hidden field named like that and set its value to what is returned by form_authenticity_token. Same applies to manually constructed Ajax requests. To make the token available through a global variable to scripts on a certain page, you could add something like this to a view:

  <%= javascript_tag "window._token = '#{form_authenticity_token}'" %>

Request forgery protection is disabled by default in test environment. If you are upgrading from Rails 1.x, add this to config/environments/test.rb:

  # Disable request forgery protection in test environment
  config.action_controller.allow_forgery_protection = false

Learn more about CSRF (Cross-Site Request Forgery) attacks

Here are some resources:

  • isc.sans.org/diary.html?storyid=1750
  • en.wikipedia.org/wiki/Cross-site_request_forgery

Keep in mind, this is NOT a silver-bullet, plug ‘n’ play, warm security blanket for your rails application. There are a few guidelines you should follow:

  • Keep your GET requests safe and idempotent. More reading material:
    • www.xml.com/pub/a/2002/04/24/deviant.html
    • www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
  • Make sure the session cookies that Rails creates are non-persistent. Check in Firefox and look for "Expires: at end of session"

Methods

protect_from_forgery

Public Instance methods

protect_from_forgery(options = {})

Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.

Example:

  class FooController < ApplicationController
    protect_from_forgery :except => :index

    # you can disable csrf protection on controller-by-controller basis:
    skip_before_filter :verify_authenticity_token
  end

Valid Options:

  • :only/:except - Passed to the before_filter call. Set which actions are verified.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb, line 67
67:       def protect_from_forgery(options = {})
68:         self.request_forgery_protection_token ||= :authenticity_token
69:         before_filter :verify_authenticity_token, :only => options.delete(:only), :except => options.delete(:except)
70:         if options[:secret] || options[:digest]
71:           ActiveSupport::Deprecation.warn("protect_from_forgery only takes :only and :except options now. :digest and :secret have no effect", caller)
72:         end
73:       end


Module: ActionController::Rescue

Module | ActionController::Rescue
In: | vendor/rails/actionpack/lib/action_controller/rescue.rb

Actions that fail to perform as expected throw exceptions. These exceptions can either be rescued for the public view (with a nice user-friendly explanation) or for the developers view (with tons of debugging information). The developers view is already implemented by the Action Controller, but the public view should be tailored to your specific application.

The default behavior for public exceptions is to render a static html file with the name of the error code thrown. If no such file exists, an empty response is sent with the correct status code.

You can override what constitutes a local request by overriding the local_request? method in your own controller. Custom rescue behavior is achieved by overriding the rescue_action_in_public and rescue_action_locally methods.

Methods

local_request? log_error render_optional_error_file rescue_action rescue_action_in_public rescue_action_locally rescue_action_without_handler

Classes and Modules

Module ActionController::Rescue::ClassMethods

Constants

LOCALHOST | = | '127.0.0.1'.freeze
DEFAULT_RESCUE_RESPONSE | = | :internal_server_error
DEFAULT_RESCUE_RESPONSES | = | { 'ActionController::RoutingError' => :not_found, 'ActionController::UnknownAction' => :not_found, 'ActiveRecord::RecordNotFound' => :not_found, 'ActiveRecord::StaleObjectError' => :conflict, 'ActiveRecord::RecordInvalid' => :unprocessable_entity, 'ActiveRecord::RecordNotSaved' => :unprocessable_entity, 'ActionController::MethodNotAllowed' => :method_not_allowed, 'ActionController::NotImplemented' => :not_implemented, 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
DEFAULT_RESCUE_TEMPLATE | = | 'diagnostics'
DEFAULT_RESCUE_TEMPLATES | = | { 'ActionView::MissingTemplate' => 'missing_template', 'ActionController::RoutingError' => 'routing_error', 'ActionController::UnknownAction' => 'unknown_action', 'ActionView::TemplateError' => 'template_error'
RESCUES_TEMPLATE_PATH | = | ActionView::Template::EagerPath.new_and_loaded( File.join(File.dirname(__FILE__), "templates"))

Protected Instance methods

local_request?(

True if the request came from localhost, 127.0.0.1. Override this method if you wish to redefine the meaning of a local request to include remote IP addresses or other criteria.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 124
124:       def local_request? #:doc:
125:         request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
126:       end
log_error(exception)

Overwrite to implement custom logging of errors. By default logs as fatal.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 79
79:       def log_error(exception) #:doc:
80:         ActiveSupport::Deprecation.silence do
81:           if ActionView::TemplateError === exception
82:             logger.fatal(exception.to_s)
83:           else
84:             logger.fatal(
85:               "\n#{exception.class} (#{exception.message}):\n  " +
86:               clean_backtrace(exception).join("\n  ") + "\n\n"
87:             )
88:           end
89:         end
90:       end
render_optional_error_file(status_code)

Attempts to render a static error page based on the status_code thrown, or just return headers if no such file exists. At first, it will try to render a localized static page. For example, if a 500 error is being handled Rails and locale is :da, it will first attempt to render the file at public/500.da.html then attempt to render public/500.html. If none of them exist, the body of the response will be left empty.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 107
107:       def render_optional_error_file(status_code)
108:         status = interpret_status(status_code)
109:         locale_path = "#{Rails.public_path}/#{status[0,3]}.#{I18n.locale}.html" if I18n.locale
110:         path = "#{Rails.public_path}/#{status[0,3]}.html"
111:
112:         if locale_path && File.exist?(locale_path)
113:           render :file => locale_path, :status => status, :content_type => Mime::HTML
114:         elsif File.exist?(path)
115:           render :file => path, :status => status, :content_type => Mime::HTML
116:         else
117:           head status
118:         end
119:       end
rescue_action(exception)

Exception handler called when the performance of an action raises an exception.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 72
72:       def rescue_action(exception)
73:         rescue_with_handler(exception) ||
74:           rescue_action_without_handler(exception)
75:       end
rescue_action_in_public(exception)

Overwrite to implement public exception handling (for requests answering false to local_request?). By default will call render_optional_error_file. Override this method to provide more user friendly error messages.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 96
96:       def rescue_action_in_public(exception) #:doc:
97:         render_optional_error_file response_code_for_rescue(exception)
98:       end
rescue_action_locally(exception)

Render detailed diagnostics for unhandled exceptions rescued from a controller action.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 130
130:       def rescue_action_locally(exception)
131:         @template.instance_variable_set("@exception", exception)
132:         @template.instance_variable_set("@rescues_path", RESCUES_TEMPLATE_PATH)
133:         @template.instance_variable_set("@contents",
134:           @template.render(:file => template_path_for_local_rescue(exception)))
135:
136:         response.content_type = Mime::HTML
137:         render_for_file(rescues_path("layout"),
138:           response_code_for_rescue(exception))
139:       end
rescue_action_without_handler(exception)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 141
141:       def rescue_action_without_handler(exception)
142:         log_error(exception) if logger
143:         erase_results if performed?
144:
145:         # Let the exception alter the response if it wants.
146:         # For example, MethodNotAllowed sets the Allow header.
147:         if exception.respond_to?(:handle_response!)
148:           exception.handle_response!(response)
149:         end
150:
151:         if consider_all_requests_local || local_request?
152:           rescue_action_locally(exception)
153:         else
154:           rescue_action_in_public(exception)
155:         end
156:       end


Module: ActionController::Rescue::ClassMethods

Module | ActionController::Rescue::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/rescue.rb


Module: ActionController::Resources

Module | ActionController::Resources
In: | vendor/rails/actionpack/lib/action_controller/resources.rb

Overview

ActionController::Resources are a way of defining RESTful \resources. A RESTful \resource, in basic terms, is something that can be pointed at and it will respond with a representation of the data requested. In real terms this could mean a user with a browser requests an HTML page, or that a desktop application requests XML data.

RESTful design is based on the assumption that there are four generic verbs that a user of an application can request from a \resource (the noun).

\Resources can be requested using four basic HTTP verbs (GET, POST, PUT, DELETE), the method used denotes the type of action that should take place.

The Different Methods and their Usage

  • GET - Requests for a \resource, no saving or editing of a \resource should occur in a GET request.
  • POST - Creation of \resources.
  • PUT - Editing of attributes on a \resource.
  • DELETE - Deletion of a \resource.

Examples

  # A GET request on the Posts resource is asking for all Posts
  GET /posts

  # A GET request on a single Post resource is asking for that particular Post
  GET /posts/1

  # A POST request on the Posts resource is asking for a Post to be created with the supplied details
  POST /posts # with => { :post => { :title => "My Whizzy New Post", :body => "I've got a brand new combine harvester" } }

  # A PUT request on a single Post resource is asking for a Post to be updated
  PUT /posts # with => { :id => 1, :post => { :title => "Changed Whizzy Title" } }

  # A DELETE request on a single Post resource is asking for it to be deleted
  DELETE /posts # with => { :id => 1 }

By using the REST convention, users of our application can assume certain things about how the data is requested and how it is returned. Rails simplifies the routing part of RESTful design by supplying you with methods to create them in your routes.rb file.

Read more about REST at en.wikipedia.org/wiki/Representational_State_Transfer

Methods

resource resources

Constants

INHERITABLE_OPTIONS = :namespace, :shallow

Public Instance methods

resource(*entities, &block)

Creates named routes for implementing verb-oriented controllers for a singleton \resource. A singleton \resource is global to its current context. For unnested singleton \resources, the \resource is global to the current user visiting the application, such as a user‘s /account profile. For nested singleton \resources, the \resource is global to its parent \resource, such as a projects \resource that has_one :project_manager. The project_manager should be mapped as a singleton \resource under projects:

  map.resources :projects do |project|
    project.resource :project_manager
  end

See resources for general conventions. These are the main differences:

  • A singular name is given to map.resource. The default controller name is still taken from the plural name.
  • To specify a custom plural name, use the :plural option. There is no :singular option.
  • No default index route is created for the singleton \resource controller.
  • When nesting singleton \resources, only the singular name is used as the path prefix (example: ‘account/messages/1’)

For example:

  map.resource :account

maps these actions in the Accounts controller:

  class AccountsController < ActionController::Base
    # GET new_account_url
    def new
      # return an HTML form for describing the new account
    end

    # POST account_url
    def create
      # create an account
    end

    # GET account_url
    def show
      # find and return the account
    end

    # GET edit_account_url
    def edit
      # return an HTML form for editing the account
    end

    # PUT account_url
    def update
      # find and update the account
    end

    # DELETE account_url
    def destroy
      # delete the account
    end
  end

Along with the routes themselves, resource generates named routes for use in controllers and views. map.resource :account produces these named routes and helpers:

  Named Route   Helpers
  ============  =============================================
  account       account_url, hash_for_account_url,
                account_path, hash_for_account_path

  new_account   new_account_url, hash_for_new_account_url,
                new_account_path, hash_for_new_account_path

  edit_account  edit_account_url, hash_for_edit_account_url,
                edit_account_path, hash_for_edit_account_path

[Source]

     # File vendor/rails/actionpack/lib/action_controller/resources.rb, line 518
518:     def resource(*entities, &block)
519:       options = entities.extract_options!
520:       entities.each { |entity| map_singleton_resource(entity, options.dup, &block) }
521:     end
resources(*entities, &block)

Creates named routes for implementing verb-oriented controllers for a collection \resource.

For example:

  map.resources :messages

will map the following actions in the corresponding controller:

  class MessagesController < ActionController::Base
    # GET messages_url
    def index
      # return all messages
    end

    # GET new_message_url
    def new
      # return an HTML form for describing a new message
    end

    # POST messages_url
    def create
      # create a new message
    end

    # GET message_url(:id => 1)
    def show
      # find and return a specific message
    end

    # GET edit_message_url(:id => 1)
    def edit
      # return an HTML form for editing a specific message
    end

    # PUT message_url(:id => 1)
    def update
      # find and update a specific message
    end

    # DELETE message_url(:id => 1)
    def destroy
      # delete a specific message
    end
  end

Along with the routes themselves, resources generates named routes for use in controllers and views. map.resources :messages produces the following named routes and helpers:

  Named Route   Helpers
  ============  =====================================================
  messages      messages_url, hash_for_messages_url,
                messages_path, hash_for_messages_path

  message       message_url(id), hash_for_message_url(id),
                message_path(id), hash_for_message_path(id)

  new_message   new_message_url, hash_for_new_message_url,
                new_message_path, hash_for_new_message_path

  edit_message  edit_message_url(id), hash_for_edit_message_url(id),
                edit_message_path(id), hash_for_edit_message_path(id)

You can use these helpers instead of url_for or methods that take url_for parameters. For example:

  redirect_to :controller => 'messages', :action => 'index'
  # and
  <%= link_to "edit this message", :controller => 'messages', :action => 'edit', :id => @message.id %>

now become:

  redirect_to messages_url
  # and
  <%= link_to "edit this message", edit_message_url(@message) # calls @message.id automatically

Since web browsers don‘t support the PUT and DELETE verbs, you will need to add a parameter ‘_method’ to your form tags. The form helpers make this a little easier. For an update form with a @message object:

  <%= form_tag message_path(@message), :method => :put %>

or

  <% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>

or

  <% form_for @message do |f| %>

which takes into account whether @message is a new record or not and generates the path and method accordingly.

The resources method accepts the following options to customize the resulting routes:

  • :collection - Add named routes for other actions that operate on the collection. Takes a hash of #{action} => #{method}, where method is :get/:post/:put/:delete, an array of any of the previous, or :any if the method does not matter. These routes map to a URL like /messages/rss, with a route of rss_messages_url.
  • :member - Same as :collection, but for actions that operate on a specific member.
  • :new - Same as :collection, but for actions that operate on the new \resource action.
  • :controller - Specify the controller name for the routes.
  • :singular - Specify the singular name used in the member routes.
  • :requirements - Set custom routing parameter requirements; this is a hash of either
      regular expressions (which must match for the route to match) or extra parameters. For example:

    map.resource :profile, :path_prefix => ':name', :requirements => { :name => /[a-zA-Z]+/, :extra => 'value' }

  will only match if the first part is alphabetic, and will pass the parameter :extra to the controller.
  • :conditions - Specify custom routing recognition conditions. \Resources sets the :method value for the method-specific routes.
  • :as - Specify a different \resource name to use in the URL path. For example:
      # products_path == '/productos'
  map.resources :products, :as => 'productos' do |product|
    # product_reviews_path(product) == '/productos/1234/comentarios'
    product.resources :product_reviews, :as => 'comentarios'
  end
  • :has_one - Specify nested \resources, this is a shorthand for mapping singleton \resources beneath the current.
  • :has_many - Same has :has_one, but for plural \resources.

    You may directly specify the routing association with has_one and has_many like:

      map.resources :notes, :has_one => :author, :has_many => [:comments, :attachments]

    This is the same as:

      map.resources :notes do |notes|
    notes.resource  :author
    notes.resources :comments
    notes.resources :attachments
  end
  • :path_names - Specify different names for the ‘new’ and ‘edit’ actions. For example:
      # new_products_path == '/productos/nuevo'
  map.resources :products, :as => 'productos', :path_names => { :new => 'nuevo', :edit => 'editar' }

    You can also set default action names from an environment, like this:

      config.action_controller.resources_path_names = { :new => 'nuevo', :edit => 'editar' }
  • :path_prefix - Set a prefix to the routes with required route variables.

    Weblog comments usually belong to a post, so you might use resources like:

      map.resources :articles
  map.resources :comments, :path_prefix => '/articles/:article_id'

    You can nest resources calls to set this automatically:

      map.resources :articles do |article|
    article.resources :comments
  end

    The comment \resources work the same, but must now include a value for :article_id.

      article_comments_url(@article)
  article_comment_url(@article, @comment)

  article_comments_url(:article_id => @article)
  article_comment_url(:article_id => @article, :id => @comment)

    If you don‘t want to load all objects from the database you might want to use the article_id directly:

      articles_comments_url(@comment.article_id, @comment)
  • :name_prefix - Define a prefix for all generated routes, usually ending in an underscore. Use this if you have named routes that may clash.
      map.resources :tags, :path_prefix => '/books/:book_id', :name_prefix => 'book_'
  map.resources :tags, :path_prefix => '/toys/:toy_id',   :name_prefix => 'toy_'

You may also use :name_prefix to override the generic named routes in a nested \resource:

  map.resources :articles do |article|
    article.resources :comments, :name_prefix => nil
  end

This will yield named \resources like so:

  comments_url(@article)
  comment_url(@article, @comment)
  • :shallow - If true, paths for nested resources which reference a specific member (ie. those with an :id parameter) will not use the parent path prefix or name prefix.

The :shallow option is inherited by any nested resource(s).

For example, ‘users’, ‘posts’ and ‘comments’ all use shallow paths with the following nested resources:

  map.resources :users, :shallow => true do |user|
    user.resources :posts do |post|
      post.resources :comments
    end
  end
  # --> GET /users/1/posts (maps to the PostsController#index action as usual)
  #     also adds the usual named route called "user_posts"
  # --> GET /posts/2 (maps to the PostsController#show action as if it were not nested)
  #     also adds the named route called "post"
  # --> GET /posts/2/comments (maps to the CommentsController#index action)
  #     also adds the named route called "post_comments"
  # --> GET /comments/2 (maps to the CommentsController#show action as if it were not nested)
  #     also adds the named route called "comment"

You may also use :shallow in combination with the has_one and has_many shorthand notations like:

  map.resources :users, :has_many => { :posts => :comments }, :shallow => true
  • :only and :except - Specify which of the seven default actions should be routed to.

:only and :except may be set to :all, :none, an action name or a list of action names. By default, routes are generated for all seven actions.

For example:

  map.resources :posts, :only => [:index, :show] do |post|
    post.resources :comments, :except => [:update, :destroy]
  end
  # --> GET /posts (maps to the PostsController#index action)
  # --> POST /posts (fails)
  # --> GET /posts/1 (maps to the PostsController#show action)
  # --> DELETE /posts/1 (fails)
  # --> POST /posts/1/comments (maps to the CommentsController#create action)
  # --> PUT /posts/1/comments/1 (fails)

If map.resources is called with multiple resources, they all get the same options applied.

Examples:

  map.resources :messages, :path_prefix => "/thread/:thread_id"
  # --> GET /thread/7/messages/1

  map.resources :messages, :collection => { :rss => :get }
  # --> GET /messages/rss (maps to the #rss action)
  #     also adds a named route called "rss_messages"

  map.resources :messages, :member => { :mark => :post }
  # --> POST /messages/1/mark (maps to the #mark action)
  #     also adds a named route called "mark_message"

  map.resources :messages, :new => { :preview => :post }
  # --> POST /messages/new/preview (maps to the #preview action)
  #     also adds a named route called "preview_new_message"

  map.resources :messages, :new => { :new => :any, :preview => :post }
  # --> POST /messages/new/preview (maps to the #preview action)
  #     also adds a named route called "preview_new_message"
  # --> /messages/new can be invoked via any request method

  map.resources :messages, :controller => "categories",
        :path_prefix => "/category/:category_id",
        :name_prefix => "category_"
  # --> GET /categories/7/messages/1
  #     has named route "category_message"

The resources method sets HTTP method restrictions on the routes it generates. For example, making an HTTP POST on new_message_url will raise a RoutingError exception. The default route in config/routes.rb overrides this and allows invalid HTTP methods for \resource routes.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/resources.rb, line 444
444:     def resources(*entities, &block)
445:       options = entities.extract_options!
446:       entities.each { |entity| map_resource(entity, options.dup, &block) }
447:     end


Class: ActionController::Response

Class | ActionController::Response
In: | vendor/rails/actionpack/lib/action_controller/response.rb
Parent: | Rack::Response

Represents an HTTP response generated by a controller action. One can use an ActionController::Response object to retrieve the current state of the response, or customize the response. An Response object can either represent a "real" HTTP response (i.e. one that is meant to be sent back to the web browser) or a test response (i.e. one that is generated from integration tests). See CgiResponse and TestResponse, respectively.

Response is mostly a Ruby on Rails framework implement detail, and should never be used directly in controllers. Controllers should use the methods defined in ActionController::Base instead. For example, if you want to set the HTTP response‘s content MIME type, then use ActionControllerBase#headers instead of Response#headers.

Nevertheless, integration tests may want to inspect controller responses in more detail, and that‘s when Response can be useful for application developers. Integration test methods such as ActionController::Integration::Session#get and ActionController::Integration::Session#post return objects of type TestResponse (which are of course also of type Response).

For example, the following demo integration "test" prints the body of the controller response to the console:

 class DemoControllerTest < ActionController::IntegrationTest
   def test_print_root_path_to_console
     get('/')
     puts @response.body
   end
 end

Methods

assign_default_content_type_and_charset! charset charset= content_type content_type= each etag etag= etag? last_modified last_modified= last_modified? location location= new prepare! redirect sending_file? set_cookie write

Constants

DEFAULT_HEADERS = { "Cache-Control" => "no-cache" }

Attributes

assigns | [RW]
layout | [RW]
redirected_to | [RW]
redirected_to_method_params | [RW]
request | [RW]
session | [RW]
template | [RW]

Public Class methods

new()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 42
42:     def initialize
43:       @status = 200
44:       @header = Rack::Utils::HeaderHash.new(DEFAULT_HEADERS)
45:
46:       @writer = lambda { |x| @body << x }
47:       @block = nil
48:
49:       @body = "",
50:       @session, @assigns = [], []
51:     end

Public Instance methods

assign_default_content_type_and_charset!()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 136
136:     def assign_default_content_type_and_charset!
137:       self.content_type ||= Mime::HTML
138:       self.charset ||= default_charset unless sending_file?
139:     end
charset()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 91
91:     def charset
92:       charset = String(headers["Content-Type"] || headers["type"]).split(";")[1]
93:       charset.blank? ? nil : charset.strip.split("=")[1]
94:     end
charset=(charset)

Set the charset of the Content-Type header. Set to nil to remove it. If no content type is set, it defaults to HTML.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 82
82:     def charset=(charset)
83:       headers["Content-Type"] =
84:         if charset
85:           "#{content_type || Mime::HTML}; charset=#{charset}"
86:         else
87:           content_type || Mime::HTML.to_s
88:         end
89:     end
content_type()

Returns the response‘s content MIME type, or nil if content type has been set.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 75
75:     def content_type
76:       content_type = String(headers["Content-Type"] || headers["type"]).split(";")[0]
77:       content_type.blank? ? nil : content_type
78:     end
content_type=(mime_type)

Sets the HTTP response‘s content MIME type. For example, in the controller you could write this:

 response.content_type = "text/plain"

If a character set has been defined for this response (see charset=) then the character set information will also be included in the content type information.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 65
65:     def content_type=(mime_type)
66:       self.headers["Content-Type"] =
67:         if mime_type =~ /charset/ || (c = charset).nil?
68:           mime_type.to_s
69:         else
70:           "#{mime_type}; charset=#{c}"
71:         end
72:     end
each(&callback)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 150
150:     def each(&callback)
151:       if @body.respond_to?(:call)
152:         @writer = lambda { |x| callback.call(x) }
153:         @body.call(self, self)
154:       elsif @body.is_a?(String)
155:         @body.each_line(&callback)
156:       else
157:         @body.each(&callback)
158:       end
159:
160:       @writer = callback
161:       @block.call(self) if @block
162:     end
etag()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 110
110:     def etag
111:       headers['ETag']
112:     end
etag=(etag)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 118
118:     def etag=(etag)
119:       if etag.blank?
120:         headers.delete('ETag')
121:       else
122:         headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
123:       end
124:     end
etag?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 114
114:     def etag?
115:       headers.include?('ETag')
116:     end
last_modified()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 96
 96:     def last_modified
 97:       if last = headers['Last-Modified']
 98:         Time.httpdate(last)
 99:       end
100:     end
last_modified=(utc_time)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 106
106:     def last_modified=(utc_time)
107:       headers['Last-Modified'] = utc_time.httpdate
108:     end
last_modified?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 102
102:     def last_modified?
103:       headers.include?('Last-Modified')
104:     end
location()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 53
53:     def location; headers['Location'] end
location=(url)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/response.rb, line 54
54:     def location=(url) headers['Location'] = url end
prepare!()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 141
141:     def prepare!
142:       assign_default_content_type_and_charset!
143:       handle_conditional_get!
144:       set_content_length!
145:       convert_content_type!
146:       convert_language!
147:       convert_cookies!
148:     end
redirect(url, status)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 126
126:     def redirect(url, status)
127:       self.status = status
128:       self.location = url.gsub(/[\r\n]/, '')
129:       self.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
130:     end
sending_file?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 132
132:     def sending_file?
133:       headers["Content-Transfer-Encoding"] == "binary"
134:     end
set_cookie(key, value)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 169
169:     def set_cookie(key, value)
170:       if value.has_key?(:http_only)
171:         ActiveSupport::Deprecation.warn(
172:           "The :http_only option in ActionController::Response#set_cookie " +
173:           "has been renamed. Please use :httponly instead.", caller)
174:         value[:httponly] ||= value.delete(:http_only)
175:       end
176:
177:       super(key, value)
178:     end
write(str)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/response.rb, line 164
164:     def write(str)
165:       @writer.call str.to_s
166:       str
167:     end


Class: ActionController::RewindableInput

Class | ActionController::RewindableInput
In: | vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
Parent: | Object

Methods

call new

Classes and Modules

Class ActionController::RewindableInput::RewindableIO

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rewindable_input.rb, line 19
19:     def initialize(app)
20:       @app = app
21:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rewindable_input.rb, line 23
23:     def call(env)
24:       env['rack.input'] = RewindableIO.new(env['rack.input'])
25:       @app.call(env)
26:     end


Class: ActionController::RewindableInput::RewindableIO

Class | ActionController::RewindableInput::RewindableIO
In: | vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
Parent: | ActiveSupport::BasicObject

Methods

method_missing new

Public Class methods

new(io)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/rewindable_input.rb, line 4
4:       def initialize(io)
5:         @io = io
6:         @rewindable = io.is_a?(::StringIO)
7:       end

Public Instance methods

method_missing(method, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/rewindable_input.rb, line 9
 9:       def method_missing(method, *args, &block)
10:         unless @rewindable
11:           @io = ::StringIO.new(@io.read)
12:           @rewindable = true
13:         end
14:
15:         @io.__send__(method, *args, &block)
16:       end


Module: ActionController::Routing

Module | ActionController::Routing
In: | vendor/rails/actionpack/lib/action_controller/routing/builder.rb vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb vendor/rails/actionpack/lib/action_controller/routing/recognition_optimisation.rb vendor/rails/actionpack/lib/action_controller/routing/route.rb vendor/rails/actionpack/lib/action_controller/routing/route_set.rb vendor/rails/actionpack/lib/action_controller/routing/segments.rb vendor/rails/actionpack/lib/action_controller/routing.rb

Routing

The routing module provides URL rewriting in native Ruby. It‘s a way to redirect incoming requests to controllers and actions. This replaces mod_rewrite rules. Best of all, Rails’ Routing works with any web server. Routes are defined in config/routes.rb.

Consider the following route, installed by Rails when you generate your application:

  map.connect ':controller/:action/:id'

This route states that it expects requests to consist of a :controller followed by an :action that in turn is fed some :id.

Suppose you get an incoming request for /blog/edit/22, you‘ll end up with:

  params = { :controller => 'blog',
             :action     => 'edit',
             :id         => '22'
          }

Think of creating routes as drawing a map for your requests. The map tells them where to go based on some predefined pattern:

  ActionController::Routing::Routes.draw do |map|
    Pattern 1 tells some request to go to one place
    Pattern 2 tell them to go to another
    ...
  end

The following symbols are special:

  :controller maps to your controller name
  :action     maps to an action with your controllers

Other names simply map to a parameter as in the case of :id.

Route priority

Not all routes are created equally. Routes have priority defined by the order of appearance of the routes in the config/routes.rb file. The priority goes from top to bottom. The last route in that file is at the lowest priority and will be applied last. If no route matches, 404 is returned.

Within blocks, the empty pattern is at the highest priority. In practice this works out nicely:

  ActionController::Routing::Routes.draw do |map|
    map.with_options :controller => 'blog' do |blog|
      blog.show '',  :action => 'list'
    end
    map.connect ':controller/:action/:view'
  end

In this case, invoking blog controller (with an URL like ’/blog/’) without parameters will activate the ‘list’ action by default.

Defaults routes and default parameters

Setting a default route is straightforward in Rails - you simply append a Hash at the end of your mapping to set any default parameters.

Example:

  ActionController::Routing:Routes.draw do |map|
    map.connect ':controller/:action/:id', :controller => 'blog'
  end

This sets up blog as the default controller if no other is specified. This means visiting ’/’ would invoke the blog controller.

More formally, you can include arbitrary parameters in the route, thus:

  map.connect ':controller/:action/:id', :action => 'show', :page => 'Dashboard'

This will pass the :page parameter to all incoming requests that match this route.

Note: The default routes, as provided by the Rails generator, make all actions in every controller accessible via GET requests. You should consider removing them or commenting them out if you‘re using named routes and resources.

Named routes

Routes can be named with the syntax map.name_of_route options, allowing for easy reference within your source as name_of_route_url for the full URL and name_of_route_path for the URI path.

Example:

  # In routes.rb
  map.login 'login', :controller => 'accounts', :action => 'login'

  # With render, redirect_to, tests, etc.
  redirect_to login_url

Arguments can be passed as well.

  redirect_to show_item_path(:id => 25)

Use map.root as a shorthand to name a route for the root path "".

  # In routes.rb
  map.root :controller => 'blogs'

  # would recognize http://www.example.com/ as
  params = { :controller => 'blogs', :action => 'index' }

  # and provide these named routes
  root_url   # => 'http://www.example.com/'
  root_path  # => ''

You can also specify an already-defined named route in your map.root call:

  # In routes.rb
  map.new_session :controller => 'sessions', :action => 'new'
  map.root :new_session

Note: when using with_options, the route is simply named after the method you call on the block parameter rather than map.

  # In routes.rb
  map.with_options :controller => 'blog' do |blog|
    blog.show    '',            :action  => 'list'
    blog.delete  'delete/:id',  :action  => 'delete',
    blog.edit    'edit/:id',    :action  => 'edit'
  end

  # provides named routes for show, delete, and edit
  link_to @article.title, show_path(:id => @article.id)

Pretty URLs

Routes can generate pretty URLs. For example:

  map.connect 'articles/:year/:month/:day',
              :controller => 'articles',
              :action     => 'find_by_date',
              :year       => /\d{4}/,
              :month      => /\d{1,2}/,
              :day        => /\d{1,2}/

Using the route above, the URL "localhost:3000/articles/2005/11/06" maps to

  params = {:year => '2005', :month => '11', :day => '06'}

Regular Expressions and parameters

You can specify a regular expression to define a format for a parameter.

  map.geocode 'geocode/:postalcode', :controller => 'geocode',
              :action => 'show', :postalcode => /\d{5}(-\d{4})?/

or, more formally:

  map.geocode 'geocode/:postalcode', :controller => 'geocode',
              :action => 'show', :requirements => { :postalcode => /\d{5}(-\d{4})?/ }

Formats can include the ‘ignorecase’ and ‘extended syntax’ regular expression modifiers:

  map.geocode 'geocode/:postalcode', :controller => 'geocode',
              :action => 'show', :postalcode => /hx\d\d\s\d[a-z]{2}/i

  map.geocode 'geocode/:postalcode', :controller => 'geocode',
              :action => 'show',:requirements => {
                :postalcode => /# Postcode format
                                \d{5} #Prefix
                                (-\d{4})? #Suffix
                                /x
              }

Using the multiline match modifier will raise an ArgumentError. Encoding regular expression modifiers are silently ignored. The match will always use the default encoding or ASCII.

Route globbing

Specifying *[string] as part of a rule like:

  map.connect '*path' , :controller => 'blog' , :action => 'unrecognized?'

will glob all remaining parts of the route that were not recognized earlier. The globbed values are in params[:path] as an array of path segments.

Route conditions

With conditions you can define restrictions on routes. Currently the only valid condition is :method.

  • :method - Allows you to specify which method can access the route. Possible values are :post, :get, :put, :delete and :any. The default value is :any, :any means that any method can access the route.

Example:

  map.connect 'post/:id', :controller => 'posts', :action => 'show',
              :conditions => { :method => :get }
  map.connect 'post/:id', :controller => 'posts', :action => 'create_comment',
              :conditions => { :method => :post }

Now, if you POST to /posts/:id, it will route to the create_comment action. A GET on the same URL will route to the show action.

Reloading routes

You can reload routes if you feel you must:

  ActionController::Routing::Routes.reload

This will clear all named routes and reload routes.rb if the file has been modified from last load. To absolutely force reloading, use reload!.

Testing Routes

The two main methods for testing your routes:

assert_routing

  def test_movie_route_properly_splits
   opts = {:controller => "plugin", :action => "checkout", :id => "2"}
   assert_routing "plugin/checkout/2", opts
  end

assert_routing lets you test whether or not the route properly resolves into options.

assert_recognizes

  def test_route_has_options
   opts = {:controller => "plugin", :action => "show", :id => "12"}
   assert_recognizes opts, "/plugins/show/12"
  end

Note the subtle difference between the two: assert_routing tests that a URL fits options while assert_recognizes tests that a URL breaks into parameters properly.

In tests you can simply pass the URL or named route to get or post.

  def send_to_jail
    get '/jail'
    assert_response :success
    assert_template "jail/front"
  end

  def goes_to_login
    get login_url
    #...
  end

View a list of all your routes

Run rake routes.

Methods

controller_relative_to inflections_with_route_reloading normalize_paths possible_controllers use_controllers! with_controllers

Classes and Modules

Module ActionController::Routing::Helpers
Module ActionController::Routing::Optimisation
Class ActionController::Routing::OptionalFormatSegment

Constants

SEPARATORS | = | %w( / . ? )
HTTP_METHODS | = | [:get, :head, :post, :put, :delete, :options]
ALLOWED_REQUIREMENTS_FOR_OPTIMISATION | = | [:controller, :action].to_set
Routes | = | RouteSet.new

Public Class methods

controller_relative_to(controller, previous)

Returns a controller path for a new controller based on a previous controller path. Handles 4 scenarios:

  • stay in the previous controller:
      controller_relative_to( nil, "groups/discussion" ) # => "groups/discussion"
  • stay in the previous namespace:
      controller_relative_to( "posts", "groups/discussion" ) # => "groups/posts"
  • forced move to the root namespace:
      controller_relative_to( "/posts", "groups/discussion" ) # => "posts"
  • previous namespace is root:
      controller_relative_to( "posts", "anything_with_no_slashes" ) # =>"posts"

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 363
363:       def controller_relative_to(controller, previous)
364:         if controller.nil?           then previous
365:         elsif controller[0] == ?/    then controller[1..-1]
366:         elsif %r{^(.*)/} =~ previous then "#{$1}/#{controller}"
367:         else controller
368:         end
369:       end
normalize_paths(paths)

Returns an array of paths, cleaned of double-slashes and relative path references.

  • "\\" and "//" become "\" or "/".
  • "/foo/bar/../config" becomes "/foo/config".

The returned array is sorted by length, descending.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 299
299:       def normalize_paths(paths)
300:         # do the hokey-pokey of path normalization...
301:         paths = paths.collect do |path|
302:           path = path.
303:             gsub("//", "/").           # replace double / chars with a single
304:             gsub("\\\\", "\\").        # replace double \ chars with a single
305:             gsub(%r{(.)[\\/]$}, '\1')  # drop final / or \ if path ends with it
306:
307:           # eliminate .. paths where possible
308:           re = %r{[^/\\]+[/\\]\.\.[/\\]}
309:           path.gsub!(re, "") while path.match(re)
310:           path
311:         end
312:
313:         # start with longest path, first
314:         paths = paths.uniq.sort_by { |path| - path.length }
315:       end
possible_controllers()

Returns the array of controller names currently available to ActionController::Routing.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 318
318:       def possible_controllers
319:         unless @possible_controllers
320:           @possible_controllers = []
321:
322:           paths = controller_paths.select { |path| File.directory?(path) && path != "." }
323:
324:           seen_paths = Hash.new {|h, k| h[k] = true; false}
325:           normalize_paths(paths).each do |load_path|
326:             Dir["#{load_path}/**/*_controller.rb"].collect do |path|
327:               next if seen_paths[path.gsub(%r{^\.[/\\]}, "")]
328:
329:               controller_name = path[(load_path.length + 1)..-1]
330:
331:               controller_name.gsub!(/_controller\.rb\Z/, '')
332:               @possible_controllers << controller_name
333:             end
334:           end
335:
336:           # remove duplicates
337:           @possible_controllers.uniq!
338:         end
339:         @possible_controllers
340:       end
use_controllers!(controller_names)

Replaces the internal list of controllers available to ActionController::Routing with the passed argument.

  ActionController::Routing.use_controllers!([ "posts", "comments", "admin/comments" ])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 344
344:       def use_controllers!(controller_names)
345:         @possible_controllers = controller_names
346:       end
with_controllers(names) {|| ...}

Expects an array of controller names as the first argument. Executes the passed block with only the named controllers named available. This method is used in internal Rails testing.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 287
287:       def with_controllers(names)
288:         prior_controllers = @possible_controllers
289:         use_controllers! names
290:         yield
291:       ensure
292:         use_controllers! prior_controllers
293:       end

Public Instance methods

inflections_with_route_reloading(&block)

Ensures that routes are reloaded when Rails inflections are updated.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing.rb, line 376
376:       def inflections_with_route_reloading(&block)
377:         returning(inflections_without_route_reloading(&block)) {
378:           ActionController::Routing::Routes.reload! if block_given?
379:         }
380:       end


Module: ActionController::Routing::Helpers

Module | ActionController::Routing::Helpers
In: | vendor/rails/actionpack/lib/action_controller/routing.rb

A helper module to hold URL related helpers.

Included Modules

PolymorphicRoutes


Module: ActionController::Routing::Optimisation

Module | ActionController::Routing::Optimisation
In: | vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb

Much of the slow performance from routes comes from the complexity of expiry, :requirements matching, defaults providing and figuring out which url pattern to use. With named routes we can avoid the expense of finding the right route. So if they‘ve provided the right number of arguments, and have no :requirements, we can just build up a string and return it.

To support building optimisations for other common cases, the generation code is separated into several classes

Methods

generate_optimisation_block

Classes and Modules

Class ActionController::Routing::Optimisation::Optimiser
Class ActionController::Routing::Optimisation::PositionalArguments
Class ActionController::Routing::Optimisation::PositionalArgumentsWithAdditionalParams

Constants

OPTIMISERS = [PositionalArguments, PositionalArgumentsWithAdditionalParams]

Public Instance methods

generate_optimisation_block(route, kind)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 13
13:       def generate_optimisation_block(route, kind)
14:         return "" unless route.optimise?
15:         OPTIMISERS.inject("") do |memo, klazz|
16:           memo << klazz.new(route, kind).source_code
17:           memo
18:         end
19:       end


Class: ActionController::Routing::Optimisation::Optimiser

Class | ActionController::Routing::Optimisation::Optimiser
In: | vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb
Parent: | Object

Methods

applicable? generation_code guard_conditions new source_code

Constants

GLOBAL_GUARD_CONDITIONS = [ "(!defined?(default_url_options) || default_url_options.blank?)", "(!defined?(controller.default_url_options) || controller.default_url_options.blank?)", "defined?(request)", "request"

Attributes

kind | [R]
route | [R]

Public Class methods

new(route, kind)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 30
30:         def initialize(route, kind)
31:           @route = route
32:           @kind  = kind
33:         end

Public Instance methods

applicable?()

Temporarily disabled :url optimisation pending proper solution to Issues around request.host etc.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 54
54:         def applicable?
55:           true
56:         end
generation_code()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 39
39:         def generation_code
40:           'nil'
41:         end
guard_conditions()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 35
35:         def guard_conditions
36:           ["false"]
37:         end
source_code()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 43
43:         def source_code
44:           if applicable?
45:             guard_condition = (GLOBAL_GUARD_CONDITIONS + guard_conditions).join(" && ")
46:             "return #{generation_code} if #{guard_condition}\n"
47:           else
48:             "\n"
49:           end
50:         end


Class: ActionController::Routing::Optimisation::PositionalArguments

Class | ActionController::Routing::Optimisation::PositionalArguments
In: | vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb
Parent: | Optimiser

Given a route

  map.person '/people/:id'

If the user calls person_url(@person), we can simply return a string like "/people/#{@person.to_param}" rather than triggering the expensive logic in url_for.

Methods

generation_code guard_conditions

Public Instance methods

generation_code()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 78
 78:         def generation_code
 79:           elements = []
 80:           idx = 0
 81:
 82:           if kind == :url
 83:             elements << '#{request.protocol}'
 84:             elements << '#{request.host_with_port}'
 85:           end
 86:
 87:           elements << '#{ActionController::Base.relative_url_root if ActionController::Base.relative_url_root}'
 88:
 89:           # The last entry in <tt>route.segments</tt> appears to *always* be a
 90:           # 'divider segment' for '/' but we have assertions to ensure that
 91:           # we don't include the trailing slashes, so skip them.
 92:           (route.segments.size == 1 ? route.segments : route.segments[0..-2]).each do |segment|
 93:             if segment.is_a?(DynamicSegment)
 94:               elements << segment.interpolation_chunk("args[#{idx}].to_param")
 95:               idx += 1
 96:             else
 97:               elements << segment.interpolation_chunk
 98:             end
 99:           end
100:           %("#{elements * ''}")
101:         end
guard_conditions()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 67
67:         def guard_conditions
68:           number_of_arguments = route.required_segment_keys.size
69:           # if they're using foo_url(:id=>2) it's one
70:           # argument, but we don't want to generate /foos/id2
71:           if number_of_arguments == 1
72:             ["args.size == 1", "!args.first.is_a?(Hash)"]
73:           else
74:             ["args.size == #{number_of_arguments}"]
75:           end
76:         end


Class: ActionController::Routing::Optimisation::PositionalArgumentsWithAdditionalParams

Class | ActionController::Routing::Optimisation::PositionalArgumentsWithAdditionalParams
In: | vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb
Parent: | PositionalArguments

This case is mostly the same as the positional arguments case above, but it supports additional query parameters as the last argument

Methods

applicable? generation_code guard_conditions

Public Instance methods

applicable?()

To avoid generating "localhost/?host=foo.example.com" we can‘t use this optimisation on routes without any segments

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 122
122:         def applicable?
123:           super && route.segment_keys.size > 0
124:         end
generation_code()

This case uses almost the same code as positional arguments, but add a question mark and args.last.to_query on the end, unless the last arg is empty

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 116
116:         def generation_code
117:           super.insert(-2, '#{\'?\' + args.last.to_query unless args.last.empty?}')
118:         end
guard_conditions()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb, line 108
108:         def guard_conditions
109:           ["args.size == #{route.segment_keys.size + 1}"] +
110:           UrlRewriter::RESERVED_OPTIONS.collect{ |key| "!args.last.has_key?(:#{key})" }
111:         end


Class: ActionController::Routing::OptionalFormatSegment

Class | ActionController::Routing::OptionalFormatSegment
In: | vendor/rails/actionpack/lib/action_controller/routing/segments.rb
Parent: | DynamicSegment

The OptionalFormatSegment allows for any resource route to have an optional :format, which decreases the amount of routes created by 50%.

Methods

extract_value interpolation_chunk match_extraction new regexp_chunk to_s

Public Class methods

new(key = nil, options = {})

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 312
312:       def initialize(key = nil, options = {})
313:         super(:format, {:optional => true}.merge(options))
314:       end

Public Instance methods

extract_value()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 328
328:       def extract_value
329:         "#{local_name} = options[:#{key}] && options[:#{key}].to_s.downcase"
330:       end
interpolation_chunk()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 316
316:       def interpolation_chunk
317:         "." + super
318:       end
match_extraction(next_capture)

the value should not include the period (.)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 333
333:       def match_extraction(next_capture)
334:         %[
335:           if (m = match[#{next_capture}])
336:             params[:#{key}] = URI.unescape(m.from(1))
337:           end
338:         ]
339:       end
regexp_chunk()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 320
320:       def regexp_chunk
321:         '/|(\.[^/?\.]+)?'
322:       end
to_s()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/routing/segments.rb, line 324
324:       def to_s
325:         '(.:format)?'
326:       end


Class: ActionController::Routing::RouteSet::Mapper

Class | ActionController::Routing::RouteSet::Mapper
In: | vendor/rails/actionpack/lib/action_controller/routing/route_set.rb
Parent: | Object

Mapper instances are used to build routes. The object passed to the draw block in config/routes.rb is a Mapper instance.

Mapper instances have relatively few instance methods, in order to avoid clashes with named routes.

Methods

connect namespace root

Included Modules

ActionController::Resources

Public Instance methods

connect(path, options = {})

Create an unnamed route with the provided path and options. See ActionController::Routing for an introduction to routes.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/route_set.rb, line 18
18:         def connect(path, options = {})
19:           @set.add_route(path, options)
20:         end
namespace(name, options = {}, &block)

Enables the use of resources in a module by setting the name_prefix, path_prefix, and namespace for the model. Example:

  map.namespace(:admin) do |admin|
    admin.resources :products,
      :has_many => [ :tags, :images, :variants ]
  end

This will create admin_products_url pointing to "admin/products", which will look for an Admin::ProductsController. It‘ll also create admin_product_tags_url pointing to "admin/products/#{product_id}/tags", which will look for Admin::TagsController.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/route_set.rb, line 47
47:         def namespace(name, options = {}, &block)
48:           if options[:namespace]
49:             with_options({:path_prefix => "#{options.delete(:path_prefix)}/#{name}", :name_prefix => "#{options.delete(:name_prefix)}#{name}_", :namespace => "#{options.delete(:namespace)}#{name}/" }.merge(options), &block)
50:           else
51:             with_options({:path_prefix => name, :name_prefix => "#{name}_", :namespace => "#{name}/" }.merge(options), &block)
52:           end
53:         end
root(options = {})

Creates a named route called "root" for matching the root level request.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/routing/route_set.rb, line 23
23:         def root(options = {})
24:           if options.is_a?(Symbol)
25:             if source_route = @set.named_routes.routes[options]
26:               options = source_route.defaults.merge({ :conditions => source_route.conditions })
27:             end
28:           end
29:           named_route("root", '', options)
30:         end


Module: ActionController::Session

Module | ActionController::Session
In: | vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb vendor/rails/actionpack/lib/action_controller/session/mem_cache_store.rb

Classes and Modules

Class ActionController::Session::AbstractStore
Class ActionController::Session::CookieStore
Class ActionController::Session::MemCacheStore


Class: ActionController::Session::AbstractStore

Class | ActionController::Session::AbstractStore
In: | vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb
Parent: | Object

Methods

call new

Classes and Modules

Class ActionController::Session::AbstractStore::SessionHash

Constants

ENV_SESSION_KEY | = | 'rack.session'.freeze
ENV_SESSION_OPTIONS_KEY | = | 'rack.session.options'.freeze
HTTP_COOKIE | = | 'HTTP_COOKIE'.freeze
SET_COOKIE | = | 'Set-Cookie'.freeze
DEFAULT_OPTIONS | = | { :key => '_session_id', :path => '/', :domain => nil, :expire_after => nil, :secure => false, :httponly => true, :cookie_only => true

Public Class methods

new(app, options = {})

[Source]

     # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 97
 97:       def initialize(app, options = {})
 98:         # Process legacy CGI options
 99:         options = options.symbolize_keys
100:         if options.has_key?(:session_path)
101:           options[:path] = options.delete(:session_path)
102:         end
103:         if options.has_key?(:session_key)
104:           options[:key] = options.delete(:session_key)
105:         end
106:         if options.has_key?(:session_http_only)
107:           options[:httponly] = options.delete(:session_http_only)
108:         end
109:
110:         @app = app
111:         @default_options = DEFAULT_OPTIONS.merge(options)
112:         @key = @default_options[:key]
113:         @cookie_only = @default_options[:cookie_only]
114:       end

Public Instance methods

call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 116
116:       def call(env)
117:         session = SessionHash.new(self, env)
118:
119:         env[ENV_SESSION_KEY] = session
120:         env[ENV_SESSION_OPTIONS_KEY] = @default_options.dup
121:
122:         response = @app.call(env)
123:
124:         session_data = env[ENV_SESSION_KEY]
125:         options = env[ENV_SESSION_OPTIONS_KEY]
126:
127:         if !session_data.is_a?(AbstractStore::SessionHash) || session_data.send(:loaded?) || options[:expire_after]
128:           session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.send(:loaded?)
129:
130:           sid = options[:id] || generate_sid
131:
132:           unless set_session(env, sid, session_data.to_hash)
133:             return response
134:           end
135:
136:           cookie = Rack::Utils.escape(@key) + '=' + Rack::Utils.escape(sid)
137:           cookie << "; domain=#{options[:domain]}" if options[:domain]
138:           cookie << "; path=#{options[:path]}" if options[:path]
139:           if options[:expire_after]
140:             expiry = Time.now + options[:expire_after]
141:             cookie << "; expires=#{expiry.httpdate}"
142:           end
143:           cookie << "; Secure" if options[:secure]
144:           cookie << "; HttpOnly" if options[:httponly]
145:
146:           headers = response[1]
147:           unless headers[SET_COOKIE].blank?
148:             headers[SET_COOKIE] << "\n#{cookie}"
149:           else
150:             headers[SET_COOKIE] = cookie
151:           end
152:         end
153:
154:         response
155:       end


Class: ActionController::Session::AbstractStore::SessionHash

Class | ActionController::Session::AbstractStore::SessionHash
In: | vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb
Parent: | Hash

Methods

[] []= data inspect new session_id to_hash

Public Class methods

new(by, env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 13
13:         def initialize(by, env)
14:           super()
15:           @by = by
16:           @env = env
17:           @loaded = false
18:         end

Public Instance methods

[](key)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 27
27:         def [](key)
28:           load! unless @loaded
29:           super
30:         end
[]=(key, value)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 32
32:         def []=(key, value)
33:           load! unless @loaded
34:           super
35:         end
data()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 43
43:         def data
44:          ActiveSupport::Deprecation.warn(
45:            "ActionController::Session::AbstractStore::SessionHash#data " +
46:            "has been deprecated. Please use #to_hash instead.", caller)
47:           to_hash
48:         end
inspect()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 50
50:         def inspect
51:           load! unless @loaded
52:           super
53:         end
session_id()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 20
20:         def session_id
21:           ActiveSupport::Deprecation.warn(
22:             "ActionController::Session::AbstractStore::SessionHash#session_id " +
23:             "has been deprecated. Please use request.session_options[:id] instead.", caller)
24:           @env[ENV_SESSION_OPTIONS_KEY][:id]
25:         end
to_hash()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb, line 37
37:         def to_hash
38:           h = {}.replace(self)
39:           h.delete_if { |k,v| v.nil? }
40:           h
41:         end


Class: ActionController::Session::CookieStore

Class | ActionController::Session::CookieStore
In: | vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb
Parent: | Object

This cookie-based session store is the Rails default. Sessions typically contain at most a user_id and flash message; both fit within the 4K cookie size limit. Cookie-based sessions are dramatically faster than the alternatives.

If you have more than 4K of session data or don‘t want your data to be visible to the user, pick another session store.

CookieOverflow is raised if you attempt to store more than 4K of data.

A message digest is included with the cookie to ensure data integrity: a user cannot alter his user_id without knowing the secret key included in the hash. New apps are generated with a pregenerated secret in config/environment.rb. Set your own for old apps you‘re upgrading.

Session options:

  • :secret: An application-wide key string or block returning a string called per generated digest. The block is called with the CGI::Session instance as an argument. It‘s important that the secret is not vulnerable to a dictionary attack. Therefore, you should choose a secret consisting of random numbers and letters and more than 30 characters. Examples:
      :secret => '449fe2e7daee471bffae2fd8dc02313d'
  :secret => Proc.new { User.current_user.secret_key }
  • :digest: The message digest algorithm used to verify session integrity defaults to ‘SHA1’ but may be any digest provided by OpenSSL, such as ‘MD5’, ‘RIPEMD160’, ‘SHA256’, etc.

To generate a secret key for an existing application, run "rake secret" and set the key in config/environment.rb.

Note that changing digest or secret invalidates all existing sessions!

Methods

call new

Classes and Modules

Class ActionController::Session::CookieStore::CookieOverflow

Constants

MAX | = | 4096 | Cookies can typically store 4096 bytes.
SECRET_MIN_LENGTH | = | 30
DEFAULT_OPTIONS | = | { :key => '_session_id', :domain => nil, :path => "/", :expire_after => nil, :httponly => true
ENV_SESSION_KEY | = | "rack.session".freeze
ENV_SESSION_OPTIONS_KEY | = | "rack.session.options".freeze
HTTP_SET_COOKIE | = | "Set-Cookie".freeze

Public Class methods

new(app, options = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb, line 58
58:       def initialize(app, options = {})
59:         # Process legacy CGI options
60:         options = options.symbolize_keys
61:         if options.has_key?(:session_path)
62:           options[:path] = options.delete(:session_path)
63:         end
64:         if options.has_key?(:session_key)
65:           options[:key] = options.delete(:session_key)
66:         end
67:         if options.has_key?(:session_http_only)
68:           options[:httponly] = options.delete(:session_http_only)
69:         end
70:
71:         @app = app
72:
73:         # The session_key option is required.
74:         ensure_session_key(options[:key])
75:         @key = options.delete(:key).freeze
76:
77:         # The secret option is required.
78:         ensure_secret_secure(options[:secret])
79:         @secret = options.delete(:secret).freeze
80:
81:         @digest = options.delete(:digest) || 'SHA1'
82:         @verifier = verifier_for(@secret, @digest)
83:
84:         @default_options = DEFAULT_OPTIONS.merge(options).freeze
85:
86:         freeze
87:       end

Public Instance methods

call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb, line 89
 89:       def call(env)
 90:         env[ENV_SESSION_KEY] = AbstractStore::SessionHash.new(self, env)
 91:         env[ENV_SESSION_OPTIONS_KEY] = @default_options.dup
 92:
 93:         status, headers, body = @app.call(env)
 94:
 95:         session_data = env[ENV_SESSION_KEY]
 96:         options = env[ENV_SESSION_OPTIONS_KEY]
 97:
 98:         if !session_data.is_a?(AbstractStore::SessionHash) || session_data.send(:loaded?) || options[:expire_after]
 99:           session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.send(:loaded?)
100:           session_data = marshal(session_data.to_hash)
101:
102:           raise CookieOverflow if session_data.size > MAX
103:
104:           cookie = Hash.new
105:           cookie[:value] = session_data
106:           unless options[:expire_after].nil?
107:             cookie[:expires] = Time.now + options[:expire_after]
108:           end
109:
110:           cookie = build_cookie(@key, cookie.merge(options))
111:           unless headers[HTTP_SET_COOKIE].blank?
112:             headers[HTTP_SET_COOKIE] << "\n#{cookie}"
113:           else
114:             headers[HTTP_SET_COOKIE] = cookie
115:           end
116:         end
117:
118:         [status, headers, body]
119:       end


Class: ActionController::Session::CookieStore::CookieOverflow

Class | ActionController::Session::CookieStore::CookieOverflow
In: | vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb
Parent: | StandardError

Raised when storing more than 4K of session data.


Class: ActionController::Session::MemCacheStore

Class | ActionController::Session::MemCacheStore
In: | vendor/rails/actionpack/lib/action_controller/session/mem_cache_store.rb
Parent: | AbstractStore

Methods

new

Public Class methods

new(app, options = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session/mem_cache_store.rb, line 7
 7:         def initialize(app, options = {})
 8:           # Support old :expires option
 9:           options[:expire_after] ||= options[:expires]
10:
11:           super
12:
13:           @default_options = {
14:             :namespace => 'rack:session',
15:             :memcache_server => 'localhost:11211'
16:           }.merge(@default_options)
17:
18:           @pool = options[:cache] || MemCache.new(@default_options[:memcache_server], @default_options)
19:           unless @pool.servers.any? { |s| s.alive? }
20:             raise "#{self} unable to find server during initialization."
21:           end
22:           @mutex = Mutex.new
23:
24:           super
25:         end


Module: ActionController::SessionManagement::ClassMethods

Module | ActionController::SessionManagement::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/session_management.rb

Methods

session session= session_options session_store session_store=

Public Instance methods

session(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session_management.rb, line 45
45:       def session(*args)
46:         ActiveSupport::Deprecation.warn(
47:           "Disabling sessions for a single controller has been deprecated. " +
48:           "Sessions are now lazy loaded. So if you don't access them, " +
49:           "consider them off. You can still modify the session cookie " +
50:           "options with request.session_options.", caller)
51:       end
session=(options = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session_management.rb, line 33
33:       def session=(options = {})
34:         self.session_store = nil if options.delete(:disabled)
35:         session_options.merge!(options)
36:       end
session_options()

Returns the hash used to configure the session. Example use:

  ActionController::Base.session_options[:secure] = true # session only available over HTTPS

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session_management.rb, line 41
41:       def session_options
42:         @session_options ||= {}
43:       end
session_store()

Returns the session store class currently used.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session_management.rb, line 25
25:       def session_store
26:         if defined? @@session_store
27:           @@session_store
28:         else
29:           Session::CookieStore
30:         end
31:       end
session_store=(store)

Set the session store to be used for keeping the session data between requests. By default, sessions are stored in browser cookies (:cookie_store), but you can also specify one of the other included stores (:active_record_store, :mem_cache_store, or your own custom class.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/session_management.rb, line 14
14:       def session_store=(store)
15:         if store == :active_record_store
16:           self.session_store = ActiveRecord::SessionStore
17:         else
18:           @@session_store = store.is_a?(Symbol) ?
19:             Session.const_get(store.to_s.camelize) :
20:             store
21:         end
22:       end


Module: ActionController::Streaming

Module | ActionController::Streaming
In: | vendor/rails/actionpack/lib/action_controller/streaming.rb

Methods for sending arbitrary data and for streaming files to the browser, instead of rendering.

Methods

send_data send_file

Constants

DEFAULT_SEND_FILE_OPTIONS | = | { :type => 'application/octet-stream'.freeze, :disposition => 'attachment'.freeze, :stream => true, :buffer_size => 4096, :x_sendfile => false
X_SENDFILE_HEADER | = | 'X-Sendfile'.freeze

Protected Instance methods

send_data(data, options = {})

Sends the given binary data to the browser. This method is similar to render :text => data, but also allows you to specify whether the browser should display the response as a file attachment (i.e. in a download dialog) or as inline data. You may also set the content type, the apparent file name, and other things.

Options:

  • :filename - suggests a filename for the browser to use.
  • :type - specifies an HTTP content type. Defaults to ‘application/octet-stream’. You can specify either a string or a symbol for a registered type register with Mime::Type.register, for example :json
  • :disposition - specifies whether the file will be shown inline or downloaded. Valid values are ‘inline’ and ‘attachment’ (default).
  • :status - specifies the status code to send with the response. Defaults to ‘200 OK’.

Generic data download:

  send_data buffer

Download a dynamically-generated tarball:

  send_data generate_tgz('dir'), :filename => 'dir.tgz'

Display an image Active Record in the browser:

  send_data image.data, :type => image.content_type, :disposition => 'inline'

See send_file for more information on HTTP Content-* headers and caching.

Tip: if you want to stream large amounts of on-the-fly generated data to the browser, then use render :text => proc { … } instead. See ActionController::Base#render for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/streaming.rb, line 138
138:       def send_data(data, options = {}) #:doc:
139:         logger.info "Sending data #{options[:filename]}" if logger
140:         send_file_headers! options.merge(:length => data.size)
141:         @performed_render = false
142:         render :status => options[:status], :text => data
143:       end
send_file(path, options = {})

Sends the file, by default streaming it 4096 bytes at a time. This way the whole file doesn‘t need to be read into memory at once. This makes it feasible to send even large files. You can optionally turn off streaming and send the whole file at once.

Be careful to sanitize the path parameter if it is coming from a web page. send_file(params[:path]) allows a malicious user to download any file on your server.

Options:

  • :filename - suggests a filename for the browser to use. Defaults to File.basename(path).
  • :type - specifies an HTTP content type. Defaults to ‘application/octet-stream’. You can specify either a string or a symbol for a registered type register with Mime::Type.register, for example :json
  • :length - used to manually override the length (in bytes) of the content that is going to be sent to the client. Defaults to File.size(path).
  • :disposition - specifies whether the file will be shown inline or downloaded. Valid values are ‘inline’ and ‘attachment’ (default).
  • :stream - whether to send the file to the user agent as it is read (true) or to read the entire file before sending (false). Defaults to true.
  • :buffer_size - specifies size (in bytes) of the buffer used to stream the file. Defaults to 4096.
  • :status - specifies the status code to send with the response. Defaults to ‘200 OK’.
  • :url_based_filename - set to true if you want the browser guess the filename from the URL, which is necessary for i18n filenames on certain browsers (setting :filename overrides this option).
  • :x_sendfile - uses X-Sendfile to send the file when set to true. This is currently only available with Lighttpd/Apache2 and specific modules installed and activated. Since this uses the web server to send the file, this may lower memory consumption on your server and it will not block your application for further requests. See blog.lighttpd.net/articles/2006/07/02/x-sendfile and tn123.ath.cx/mod_xsendfile/ for details. Defaults to false.

The default Content-Type and Content-Disposition headers are set to download arbitrary binary files in as many browsers as possible. IE versions 4, 5, 5.5, and 6 are all known to have a variety of quirks (especially when downloading over SSL).

Simple download:

  send_file '/path/to.zip'

Show a JPEG in the browser:

  send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'

Show a 404 page in the browser:

  send_file '/path/to/404.html', :type => 'text/html; charset=utf-8', :status => 404

Read about the other Content-* HTTP headers if you‘d like to provide the user with more information (such as Content-Description) in www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.

Also be aware that the document may be cached by proxies and browsers. The Pragma and Cache-Control headers declare how the file may be cached by intermediaries. They default to require clients to validate with the server before releasing cached responses. See www.mnot.net/cache_docs/ for an overview of web caching and www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 for the Cache-Control header spec.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/streaming.rb, line 77
 77:       def send_file(path, options = {}) #:doc:
 78:         raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
 79:
 80:         options[:length]   ||= File.size(path)
 81:         options[:filename] ||= File.basename(path) unless options[:url_based_filename]
 82:         send_file_headers! options
 83:
 84:         @performed_render = false
 85:
 86:         if options[:x_sendfile]
 87:           logger.info "Sending #{X_SENDFILE_HEADER} header #{path}" if logger
 88:           head options[:status], X_SENDFILE_HEADER => path
 89:         else
 90:           if options[:stream]
 91:             render :status => options[:status], :text => Proc.new { |response, output|
 92:               logger.info "Streaming file #{path}" unless logger.nil?
 93:               len = options[:buffer_size] || 4096
 94:               File.open(path, 'rb') do |file|
 95:                 while buf = file.read(len)
 96:                   output.write(buf)
 97:                 end
 98:               end
 99:             }
100:           else
101:             logger.info "Sending file #{path}" unless logger.nil?
102:             File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read }
103:           end
104:         end
105:       end


Class: ActionController::TestCase

Class | ActionController::TestCase
In: | vendor/rails/actionpack/lib/action_controller/test_case.rb
Parent: | ActiveSupport::TestCase

Superclass for ActionController functional tests. Functional tests allow you to test a single controller action per test method. This should not be confused with integration tests (see ActionController::IntegrationTest), which are more like "stories" that can involve multiple controllers and mutliple actions (i.e. multiple different HTTP requests).

Basic example

Functional tests are written as follows:

  1. First, one uses the get, post, put, delete or head method to simulate an HTTP request.
  2. Then, one asserts whether the current state is as expected. "State" can be anything: the controller‘s HTTP response, the database contents, etc.

For example:

  class BooksControllerTest < ActionController::TestCase
    def test_create
      # Simulate a POST response with the given HTTP parameters.
      post(:create, :book => { :title => "Love Hina" })

      # Assert that the controller tried to redirect us to
      # the created book's URI.
      assert_response :found

      # Assert that the controller really put the book in the database.
      assert_not_nil Book.find_by_title("Love Hina")
    end
  end

Special instance variables

ActionController::TestCase will also automatically provide the following instance variables for use in the tests:

@controller: | The controller instance that will be tested.
@request: | An ActionController::TestRequest, representing the current HTTP request. You can modify this object before sending the HTTP request. For example, you might want to set some session properties before sending a GET request.
@response: | An ActionController::TestResponse object, representing the response of the last HTTP response. In the above example, @response becomes valid after calling post. If the various assert methods are not sufficient, then you may use this object to inspect the HTTP response in detail.

(Earlier versions of Rails required each functional test to subclass Test::Unit::TestCase and define @controller, @request, @response in setup.)

Controller is automatically inferred

ActionController::TestCase will automatically infer the controller under test from the test class name. If the controller cannot be inferred from the test class name, you can explicity set it with tests.

  class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
    tests WidgetController
  end

Testing controller internals

In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions can be used against. These collections are:

  • assigns: Instance variables assigned in the action that are available for the view.
  • session: Objects being saved in the session.
  • flash: The flash objects currently in the session.
  • cookies: Cookies being sent to the user on this request.

These collections can be used just like any other hash:

  assert_not_nil assigns(:person) # makes sure that a @person instance variable was set
  assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
  assert flash.empty? # makes sure that there's nothing in the flash

For historic reasons, the assigns hash uses string-based keys. So assigns[:person] won‘t work, but assigns["person"] will. To appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing. So assigns(:person) will work just like assigns["person"], but again, assigns[:person] will not work.

On top of the collections, you have the complete url that a given action redirected to available in redirect_to_url.

For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another action call which can then be asserted against.

Manipulating the request collections

The collections described above link to the response, so you can test if what the actions were expected to do happened. But sometimes you also want to manipulate these collections in the incoming request. This is really only relevant for sessions and cookies, though. For sessions, you just do:

  @request.session[:key] = "value"
  @request.cookies["key"] = "value"

Testing named routes

If you‘re using named routes, they can be easily tested using the original named routes’ methods straight in the test case. Example:

 assert_redirected_to page_url(:title => 'foo')

Methods

controller_class controller_class= determine_default_controller_class prepare_controller_class rescue_action_in_public! setup_controller_request_and_response tests

Included Modules

TestProcess Assertions

Classes and Modules

Module ActionController::TestCase::Assertions
Module ActionController::TestCase::RaiseActionExceptions

Public Class methods

controller_class()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 165
165:       def controller_class
166:         if current_controller_class = read_inheritable_attribute(:controller_class)
167:           current_controller_class
168:         else
169:           self.controller_class = determine_default_controller_class(name)
170:         end
171:       end
controller_class=(new_class)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 160
160:       def controller_class=(new_class)
161:         prepare_controller_class(new_class) if new_class
162:         write_inheritable_attribute(:controller_class, new_class)
163:       end
determine_default_controller_class(name)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 173
173:       def determine_default_controller_class(name)
174:         name.sub(/Test$/, '').constantize
175:       rescue NameError
176:         nil
177:       end
prepare_controller_class(new_class)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 179
179:       def prepare_controller_class(new_class)
180:         new_class.send :include, RaiseActionExceptions
181:       end
tests(controller_class)

Sets the controller class name. Useful if the name can‘t be inferred from test class. Expects controller_class as a constant. Example: tests WidgetController.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 156
156:       def tests(controller_class)
157:         self.controller_class = controller_class
158:       end

Public Instance methods

rescue_action_in_public!()

Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 200
200:     def rescue_action_in_public!
201:       @request.remote_addr = '208.77.188.166' # example.com
202:     end
setup_controller_request_and_response()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 184
184:     def setup_controller_request_and_response
185:       @request = TestRequest.new
186:       @response = TestResponse.new
187:
188:       if klass = self.class.controller_class
189:         @controller ||= klass.new rescue nil
190:       end
191:
192:       if @controller
193:         @controller.request = @request
194:         @controller.params = {}
195:         @controller.send(:initialize_current_url)
196:       end
197:     end


Module: ActionController::TestCase::Assertions

Module | ActionController::TestCase::Assertions
In: | vendor/rails/actionpack/lib/action_controller/test_case.rb

Methods

clean_backtrace

Included Modules

ActionController::Assertions

Public Instance methods

clean_backtrace() {|| ...}

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 113
113:       def clean_backtrace(&block)
114:         yield
115:       rescue ActiveSupport::TestCase::Assertion => error
116:         framework_path = Regexp.new(File.expand_path("#{File.dirname(__FILE__)}/assertions"))
117:         error.backtrace.reject! { |line| File.expand_path(line) =~ framework_path }
118:         raise
119:       end


Module: ActionController::TestCase::RaiseActionExceptions

Module | ActionController::TestCase::RaiseActionExceptions
In: | vendor/rails/actionpack/lib/action_controller/test_case.rb

When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else than 0.0.0.0.

The exception is stored in the exception accessor for further inspection.

Methods

included rescue_action_without_handler

Public Class methods

included(base)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 130
130:       def self.included(base)
131:         base.class_eval do
132:           attr_accessor :exception
133:           protected :exception, :exception=
134:         end
135:       end

Protected Instance methods

rescue_action_without_handler(e)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_case.rb, line 138
138:         def rescue_action_without_handler(e)
139:           self.exception = e
140:
141:           if request.remote_addr == "0.0.0.0"
142:             raise(e)
143:           else
144:             super(e)
145:           end
146:         end


Module: ActionController::TestProcess

Module | ActionController::TestProcess
In: | vendor/rails/actionpack/lib/action_controller/test_process.rb

Methods

assigns build_request_uri cookies delete find_all_tag find_tag fixture_file_upload flash get head html_document included method_missing post process put redirect_to_url session with_routing xhr xml_http_request

Included Modules

ProcessWithTest

Public Class methods

included(base)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 387
387:     def self.included(base)
388:       # Executes a request simulating GET HTTP method and set/volley the response
389:       def get(action, parameters = nil, session = nil, flash = nil)
390:         process(action, parameters, session, flash, "GET")
391:       end
392:
393:       # Executes a request simulating POST HTTP method and set/volley the response
394:       def post(action, parameters = nil, session = nil, flash = nil)
395:         process(action, parameters, session, flash, "POST")
396:       end
397:
398:       # Executes a request simulating PUT HTTP method and set/volley the response
399:       def put(action, parameters = nil, session = nil, flash = nil)
400:         process(action, parameters, session, flash, "PUT")
401:       end
402:
403:       # Executes a request simulating DELETE HTTP method and set/volley the response
404:       def delete(action, parameters = nil, session = nil, flash = nil)
405:         process(action, parameters, session, flash, "DELETE")
406:       end
407:
408:       # Executes a request simulating HEAD HTTP method and set/volley the response
409:       def head(action, parameters = nil, session = nil, flash = nil)
410:         process(action, parameters, session, flash, "HEAD")
411:       end
412:     end

Public Instance methods

assigns(key = nil)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 452
452:     def assigns(key = nil)
453:       if key.nil?
454:         @response.template.assigns
455:       else
456:         @response.template.assigns[key.to_s]
457:       end
458:     end
build_request_uri(action, parameters)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 476
476:     def build_request_uri(action, parameters)
477:       unless @request.env['REQUEST_URI']
478:         options = @controller.__send__(:rewrite_options, parameters)
479:         options.update(:only_path => true, :action => action)
480:
481:         url = ActionController::UrlRewriter.new(@request, parameters)
482:         @request.set_REQUEST_URI(url.rewrite(options))
483:       end
484:     end
cookies()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 468
468:     def cookies
469:       @response.cookies
470:     end
delete(action, parameters = nil, session = nil, flash = nil)

Executes a request simulating DELETE HTTP method and set/volley the response

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 404
404:       def delete(action, parameters = nil, session = nil, flash = nil)
405:         process(action, parameters, session, flash, "DELETE")
406:       end
find_all_tag(conditions)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 495
495:     def find_all_tag(conditions)
496:       html_document.find_all(conditions)
497:     end
find_tag(conditions)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 491
491:     def find_tag(conditions)
492:       html_document.find(conditions)
493:     end
fixture_file_upload(path, mime_type = nil, binary = false)

Shortcut for ActionController::TestUploadedFile.new(ActionController::TestCase.fixture_path + path, type):

  post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')

To upload binary files on Windows, pass :binary as the last parameter. This will not affect other platforms:

  post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 515
515:     def fixture_file_upload(path, mime_type = nil, binary = false)
516:       fixture_path = ActionController::TestCase.send(:fixture_path) if ActionController::TestCase.respond_to?(:fixture_path)
517:       ActionController::TestUploadedFile.new("#{fixture_path}#{path}", mime_type, binary)
518:     end
flash()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 464
464:     def flash
465:       @response.flash
466:     end
get(action, parameters = nil, session = nil, flash = nil)

Executes a request simulating GET HTTP method and set/volley the response

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 389
389:       def get(action, parameters = nil, session = nil, flash = nil)
390:         process(action, parameters, session, flash, "GET")
391:       end
head(action, parameters = nil, session = nil, flash = nil)

Executes a request simulating HEAD HTTP method and set/volley the response

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 409
409:       def head(action, parameters = nil, session = nil, flash = nil)
410:         process(action, parameters, session, flash, "HEAD")
411:       end
html_document()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 486
486:     def html_document
487:       xml = @response.content_type =~ /xml$/
488:       @html_document ||= HTML::Document.new(@response.body, false, xml)
489:     end
method_missing(selector, *args, &block)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 499
499:     def method_missing(selector, *args, &block)
500:       if @controller && ActionController::Routing::Routes.named_routes.helpers.include?(selector)
501:         @controller.send(selector, *args, &block)
502:       else
503:         super
504:       end
505:     end
post(action, parameters = nil, session = nil, flash = nil)

Executes a request simulating POST HTTP method and set/volley the response

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 394
394:       def post(action, parameters = nil, session = nil, flash = nil)
395:         process(action, parameters, session, flash, "POST")
396:       end
process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 414
414:     def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
415:       # Sanity check for required instance variables so we can give an
416:       # understandable error message.
417:       %w(@controller @request @response).each do |iv_name|
418:         if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
419:           raise "#{iv_name} is nil: make sure you set it in your test's setup method."
420:         end
421:       end
422:
423:       @request.recycle!
424:       @response.recycle!
425:
426:       @html_document = nil
427:       @request.env['REQUEST_METHOD'] = http_method
428:
429:       @request.action = action.to_s
430:
431:       parameters ||= {}
432:       @request.assign_parameters(@controller.class.controller_path, action.to_s, parameters)
433:
434:       @request.session = ActionController::TestSession.new(session) unless session.nil?
435:       @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
436:       build_request_uri(action, parameters)
437:
438:       Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
439:       @controller.process_with_test(@request, @response)
440:     end
put(action, parameters = nil, session = nil, flash = nil)

Executes a request simulating PUT HTTP method and set/volley the response

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 399
399:       def put(action, parameters = nil, session = nil, flash = nil)
400:         process(action, parameters, session, flash, "PUT")
401:       end
redirect_to_url()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 472
472:     def redirect_to_url
473:       @response.redirect_url
474:     end
session()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 460
460:     def session
461:       @request.session
462:     end
with_routing() {|temporary_routes| ...}

A helper to make it easier to test different route configurations. This method temporarily replaces ActionController::Routing::Routes with a new RouteSet instance.

The new instance is yielded to the passed block. Typically the block will create some routes using map.draw { map.connect … }:

  with_routing do |set|
    set.draw do |map|
      map.connect ':controller/:action/:id'
        assert_equal(
          ['/content/10/show', {}],
          map.generate(:controller => 'content', :id => 10, :action => 'show')
      end
    end
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 537
537:     def with_routing
538:       real_routes = ActionController::Routing::Routes
539:       ActionController::Routing.module_eval { remove_const :Routes }
540:
541:       temporary_routes = ActionController::Routing::RouteSet.new
542:       ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
543:
544:       yield temporary_routes
545:     ensure
546:       if ActionController::Routing.const_defined? :Routes
547:         ActionController::Routing.module_eval { remove_const :Routes }
548:       end
549:       ActionController::Routing.const_set(:Routes, real_routes) if real_routes
550:     end
xhr(request_method, action, parameters = nil, session = nil, flash = nil)

Alias for xml_http_request

xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 442
442:     def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
443:       @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
444:       @request.env['HTTP_ACCEPT'] =  [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
445:       returning __send__(request_method, action, parameters, session, flash) do
446:         @request.env.delete 'HTTP_X_REQUESTED_WITH'
447:         @request.env.delete 'HTTP_ACCEPT'
448:       end
449:     end


Class: ActionController::TestResponse

Class | ActionController::TestResponse
In: | vendor/rails/actionpack/lib/action_controller/test_process.rb
Parent: | Response

Integration test methods such as ActionController::Integration::Session#get and ActionController::Integration::Session#post return objects of class TestResponse, which represent the HTTP response results of the requested controller actions.

See Response for more information on controller response objects.

Methods

recycle!

Included Modules

TestResponseBehavior

Public Instance methods

recycle!()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 281
281:     def recycle!
282:       headers.delete('ETag')
283:       headers.delete('Last-Modified')
284:     end


Class: ActionController::TestUploadedFile

Class | ActionController::TestUploadedFile
In: | vendor/rails/actionpack/lib/action_controller/test_process.rb
Parent: | Object

Methods

new

External Aliases

path -> local_path

Attributes

content_type | [RW] | The content type of the "uploaded" file
original_filename | [R] | The filename, not including the path, of the "uploaded" file

Public Class methods

new(path, content_type = Mime::TEXT, binary = false)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/test_process.rb, line 365
365:     def initialize(path, content_type = Mime::TEXT, binary = false)
366:       raise "#{path} file does not exist" unless File.exist?(path)
367:       @content_type = content_type
368:       @original_filename = path.sub(/^.*#{File::SEPARATOR}([^#{File::SEPARATOR}]+)$/) { $1 }
369:       @tempfile = Tempfile.new(@original_filename)
370:       @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
371:       @tempfile.binmode if binary
372:       FileUtils.copy_file(path, @tempfile.path)
373:     end


Module: ActionController::Translation

Module | ActionController::Translation
In: | vendor/rails/actionpack/lib/action_controller/translation.rb

Methods

l localize t translate

Public Instance methods

l(*args)

Alias for localize

localize(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/translation.rb, line 8
 8:     def localize(*args)
 9:       I18n.localize *args
10:     end
t(*args)

Alias for translate

translate(*args)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/translation.rb, line 3
3:     def translate(*args)
4:       I18n.translate *args
5:     end


Module: ActionController::UploadedFile

Module | ActionController::UploadedFile
In: | vendor/rails/actionpack/lib/action_controller/uploaded_file.rb

Methods

extended included original_filename

Public Class methods

extended(object)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 10
10:     def self.extended(object)
11:       object.class_eval do
12:         attr_accessor :original_path, :content_type
13:         alias_method :local_path, :path
14:       end
15:     end
included(base)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 3
3:     def self.included(base)
4:       base.class_eval do
5:         attr_accessor :original_path, :content_type
6:         alias_method :local_path, :path
7:       end
8:     end

Public Instance methods

original_filename()

Take the basename of the upload‘s original filename. This handles the full Windows paths given by Internet Explorer (and perhaps other broken user agents) without affecting those which give the lone filename. The Windows regexp is adapted from Perl‘s File::Basename.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/uploaded_file.rb, line 22
22:     def original_filename
23:       unless defined? @original_filename
24:         @original_filename =
25:           unless original_path.blank?
26:             if original_path =~ /^(?:.*[:\\\/])?(.*)/m
27:               $1
28:             else
29:               File.basename original_path
30:             end
31:           end
32:       end
33:       @original_filename
34:     end


Class: ActionController::UploadedStringIO

Class | ActionController::UploadedStringIO
In: | vendor/rails/actionpack/lib/action_controller/uploaded_file.rb
Parent: | StringIO

Included Modules

UploadedFile


Class: ActionController::UploadedTempfile

Class | ActionController::UploadedTempfile
In: | vendor/rails/actionpack/lib/action_controller/uploaded_file.rb
Parent: | Tempfile

Included Modules

UploadedFile


Module: ActionController::UrlWriter

Module | ActionController::UrlWriter
In: | vendor/rails/actionpack/lib/action_controller/url_rewriter.rb

In routes.rb one defines URL-to-controller mappings, but the reverse is also possible: an URL can be generated from one of your routing definitions. URL generation functionality is centralized in this module.

See ActionController::Routing and ActionController::Resources for general information about routing and routes.rb.

Tip: If you need to generate URLs from your models or some other place, then ActionController::UrlWriter is what you‘re looking for. Read on for an introduction.

URL generation from parameters

As you may know, some functions - such as ActionController::Base#url_for and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set of parameters. For example, you‘ve probably had the chance to write code like this in one of your views:

  <%= link_to('Click here', :controller => 'users',
          :action => 'new', :message => 'Welcome!') %>

  #=> Generates a link to: /users/new?message=Welcome%21

link_to, and all other functions that require URL generation functionality, actually use ActionController::UrlWriter under the hood. And in particular, they use the ActionController::UrlWriter#url_for method. One can generate the same path as the above example by using the following code:

  include UrlWriter
  url_for(:controller => 'users',
          :action => 'new',
          :message => 'Welcome!',
          :only_path => true)
  # => "/users/new?message=Welcome%21"

Notice the :only_path => true part. This is because UrlWriter has no information about the website hostname that your Rails app is serving. So if you want to include the hostname as well, then you must also pass the :host argument:

  include UrlWriter
  url_for(:controller => 'users',
          :action => 'new',
          :message => 'Welcome!',
          :host => 'www.example.com')        # Changed this.
  # => "http://www.example.com/users/new?message=Welcome%21"

By default, all controllers and views have access to a special version of url_for, that already knows what the current hostname is. So if you use url_for in your controllers or your views, then you don‘t need to explicitly pass the :host argument.

For convenience reasons, mailers provide a shortcut for ActionController::UrlWriter#url_for. So within mailers, you only have to type ‘url_for’ instead of ‘ActionController::UrlWriter#url_for’ in full. However, mailers don‘t have hostname information, and what‘s why you‘ll still have to specify the :host argument when generating URLs in mailers.

URL generation for named routes

UrlWriter also allows one to access methods that have been auto-generated from named routes. For example, suppose that you have a ‘users’ resource in your routes.rb:

  map.resources :users

This generates, among other things, the method users_path. By default, this method is accessible from your controllers, views and mailers. If you need to access this auto-generated method from other places (such as a model), then you can do that in two ways.

The first way is to include ActionController::UrlWriter in your class:

  class User < ActiveRecord::Base
    include ActionController::UrlWriter         # !!!

    def name=(value)
      write_attribute('name', value)
      write_attribute('base_uri', users_path)   # !!!
    end
  end

The second way is to access them through ActionController::UrlWriter. The autogenerated named routes methods are available as class methods:

  class User < ActiveRecord::Base
    def name=(value)
      write_attribute('name', value)
      path = ActionController::UrlWriter.users_path   # !!!
      write_attribute('base_uri', path)               # !!!
    end
  end

Methods

url_for

Public Instance methods

url_for(options)

Generate a url based on the options provided, default_url_options and the routes defined in routes.rb. The following options are supported:

  • :only_path - If true, the relative url is returned. Defaults to false.
  • :protocol - The protocol to connect to. Defaults to ‘http’.
  • :host - Specifies the host the link should be targetted at. If :only_path is false, this option must be provided either explicitly, or via default_url_options.
  • :port - Optionally specify the port to connect to.
  • :anchor - An anchor name to be appended to the path.
  • :skip_relative_url_root - If true, the url is not constructed using the relative_url_root set in ActionController::Base.relative_url_root.
  • :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/"

Any other key (:controller, :action, etc.) given to url_for is forwarded to the Routes module.

Examples:

   url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080'    # => 'http://somehost.org:8080/tasks/testing'
   url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true    # => '/tasks/testing#ok'
   url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true  # => 'http://somehost.org/tasks/testing/'
   url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33'  # => 'http://somehost.org/tasks/testing?number=33'

[Source]

     # File vendor/rails/actionpack/lib/action_controller/url_rewriter.rb, line 126
126:     def url_for(options)
127:       options = self.class.default_url_options.merge(options)
128:
129:       url = ''
130:
131:       unless options.delete(:only_path)
132:         url << (options.delete(:protocol) || 'http')
133:         url << '://' unless url.match("://")
134:
135:         raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host]
136:
137:         url << options.delete(:host)
138:         url << ":#{options.delete(:port)}" if options.key?(:port)
139:       else
140:         # Delete the unused options to prevent their appearance in the query string.
141:         [:protocol, :host, :port, :skip_relative_url_root].each { |k| options.delete(k) }
142:       end
143:       trailing_slash = options.delete(:trailing_slash) if options.key?(:trailing_slash)
144:       url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
145:       anchor = "##{CGI.escape options.delete(:anchor).to_param.to_s}" if options[:anchor]
146:       generated = Routing::Routes.generate(options, {})
147:       url << (trailing_slash ? generated.sub(/\?|\z/) { "/" + $& } : generated)
148:       url << anchor if anchor
149:
150:       url
151:     end


Module: ActionController::Verification::ClassMethods

Module | ActionController::Verification::ClassMethods
In: | vendor/rails/actionpack/lib/action_controller/verification.rb

This module provides a class-level method for specifying that certain actions are guarded against being called without certain prerequisites being met. This is essentially a special kind of before_filter.

An action may be guarded against being invoked without certain request parameters being set, or without certain session values existing.

When a verification is violated, values may be inserted into the flash, and a specified redirection is triggered. If no specific action is configured, verification failures will by default result in a 400 Bad Request response.

Usage:

  class GlobalController < ActionController::Base
    # Prevent the #update_settings action from being invoked unless
    # the 'admin_privileges' request parameter exists. The
    # settings action will be redirected to in current controller
    # if verification fails.
    verify :params => "admin_privileges", :only => :update_post,
           :redirect_to => { :action => "settings" }

    # Disallow a post from being updated if there was no information
    # submitted with the post, and if there is no active post in the
    # session, and if there is no "note" key in the flash. The route
    # named category_url will be redirected to if verification fails.

    verify :params => "post", :session => "post", "flash" => "note",
           :only => :update_post,
           :add_flash => { "alert" => "Failed to create your message" },
           :redirect_to => :category_url

Note that these prerequisites are not business rules. They do not examine the content of the session or the parameters. That level of validation should be encapsulated by your domain model or helper methods in the controller.

Methods

verify

Public Instance methods

verify(options={})

Verify the given actions so that if certain prerequisites are not met, the user is redirected to a different action. The options parameter is a hash consisting of the following key/value pairs:

:params: | a single key or an array of keys that must be in the params hash in order for the action(s) to be safely called.
:session: | a single key or an array of keys that must be in the session in order for the action(s) to be safely called.
:flash: | a single key or an array of keys that must be in the flash in order for the action(s) to be safely called.
:method: | a single key or an array of keys—any one of which must match the current request method in order for the action(s) to be safely called. (The key should be a symbol: :get or :post, for example.)
:xhr: | true/false option to ensure that the request is coming from an Ajax call or not.
:add_flash: | a hash of name/value pairs that should be merged into the session‘s flash if the prerequisites cannot be satisfied.
:add_headers: | a hash of name/value pairs that should be merged into the response‘s headers hash if the prerequisites cannot be satisfied.
:redirect_to: | the redirection parameters to be used when redirecting if the prerequisites cannot be satisfied. You can redirect either to named route or to the action in some controller.
:render: | the render parameters to be used when the prerequisites cannot be satisfied.
:only: | only apply this verification to the actions specified in the associated array (may also be a single value).
:except: | do not apply this verification to the actions specified in the associated array (may also be a single value).

[Source]

    # File vendor/rails/actionpack/lib/action_controller/verification.rb, line 81
81:       def verify(options={})
82:         before_filter :only => options[:only], :except => options[:except] do |c|
83:           c.__send__ :verify_action, options
84:         end
85:       end


File: dom_assertions.rb

dom_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: model_assertions.rb

model_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: response_assertions.rb

response_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: routing_assertions.rb

routing_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: selector_assertions.rb

selector_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: tag_assertions.rb

tag_assertions.rb

Path: | vendor/rails/actionpack/lib/action_controller/assertions/tag_assertions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: base.rb

base.rb

Path: | vendor/rails/actionpack/lib/action_controller/base.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

set


File: benchmarking.rb

benchmarking.rb

Path: | vendor/rails/actionpack/lib/action_controller/benchmarking.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

benchmark


File: caching.rb

caching.rb

Path: | vendor/rails/actionpack/lib/action_controller/caching.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

fileutils uri set


File: actions.rb

actions.rb

Path: | vendor/rails/actionpack/lib/action_controller/caching/actions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

set


File: fragments.rb

fragments.rb

Path: | vendor/rails/actionpack/lib/action_controller/caching/fragments.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: pages.rb

pages.rb

Path: | vendor/rails/actionpack/lib/action_controller/caching/pages.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

fileutils uri


File: sweeping.rb

sweeping.rb

Path: | vendor/rails/actionpack/lib/action_controller/caching/sweeping.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: cgi_ext.rb

cgi_ext.rb

Path: | vendor/rails/actionpack/lib/action_controller/cgi_ext.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

action_controller/cgi_ext/stdinput action_controller/cgi_ext/query_extension action_controller/cgi_ext/cookie


File: cookie.rb

cookie.rb

Path: | vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

delegate


File: query_extension.rb

query_extension.rb

Path: | vendor/rails/actionpack/lib/action_controller/cgi_ext/query_extension.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi


File: stdinput.rb

stdinput.rb

Path: | vendor/rails/actionpack/lib/action_controller/cgi_ext/stdinput.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi


File: cgi_process.rb

cgi_process.rb

Path: | vendor/rails/actionpack/lib/action_controller/cgi_process.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

action_controller/cgi_ext


File: cookies.rb

cookies.rb

Path: | vendor/rails/actionpack/lib/action_controller/cookies.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: dispatcher.rb

dispatcher.rb

Path: | vendor/rails/actionpack/lib/action_controller/dispatcher.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: failsafe.rb

failsafe.rb

Path: | vendor/rails/actionpack/lib/action_controller/failsafe.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: filters.rb

filters.rb

Path: | vendor/rails/actionpack/lib/action_controller/filters.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: flash.rb

flash.rb

Path: | vendor/rails/actionpack/lib/action_controller/flash.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: headers.rb

headers.rb

Path: | vendor/rails/actionpack/lib/action_controller/headers.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

active_support/memoizable


File: helpers.rb

helpers.rb

Path: | vendor/rails/actionpack/lib/action_controller/helpers.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

active_support/dependencies


File: http_authentication.rb

http_authentication.rb

Path: | vendor/rails/actionpack/lib/action_controller/http_authentication.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: integration.rb

integration.rb

Path: | vendor/rails/actionpack/lib/action_controller/integration.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

stringio uri active_support/test_case


File: layout.rb

layout.rb

Path: | vendor/rails/actionpack/lib/action_controller/layout.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: middleware_stack.rb

middleware_stack.rb

Path: | vendor/rails/actionpack/lib/action_controller/middleware_stack.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: middlewares.rb

middlewares.rb

Path: | vendor/rails/actionpack/lib/action_controller/middlewares.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: mime_responds.rb

mime_responds.rb

Path: | vendor/rails/actionpack/lib/action_controller/mime_responds.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: mime_type.rb

mime_type.rb

Path: | vendor/rails/actionpack/lib/action_controller/mime_type.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

set action_controller/mime_types


File: mime_types.rb

mime_types.rb

Path: | vendor/rails/actionpack/lib/action_controller/mime_types.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Build list of Mime types for HTTP responses www.iana.org/assignments/media-types/


File: params_parser.rb

params_parser.rb

Path: | vendor/rails/actionpack/lib/action_controller/params_parser.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: performance_test.rb

performance_test.rb

Path: | vendor/rails/actionpack/lib/action_controller/performance_test.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

active_support/testing/performance active_support/testing/default


File: polymorphic_routes.rb

polymorphic_routes.rb

Path: | vendor/rails/actionpack/lib/action_controller/polymorphic_routes.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: record_identifier.rb

record_identifier.rb

Path: | vendor/rails/actionpack/lib/action_controller/record_identifier.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: reloader.rb

reloader.rb

Path: | vendor/rails/actionpack/lib/action_controller/reloader.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: request.rb

request.rb

Path: | vendor/rails/actionpack/lib/action_controller/request.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

tempfile stringio strscan active_support/memoizable action_controller/cgi_ext


File: request_forgery_protection.rb

request_forgery_protection.rb

Path: | vendor/rails/actionpack/lib/action_controller/request_forgery_protection.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: rescue.rb

rescue.rb

Path: | vendor/rails/actionpack/lib/action_controller/rescue.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: resources.rb

resources.rb

Path: | vendor/rails/actionpack/lib/action_controller/resources.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: response.rb

response.rb

Path: | vendor/rails/actionpack/lib/action_controller/response.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

digest/md5


File: rewindable_input.rb

rewindable_input.rb

Path: | vendor/rails/actionpack/lib/action_controller/rewindable_input.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: routing.rb

routing.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi uri action_controller/routing/optimisations action_controller/routing/routing_ext action_controller/routing/route action_controller/routing/segments action_controller/routing/builder action_controller/routing/route_set action_controller/routing/recognition_optimisation


File: builder.rb

builder.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/builder.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: optimisations.rb

optimisations.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/optimisations.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: recognition_optimisation.rb

recognition_optimisation.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/recognition_optimisation.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: route.rb

route.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/route.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: route_set.rb

route_set.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/route_set.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: routing_ext.rb

routing_ext.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/routing_ext.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: segments.rb

segments.rb

Path: | vendor/rails/actionpack/lib/action_controller/routing/segments.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: abstract_store.rb

abstract_store.rb

Path: | vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: cookie_store.rb

cookie_store.rb

Path: | vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: mem_cache_store.rb

mem_cache_store.rb

Path: | vendor/rails/actionpack/lib/action_controller/session/mem_cache_store.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: session_management.rb

session_management.rb

Path: | vendor/rails/actionpack/lib/action_controller/session_management.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: status_codes.rb

status_codes.rb

Path: | vendor/rails/actionpack/lib/action_controller/status_codes.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: streaming.rb

streaming.rb

Path: | vendor/rails/actionpack/lib/action_controller/streaming.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: test_case.rb

test_case.rb

Path: | vendor/rails/actionpack/lib/action_controller/test_case.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

active_support/test_case action_controller/test_process


File: test_process.rb

test_process.rb

Path: | vendor/rails/actionpack/lib/action_controller/test_process.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

stringio tempfile


File: translation.rb

translation.rb

Path: | vendor/rails/actionpack/lib/action_controller/translation.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: uploaded_file.rb

uploaded_file.rb

Path: | vendor/rails/actionpack/lib/action_controller/uploaded_file.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: url_rewriter.rb

url_rewriter.rb

Path: | vendor/rails/actionpack/lib/action_controller/url_rewriter.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: html-scanner.rb

html-scanner.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: document.rb

document.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

html/tokenizer html/node html/selector html/sanitizer


File: node.rb

node.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

strscan


File: sanitizer.rb

sanitizer.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: selector.rb

selector.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: tokenizer.rb

tokenizer.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

strscan


File: version.rb

version.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/version.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: rack.rb

rack.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Copyright (C) 2007, 2008, 2009 Christian Neukirchen <purl.org/net/chneukirchen>

Rack is freely distributable under the terms of an MIT-style license. See COPYING or www.opensource.org/licenses/mit-license.php.


File: camping.rb

camping.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: handler.rb

handler.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: request.rb

request.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: basic.rb

basic.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/auth/abstract/handler rack/auth/abstract/request


File: md5.rb

md5.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/auth/abstract/handler rack/auth/digest/request rack/auth/digest/params rack/auth/digest/nonce digest/md5


File: nonce.rb

nonce.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

digest/md5


File: params.rb

params.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: request.rb

request.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/auth/abstract/request rack/auth/digest/params rack/auth/digest/nonce


File: openid.rb

openid.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net

Required files

rack/request rack/utils rack/auth/abstract/handler uri openid openid/extension openid/store/memory


File: builder.rb

builder.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: cascade.rb

cascade.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: chunked.rb

chunked.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: commonlogger.rb

commonlogger.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: conditionalget.rb

conditionalget.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: content_length.rb

content_length.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: content_type.rb

content_type.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: deflater.rb

deflater.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

zlib stringio time rack/utils


File: directory.rb

directory.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

time rack/utils rack/mime


File: file.rb

file.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

time rack/utils rack/mime


File: handler.rb

handler.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: cgi.rb

cgi.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/content_length


File: evented_mongrel.rb

evented_mongrel.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

swiftcore/evented_mongrel


File: fastcgi.rb

fastcgi.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

fcgi socket rack/content_length


File: lsws.rb

lsws.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

lsapi rack/content_length


File: mongrel.rb

mongrel.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

mongrel stringio rack/content_length rack/chunked


File: scgi.rb

scgi.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

scgi stringio rack/content_length rack/chunked


File: swiftiplied_mongrel.rb

swiftiplied_mongrel.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

swiftcore/swiftiplied_mongrel


File: thin.rb

thin.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

thin rack/content_length rack/chunked


File: webrick.rb

webrick.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

webrick stringio rack/content_length


File: head.rb

head.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: lint.rb

lint.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: lobster.rb

lobster.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

zlib rack/request rack/response


File: lock.rb

lock.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: methodoverride.rb

methodoverride.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: mime.rb

mime.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: mock.rb

mock.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

uri stringio rack/lint rack/utils rack/response


File: recursive.rb

recursive.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

uri


File: reloader.rb

reloader.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

thread


File: request.rb

request.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/utils


File: response.rb

response.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

rack/request rack/utils


File: id.rb

id.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net bugrep: Andreas Zehnder

Required files

time rack/request rack/response


File: cookie.rb

cookie.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

openssl rack/request rack/response


File: memcache.rb

memcache.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net

Required files

rack/session/abstract/id memcache


File: pool.rb

pool.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net THANKS:

  apeiros, for session id generation, expiry setup, and threadiness
  sergio, threadiness and bugreps

Required files

rack/session/abstract/id thread


File: showexceptions.rb

showexceptions.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

ostruct erb rack/request rack/utils


File: showstatus.rb

showstatus.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

erb rack/request rack/utils


File: static.rb

static.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: urlmap.rb

urlmap.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: utils.rb

utils.rb

Path: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

set tempfile


File: verification.rb

verification.rb

Path: | vendor/rails/actionpack/lib/action_controller/verification.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/actionpack/CHANGELOG
Last Update: | Sun Mar 15 23:31:32 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]
  • Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable 2095 [Gregg Pollack]
  • Fixed that passing a custom form builder would be forwarded to nested fields_for calls 2023 [Eloy Duran/Nate Wiger]
  • Form option helpers now support disabled option tags and the use of lambdas for selecting/disabling option tags from collections 837 [Tekin]
  • Added partial scoping to TranslationHelper#translate, so if you call
translate(".foo") from the people/index.html.erb template,
you‘ll actually be calling I18n.translate("people.index.foo")
[DHH]
  • Fix a syntax error in current_page?() that was prevent matches against URL‘s with multiple query parameters 1385, 1868 [chris finne/Andrew White]
  • Added localized rescue template when I18n.locale is set (ex: public/404.da.html) 1835 [José Valim]
  • Make the form_for and fields_for helpers support the new Active Record nested update options. 1202 [Eloy Duran]
                  <% form_for @person do |person_form| %>
                ...
                <% person_form.fields_for :projects do |project_fields| %>
                  <% if project_fields.object.active? %>
                    Name: <%= project_fields.text_field :name %>
                  <% end %>
                <% end %>
              <% end %>
  • Added grouped_options_for_select helper method for wrapping option tags in optgroups. 977 [Jon Crawford]
  • Implement HTTP Digest authentication. 1230 [Gregg Kellogg, Pratik Naik] Example :

    class DummyDigestController < ActionController::Base

      USERS = { "lifo" => 'world' }

  before_filter :authenticate

  def index
    render :text => "Hello Secret"
  end

  private

  def authenticate
    authenticate_or_request_with_http_digest("Super Secret") do |username|
      # Return the user's password
      USERS[username]
    end
  end

    end

  • Improved i18n support for the number_to_human_size helper. Changes the storage_units translation data; update your translations accordingly. 1634 [Yaroslav Markin]
      storage_units:
    # %u is the storage unit, %n is the number (default: 2 MB)
    format: "%n %u"
    units:
      byte:
        one: "Byte"
        other: "Bytes"
      kb: "KB"
      mb: "MB"
      gb: "GB"
      tb: "TB"
  • Added :silence option to BenchmarkHelper#benchmark and turned log_level into a hash parameter and deprecated the old use [DHH]
  • Fixed the AssetTagHelper cache to use the computed asset host as part of the cache key instead of just assuming the its a string 1299 [DHH]
  • Make ActionController#render(string) work as a shortcut for render :file/:template/:action => string. [1435] [Pratik Naik] Examples:

    # Instead of render(:action => ‘other_action’) render(‘other_action’) # argument has no ’/’ render(:other_action)

    # Instead of render(:template => ‘controller/action’) render(‘controller/action’) # argument must not begin with a ’/’, but contain a ’/’

    # Instead of render(:file => ’/Users/lifo/home.html.erb’) render(’/Users/lifo/home.html.erb’) # argument must begin with a ’/’

  • Add :prompt option to date/time select helpers. 561 [Sam Oliver]
  • Fixed that send_file shouldn‘t set an etag 1578 [Hongli Lai]
  • Allow users to opt out of the spoofing checks in Request#remote_ip. Useful for sites whose traffic regularly triggers false positives. [Darren Boyd]
  • Deprecated formatted_polymorphic_url. [Jeremy Kemper]
  • Added the option to declare an asset_host as an object that responds to call (see github.com/dhh/asset-hosting-with-minimum-ssl for an example) [David Heinemeier Hansson]
  • Added support for multiple routes.rb files (useful for plugin engines). This also means that draw will no longer clear the route set, you have to do that by hand (shouldn‘t make a difference to you unless you‘re doing some funky stuff) [David Heinemeier Hansson]
  • Dropped formatted_* routes in favor of just passing in :format as an option. This cuts resource routes generation in half 1359 [aaronbatalion]
  • Remove support for old double-encoded cookies from the cookie store. These values haven‘t been generated since before 2.1.0, and any users who have visited the app in the intervening 6 months will have had their cookie upgraded. [Michael Koziarski]
  • Allow helpers directory to be overridden via ActionController::Base.helpers_dir 1424 [Sam Pohlenz]
  • Remove deprecated ActionController::Base#assign_default_content_type_and_charset
  • Changed the default of ActionView#render to assume partials instead of files when not given an options hash [David Heinemeier Hansson]. Examples:
      # Instead of <%= render :partial => "account" %>
  <%= render "account" %>

  # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %>
  <%= render "account", :account => @buyer %>

  # @account is an Account instance, so it uses the RecordIdentifier to replace
  # <%= render :partial => "accounts/account", :locals => { :account => @account } %>
  <%= render(@account) %>

  # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
  # <%= render :partial => "posts/post", :collection => @posts %>
  <%= render(@posts) %>
  • Remove deprecated render_component. Please use the plugin from github.com/rails/render_component/tree/master [Pratik Naik]
  • Fixed RedCloth and BlueCloth shouldn‘t preload. Instead just assume that they‘re available if you want to use textilize and markdown and let autoload require them [David Heinemeier Hansson]

*2.2.2 (November 21st, 2008)*

  • I18n: translate number_to_human_size. Add storage_units: [Bytes, KB, MB, GB, TB] to your translations. 1448 [Yaroslav Markin]
  • Restore backwards compatible functionality for setting relative_url_root. Include deprecation
  • Switched the CSRF module to use the request content type to decide if the request is forgeable. 1145 [Jeff Cohen]
  • Added :only and :except to map.resources to let people cut down on the number of redundant routes in an application. Typically only useful for huge routesets. 1215 [Tom Stuart]
     map.resources :products, :only => :show do |product|
   product.resources :images, :except => :destroy
 end
  • Added render :js for people who want to render inline JavaScript replies without using RJS [David Heinemeier Hansson]
  • Fixed that polymorphic_url should compact given array 1317 [hiroshi]
  • Fixed the sanitize helper to avoid double escaping already properly escaped entities 683 [antonmos/Ryan McGeary]
  • Fixed that FormTagHelper generated illegal html if name contained square brackets 1238 [Vladimir Dobriakov]
  • Fix regression bug that made date_select and datetime_select raise a Null Pointer Exception when a nil date/datetime was passed and only month and year were displayed 1289 [Bernardo Padua/Tor Erik]
  • Simplified the logging format for parameters (don‘t include controller, action, and format as duplicates) [David Heinemeier Hansson]
  • Remove the logging of the Session ID when the session store is CookieStore [David Heinemeier Hansson]
  • Fixed regex in redirect_to to fully support URI schemes 1247 [Seth Fitzsimmons]
  • Fixed bug with asset timestamping when using relative_url_root 1265 [Joe Goldwasser]

*2.2.0 [RC1] (October 24th, 2008)*

  • Fix incorrect closing CDATA delimiter and that HTML::Node.parse would blow up on unclosed CDATA sections [packagethief]
  • Added stale? and fresh_when methods to provide a layer of abstraction above request.fresh? and friends [David Heinemeier Hansson]. Example:
      class ArticlesController < ApplicationController
    def show_with_respond_to_block
      @article = Article.find(params[:id])

      # If the request sends headers that differs from the options provided to stale?, then
      # the request is indeed stale and the respond_to block is triggered (and the options
      # to the stale? call is set on the response).
      #
      # If the request headers match, then the request is fresh and the respond_to block is
      # not triggered. Instead the default render will occur, which will check the last-modified
      # and etag headers and conclude that it only needs to send a "304 Not Modified" instead
      # of rendering the template.
      if stale?(:last_modified => @article.published_at.utc, :etag => @article)
        respond_to do |wants|
          # normal response processing
        end
      end
    end

    def show_with_implied_render
      @article = Article.find(params[:id])

      # Sets the response headers and checks them against the request, if the request is stale
      # (i.e. no match of either etag or last-modified), then the default render of the template happens.
      # If the request is fresh, then the default render will return a "304 Not Modified"
      # instead of rendering the template.
      fresh_when(:last_modified => @article.published_at.utc, :etag => @article)
    end
  end
  • Added inline builder yield to atom_feed_helper tags where appropriate [Sam Ruby]. Example:
      entry.summary :type => 'xhtml' do |xhtml|
    xhtml.p pluralize(order.line_items.count, "line item")
    xhtml.p "Shipped to #{order.address}"
    xhtml.p "Paid by #{order.pay_type}"
  end
  • Make PrototypeHelper#submit_to_remote a wrapper around PrototypeHelper#button_to_remote. [Tarmo Tänav]
  • Set HttpOnly for the cookie session store‘s cookie. 1046
  • Added FormTagHelper#image_submit_tag confirm option 784 [Alastair Brunton]
  • Fixed FormTagHelper#submit_tag with :disable_with option wouldn‘t submit the button‘s value when was clicked 633 [Jose Fernandez]
  • Stopped logging template compiles as it only clogs up the log [David Heinemeier Hansson]
  • Changed the X-Runtime header to report in milliseconds [David Heinemeier Hansson]
  • Changed BenchmarkHelper#benchmark to report in milliseconds [David Heinemeier Hansson]
  • Changed logging format to be millisecond based and skip misleading stats [David Heinemeier Hansson]. Went from:
      Completed in 0.10000 (4 reqs/sec) | Rendering: 0.04000 (40%) | DB: 0.00400 (4%) | 200 OK [http://example.com]

    …to:

      Completed in 100ms (View: 40, DB: 4) | 200 OK [http://example.com]
  • Add support for shallow nesting of routes. 838 [S. Brent Faulkner]

    Example :

    map.resources :users, :shallow => true do |user|

      user.resources :posts

    end

    • GET /users/1/posts (maps to PostsController#index action as usual) named route "user_posts" is added as usual.
    • GET /posts/2 (maps to PostsController#show action as if it were not nested) Additionally, named route "post" is added too.
  • Added button_to_remote helper. 3641 [Donald Piret, Tarmo Tänav]
  • Deprecate render_component. Please use render_component plugin from github.com/rails/render_component/tree/master [Pratik Naik]
  • Routes may be restricted to lists of HTTP methods instead of a single method or :any. 407 [Brennan Dunn, Gaius Centus Novus]
      map.resource :posts, :collection => { :search => [:get, :post] }
  map.session 'session', :requirements => { :method => [:get, :post, :delete] }
  • Deprecated implicit local assignments when rendering partials [Josh Peek]
  • Introduce current_cycle helper method to return the current value without bumping the cycle. 417 [Ken Collins]
  • Allow polymorphic_url helper to take url options. 880 [Tarmo Tänav]
  • Switched integration test runner to use Rack processor instead of CGI [Josh Peek]
  • Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck]
  • Added back ActionController::Base.allow_concurrency flag [Josh Peek]
  • AbstractRequest.relative_url_root is no longer automatically configured by a HTTP header. It can now be set in your configuration environment with config.action_controller.relative_url_root [Josh Peek]
  • Update Prototype to 1.6.0.2 599 [Patrick Joyce]
  • Conditional GET utility methods. [Jeremy Kemper]
      response.last_modified = @post.updated_at
  response.etag = [:admin, @post, current_user]

  if request.fresh?(response)
    head :not_modified
  else
    # render ...
  end
  • All 2xx requests are considered successful [Josh Peek]
  • Fixed that AssetTagHelper#compute_public_path shouldn‘t cache the asset_host along with the source or per-request proc‘s won‘t run [David Heinemeier Hansson]
  • Removed config.action_view.cache_template_loading, use config.cache_classes instead [Josh Peek]
  • Get buffer for fragment cache from template‘s @output_buffer [Josh Peek]
  • Set config.action_view.warn_cache_misses = true to receive a warning if you perform an action that results in an expensive disk operation that could be cached [Josh Peek]
  • Refactor template preloading. New abstractions include Renderable mixins and a refactored Template class [Josh Peek]
  • Changed ActionView::TemplateHandler#render API method signature to render(template, local_assigns = {}) [Josh Peek]
  • Changed PrototypeHelper#submit_to_remote to PrototypeHelper#button_to_remote to stay consistent with link_to_remote (submit_to_remote still works as an alias) 8994 [clemens]
  • Add :recursive option to javascript_include_tag and stylesheet_link_tag to be used along with :all. 480 [Damian Janowski]
  • Allow users to disable the use of the Accept header [Michael Koziarski]
      The accept header is poorly implemented by browsers and causes strange
      errors when used on public sites where crawlers make requests too.  You
      can use formatted urls (e.g. /people/1.xml) to support API clients in a
      much simpler way.

      To disable the header you need to set:

      config.action_controller.use_accept_header = false
  • Do not stat template files in production mode before rendering. You will no longer be able to modify templates in production mode without restarting the server [Josh Peek]
  • Deprecated TemplateHandler line offset [Josh Peek]
  • Allow caches_action to accept cache store options. 416. [José Valim]. Example:

    caches_action :index, :redirected, :if => Proc.new { |c| !c.request.format.json? }, :expires_in => 1.hour

  • Remove define_javascript_functions, javascript_include_tag and friends are far superior. [Michael Koziarski]
  • Deprecate :use_full_path render option. The supplying the option no longer has an effect [Josh Peek]
  • Add :as option to render a collection of partials with a custom local variable name. 509 [Simon Jefford, Pratik Naik]

    render :partial => ‘other_people’, :collection => @people, :as => :person

    This will let you access objects of @people as ‘person’ local variable inside ‘other_people’ partial template.

  • time_zone_select: support for regexp matching of priority zones. Resolves 195 [Ernie Miller]
  • Made ActionView::Base#render_file private [Josh Peek]
  • Refactor and simplify the implementation of assert_redirected_to. Arguments are now normalised relative to the controller being tested, not the root of the application. [Michael Koziarski]

    This could cause some erroneous test failures if you were redirecting between controllers in different namespaces and wrote your assertions relative to the root of the application.

  • Remove follow_redirect from controller functional tests.
          If you want to follow redirects you can use integration tests.  The functional test
      version was only useful if you were using redirect_to :id=>...
  • Fix polymorphic_url with singleton resources. 461 [Tammer Saleh]
  • Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek]
  • Added block-call style to link_to [Sam Stephenson/David Heinemeier Hansson]. Example:
      <% link_to(@profile) do %>
    <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
  <% end %>
  • Performance: integration test benchmarking and profiling. [Jeremy Kemper]
  • Make caching more aware of mime types. Ensure request format is not considered while expiring cache. [Jonathan del Strother]
  • Drop ActionController::Base.allow_concurrency flag [Josh Peek]
  • More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper]
  • Added page.reload functionality. Resolves 277. [Sean Huber]
  • Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn‘t match (not just if they‘re both present) [Mark Imbriaco, Bradford Folkens]
  • Allow caches_action to accept a layout option [José Valim]
  • Added Rack processor [Ezra Zygmuntowicz, Josh Peek]

*2.1.0 (May 31st, 2008)*

  • InstanceTag#default_time_from_options overflows to DateTime [Geoff Buesing]
  • Fixed that forgery protection can be used without session tracking (Peter Jones) [139]
  • Added session(:on) to turn session management back on in a controller subclass if the superclass turned it off (Peter Jones) [136]
  • Change the request forgery protection to go by Content-Type instead of request.format so that you can‘t bypass it by POSTing to "#{request.uri}.xml" [Rick Olson]
  • InstanceTag#default_time_from_options with hash args uses Time.current as default; respects hash settings when time falls in system local spring DST gap [Geoff Buesing]
  • select_date defaults to Time.zone.today when config.time_zone is set [Geoff Buesing]
  • Fixed that TextHelper#text_field would corrypt when raw HTML was used as the value (mchenryc, Kevin Glowacz) [80]
  • Added ActionController::TestCase#rescue_action_in_public! to control whether the action under test should use the regular rescue_action path instead of simply raising the exception inline (great for error testing) [David Heinemeier Hansson]
  • Reduce number of instance variables being copied from controller to view. [Pratik Naik]
  • select_datetime and select_time default to Time.zone.now when config.time_zone is set [Geoff Buesing]
  • datetime_select defaults to Time.zone.now when config.time_zone is set [Geoff Buesing]
  • Remove ActionController::Base#view_controller_internals flag. [Pratik Naik]
  • Add conditional options to caches_page method. [Paul Horsfall]
  • Move missing template logic to ActionView. [Pratik Naik]
  • Introduce ActionView::InlineTemplate class. [Pratik Naik]
  • Automatically parse posted JSON content for Mime::JSON requests. [Rick Olson]

    POST /posts {"post": {"title": "Breaking News"}}

    def create

      @post = Post.create params[:post]
  # ...

    end

  • add json_escape ERB util to escape html entities in json strings that are output in HTML pages. [Rick Olson]
  • Provide a helper proxy to access helper methods from outside views. Closes 10839 [Josh Peek] e.g. ApplicationController.helpers.simple_format(text)
  • Improve documentation. [Xavier Noria, leethal, jerome]
  • Ensure RJS redirect_to doesn‘t html-escapes string argument. Closes 8546 [Josh Peek, eventualbuddha, Pratik Naik]
  • Support render :partial => collection of heterogeneous elements. 11491 [Zach Dennis]
  • Avoid remote_ip spoofing. [Brian Candler]
  • Added support for regexp flags like ignoring case in the :requirements part of routes declarations 11421 [NeilW]
  • Fixed that ActionController::Base#read_multipart would fail if boundary was exactly 10240 bytes 10886 [ariejan]
  • Fixed HTML::Tokenizer (used in sanitize helper) didn‘t handle unclosed CDATA tags 10071 [esad, packagethief]
  • Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert]
  • Fixed that FormHelper#radio_button would produce invalid ids 11298 [harlancrystal]
  • Added :confirm option to submit_tag 11415 [Emilio Tagua]
  • Fixed NumberHelper#number_with_precision to properly round in a way that works equally on Mac, Windows, Linux (closes 11409, 8275, 10090, 8027) [zhangyuanyi]
  • Allow the simple_format text_helper to take an html_options hash for each paragraph. 2448 [François Beausoleil, Chris O‘Sullivan]
  • Fix regression from filter refactoring where re-adding a skipped filter resulted in it being called twice. [Rick Olson]
  • Refactor filters to use Active Support callbacks. 11235 [Josh Peek]
  • Fixed that polymorphic routes would modify the input array 11363 [thomas.lee]
  • Added :format option to NumberHelper#number_to_currency to enable better localization support 11149 [lylo]
  • Fixed that TextHelper#excerpt would include one character too many 11268 [Irfy]
  • Fix more obscure nested parameter hash parsing bug. 10797 [thomas.lee]
  • Added ActionView::Helpers::register_javascript/stylesheet_expansion to make it easier for plugin developers to inject multiple assets. 10350 [lotswholetime]
  • Fix nested parameter hash parsing bug. 10797 [thomas.lee]
  • Allow using named routes in ActionController::TestCase before any request has been made. Closes 11273 [Eloy Duran]
  • Fixed that sweepers defined by cache_sweeper will be added regardless of the perform_caching setting. Instead, control whether the sweeper should be run with the perform_caching setting. This makes testing easier when you want to turn perform_caching on/off [David Heinemeier Hansson]
  • Make MimeResponds::Responder#any work without explicit types. Closes 11140 [jaw6]
  • Better error message for type conflicts when parsing params. Closes 7962 [spicycode, matt]
  • Remove unused ActionController::Base.template_class. Closes 10787 [Pratik Naik]
  • Moved template handlers related code from ActionView::Base to ActionView::Template. [Pratik Naik]
  • Tests for div_for and content_tag_for helpers. Closes 11223 [Chris O‘Sullivan]
  • Allow file uploads in Integration Tests. Closes 11091 [RubyRedRick]
  • Refactor partial rendering into a PartialTemplate class. [Pratik Naik]
  • Added that requests with JavaScript as the priority mime type in the accept header and no format extension in the parameters will be treated as though their format was :js when it comes to determining which template to render. This makes it possible for JS requests to automatically render action.js.rjs files without an explicit respond_to block [David Heinemeier Hansson]
  • Tests for distance_of_time_in_words with TimeWithZone instances. Closes 10914 [Ernesto Jimenez]
  • Remove support for multivalued (e.g., ’&’-delimited) cookies. [Jamis Buck]
  • Fix problem with render :partial collections, records, and locals. 11057 [lotswholetime]
  • Added support for naming concrete classes in sweeper declarations [David Heinemeier Hansson]
  • Remove ERB trim variables from trace template in case ActionView::Base.erb_trim_mode is changed in the application. 10098 [Tim Pope, Chris Kampmeier]
  • Fix typo in form_helper documentation. 10650 [Xavier Shay, Chris Kampmeier]
  • Fix bug with setting Request#format= after the getter has cached the value. 10889 [cch1]
  • Correct inconsistencies in RequestForgeryProtection docs. 11032 [Mislav Marohnić]
  • Introduce a Template class to ActionView. 11024 [Pratik Naik]
  • Introduce the :index option for form_for and fields_for to simplify multi-model forms (see railscasts.com/episodes/75). 9883 [rmm5t]
  • Introduce map.resources :cards, :as => ‘tarjetas’ to use a custom resource name in the URL: cards_path == ’/tarjetas’. 10578 [blj]
  • TestSession supports indifferent access. 7372 [tamc, Arsen7, mhackett, julik, jean.helou]
  • Make assert_routing aware of the HTTP method used. 8039 [mpalmer] e.g. assert_routing({ :method => ‘put’, :path => ’/product/321’ }, { :controller => "product", :action => "update", :id => "321" })
  • Make map.root accept a single symbol as an argument to declare an alias. 10818 [bscofield]

    e.g. map.dashboard ’/dashboard’, :controller=>’dashboard‘

          map.root      :dashboard
  • Handle corner case with image_tag when passed ‘messed up’ image names. 9018 [Duncan Beevers, mpalmer]
  • Add label_tag helper for generating elements. 10802 [DefV]
  • Introduce TemplateFinder to handle view paths and lookups. 10800 [Pratik Naik]
  • Performance: optimize route recognition. Large speedup for apps with many resource routes. 10835 [oleganza]
  • Make render :partial recognise form builders and use the _form partial. 10814 [Damian Janowski]
  • Allow users to declare other namespaces when using the atom feed helpers. 10304 [david.calavera]
  • Introduce send_file :x_sendfile => true to send an X-Sendfile response header. [Jeremy Kemper]
  • Fixed ActionView::Helpers::ActiveRecordHelper::form for when protect_from_forgery is used 10739 [Jeremy Evans]
  • Provide nicer access to HTTP Headers. Instead of request.env["HTTP_REFERRER"] you can now use request.headers["Referrer"]. [Michael Koziarski]
  • UrlWriter respects relative_url_root. 10748 [Cheah Chu Yeow]
  • The asset_host block takes the controller request as an optional second argument. Example: use a single asset host for SSL requests. 10549 [Cheah Chu Yeow, Peter B, Tom Taylor]
  • Support render :text => nil. 6684 [tjennings, PotatoSalad, Cheah Chu Yeow]
  • assert_response failures include the exception message. 10688 [Seth Rasmussen]
  • All fragment cache keys are now by default prefixed with the "views/" namespace [David Heinemeier Hansson]
  • Moved the caching stores from ActionController::Caching::Fragments::*
to ActiveSupport::Cache::*.
If you‘re explicitly referring to a store, like
ActionController::Caching::Fragments::MemoryStore, you need to update that
reference with ActiveSupport::Cache::MemoryStore
[David Heinemeier Hansson]
  • Deprecated ActionController::Base.fragment_cache_store for ActionController::Base.cache_store [David Heinemeier Hansson]
  • Made fragment caching in views work for rjs and builder as well 6642 [Dee Zsombor]
  • Fixed rendering of partials with layout when done from site layout 9209 [antramm]
  • Fix atom_feed_helper to comply with the atom spec. Closes 10672 [Xavier Shay]
    • The tags created do not contain a date (feedvalidator.org/docs/error/InvalidTAG.html)
    • IDs are not guaranteed unique
    • A default self link was not provided, contrary to the documentation
    • NOTE: This changes tags for existing atom entries, but at least they validate now.
  • Correct indentation in tests. Closes 10671 [Luca Guidi]
  • Fix that auto_link looks for =’s in url paths (Amazon urls have them). Closes 10640 [Brad Greenlee]
  • Ensure that test case setup is run even if overridden. 10382 [Josh Peek]
  • Fix HTML Sanitizer to allow trailing spaces in CSS style attributes. Closes 10566 [wesley.moxam]
  • Add :default option to time_zone_select. 10590 [Matt Aimonetti]

*2.0.2* (December 16th, 2007)

  • Added delete_via_redirect and put_via_redirect to integration testing 10497 [philodespotos]
  • Allow headers[‘Accept’] to be set by hand when calling xml_http_request 10461 [BMorearty]
  • Added OPTIONS to list of default accepted HTTP methods 10449 [holoway]
  • Added option to pass proc to ActionController::Base.asset_host for maximum configurability 10521 [Cheah Chu Yeow]. Example:
      ActionController::Base.asset_host = Proc.new { |source|
    if source.starts_with?('/images')
      "http://images.example.com"
    else
      "http://assets.example.com"
    end
  }
  • Fixed that ActionView#file_exists? would be incorrect if @first_render is set 10569 [dbussink]
  • Added that Array#to_param calls to_param on all it‘s elements 10473 [brandon]
  • Ensure asset cache directories are automatically created. 10337 [Josh Peek, Cheah Chu Yeow]
  • render :xml and :json preserve custom content types. 10388 [jmettraux, Cheah Chu Yeow]
  • Refactor Action View template handlers. 10437, 10455 [Josh Peek]
  • Fix DoubleRenderError message and leave out mention of returning false from filters. Closes 10380 [Frederick Cheung]
  • Clean up some cruft around ActionController::Base#head. Closes 10417 [ssoroka]

*2.0.1* (December 7th, 2007)

  • Fixed send_file/binary_content for testing 8044 [tolsen]
  • When a NonInferrableControllerError is raised, make the proposed fix clearer in the error message. Closes 10199 [Jack Danger Canty]
  • Update Prototype to 1.6.0.1. [sam]
  • Update script.aculo.us to 1.8.0.1. [madrobby]
  • Add ‘disabled’ attribute to <OPTION> separators used in time zone and country selects. Closes 10354 [Josh Susser]
  • Added the same record identification guessing rules to fields_for as form_for has [David Heinemeier Hansson]
  • Fixed that verification violations with no specified action didn‘t halt the chain (now they do with a 400 Bad Request) [David Heinemeier Hansson]
  • Raise UnknownHttpMethod exception for unknown HTTP methods. Closes 10303 [Tarmo Tänav]
  • Update to Prototype -r8232. [sam]
  • Make sure the optimisation code for routes doesn‘t get used if :host, :anchor or :port are provided in the hash arguments. [pager, Michael Koziarski] 10292
  • Added protection from trailing slashes on page caching 10229 [devrieda]
  • Asset timestamps are appended, not prepended. Closes 10276 [Mike Naberezny]
  • Minor inconsistency in description of render example. Closes 10029 [ScottSchram]
  • Add prepend_view_path and append_view_path instance methods on ActionController::Base for consistency with the class methods. [Rick Olson]
  • Refactor sanitizer helpers into HTML classes and make it easy to swap them out with custom implementations. Closes 10129. [Rick Olson]
  • Add deprecation for old subtemplate syntax for ActionMailer templates, use render :partial [Rick Olson]
  • Fix TemplateError so it doesn‘t bomb on exceptions while running tests [Rick Olson]
  • Fixed that named routes living under resources shouldn‘t have double slashes 10198 [Isaac Feliu]
  • Make sure that cookie sessions use a secret that is at least 30 chars in length. [Michael Koziarski]
  • Fixed that partial rendering should look at the type of the first render to determine its own type if no other clues are available (like when using text.plain.erb as the extension in AM) 10130 [java]
  • Fixed that has_many :through associations should render as collections too 9051 [mathie/Jack Danger Canty]
  • Added :mouseover short-cut to AssetTagHelper#image_tag for doing easy image swaps 6893 [joost]
  • Fixed handling of non-domain hosts 9479 [purp]
  • Fix syntax error in documentation example for cycle method. Closes 8735 [foca]
  • Document :with option for link_to_remote. Closes 8765 [Ryan Bates]
  • Document :minute_step option for time_select. Closes 8814 [brupm]
  • Explain how to use the :href option for link_to_remote to degrade gracefully in the absence of JavaScript. Closes 8911 [vlad]
  • Disambiguate :size option for text area tag. Closes 8955 [redbeard]
  • Fix broken tag in assert_tag documentation. Closes 9037 [mfazekas]
  • Add documentation for route conditions. Closes 9041 [innu, Manfred Stienstra]
  • Fix typo left over from previous typo fix in url helper. Closes 9414 [Henrik N]
  • Fixed that ActionController::CgiRequest#host_with_port() should handle standard port 10082 [moro]
  • Update Prototype to 1.6.0 and script.aculo.us to 1.8.0. [sam, madrobby]
  • Expose the cookie jar as a helper method (before the view would just get the raw cookie hash) [David Heinemeier Hansson]
  • Integration tests: get_ and post_via_redirect take a headers hash. 9130 [simonjefford]
  • Simplfy view_paths implementation. ActionView templates get the exact object, not a dup. [Rick Olson]
  • Update tests for ActiveSupport‘s JSON escaping change. [Rick Olson]
  • FormHelper‘s auto_index should use to_param instead of id_before_type_cast. Closes 9994 [mattly]
  • Doc typo fixes for ActiveRecordHelper. Closes 9973 [mikong]
  • Make example parameters in restful routing docs idiomatic. Closes 9993 [Jack Danger Canty]
  • Make documentation comment for mime responders match documentation example. Closes 9357 [yon]
  • Introduce a new test case class for functional tests. ActionController::TestCase. [Michael Koziarski]
  • Fix incorrect path in helper rdoc. Closes 9926 [viktor tron]
  • Partials also set ‘object’ to the default partial variable. 8823 [Nick Retallack, Jeremy Kemper]
  • Request profiler. [Jeremy Kemper]
      $ cat login_session.rb
  get_with_redirect '/'
  say "GET / => #{path}"
  post_with_redirect '/sessions', :username => 'john', :password => 'doe'
  say "POST /sessions => #{path}"
  $ ./script/performance/request -n 10 login_session.rb
  • Disabled checkboxes don‘t submit a form value. 9301 [vladr, robinjfisher]
  • Added tests for options to ActiveRecordHelper#form. Closes 7213 [richcollins, mikong, Mislav Marohnić]
  • Changed before_filter halting to happen automatically on render or redirect but no longer on simply returning false [David Heinemeier Hansson]
  • Ensure that cookies handle array values correctly. Closes 9937 [queso]
  • Make sure resource routes don‘t clash with internal helpers like javascript_path, image_path etc. 9928 [Geoff Buesing]
  • caches_page uses a single after_filter instead of one per action. 9891 [Pratik Naik]
  • Update Prototype to 1.6.0_rc1 and script.aculo.us to 1.8.0 preview 0. [sam, madrobby]
  • Dispatcher: fix that to_prepare should only run once in production. 9889 [Nathaniel Talbott]
  • Memcached sessions: add session data on initialization; don‘t silently discard exceptions; add unit tests. 9823 [kamk]
  • error_messages_for also takes :message and :header_message options which defaults to the old "There were problems with the following fields:" and "<count> errors prohibited this <object_name> from being saved". 8270 [rmm5t, zach-inglis-lt3]
  • Make sure that custom inflections are picked up by map.resources. 9815 [Mislav Marohnić]
  • Changed SanitizeHelper#sanitize to only allow the custom attributes and tags when specified in the call [David Heinemeier Hansson]
  • Extracted sanitization methods from TextHelper to SanitizeHelper [David Heinemeier Hansson]
  • rescue_from accepts :with => lambda { |exception| … } or a normal block. 9827 [Pratik Naik]
  • Add :status to redirect_to allowing users to choose their own response code without manually setting headers. 8297 [Coda Hale, chasgrundy]
  • Add link_to :back which uses your referrer with a fallback to a javascript link. 7366 [eventualbuddha, Tarmo Tänav]
  • error_messages_for and friends also work with local variables. 9699 [Frederick Cheung]
  • Fix url_for, redirect_to, etc. with :controller => :symbol instead of ‘string’. 8562, 9525 [Justin Lynn, Tarmo Tänav, shoe]
  • Use require_library_or_gem to load the memcache library for the MemCache session and fragment cache stores. Closes 8662. [Rick Olson]
  • Move ActionController::Routing.optimise_named_routes to ActionController::Base.optimise_named_routes. Now you can set it in the config. [Rick Olson]

    config.action_controller.optimise_named_routes = false

  • ActionController::Routing::DynamicSegment#interpolation_chunk should call to_s on all values before calling URI.escape. [Rick Olson]
  • Only accept session ids from cookies, prevents session fixation attacks. [bradediger]

*2.0.0 [Preview Release]* (September 29th, 2007) [Includes duplicates of changes from 1.12.2 - 1.13.3]

  • Fixed that render template did not honor exempt_from_layout 9698 [pezra]
  • Better error messages if you leave out the :secret option for request forgery protection. Closes 9670 [Rick Olson]
  • Allow ability to disable request forgery protection, disable it in test mode by default. Closes 9693 [Pratik Naik]
  • Avoid calling is_missing on LoadErrors. Closes 7460. [ntalbott]
  • Move Railties’ Dispatcher to ActionController::Dispatcher, introduce before_ and after_dispatch callbacks, and warm up to non-CGI requests. [Jeremy Kemper]
  • The tag helper may bypass escaping. [Jeremy Kemper]
  • Cache asset ids. [Jeremy Kemper]
  • Optimized named routes respect AbstractRequest.relative_url_root. 9612 [Daniel Morrison, Jeremy Kemper]
  • Introduce ActionController::Base.rescue_from to declare exception-handling methods. Cleaner style than the case-heavy rescue_action_in_public. 9449 [Norbert Crombach]
  • Rename some RequestForgeryProtection methods. The class method is now protect_from_forgery, and the default parameter is now ‘authenticity_token’. [Rick Olson]
  • Merge csrf_killer plugin into rails. Adds RequestForgeryProtection model that verifies session-specific _tokens for non-GET requests. [Rick Olson]
  • Secure sanitize, strip_tags, and strip_links helpers against xss attacks. Closes 8877. [Rick Olson, Pratik Naik, Jacques Distler]

    This merges and renames the popular white_list helper (along with some css sanitizing from Jacques Distler version of the same plugin). Also applied updated versions of strip_tags and strip_links from 8877.

  • Remove use of & logic operator. Closes 8114. [watson]
  • Fixed JavaScriptHelper#escape_javascript to also escape closing tags 8023 [Ruy Asan]
  • Fixed TextHelper#word_wrap for multiline strings with extra carrier returns 8663 [seth]
  • Fixed that setting the :host option in url_for would automatically turn off :only_path (since :host would otherwise not be shown) 9586 [Bounga]
  • Added FormHelper#label. 8641, 9850 [jcoglan, Jarkko Laine]
  • Added AtomFeedHelper (slightly improved from the atom_feed_helper plugin) [David Heinemeier Hansson]
  • Prevent errors when generating routes for uncountable resources, (i.e. sheep where plural == singluar). map.resources :sheep now creates sheep_index_url for the collection and sheep_url for the specific item. [Michael Koziarski]
  • Added support for HTTP Only cookies (works in IE6+ and FF 2.0.5+) as an improvement for XSS attacks 8895 [Pratik Naik, Mark Somerville]
  • Don‘t warn when a path segment precedes a required segment. Closes 9615. [Nicholas Seckar]
  • Fixed CaptureHelper#content_for to work with the optional content parameter instead of just the block 9434 [sandofsky/wildchild].
  • Added Mime::Type.register_alias for dealing with different formats using the same mime type [David Heinemeier Hansson]. Example:
      class PostsController < ApplicationController
    before_filter :adjust_format_for_iphone

    def index
      @posts = Post.find(:all)

      respond_to do |format|
        format.html   # => renders index.html.erb and uses "text/html" as the content type
        format.iphone # => renders index.iphone.erb and uses "text/html" as the content type
      end
    end

    private
      def adjust_format_for_iphone
        if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/iPhone/]
          request.format = :iphone
        end
      end
  end
  • Added that render :json will automatically call .to_json unless it‘s being passed a string [David Heinemeier Hansson].
  • Autolink behaves well with emails embedded in URLs. 7313 [Jeremy McAnally, Tarmo Tänav]
  • Fixed that default layouts did not take the format into account 9564 [Pratik Naik]
  • Fixed optimized route segment escaping. 9562 [wildchild, Jeremy Kemper]
  • Added block acceptance to JavaScriptHelper#javascript_tag. 7527 [Bob Silva, Tarmo Tänav, rmm5t]
  • root_path returns ’/’ not ’’. 9563 [Pratik Naik]
  • Fixed that setting request.format should also affect respond_to blocks [David Heinemeier Hansson]
  • Add option to force binary mode on tempfile used for fixture_file_upload. 6380 [Jonathan Viney]
  • Fixed that resource namespaces wouldn‘t stick to all nested resources 9399 [pixeltrix]
  • Moved ActionController::Macros::AutoComplete into the auto_complete plugin on the official Rails svn. 9512 [Pratik Naik]
  • Moved ActionController::Macros::InPlaceEditing into the in_place_editor plugin on the official Rails svn. 9513 [Pratik Naik]
  • Removed deprecated form of calling xml_http_request/xhr without the first argument being the http verb [David Heinemeier Hansson]
  • Removed deprecated methods [David Heinemeier Hansson]:
    • ActionController::Base#keep_flash (use flash.keep instead)
    • ActionController::Base#expire_matched_fragments (just call expire_fragment with a regular expression)
    • ActionController::Base.template_root/= methods (use ActionController#Base.view_paths/= instead)
    • ActionController::Base.cookie (use ActionController#Base.cookies[]= instead)
  • Removed the deprecated behavior of appending ".png" to image_tag/image_path calls without an existing extension [David Heinemeier Hansson]
  • Removed ActionController::Base.scaffold — it went through the whole idea of scaffolding (card board walls you remove and tweak one by one). Use the scaffold generator instead (it does resources too now!) [David Heinemeier Hansson]
  • Optimise named route generation when using positional arguments. [Michael Koziarski]

    This change delivers significant performance benefits for the most common usage scenarios for modern rails applications by avoiding the costly trip through url_for. Initial benchmarks indicate this is between 6 and 20 times as fast.

  • Explicitly require active_record/query_cache before using it. [Jeremy Kemper]
  • Fix layout overriding response status. 9476 [lotswholetime]
  • Add field_set_tag for generating field_sets, closes 9477. [Damian Janowski]
  • Allow additional parameters to be passed to named route helpers when using positional arguments. Closes 8930 [Ian White]
  • Make render :partial work with a :collection of Hashes, previously this wasn‘t possible due to backwards compatibility restrictions. [Pratik Naik]
  • request.host works with IPv6 addresses. 9458 [yuya]
  • Fix bug where action caching sets the content type to the ActionCachePath object. Closes 9282 [mindforge]
  • Find layouts even if they‘re not in the first view_paths directory. Closes 9258 [caio]
  • Major improvement to the documentation for the options / select form helpers. Closes 9038 [Chris Kampmeier, jardeon, wesg]
  • Fix number_to_human_size when using different precisions. Closes 7536. [RichardStrand, mpalmer]
  • Added partial layouts (see example in action_view/lib/partials.rb) [David Heinemeier Hansson]
  • Allow you to set custom :conditions on resource routes. [Rick Olson]
  • Fixed that file.content_type for uploaded files would include a trailing \r 9053 [Brad Greenlee]
  • url_for now accepts a series of symbols representing the namespace of the record [Josh Knowles]
  • Make :trailing_slash work with query parameters for url_for. Closes 4004 [nov]
  • Make sure missing template exceptions actually say which template they were looking for. Closes 8683 [dasil003]
  • Fix errors with around_filters which do not yield, restore 1.1 behaviour with after filters. Closes 8891 [Stefan Kaes]

    After filters will *no longer* be run if an around_filter fails to yield, users relying on this behaviour are advised to put the code in question after a yield statement in an around filter.

  • Allow you to delete cookies with options. Closes 3685 [Josh Peek, Chris Wanstrath]
  • Allow you to render views with periods in the name. Closes 8076 [Norbert Crombach]

    render :partial => ‘show.html.erb‘

  • Improve capture helper documentation. 8796 [Chris Kampmeier]
  • Prefix nested resource named routes with their action name, e.g. new_group_user_path(@group) instead of group_new_user_path(@group). The old nested action named route is deprecated in Rails 1.2.4. 8558 [David Chelimsky]
  • Allow sweepers to be created solely for expiring after controller actions, not model changes [David Heinemeier Hansson]
  • Added assigns method to ActionController::Caching::Sweeper to easily access instance variables on the controller [David Heinemeier Hansson]
  • Give the legacy X-POST_DATA_FORMAT header greater precedence during params parsing for backward compatibility. [Jeremy Kemper]
  • Fixed that link_to with an href of # when using :method will not allow for click-through without JavaScript 7037 [Steven Bristol, Josh Peek]
  • Fixed that radio_button_tag should generate unique ids 3353 [Bob Silva, Rebecca, Josh Peek]
  • Fixed that HTTP authentication should work if the header is called REDIRECT_X_HTTP_AUTHORIZATION as well 6754 [Mislav Marohnić]
  • Don‘t mistakenly interpret the request uri as the query string. 8731 [Pratik Naik, Jeremy Kemper]
  • Make ActionView#view_paths an attr_accessor for real this time. Also, don‘t perform an unnecessary compact on the @view_paths array in initialize. Closes 8582 [dasil003, julik, Rick Olson]
  • Tolerate missing content type on multipart file uploads. Fix for Safari 3. [Jeremy Kemper]
  • Deprecation: remove pagination. Install the classic_pagination plugin for forward compatibility, or move to the superior will_paginate plugin. 8157 [Josh Peek]
  • Action caching is limited to GET requests returning 200 OK status. 3335 [tom@craz8.com, halfbyte, Dan Kubb, Josh Peek]
  • Improve Text Helper test coverage. 7274 [Rob Sanheim, Josh Peek]
  • Improve helper test coverage. 7208, 7212, 7215, 7233, 7234, 7235, 7236, 7237, 7238, 7241, 7243, 7244 [Rich Collins, Josh Peek]
  • Improve UrlRewriter tests. 7207 [Rich Collins]
  • Resources: url_for([parent, child]) generates /parents/1/children/2 for the nested resource. Likewise with the other simply helpful methods like form_for and link_to. 6432 [mhw, Jonathan Vaught, lotswholetime]
  • Assume html format when rendering partials in RJS. 8076 [Rick Olson]
  • Don‘t double-escape url_for in views. 8144 [Rich Collins, Josh Peek]
  • Allow JSON-style values for the :with option of observe_field. Closes 8557 [kommen]
  • Remove RAILS_ROOT from backtrace paths. 8540 [Tim Pope]
  • Routing: map.resource :logo routes to LogosController so the controller may be reused for multiple nestings or namespaces. [Jeremy Kemper]
  • render :partial recognizes Active Record associations as Arrays. 8538 [Kamal Fariz Mahyuddin]
  • Routing: drop semicolon and comma as route separators. [Jeremy Kemper]
  • request.remote_ip understands X-Forwarded-For addresses with nonstandard whitespace. 7386 [moses]
  • Don‘t prepare response when rendering a component. 8493 [jsierles]
  • Reduce file stat calls when checking for template changes. 7736 [alex]
  • Added custom path cache_page/expire_page parameters in addition to the options hashes [David Heinemeier Hansson]. Example:
      def index
    caches_page(response.body, "/index.html")
  end
  • Action Caching speedup. 8231 [Stefan Kaes]
  • Wordsmith resources documentation. 8484 [marclove]
  • Fix syntax error in code example for routing documentation. 8377. [Norbert Crombach]
  • Routing: respond with 405 Method Not Allowed status when the route path matches but the HTTP method does not. 6953 [Josh Peek, defeated, Dan Kubb, Coda Hale]
  • Add support for assert_select_rjs with :show and :hide. 7780 [dchelimsky]
  • Make assert_select‘s failure messages clearer about what failed. 7779 [dchelimsky]
  • Introduce a default respond_to block for custom types. 8174 [Josh Peek]
  • auto_complete_field takes a :method option so you can GET or POST. 8120 [zapnap]
  • Added option to suppress :size when using :maxlength for FormTagHelper#text_field 3112 [Tim Pope]
  • catch possible WSOD when trying to render a missing partial. Closes 8454 [Jonathan del Strother]
  • Rewind request body after reading it, if possible. 8438 [s450r1]
  • Resource namespaces are inherited by their has_many subresources. 8280 [marclove, Geoff Garside]
  • Fix filtered parameter logging with nil parameter values. 8422 [choonkeat]
  • Integration tests: alias xhr to xml_http_request and add a request_method argument instead of always using POST. 7124 [Nik Wakelin, François Beausoleil, Wizard]
  • Document caches_action. 5419 [Jarkko Laine]
  • Update to Prototype 1.5.1. [Sam Stephenson]
  • Allow routes to be decalred under namespaces [Tobias Lütke]:

    map.namespace :admin do |admin|

      admin.root :controller => "products"
  admin.feed 'feed.xml', :controller => 'products', :action => 'feed', :format => 'xml'

    end

  • Update to script.aculo.us 1.7.1_beta3. [Thomas Fuchs]
  • observe_form always sends the serialized form. 5271 [Manfred Stienstra, normelton@gmail.com]
  • Parse url-encoded and multipart requests ourselves instead of delegating to CGI. [Jeremy Kemper]
  • select :include_blank option can be set to a string instead of true, which just uses an empty string. 7664 [Wizard]
  • Added url_for usage on render :location, which allows for record identification [David Heinemeier Hansson]. Example:
      render :xml => person, :status => :created, :location => person

    …expands the location to person_url(person).

  • Introduce the request.body stream. Lazy-read to parse parameters rather than always setting RAW_POST_DATA. Reduces the memory footprint of large binary PUT requests. [Jeremy Kemper]
  • Add some performance enhancements to ActionView.
    • Cache base_paths in @@cached_base_paths
    • Cache template extensions in @@cached_template_extension
    • Remove unnecessary rescues
  • Assume that rendered partials go by the HTML format by default

    def my_partial

      render :update do |page|
    # in this order
    # _foo.html.erb
    # _foo.erb
    # _foo.rhtml
    page.replace :foo, :partial => 'foo'
  end

    end

  • Added record identifications to FormHelper#form_for and PrototypeHelper#remote_form_for [David Heinemeier Hansson]. Examples:
      <% form_for(@post) do |f| %>
    ...
  <% end %>

    This will expand to be the same as:

      <% form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
    ...
  <% end %>

    And for new records:

      <% form_for(Post.new) do |f| %>
    ...
  <% end %>

    This will expand to be the same as:

      <% form_for :post, @post, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>
    ...
  <% end %>
  • Rationalize route path escaping according to RFC 2396 section 3.3. 7544, 8307. [Jeremy Kemper, Chris Roos, begemot, jugend]
  • Added record identification with polymorphic routes for ActionController::Base#url_for and ActionView::Base#url_for [David Heinemeier Hansson]. Examples:
      redirect_to(post)         # => redirect_to(posts_url(post))         => Location: http://example.com/posts/1
  link_to(post.title, post) # => link_to(post.title, posts_url(post)) => <a href="/posts/1">Hello world</a>

    Any method that calls url_for on its parameters will automatically benefit from this.

  • Removed deprecated parameters_for_method_reference concept (legacy from before named routes) [David Heinemeier Hansson]
  • Add ActionController::Routing::Helpers, a module to contain common URL helpers such as polymorphic_url. [Nicholas Seckar]
  • Included the HttpAuthentication plugin as part of core (ActionController::HttpAuthentication::Basic) [David Heinemeier Hansson]
  • Modernize documentation for form helpers. [Jeremy McAnally]
  • Add brief introduction to REST to the resources documentation. [fearoffish]
  • Fix various documentation typos throughout ActionPack. [Henrik N]
  • Enhance documentation and add examples for url_for. [Jeremy McAnally]
  • Fix documentation typo in routes. [Norbert Crombach, pam]
  • Sweep flash when filter chain is halted. [Caio Chassot <lists@v2studio.com>]
  • Fixed that content_tag with a block will just return the result instead of concate it if not used in a ERb view 7857, 7432 [michael.niessner]
  • Replace the current block/continuation filter chain handling by an implementation based on a simple loop. 8226 [Stefan Kaes]
  • Update UrlWriter to accept :anchor parameter. Closes 6771. [Chris McGrath]
  • Added RecordTagHelper for using RecordIdentifier conventions on divs and other container elements [David Heinemeier Hansson]. Example:
      <% div_for(post) do %>     <div id="post_45" class="post">
    <%= post.body %>           What a wonderful world!
  <% end %>                  </div>
  • Added page[record] accessor to JavaScriptGenerator that relies on RecordIdentifier to find the right dom id [David Heinemeier Hansson]. Example:
      format.js do
    # Calls: new Effect.fade('post_45');
    render(:update) { |page| page[post].visual_effect(:fade) }
  end
  • Added RecordIdentifier to enforce view conventions on records for dom ids, classes, and partial paths [David Heinemeier Hansson]
  • Added map.namespace to deal with the common situation of admin sections and the like [David Heinemeier Hansson]
      Before:

    map.resources :products, :path_prefix => "admin", :controller => "admin/products", :collection => { :inventory => :get }, :member => { :duplicate => :post }
    map.resources :tags, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_tags"
    map.resources :images, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_images"
    map.resources :variants, :name_prefix => 'admin_product_', :path_prefix => "admin/products/:product_id", :controller => "admin/product_variants"

  After:

    map.namespace(:admin) do |admin|
      admin.resources :products,
        :collection => { :inventory => :get },
        :member     => { :duplicate => :post },
        :has_many   => [ :tags, :images, :variants ]
    end
  • Added :name_prefix as standard for nested resources [David Heinemeier Hansson]. WARNING: May be backwards incompatible with your app
      Before:

    map.resources :emails do |emails|
      emails.resources :comments,    :name_prefix => "email_"
      emails.resources :attachments, :name_prefix => "email_"
    end

  After:

    map.resources :emails do |emails|
      emails.resources :comments
      emails.resources :attachments
    end

  This does mean that if you intended to have comments_url go to /emails/5/comments, then you'll have to set :name_prefix to nil explicitly.
  • Added :has_many and :has_one for declaring plural and singular resources beneath the current [David Heinemeier Hansson]
      Before:

    map.resources :notes do |notes|
      notes.resources :comments
      notes.resources :attachments
      notes.resource :author
    end

  After:

    map.resources :notes, :has_many => [ :comments, :attachments ], :has_one => :author
  • Added that render :xml will try to call to_xml if it can [David Heinemeier Hansson]. Makes these work:
      render :xml => post
  render :xml => comments
  • Added :location option to render so that the common pattern of rendering a response after creating a new resource is now a 1-liner [David Heinemeier Hansson]
      render :xml => post.to_xml, :status => :created, :location => post_url(post)
  • Ensure that render_text only adds string content to the body of the response [David Heinemeier Hansson]
  • Return the string representation from an Xml Builder when rendering a partial. Closes 5044 [Tim Pope]
  • Fixed that parameters from XML should also be presented in a hash with indifferent access [David Heinemeier Hansson]
  • Tweak template format rules so that the ACCEPT header is only used if it‘s text/javascript. This is so ajax actions without a :format param get recognized as Mime::JS. [Rick Olson]
  • The default respond_to blocks don‘t set a specific extension anymore, so that both ‘show.rjs’ and ‘show.js.rjs’ will work. [Rick Olson]
  • Allow layouts with extension of .html.erb. Closes 8032 [Josh Knowles]
  • Change default respond_to templates for xml and rjs formats. [Rick Olson]
    • Default xml template goes from #{action_name}.rxml => #{action_name}.xml.builder.
    • Default rjs template goes from #{action_name}.rjs => #{action_name}.js.rjs.

    You can still specify your old templates:

      respond_to do |format|
    format.xml do
      render :action => "#{action_name}.rxml"
    end
  end
  • Fix WSOD due to modification of a formatted template extension so that requests to templates like ‘foo.html.erb’ fail on the second hit. [Rick Olson]
  • Fix WSOD when template compilation fails [Rick Olson]
  • Change ActionView template defaults. Look for templates using the request format first, such as "show.html.erb" or "show.xml.builder", before looking for the old defaults like "show.erb" or "show.builder" [Rick Olson]
  • Highlight helper highlights one or many terms in a single pass. [Jeremy Kemper]
  • Dropped the use of ; as a separator of non-crud actions on resources and went back to the vanilla slash. It was a neat idea, but lots of the non-crud actions turned out not to be RPC (as the ; was primarily intended to discourage), but legitimate sub-resources, like /parties/recent, which didn‘t deserve the uglification of /parties;recent. Further more, the semicolon caused issues with caching and HTTP authentication in Safari. Just Not Worth It [David Heinemeier Hansson]
  • Added that FormTagHelper#submit_tag will return to its original state if the submit fails and you‘re using :disable_with [David Heinemeier Hansson]
  • Cleaned up, corrected, and mildly expanded ActionPack documentation. Closes 7190 [Jeremy McAnally]
  • Small collection of ActionController documentation cleanups. Closes 7319 [Jeremy McAnally]
  • Make sure the route expiry hash is constructed by comparing the to_param-ized values of each hash. [Jamis Buck]
  • Allow configuration of the default action cache path for caches_action calls. [Rick Olson]

    class ListsController < ApplicationController

      caches_action :index, :cache_path => Proc.new { |controller|
    controller.params[:user_id] ?
      controller.send(:user_lists_url, c.params[:user_id]) :
      controller.send(:lists_url) }

    end

  • Performance: patch cgi/session/pstore to require digest/md5 once rather than per initialize. 7583 [Stefan Kaes]
  • Cookie session store: ensure that new sessions doesn‘t reuse data from a deleted session in the same request. [Jeremy Kemper]
  • Deprecation: verification with :redirect_to => :named_route shouldn‘t be deprecated. 7525 [Justin French]
  • Cookie session store: raise ArgumentError when :session_key is blank. [Jeremy Kemper]
  • Deprecation: remove deprecated request, redirect, and dependency methods. Remove deprecated instance variables. Remove deprecated url_for(:symbol, *args) and redirect_to(:symbol, *args) in favor of named routes. Remove uses_component_template_root for toplevel components directory. Privatize deprecated render_partial and render_partial_collection view methods. Remove deprecated link_to_image, link_image_to, update_element_function, start_form_tag, and end_form_tag helper methods. Remove deprecated human_size helper alias. [Jeremy Kemper]
  • Consistent public/protected/private visibility for chained methods. 7813 [Dan Manges]
  • Prefer MIME constants to strings. 7707 [Dan Kubb]
  • Allow array and hash query parameters. Array route parameters are converted/to/a/path as before. 6765, 7047, 7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan]

# Add a dbman attr_reader for CGI::Session and make CGI::Session::CookieStore#generate_digest public so it‘s easy to generate digests using the cookie store‘s secret. [Rick Olson]

  • Added Request#url that returns the complete URL used for the request [David Heinemeier Hansson]
  • Extract dynamic scaffolding into a plugin. 7700 [Josh Peek]
  • Added user/password options for url_for to add http authentication in a URL [David Heinemeier Hansson]
  • Fixed that FormTagHelper#text_area_tag should disregard :size option if it‘s not a string [Brendon Davidson]
  • Set the original button value in an attribute of the button when using the :disable_with key with submit_tag, so that the original can be restored later. [Jamis Buck]
  • session_enabled? works with session :off. 6680 [Jonathan del Strother]
  • Added :port and :host handling to UrlRewriter (which unified url_for usage, regardless of whether it‘s called in view or controller) 7616 [alancfrancis]
  • Allow send_file/send_data to use a registered mime type as the :type parameter 7620 [jonathan]
  • Allow routing requirements on map.resource(s) 7633 [quixoten]. Example:

    map.resources :network_interfaces, :requirements => { :id => /^\d+\.\d+\.\d+\.\d+$/ }

  • Cookie session store: empty and unchanged sessions don‘t write a cookie. [Jeremy Kemper]
  • Added helper(:all) as a way to include all helpers from app/helpers/**/*.rb in ApplicationController [David Heinemeier Hansson]
  • Integration tests: introduce methods for other HTTP methods. 6353 [caboose]
  • Routing: better support for escaped values in route segments. 7544 [Chris

Roos]

  • Introduce a cookie-based session store as the Rails default. Sessions typically contain at most a user_id and flash message; both fit within the 4K cookie size limit. A secure message digest is included with the cookie to ensure data integrity (a user cannot alter his user_id without knowing the secret key included in the digest). If you have more than 4K of session data or don‘t want your data to be visible to the user, pick another session store. Cookie-based sessions are dramatically faster than the alternatives. [Jeremy Kemper]

    Example config/environment.rb:

      # Use an application-wide secret key and the default SHA1 message digest.
  config.action_controller.session = { :secret => "can't touch this" }

  # Store a secret key per user and employ a stronger message digest.
  config.action_controller.session = {
    :digest => 'SHA512',
    :secret => Proc.new { User.current.secret_key }
  }
  • Added .erb and .builder as preferred aliases to the now deprecated .rhtml and .rxml extensions [Chad Fowler]. This is done to separate the renderer from the mime type. .erb templates are often used to render emails, atom, csv, whatever. So labeling them .rhtml doesn‘t make too much sense. The same goes for .rxml, which can be used to build everything from HTML to Atom to whatever. .rhtml and .rxml will continue to work until Rails 3.0, though. So this is a slow phasing out. All generators and examples will start using the new aliases, though.
  • Added caching option to AssetTagHelper#stylesheet_link_tag and AssetTagHelper#javascript_include_tag [David Heinemeier Hansson]. Examples:
      stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is false =>
    <link href="/stylesheets/style1.css"  media="screen" rel="Stylesheet" type="text/css" />
    <link href="/stylesheets/styleB.css"  media="screen" rel="Stylesheet" type="text/css" />
    <link href="/stylesheets/styleX2.css" media="screen" rel="Stylesheet" type="text/css" />

  stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is true =>
    <link href="/stylesheets/all.css"  media="screen" rel="Stylesheet" type="text/css" />

    …when caching is on, all.css is the concatenation of style1.css, styleB.css, and styleX2.css. Same deal for JavaScripts.

  • Work around the two connection per host browser limit: use asset%d.myapp.com to distribute asset requests among asset[0123].myapp.com. Use a DNS wildcard or CNAMEs to map these hosts to your asset server. See www.die.net/musings/page_load_time/ for background. [Jeremy Kemper]
  • Added default mime type for CSS (Mime::CSS) [David Heinemeier Hansson]
  • Added that rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. [David Heinemeier Hansson]
  • Added X-Runtime to all responses with the request run time [David Heinemeier Hansson]
  • Add Mime::Type convenience methods to check the current mime type. [Rick Olson]

    request.format.html? # => true if Mime::HTML request.format.jpg? # => true if Mime::JPG

    # ActionController sample usage: # the session will be disabled for non html/ajax requests session :off, :if => Proc.new { |req| !(req.format.html? || req.format.js?) }

  • Performance: patch cgi/session to require digest/md5 once rather than per create_new_id. [Stefan Kaes]
  • Add a :url_based_filename => true option to ActionController::Streaming::send_file, which allows URL-based filenames. [Thomas Fuchs]
  • Fix that FormTagHelper#submit_tag using :disable_with should trigger the onsubmit handler of its form if available [David Heinemeier Hansson]
  • Fix render_file so that TemplateError is called with the correct params and you don‘t get the WSOD. [Rick Olson]
  • Fix issue with deprecation messing up template_root= usage. Add prepend_view_path and append_view_path to allow modification of a copy of the

superclass’ view_paths. [Rick Olson]

  • Allow Controllers to have multiple view_paths instead of a single template_root. Closes 2754 [John Long]
  • Add much-needed html-scanner tests. Fixed CDATA parsing bug. [Rick Olson]
  • improve error message for Routing for named routes. Closes 7346 [Rob Sanheim]
  • Added enhanced docs to routing assertions. Closes 7359 [Rob Sanheim]
  • fix form_for example in ActionController::Resources documentation. Closes 7362 [gnarg]
  • Make sure that the string returned by TextHelper#truncate is actually a string, not a char proxy — that should only be used internally while working on a multibyte-safe way of truncating [David Heinemeier Hansson]
  • Added FormBuilder#submit as a delegate for FormTagHelper#submit_tag [David Heinemeier Hansson]
  • Allow Routes to generate all urls for a set of options by specifying :generate_all => true. Allows caching to properly set or expire all paths for a resource. References 1739. [Nicholas Seckar]
  • Change the query parser to map empty GET params to "" rather than nil. Closes 5694. [Nicholas Seckar]
  • date_select and datetime_select take a :default option. 7052 [Nik Wakelin]
      date_select "post", "written_on", :default => 3.days.from_now
  date_select "credit_card", "bill_due", :default => { :day => 20 }
  • select :multiple => true suffixes the attribute name with [] unless already suffixed. 6977 [nik.kakelin, ben, julik]
  • Improve routes documentation. 7095 [zackchandler]
  • mail_to :encode => ‘hex’ also encodes the mailto: part of the href attribute as well as the linked email when no name is given. 2061 [Jarkko Laine, pfc.pille@gmx.net]
  • Resource member routes require :id, eliminating the ambiguous overlap with collection routes. 7229 [dkubb]
  • Remove deprecated assertions. [Jeremy Kemper]
  • Change session restoration to allow namespaced models to be autoloaded. Closes 6348. [Nicholas Seckar]
  • Fix doubly appearing parameters due to string and symbol mixups. Closes 2551. [Anthony Eden]
  • Fix overly greedy rescues when loading helpers. Fixes 6268. [Nicholas Seckar]
  • Fixed NumberHelper#number_with_delimiter to use "." always for splitting the original number, not the delimiter parameter 7389 [ceefour]
  • Autolinking recognizes trailing and embedded . , : ; 7354 [Jarkko Laine]
  • Make TextHelper::auto_link recognize URLs with colons in path correctly, fixes 7268. [imajes]
  • Update to script.aculo.us 1.7.0. [Thomas Fuchs]
  • Modernize cookie testing code, and increase coverage (Heckle++) 7101 [Kevin Clark]
  • Improve Test Coverage for ActionController::Routing::Route#matches_controller_and_action? (Heckle++) 7115 [Kevin Clark]
  • Heckling ActionController::Resources::Resource revealed that set_prefixes didn‘t break when :name_prefix was munged. 7081 [Kevin Clark]
  • Fix distance_of_time_in_words to report accurately against the Duration class. 7114 [eventualbuddha]
  • Refactor form_tag to allow easy extending. [Rick Olson]
  • Update to Prototype 1.5.0. [Sam Stephenson]
  • RecordInvalid, RecordNotSaved => 422 Unprocessable Entity, StaleObjectError => 409 Conflict. 7097 [dkubb]
  • Allow fields_for to be nested inside form_for, so that the name and id get properly constructed [Jamis Buck]
  • Allow inGroupsOf and eachSlice to be called through rjs. 7046 [Cody Fauser]
  • Allow exempt_from_layout :rhtml. 6742, 7026 [Dan Manges, Squeegy]
  • Recognize the .txt extension as Mime::TEXT [Rick Olson]
  • Fix parsing of array[] CGI parameters so extra empty values aren‘t included. 6252 [Nicholas Seckar, aiwilliams, brentrowland]
  • link_to_unless_current works with full URLs as well as paths. 6891 [Jarkko Laine, Manfred Stienstra, idrifter]
  • Lookup the mime type for auto_discovery_link_tag in the Mime::Type class. Closes 6941 [Josh Peek]
  • Fix bug where nested resources ignore a parent singleton parent‘s path prefix. Closes 6940 [Dan Kubb]
  • Fix no method error with error_messages_on. Closes 6935 [nik.wakelin Koz]
  • Slight doc tweak to the ActionView::Helpers::PrototypeHelper#replace docs. Closes 6922 [Steven Bristol]
  • Slight doc tweak to prepend_filter. Closes 6493 [Jeremy Voorhis]
  • Add more extensive documentation to the AssetTagHelper. Closes 6452 [Bob Silva]
  • Clean up multiple calls to stringify_keys in TagHelper, add better documentation and testing for TagHelper. Closes 6394 [Bob Silva]
  • [DOCS] fix reference to ActionController::Macros::AutoComplete for text_field_with_auto_complete. Closes 2578 [Jan Prill]
  • Make sure html_document is reset between integration test requests. [ctm]
  • Set session to an empty hash if :new_session => false and no session cookie or param is present. CGI::Session was raising an unrescued ArgumentError. [Josh Susser]
  • Routing uses URI escaping for path components and CGI escaping for query parameters. [darix, Jeremy Kemper]
  • Fix assert_redirected_to bug where redirecting from a nested to to a top-level controller incorrectly added the current controller‘s nesting. Closes 6128. [Rick Olson]
  • Singleton resources: POST /singleton => create, GET /singleton/new => new. [Jeremy Kemper]
  • Use 400 Bad Request status for unrescued ActiveRecord::RecordInvalid exceptions. [Jeremy Kemper]
  • Silence log_error deprecation warnings from inspecting deprecated instance variables. [Nate Wiger]
  • Only cache GET requests with a 200 OK response. 6514, 6743 [RSL, anamba]
  • Add a ‘referer’ attribute to TestRequest. [Jamis Buck]
  • Ensure render :json => … skips the layout. Closes 6808 [Josh Peek]
  • Fix HTML::Node to output double quotes instead of single quotes. Closes 6845 [mitreandy]
  • Correctly report which filter halted the chain. 6699 [Martin Emde]
  • Fix a bug in Routing where a parameter taken from the path of the current request could not be used as a query parameter for the next. Closes 6752. [Nicholas Seckar]
  • Unrescued ActiveRecord::RecordNotFound responds with 404 instead of 500. [Jeremy Kemper]
  • Improved auto_link to match more valid urls correctly [Tobias Lütke]
  • Add singleton resources. [Rick Olson]

    map.resource :account

    GET /account GET /account;edit UPDATE /account DELETE /account

  • respond_to recognizes JSON. render :json => @person.to_json automatically sets the content type and takes a :callback option to specify a client-side function to call using the rendered JSON as an argument. 4185 [Scott Raymond, eventualbuddha]
      # application/json response with body 'Element.show({:name: "David"})'
  respond_to do |format|
    format.json { render :json => { :name => "David" }.to_json, :callback => 'Element.show' }
  end
  • Makes :discard_year work without breaking multi-attribute parsing in AR. 1260, 3800 [sean@ardismg.com, jmartin@desertflood.com, stephen@touset.org, Bob Silva]
  • Adds html id attribute to date helper elements. 1050, 1382 [mortonda@dgrmm.net, David North, Bob Silva]
  • Add :index and @auto_index capability to model driven date/time selects. 847, 2655 [moriq, Doug Fales, Bob Silva]
  • Add :order to datetime_select, select_datetime, and select_date. 1427 [Timothee Peignier, Patrick Lenz, Bob Silva]
  • Added time_select to work with time values in models. Update scaffolding. 2489, 2833 [Justin Palmer, Andre Caum, Bob Silva]
  • Added :include_seconds to select_datetime, datetime_select and time_select. 2998 [csn, Bob Silva]
  • All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. 363 [tomasj, Bob Silva]
  • Adds :time_separator to select_time and :date_separator to select_datetime. Preserves BC. 3811 [Bob Silva]
  • Added map.root as an alias for map.connect ’’ [David Heinemeier Hansson]
  • Added Request#format to return the format used for the request as a mime type. If no format is specified, the first Request#accepts type is used. This means you can stop using respond_to for anything else than responses [David Heinemeier Hansson]. Examples:
      GET /posts/5.xml   | request.format => Mime::XML
  GET /posts/5.xhtml | request.format => Mime::HTML
  GET /posts/5       | request.format => request.accepts.first (usually Mime::HTML for browsers)
  • Added the option for extension aliases to mime type registration [David Heinemeier Hansson]. Example (already in the default routes):
      Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )

    …will respond on both .html and .xhtml.

  • @response.redirect_url works with 201 Created responses: just return headers[‘Location’] rather than checking the response status. [Jeremy Kemper]
  • Added CSV to Mime::SET so that respond_to csv will work [Cody Fauser]
  • Fixed that HEAD should return the proper Content-Length header (that is, actually use @body.size, not just 0) [David Heinemeier Hansson]
  • Added GET-masquarading for HEAD, so request.method will return :get even for HEADs. This will help anyone relying on case request.method to automatically work with HEAD and map.resources will also allow HEADs to all GET actions. Rails automatically throws away the response content in a reply to HEAD, so you don‘t even need to worry about that. If you, for whatever reason, still need to distinguish between GET and HEAD in some edge case, you can use Request#head? and even Request.headers["REQUEST_METHOD"] for get the "real" answer. Closes 6694 [David Heinemeier Hansson]
  • Update Routing to complain when :controller is not specified by a route. Closes 6669. [Nicholas Seckar]
  • Ensure render_to_string cleans up after itself when an exception is raised. 6658 [Rob Sanheim]
  • Extract template_changed_since? from compile_template? so plugins may override its behavior for non-file-based templates. 6651 [Jeff Barczewski]
  • Update to Prototype and script.aculo.us [5579]. [Thomas Fuchs]
  • simple_format helper doesn‘t choke on nil. 6644 [jerry426]
  • Update to Prototype 1.5.0_rc2 [5550] which makes it work in Opera again [Thomas Fuchs]
  • Reuse named route helper module between Routing reloads. Use remove_method to delete named route methods after each load. Since the module is never collected, this fixes a significant memory leak. [Nicholas Seckar]
  • ActionView::Base.erb_variable accessor names the buffer variable used to render templates. Defaults to _erbout; use _buf for erubis. [Rick Olson]
  • assert_select_rjs :remove. [Dylan Egan]
  • Always clear model associations from session. 4795 [sd@notso.net, andylien@gmail.com]
  • Update to Prototype 1.5.0_rc2. [Sam Stephenson]
  • Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. [Sam Stephenson]
  • Sync ActionController::StatusCodes::STATUS_CODES with www.iana.org/assignments/http-status-codes. 6586 [dkubb]
  • Multipart form values may have a content type without being treated as uploaded files if they do not provide a filename. 6401 [Andreas Schwarz, Jeremy Kemper]
  • assert_response supports symbolic status codes. 6569 [Kevin Clark]
      assert_response :ok
  assert_response :not_found
  assert_response :forbidden
  • Cache parsed query parameters. 6559 [Stefan Kaes]
  • Deprecate JavaScriptHelper#update_element_function, which is superseeded by RJS [Thomas Fuchs]
  • pluralize helper interprets nil as zero. 6474 [Tim Pope]
  • Fix invalid test fixture exposed by stricter Ruby 1.8.5 multipart parsing. 6524 [Bob Silva]
  • Set ActionView::Base.default_form_builder once rather than passing the :builder option to every form or overriding the form helper methods. [Jeremy Kemper]
  • Deprecate expire_matched_fragments. Use expire_fragment instead. 6535 [Bob Silva]
  • Update to latest Prototype, which doesn‘t serialize disabled form elements, adds clone() to arrays, empty/non-string Element.update() and adds a fixes excessive error reporting in WebKit beta versions [Thomas Fuchs]
  • Deprecate start_form_tag and end_form_tag. Use form_tag / ’</form>’ from now on. [Rick Olson]
  • Added block-usage to PrototypeHelper#form_remote_tag, document block-usage of FormTagHelper#form_tag [Rick Olson]
  • Add a 0 margin/padding div around the hidden _method input tag that form_tag outputs. [Rick Olson]
  • Added block-usage to TagHelper#content_tag [David Heinemeier Hansson]. Example:
     <% content_tag :div, :class => "strong" %>
   Hello world!
 <% end %>

    Will output:

      <div class="strong">Hello world!</div>
  • Deprecated UrlHelper#link_to_image and UrlHelper#link_to :post => true 6409 [Bob Silva]
  • Upgraded NumberHelper with number_to_phone support international formats to comply with ITU E.123 by supporting area codes with less than 3 digits, added precision argument to number_to_human_size (defaults to 1) 6421 [Bob Silva]
  • Fixed that setting RAILS_ASSET_ID to "" should not add a trailing slash after assets 6454 [Bob Silva/chrismear]
  • Force *_url named routes to show the host in ActionView [Rick Olson]

    <%= url_for … %> # no host <%= foo_path %> # no host <%= foo_url %> # host!

  • Add support for converting blocks into function arguments to JavaScriptGenerator#call and JavaScriptProxy#call. [Sam Stephenson]
  • Add JavaScriptGenerator#literal for wrapping a string in an object whose to_json is the string itself. [Sam Stephenson]
  • Add <%= escape_once html %> to escape html while leaving any currently escaped entities alone. Fix button_to double-escaping issue. [Rick Olson]
  • Fix double-escaped entities, such as &amp;amp;, &amp;123;, etc. [Rick Olson]
  • Fix deprecation warnings when rendering the template error template. [Nicholas Seckar]
  • Fix routing to correctly determine when generation fails. Closes 6300. [psross].
  • Fix broken assert_generates when extra keys are being checked. [Jamis Buck]
  • Replace KCODE checks with String#chars for truncate. Closes 6385 [Manfred Stienstra]
  • Make page caching respect the format of the resource that is being requested even if the current route is the default route so that, e.g. posts.rss is not transformed by url_for to ’/’ and subsequently cached as ’/index.html’ when it should be cached as ’/posts.rss’. [Marcel Molina Jr.]
  • Use String#chars in TextHelper::excerpt. Closes 6386 [Manfred Stienstra]
  • Install named routes into ActionView::Base instead of proxying them to the view via helper_method. Closes 5932. [Nicholas Seckar]
  • Update to latest Prototype and script.aculo.us trunk versions [Thomas Fuchs]
  • Fix relative URL root matching problems. [Mark Imbriaco]
  • Fix filter skipping in controller subclasses. 5949, 6297, 6299 [Martin Emde]
  • render_text may optionally append to the response body. render_javascript appends by default. This allows you to chain multiple render :update calls by setting @performed_render = false between them (awaiting a better public API). [Jeremy Kemper]
  • Rename test assertion to prevent shadowing. Closes 6306. [psross]
  • Fixed that NumberHelper#number_to_delimiter should respect precision of higher than two digits 6231 [Philip Hallstrom]
  • Fixed that FormHelper#radio_button didn‘t respect an :id being passed in 6266 [evansj]
  • Added an html_options hash parameter to javascript_tag() and update_page_tag() helpers 6311 [tzaharia]. Example:
      update_page_tag :defer => 'true' { |page| ... }

    Gives:

      <script defer="true" type="text/javascript">...</script>

    Which is needed for dealing with the IE6 DOM when it‘s not yet fully loaded.

  • Fixed that rescue template path shouldn‘t be hardcoded, then it‘s easier to hook in your own 6295 [Mike Naberezny]
  • Fixed escaping of backslashes in JavaScriptHelper#escape_javascript 6302 [sven@c3d2.de]
  • Fixed that some 500 rescues would cause 500‘s themselves because the response had not yet been generated 6329 [cmselmer]
  • respond_to :html doesn‘t assume .rhtml. 6281 [Hampton Catlin]
  • Fixed some deprecation warnings in ActionPack [Rick Olson]
  • assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. 6240 [japgolly]
  • Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. [Jeremy Kemper]
  • Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples:
      head :status => 404        # expands to "404 Not Found"
  head :status => :not_found # expands to "404 Not Found"
  head :status => :created   # expands to "201 Created"
  • Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples:
      head :status => 404 # return an empty response with a 404 status
  head :location => person_path(@person), :status => 201
  • Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. [Rick Olson]
  • strip_links is case-insensitive. 6285 [tagoh, Bob Silva]
  • Clear the cache of possible controllers whenever Routes are reloaded. [Nicholas Seckar]
  • Filters overhaul including meantime filter support using around filters + blocks. 5949 [Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper]
  • Update RJS render tests. [sam]
  • Update CGI process to allow sessions to contain namespaced models. Closes 4638. [dfelstead@site5.com]
  • Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => ‘index’). Closes 5950. [Nicholas Seckar]
  • Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. 3368, 6226 [sdsykes, fhanshaw@vesaria.com]
  • Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples:
      respond_to do |format|
    format.html { render :text => "I'm being sent as text/html" }
    format.rss  { render :text => "I'm being sent as application/rss+xml" }
    format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML }
  end
  • Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) [David Heinemeier Hansson]
  • Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do:
      response.headers["Content-Type"] = "application/atom+xml; charset=utf-8"

    …now:

      response.content_type = Mime::ATOM
  response.charset      = "utf-8"
  • Updated prototype.js to 1.5.0_rc1 with latest fixes. [Rick Olson]
    • XPATH support
    • Make Form.getElements() return elements in the correct order
    • fix broken Form.serialize return
  • Declare file extensions exempt from layouts. 6219 [brandon]
      Example: ActionController::Base.exempt_from_layout 'rpdf'
  • Add chained replace/update support for assert_select_rjs [Rick Olson]
      Given RJS like...

    page['test1'].replace "<div id=\"1\">foo</div>"
    page['test2'].replace_html "<div id=\"2\">foo</div>"

  Test it with...

    assert_select_rjs :chained_replace
    assert_select_rjs :chained_replace, "test1"

    assert_select_rjs :chained_replace_html
    assert_select_rjs :chained_replace_html, "test2"
  • Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. 6132, 6178 [choonkeat@gmail.com]
  • Skip params with empty names, such as the &=Save query string from <input type="submit"/>. 2569 [Manfred Stienstra, raphinou@yahoo.com]
  • Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. 2799 [Eric Hodel]
  • Add descriptive messages to the exceptions thrown by cgi_methods. 6091, 6103 [Nicholas Seckar, Bob Silva]
  • Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, 6068 [petermichaux@gmail.com]
  • Update UrlWriter to support :only_path. [Nicholas Seckar, Dave Thomas]
  • Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this:
      link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide }

    …can be written like this:

      link_to("Hider", :class => "hider_link") { |p| p[:something].hide }
  • Update to script.aculo.us 1.6.3 [Thomas Fuchs]
  • Update to Prototype 1.5.0_rc1 [sam]
  • Added access to nested attributes in RJS 4548 [richcollins@gmail.com]. Examples:
      page['foo']['style']                  # => $('foo').style;
  page['foo']['style']['color']         # => $('blank_slate').style.color;
  page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red';
  page['foo']['style'].color = 'red'    # => $('blank_slate').style.color = 'red';
  • Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes 5102) [eule@space.ch]
  • Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn‘t have an extension [David Heinemeier Hansson]
  • Fixed FormOptionsHelper#select to respect :selected value 5813
  • Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph 5835 [moriq@moriq.com]
  • Fixed TextHelper#pluralize to handle 1 as a string 5909 [rails@bencurtis.com]
  • Improved resolution of DateHelper#distance_of_time_in_words for better precision 5994 [Bob Silva]
  • Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" [David Heinemeier Hansson]
  • Integration tests: thoroughly test ActionController::Integration::Session. 6022 [Kevin Clark]
      (tests skipped unless you `gem install mocha`)
  • Added deprecation language for pagination which will become a plugin by Rails 2.0 [David Heinemeier Hansson]
  • Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 [David Heinemeier Hansson]
  • Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support [David Heinemeier Hansson]
  • Added assert_select* for CSS selector-based testing (deprecates assert_tag) 5936 [assaf.arkin@gmail.com]
  • radio_button_tag generates unique id attributes. 3353 [Bob Silva, somekool@gmail.com]
  • strip_tags passes through blank args such as nil or "". 2229, 6702 [duncan@whomwah.com, dharana]
  • Cleanup assert_tag :children counting. 2181 [jamie@bravenet.com]
  • button_to accepts :method so you can PUT and DELETE with it. 6005 [Dan Webb]
  • Update sanitize text helper to strip plaintext tags, and <img src="javascript:bang">. [Rick Olson]
  • Update routing documentation. Closes 6017 [Nathan Witmer]
  • Add routing tests to assert that RoutingError is raised when conditions aren‘t met. Closes 6016 [Nathan Witmer]
  • Deprecation: update docs. 5998 [Jakob Skjerning, Kevin Clark]
  • Make auto_link parse a greater subset of valid url formats. [Jamis Buck]
  • Integration tests: headers beginning with X aren‘t excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. [Mike Clark]
  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Fix send_data documentation typo. 5982 [brad@madriska.com]
  • Switch to using FormEncodedPairParser for parsing request parameters. [Nicholas Seckar, David Heinemeier Hansson]
  • respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. [Tobias Lütke]
  • Deprecation: test deprecated instance vars in partials. [Jeremy Kemper]
  • Add UrlWriter to allow writing urls from Mailers and scripts. [Nicholas Seckar]
  • Clean up and run the Active Record integration tests by default. 5854 [Kevin Clark, Jeremy Kemper]
  • Correct example in cookies docs. 5832 [jessemerriman@warpmail.net]
  • Updated to script.aculo.us 1.6.2 [Thomas Fuchs]
  • Relax Routing‘s anchor pattern warning; it was preventing use of [^/] inside restrictions. [Nicholas Seckar]
  • Add controller_paths variable to Routing. [Nicholas Seckar]
  • Fix assert_redirected_to issue with named routes for module controllers. [Rick Olson]
  • Tweak RoutingError message to show option diffs, not just missing named route significant keys. [Rick Olson]
  • Invoke method_missing directly on hidden actions. Closes 3030. [Nicholas Seckar]
  • Require Tempfile explicitly for TestUploadedFile due to changes in class auto loading. [Rick Olson]
  • Add RoutingError exception when RouteSet fails to generate a path from a Named Route. [Rick Olson]
  • Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
  • Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. [Jeremy Kemper]
  • Add support for the param_name parameter to the auto_complete_field helper. 5026 [david.a.williams@gmail.com]
  • Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You‘ll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. [Jeremy Kemper]
  • Make Routing noisy when an anchor regexp is assigned to a segment. 5674 [François Beausoleil]
  • Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" 5611 [pjhyett@gmail.com]
  • Short documentation to mention use of Mime::Type.register. 5710 [choonkeat@gmail.com]
  • Make controller_path available as an instance method. 5724 [jmckible@gmail.com]
  • Update query parser to support adjacent hashes. [Nicholas Seckar]
  • Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn‘t on the webserver. [Marcel Molina Jr.]
  • Restrict Request Method hacking with ?_method to POST requests. [Rick Olson]
  • Fix bug when passing multiple options to SimplyRestful, like :new => { :preview => :get, :draft => :get }. [Rick Olson, Josh Susser, Lars Pind]
  • Dup the options passed to map.resources so that multiple resources get the same options. [Rick Olson]
  • Fixed the new_#{resource}_url route and added named route tests for Simply Restful. [Rick Olson]
  • Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!):
      map.resources :messages
  map.resources :messages, :comments
  map.resources :messages, :new => { :preview => :post }
  • Fixed that integration simulation of XHRs should set Accept header as well [Edward Frederick]
  • TestRequest#reset_session should restore a TestSession, not a hash [Michael Koziarski]
  • Don‘t search a load-path of ’.’ for controller files [Jamis Buck]
  • Update integration.rb to require test_process explicitly instead of via Dependencies. [Nicholas Seckar]
  • Fixed that you can still access the flash after the flash has been reset in reset_session. Closes 5584 [lmarlow]
  • Allow form_for and fields_for to work with indexed form inputs. [Jeremy Kemper, Matt Lyon]

    <% form_for ‘post[]’, @post do |f| -%> <% end -%>

  • Remove leak in development mode by replacing define_method with module_eval. [Nicholas Seckar]
  • Provide support for decimal columns to form helpers. Closes 5672. [Dave Thomas]
  • Update documentation for erb trim syntax. 5651 [matt@mattmargolis.net]
  • Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. 3586 [olivier_ansaldi@yahoo.com, sebastien@goetzilla.info]
  • Reset @html_document between requests so assert_tag works. 4810 [Jarkko Laine, easleydp@gmail.com]
  • Update render :partial documentation. 5646 [matt@mattmargolis.net]
  • Integration tests behave well with render_component. 4632 [edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com]
  • Added exception handling of missing layouts 5373 [chris@ozmm.org]
  • Fixed that real files and symlinks should be treated the same when compiling templates 5438 [zachary@panandscan.com]
  • Fixed that the flash should be reset when reset_session is called 5584 [Shugo Maeda]
  • Added special case for "1 Byte" in NumberHelper#number_to_human_size 5593 [murpyh@rubychan.de]
  • Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) [David Heinemeier Hansson]
  • Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. [Nicholas Seckar]
  • Avoid naming collision among compiled view methods. [Jeremy Kemper]
  • Fix CGI extensions when they expect string but get nil in Windows. Closes 5276 [Mislav Marohnić]
  • Determine the correct template_root for deeply nested components. 2841 [s.brink@web.de]
  • Fix that routes with *path segments in the recall can generate URLs. [Rick Olson]
  • Fix strip_links so that it doesn‘t hang on multiline <acronym> tags [Jamis Buck]
  • Remove problematic control chars in rescue template. 5316 [Stefan Kaes]
  • Make sure passed routing options are not mutated by routing code. 5314 [Blair Zajac]
  • Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. [Jamis Buck]
  • Escape the path before routing recognition. 3671
  • Make sure :id and friends are unescaped properly. 5275 [me@julik.nl]
  • Fix documentation for with_routing to reflect new reality. 5281 [rramdas@gmail.com]
  • Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). 210 [mklame@atxeu.com, matthew@walker.wattle.id.au]
  • Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types [David Heinemeier Hansson]
  • Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif)
  • Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM
  • Add :status option to send_data and send_file. Defaults to ‘200 OK’. 5243 [Manfred Stienstra <m.stienstra@fngtps.com>]
  • Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. [Nicholas Seckar, Jamis Buck]

    map.connect ’/foo/:id’, :controller => ’…’, :action => ’…’ map.connect ’/foo/:id.:format’, :controller => ’…’, :action => ’…’ map.connect ’/foo/:id’, …, :conditions => { :method => :get }

  • Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. [Jeremy Kemper]
  • Accept multipart PUT parameters. 5235 [guy.naor@famundo.com]
  • Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example:

    class WeblogController < ActionController::Base

      def index
    @posts = Post.find :all

    respond_to do |format|
      format.html
      format.xml { render :xml => @posts.to_xml }
      format.rss { render :action => "feed.rxml" }
    end
  end

    end

    # returns HTML when requested by a browser, since the browser # has the HTML mimetype at the top of its priority list Accept: text/html GET /weblog

    # returns the XML Accept: application/xml GET /weblog

    # returns the HTML Accept: application/xml GET /weblog.html

    # returns the XML Accept: text/html GET /weblog.xml

    All this relies on the fact that you have a route that includes .:format.

  • Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post [David Heinemeier Hansson]
  • Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete [David Heinemeier Hansson]
  • follow_redirect doesn‘t complain about being redirected to the same controller. 5153 [dymo@mk.ukrtelecom.ua]
  • Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. [Kevin Clark]
  • Fix NoMethodError when parsing params like &&. [Adam Greenfield]
  • Fix flip flopped logic in docs for url_for‘s :only_path option. Closes 4998. [esad@esse.at]
  • form.text_area handles the :size option just like the original text_area (:size => ‘60x10’ becomes cols="60" rows="10"). [Jeremy Kemper]
  • Excise ingrown code from FormOptionsHelper#options_for_select. 5008 [anonymous]
  • Small fix in routing to allow dynamic routes (broken after [4242]) [Rick Olson]
      map.connect '*path', :controller => 'files', :action => 'show'
  • Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Use flush between switching from write to syswrite. Closes 4907. [Blair Zajac <blair@orcaware.com>]
  • Documentation fix: integration test scripts don‘t require integration_test. Closes 4914. [Frederick Ros <sl33p3r@free.fr>]
  • ActionController::Base Summary documentation rewrite. Closes 4900. [Kevin Clark]
  • Fix text_helper.rb documentation rendering. Closes 4725. [Frederick Ros]
  • Fixes bad rendering of JavaScriptMacrosHelper rdoc (closes 4910) [Frederick Ros]
  • Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes 4186. [andrew@redlinesoftware.com, Marcel Molina Jr.]

    error_messages_for :account, :user, :subscription, :object_name => :account

  • Enhance documentation for setting headers in integration tests. Skip auto HTTP prepending when its already there. Closes 4079. [Rick Olson]
  • Documentation for AbstractRequest. Closes 4895. [Kevin Clark]
  • Refactor various InstanceTag instance method to class methods. Closes 4800. [Stefan Kaes]
  • Remove all remaining references to @params in the documentation. [Marcel Molina Jr.]
  • Add documentation for redirect_to :back‘s RedirectBackError exception. [Marcel Molina Jr.]
  • Update layout and content_for documentation to use yield rather than magic @content_for instance variables. [Marcel Molina Jr.]
  • Fix assert_redirected_to tests according to real-world usage. Also, don‘t fail if you add an extra :controller option: [Rick Olson]
      redirect_to :action => 'new'
  assert_redirected_to :controller => 'monkeys', :action => 'new'
  • Cache CgiRequest#request_parameters so that multiple calls don‘t re-parse multipart data. [Rick Olson]
  • Diff compared routing options. Allow assert_recognizes to take a second arg as a hash to specify optional request method [Rick Olson]
      assert_recognizes({:controller => 'users', :action => 'index'}, 'users')
  assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post})
  • Diff compared options with assert_redirected_to [Rick Olson]
  • Add support in routes for semicolon delimited "subpaths", like /books/:id;:action [Jamis Buck]
  • Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes 4804. [zraii@comcast.net, Sam Stephenson]
  • Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for [David Heinemeier Hansson]
  • Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. [Jamis Buck]
  • Added :add_headers option to verify which merges a hash of name/value pairs into the response‘s headers hash if the prerequisites cannot be satisfied. [Sam Stephenson] ex. verify :only => :speak, :method => :post,
               :render => { :status => 405, :text => "Must be post" },
           :add_headers => { "Allow" => "POST" }
  • Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled 1897 [jeremye@bsa.ca.gov]

*1.13.3* (March 12th, 2007)

  • Apply [5709] to stable.
  • session_enabled? works with session :off. 6680 [Jonathan del Strother]
  • Performance: patch cgi/session to require digest/md5 once rather than per create_new_id. [Stefan Kaes]

*1.13.2* (February 5th, 2007)

  • Add much-needed html-scanner tests. Fixed CDATA parsing bug. [Rick Olson]
  • improve error message for Routing for named routes. [Rob Sanheim]
  • Added enhanced docs to routing assertions. [Rob Sanheim]
  • fix form_for example in ActionController::Resources documentation. [gnarg]
  • Add singleton resources from trunk [Rick Olson]
  • select :multiple => true suffixes the attribute name with [] unless already suffixed. 6977 [nik.kakelin, ben, julik]
  • Improve routes documentation. 7095 [zackchandler]
  • Resource member routes require :id, eliminating the ambiguous overlap with collection routes. 7229 [dkubb]
  • Fixed NumberHelper#number_with_delimiter to use "." always for splitting the original number, not the delimiter parameter 7389 [ceefour]
  • Autolinking recognizes trailing and embedded . , : ; 7354 [Jarkko Laine]
  • Make TextHelper::auto_link recognize URLs with colons in path correctly, fixes 7268. [imajes]
  • Improved auto_link to match more valid urls correctly [Tobias Lütke]

*1.13.1* (January 18th, 2007)

  • Fixed content-type bug in Prototype [sam]

*1.13.0* (January 16th, 2007)

  • Modernize cookie testing code, and increase coverage (Heckle++) 7101 [Kevin Clark]
  • Heckling ActionController::Resources::Resource revealed that set_prefixes didn‘t break when :name_prefix was munged. 7081 [Kevin Clark]
  • Update to Prototype 1.5.0. [Sam Stephenson]
  • Allow exempt_from_layout :rhtml. 6742, 7026 [Dan Manges, Squeegy]
  • Fix parsing of array[] CGI parameters so extra empty values aren‘t included. 6252 [Nicholas Seckar, aiwilliams, brentrowland]
  • link_to_unless_current works with full URLs as well as paths. 6891 [Jarkko Laine, Manfred Stienstra, idrifter]
  • Fix HTML::Node to output double quotes instead of single quotes. Closes 6845 [mitreandy]
  • Fix no method error with error_messages_on. Closes 6935 [nik.wakelin Koz]
  • Slight doc tweak to the ActionView::Helpers::PrototypeHelper#replace docs. Closes 6922 [Steven Bristol]
  • Slight doc tweak to prepend_filter. Closes 6493 [Jeremy Voorhis]
  • Add more extensive documentation to the AssetTagHelper. Closes 6452 [Bob Silva]
  • Clean up multiple calls to stringify_keys in TagHelper, add better documentation and testing for TagHelper. Closes 6394 [Bob Silva]
  • [DOCS] fix reference to ActionController::Macros::AutoComplete for text_field_with_auto_complete. Closes 2578 [Jan Prill]
  • Make sure html_document is reset between integration test requests. [ctm]
  • Set session to an empty hash if :new_session => false and no session cookie or param is present. CGI::Session was raising an unrescued ArgumentError. [Josh Susser]
  • Fix assert_redirected_to bug where redirecting from a nested to to a top-level controller incorrectly added the current controller‘s nesting. Closes 6128. [Rick Olson]
  • Ensure render :json => … skips the layout. 6808 [Josh Peek]
  • Silence log_error deprecation warnings from inspecting deprecated instance variables. [Nate Wiger]
  • Only cache GET requests with a 200 OK response. 6514, 6743 [RSL, anamba]
  • Correctly report which filter halted the chain. 6699 [Martin Emde]
  • respond_to recognizes JSON. render :json => @person.to_json automatically sets the content type and takes a :callback option to specify a client-side function to call using the rendered JSON as an argument. 4185 [Scott Raymond, eventualbuddha]
      # application/json response with body 'Element.show({:name: "David"})'
  respond_to do |format|
    format.json { render :json => { :name => "David" }.to_json, :callback => 'Element.show' }
  end
  • Makes :discard_year work without breaking multi-attribute parsing in AR. 1260, 3800 [sean@ardismg.com, jmartin@desertflood.com, stephen@touset.org, Bob Silva]
  • Adds html id attribute to date helper elements. 1050, 1382 [mortonda@dgrmm.net, David North, Bob Silva]
  • Add :index and @auto_index capability to model driven date/time selects. 847, 2655 [moriq, Doug Fales, Bob Silva]
  • Add :order to datetime_select, select_datetime, and select_date. 1427 [Timothee Peignier, Patrick Lenz, Bob Silva]
  • Added time_select to work with time values in models. Update scaffolding. 2489, 2833 [Justin Palmer, Andre Caum, Bob Silva]
  • Added :include_seconds to select_datetime, datetime_select and time_select. 2998 [csn, Bob Silva]
  • All date/datetime selects can now accept an array of month names with :use_month_names. Allows for localization. 363 [tomasj, Bob Silva]
  • Adds :time_separator to select_time and :date_separator to select_datetime. Preserves BC. 3811 [Bob Silva]
  • @response.redirect_url works with 201 Created responses: just return headers[‘Location’] rather than checking the response status. [Jeremy Kemper]
  • Fixed that HEAD should return the proper Content-Length header (that is, actually use @body.size, not just 0) [David Heinemeier Hansson]
  • Added GET-masquarading for HEAD, so request.method will return :get even for HEADs. This will help anyone relying on case request.method to automatically work with HEAD and map.resources will also allow HEADs to all GET actions. Rails automatically throws away the response content in a reply to HEAD, so you don‘t even need to worry about that. If you, for whatever reason, still need to distinguish between GET and HEAD in some edge case, you can use Request#head? and even Request.headers["REQUEST_METHOD"] for get the "real" answer. Closes 6694 [David Heinemeier Hansson]

*1.13.0 RC1* (r5619, November 22nd, 2006)

  • Update Routing to complain when :controller is not specified by a route. Closes 6669. [Nicholas Seckar]
  • Ensure render_to_string cleans up after itself when an exception is raised. 6658 [rsanheim]
  • Update to Prototype and script.aculo.us [5579]. [Sam Stephenson, Thomas Fuchs]
  • simple_format helper doesn‘t choke on nil. 6644 [jerry426]
  • Reuse named route helper module between Routing reloads. Use remove_method to delete named route methods after each load. Since the module is never collected, this fixes a significant memory leak. [Nicholas Seckar]
  • Deprecate standalone components. [Jeremy Kemper]
  • Always clear model associations from session. 4795 [sd@notso.net, andylien@gmail.com]
  • Remove JavaScriptLiteral in favor of ActiveSupport::JSON::Variable. [Sam Stephenson]
  • Sync ActionController::StatusCodes::STATUS_CODES with www.iana.org/assignments/http-status-codes. 6586 [dkubb]
  • Multipart form values may have a content type without being treated as uploaded files if they do not provide a filename. 6401 [Andreas Schwarz, Jeremy Kemper]
  • assert_response supports symbolic status codes. 6569 [Kevin Clark]
      assert_response :ok
  assert_response :not_found
  assert_response :forbidden
  • Cache parsed query parameters. 6559 [Stefan Kaes]
  • Deprecate JavaScriptHelper#update_element_function, which is superseeded by RJS [Thomas Fuchs]
  • Fix invalid test fixture exposed by stricter Ruby 1.8.5 multipart parsing. 6524 [Bob Silva]
  • Set ActionView::Base.default_form_builder once rather than passing the :builder option to every form or overriding the form helper methods. [Jeremy Kemper]
  • Deprecate expire_matched_fragments. Use expire_fragment instead. 6535 [Bob Silva]
  • Deprecate start_form_tag and end_form_tag. Use form_tag / ’</form>’ from now on. [Rick Olson]
  • Added block-usage to PrototypeHelper#form_remote_tag, document block-usage of FormTagHelper#form_tag [Rick Olson]
  • Add a 0 margin/padding div around the hidden _method input tag that form_tag outputs. [Rick Olson]
  • Added block-usage to TagHelper#content_tag [David Heinemeier Hansson]. Example:
     <% content_tag :div, :class => "strong" %>
   Hello world!
 <% end %>

    Will output:

      <div class="strong">Hello world!</div>
  • Deprecated UrlHelper#link_to_image and UrlHelper#link_to :post => true 6409 [Bob Silva]
  • Upgraded NumberHelper with number_to_phone support international formats to comply with ITU E.123 by supporting area codes with less than 3 digits, added precision argument to number_to_human_size (defaults to 1) 6421 [Bob Silva]
  • Fixed that setting RAILS_ASSET_ID to "" should not add a trailing slash after assets 6454 [Bob Silva/chrismear]
  • Force *_url named routes to show the host in ActionView [Rick Olson]

    <%= url_for … %> # no host <%= foo_path %> # no host <%= foo_url %> # host!

  • Add support for converting blocks into function arguments to JavaScriptGenerator#call and JavaScriptProxy#call. [Sam Stephenson]
  • Add JavaScriptGenerator#literal for wrapping a string in an object whose to_json is the string itself. [Sam Stephenson]
  • Add <%= escape_once html %> to escape html while leaving any currently escaped entities alone. Fix button_to double-escaping issue. [Rick Olson]
  • Fix double-escaped entities, such as &amp;amp;, &amp;123;, etc. [Rick Olson]
  • Fix routing to correctly determine when generation fails. Closes 6300. [psross].
  • Fix broken assert_generates when extra keys are being checked. [Jamis Buck]
  • Replace KCODE checks with String#chars for truncate. Closes 6385 [Manfred Stienstra]
  • Make page caching respect the format of the resource that is being requested even if the current route is the default route so that, e.g. posts.rss is not transformed by url_for to ’/’ and subsequently cached as ’/index.html’ when it should be cached as ’/posts.rss’. [Marcel Molina Jr.]
  • Use String#chars in TextHelper::excerpt. Closes 6386 [Manfred Stienstra]
  • Fix relative URL root matching problems. [Mark Imbriaco]
  • Fix filter skipping in controller subclasses. 5949, 6297, 6299 [Martin Emde]
  • render_text may optionally append to the response body. render_javascript appends by default. This allows you to chain multiple render :update calls by setting @performed_render = false between them (awaiting a better public API). [Jeremy Kemper]
  • Rename test assertion to prevent shadowing. Closes 6306. [psross]
  • Fixed that NumberHelper#number_to_delimiter should respect precision of higher than two digits 6231 [Philip Hallstrom]
  • Fixed that FormHelper#radio_button didn‘t respect an :id being passed in 6266 [evansj]
  • Added an html_options hash parameter to javascript_tag() and update_page_tag() helpers 6311 [tzaharia]. Example:
      update_page_tag :defer => 'true' { |page| ... }

    Gives:

      <script defer="true" type="text/javascript">...</script>

    Which is needed for dealing with the IE6 DOM when it‘s not yet fully loaded.

  • Fixed that rescue template path shouldn‘t be hardcoded, then it‘s easier to hook in your own 6295 [Mike Naberezny]
  • Fixed escaping of backslashes in JavaScriptHelper#escape_javascript 6302 [sven@c3d2.de]
  • Fixed that some 500 rescues would cause 500‘s themselves because the response had not yet been generated 6329 [cmselmer]
  • respond_to :html doesn‘t assume .rhtml. 6281 [Hampton Catlin]
  • Fixed some deprecation warnings in ActionPack [Rick Olson]
  • assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. 6240 [japgolly]
  • Deprecation: @cookies, @headers, @request, @response will be removed after 1.2. Use the corresponding method instead. [Jeremy Kemper]
  • Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples:
      head :status => 404        # expands to "404 Not Found"
  head :status => :not_found # expands to "404 Not Found"
  head :status => :created   # expands to "201 Created"
  • Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples:
      head :status => 404 # return an empty response with a 404 status
  head :location => person_path(@person), :status => 201
  • Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. [Rick Olson]
  • strip_links is case-insensitive. 6285 [tagoh, Bob Silva]
  • Clear the cache of possible controllers whenever Routes are reloaded. [Nicholas Seckar]
  • Filters overhaul including meantime filter support using around filters + blocks. 5949 [Martin Emde, Roman Le Negrate, Stefan Kaes, Jeremy Kemper]
  • Update CGI process to allow sessions to contain namespaced models. Closes 4638. [dfelstead@site5.com]
  • Fix routing to respect user provided requirements and defaults when assigning default routing options (such as :action => ‘index’). Closes 5950. [Nicholas Seckar]
  • Rescue Errno::ECONNRESET to handle an unexpectedly closed socket connection. Improves SCGI reliability. 3368, 6226 [sdsykes, fhanshaw@vesaria.com]
  • Added that respond_to blocks will automatically set the content type to be the same as is requested [David Heinemeier Hansson]. Examples:
      respond_to do |format|
    format.html { render :text => "I'm being sent as text/html" }
    format.rss  { render :text => "I'm being sent as application/rss+xml" }
    format.atom { render :text => "I'm being sent as application/xml", :content_type => Mime::XML }
  end
  • Added utf-8 as the default charset for all renders. You can change this default using ActionController::Base.default_charset=(encoding) [David Heinemeier Hansson]
  • Added proper getters and setters for content type and charset [David Heinemeier Hansson]. Example of what we used to do:
      response.headers["Content-Type"] = "application/atom+xml; charset=utf-8"

    …now:

      response.content_type = Mime::ATOM
  response.charset      = "utf-8"
  • Declare file extensions exempt from layouts. 6219 [brandon]
      Example: ActionController::Base.exempt_from_layout 'rpdf'
  • Add chained replace/update support for assert_select_rjs [Rick Olson]
      Given RJS like...

    page['test1'].replace "<div id=\"1\">foo</div>"
    page['test2'].replace_html "<div id=\"2\">foo</div>"

  Test it with...

    assert_select_rjs :chained_replace
    assert_select_rjs :chained_replace, "test1"

    assert_select_rjs :chained_replace_html
    assert_select_rjs :chained_replace_html, "test2"
  • Load helpers in alphabetical order for consistency. Resolve cyclic javascript_helper dependency. 6132, 6178 [choonkeat@gmail.com]
  • Skip params with empty names, such as the &=Save query string from <input type="submit"/>. 2569 [Manfred Stienstra, raphinou@yahoo.com]
  • Fix assert_tag so that :content => "foo" does not match substrings, but only exact strings. Use :content => /foo/ to match substrings. 2799 [Eric Hodel]
  • Update JavaScriptGenerator#show/hide/toggle/remove to new Prototype syntax for multiple ids, 6068 [petermichaux@gmail.com]
  • Update UrlWriter to support :only_path. [Nicholas Seckar, Dave Thomas]
  • Fixed JavaScriptHelper#link_to_function and JavaScriptHelper#button_to_function to have the script argument be optional [David Heinemeier Hansson]. So what used to require a nil, like this:
      link_to("Hider", nil, :class => "hider_link") { |p| p[:something].hide }

    …can be written like this:

      link_to("Hider", :class => "hider_link") { |p| p[:something].hide }
  • Added access to nested attributes in RJS 4548 [richcollins@gmail.com]. Examples:
      page['foo']['style']                  # => $('foo').style;
  page['foo']['style']['color']         # => $('blank_slate').style.color;
  page['foo']['style']['color'] = 'red' # => $('blank_slate').style.color = 'red';
  page['foo']['style'].color = 'red'    # => $('blank_slate').style.color = 'red';
  • Fixed that AssetTagHelper#image_tag and others using compute_public_path should not modify the incoming source argument (closes 5102) [eule@space.ch]
  • Deprecated the auto-appending of .png to AssetTagHelper#image_tag calls that doesn‘t have an extension [David Heinemeier Hansson]
  • Fixed FormOptionsHelper#select to respect :selected value 5813
  • Fixed TextHelper#simple_format to deal with multiple single returns within a single paragraph 5835 [moriq@moriq.com]
  • Fixed TextHelper#pluralize to handle 1 as a string 5909 [rails@bencurtis.com]
  • Improved resolution of DateHelper#distance_of_time_in_words for better precision 5994 [Bob Silva]
  • Changed that uncaught exceptions raised any where in the application will cause RAILS_ROOT/public/500.html to be read and shown instead of just the static "Application error (Rails)" [David Heinemeier Hansson]
  • Added deprecation language for pagination which will become a plugin by Rails 2.0 [David Heinemeier Hansson]
  • Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 [David Heinemeier Hansson]
  • Deprecated all of ActionController::Dependencies. All dependency loading is now handled from Active Support [David Heinemeier Hansson]
  • Added assert_select* for CSS selector-based testing (deprecates assert_tag) 5936 [assaf.arkin@gmail.com]
  • radio_button_tag generates unique id attributes. 3353 [Bob Silva, somekool@gmail.com]
  • strip_tags passes through blank args such as nil or "". 2229, 6702 [duncan@whomwah.com, dharana]
  • Cleanup assert_tag :children counting. 2181 [jamie@bravenet.com]
  • button_to accepts :method so you can PUT and DELETE with it. 6005 [Dan Webb]
  • Update sanitize text helper to strip plaintext tags, and <img src="javascript:bang">. [Rick Olson]
  • Add routing tests to assert that RoutingError is raised when conditions aren‘t met. Closes 6016 [Nathan Witmer]
  • Make auto_link parse a greater subset of valid url formats. [Jamis Buck]
  • Integration tests: headers beginning with X aren‘t excluded from the HTTP_ prefix, so X-Requested-With becomes HTTP_X_REQUESTED_WITH as expected. [Mike Clark]
  • Switch to using FormEncodedPairParser for parsing request parameters. [Nicholas Seckar, David Heinemeier Hansson]
  • respond_to .html now always renders #{action_name}.rhtml so that registered custom template handlers do not override it in priority. Custom mime types require a block and throw proper error now. [Tobias Lütke]
  • Deprecation: test deprecated instance vars in partials. [Jeremy Kemper]
  • Add UrlWriter to allow writing urls from Mailers and scripts. [Nicholas Seckar]
  • Relax Routing‘s anchor pattern warning; it was preventing use of [^/] inside restrictions. [Nicholas Seckar]
  • Add controller_paths variable to Routing. [Nicholas Seckar]
  • Fix assert_redirected_to issue with named routes for module controllers. [Rick Olson]
  • Tweak RoutingError message to show option diffs, not just missing named route significant keys. [Rick Olson]
  • Invoke method_missing directly on hidden actions. Closes 3030. [Nicholas Seckar]
  • Add RoutingError exception when RouteSet fails to generate a path from a Named Route. [Rick Olson]
  • Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
  • Deprecation: check whether instance variables have been monkeyed with before assigning them to deprecation proxies. Raises a RuntimeError if so. [Jeremy Kemper]
  • Add support for the param_name parameter to the auto_complete_field helper. 5026 [david.a.williams@gmail.com]
  • Deprecation! @params, @session, @flash will be removed after 1.2. Use the corresponding instance methods instead. You‘ll get printed warnings during tests and logged warnings in dev mode when you access either instance variable directly. [Jeremy Kemper]
  • Make Routing noisy when an anchor regexp is assigned to a segment. 5674 [François Beausoleil]
  • Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" 5611 [pjhyett@gmail.com]
  • Make controller_path available as an instance method. 5724 [jmckible@gmail.com]
  • Update query parser to support adjacent hashes. [Nicholas Seckar]
  • Make action caching aware of different formats for the same action so that, e.g. foo.xml is cached separately from foo.html. Implicitly set content type when reading in cached content with mime revealing extensions so the entire onous isn‘t on the webserver. [Marcel Molina Jr.]
  • Restrict Request Method hacking with ?_method to POST requests. [Rick Olson]
  • Fixed the new_#{resource}_url route and added named route tests for Simply Restful. [Rick Olson]
  • Added map.resources from the Simply Restful plugin [David Heinemeier Hansson]. Examples (the API has changed to use plurals!):
      map.resources :messages
  map.resources :messages, :comments
  map.resources :messages, :new => { :preview => :post }
  • Fixed that integration simulation of XHRs should set Accept header as well [Edward Frederick]
  • TestRequest#reset_session should restore a TestSession, not a hash [Michael Koziarski]
  • Don‘t search a load-path of ’.’ for controller files [Jamis Buck]
  • Update integration.rb to require test_process explicitly instead of via Dependencies. [Nicholas Seckar]
  • Fixed that you can still access the flash after the flash has been reset in reset_session. Closes 5584 [lmarlow]
  • Allow form_for and fields_for to work with indexed form inputs. [Jeremy Kemper, Matt Lyon]

    <% form_for ‘post[]’, @post do |f| -%> <% end -%>

  • Remove leak in development mode by replacing define_method with module_eval. [Nicholas Seckar]
  • Provide support for decimal columns to form helpers. Closes 5672. [Dave Thomas]
  • Pass :id => nil or :class => nil to error_messages_for to supress that html attribute. 3586 [olivier_ansaldi@yahoo.com, sebastien@goetzilla.info]
  • Reset @html_document between requests so assert_tag works. 4810 [Jarkko Laine, easleydp@gmail.com]
  • Integration tests behave well with render_component. 4632 [edward.frederick@revolution.com, dev.rubyonrails@maxdunn.com]
  • Added exception handling of missing layouts 5373 [chris@ozmm.org]
  • Fixed that real files and symlinks should be treated the same when compiling templates 5438 [zachary@panandscan.com]
  • Fixed that the flash should be reset when reset_session is called 5584 [Shugo Maeda]
  • Added special case for "1 Byte" in NumberHelper#number_to_human_size 5593 [murpyh@rubychan.de]
  • Fixed proper form-encoded parameter parsing for requests with "Content-Type: application/x-www-form-urlencoded; charset=utf-8" (note the presence of a charset directive) [David Heinemeier Hansson]
  • Add route_name_path method to generate only the path for a named routes. For example, map.person will add person_path. [Nicholas Seckar]
  • Avoid naming collision among compiled view methods. [Jeremy Kemper]
  • Fix CGI extensions when they expect string but get nil in Windows. Closes 5276 [Mislav Marohnić]
  • Determine the correct template_root for deeply nested components. 2841 [s.brink@web.de]
  • Fix that routes with *path segments in the recall can generate URLs. [Rick Olson]
  • Fix strip_links so that it doesn‘t hang on multiline <acronym> tags [Jamis Buck]
  • Remove problematic control chars in rescue template. 5316 [Stefan Kaes]
  • Make sure passed routing options are not mutated by routing code. 5314 [Blair Zajac]
  • Make sure changing the controller from foo/bar to bing/bang does not change relative to foo. [Jamis Buck]
  • Escape the path before routing recognition. 3671
  • Make sure :id and friends are unescaped properly. 5275 [me@julik.nl]
  • Rewind readable CGI params so others may reread them (such as CGI::Session when passing the session id in a multipart form). 210 [mklame@atxeu.com, matthew@walker.wattle.id.au]
  • Added Mime::TEXT (text/plain) and Mime::ICS (text/calendar) as new default types [David Heinemeier Hansson]
  • Added Mime::Type.register(string, symbol, synonyms = []) for adding new custom mime types [David Heinemeier Hansson]. Example: Mime::Type.register("image/gif", :gif)
  • Added support for Mime objects in render :content_type option [David Heinemeier Hansson]. Example: render :text => some_atom, :content_type => Mime::ATOM
  • Add :status option to send_data and send_file. Defaults to ‘200 OK’. 5243 [Manfred Stienstra <m.stienstra@fngtps.com>]
  • Routing rewrite. Simpler, faster, easier to understand. The published API for config/routes.rb is unchanged, but nearly everything else is different, so expect breakage in plugins and libs that try to fiddle with routes. [Nicholas Seckar, Jamis Buck]

    map.connect ’/foo/:id’, :controller => ’…’, :action => ’…’ map.connect ’/foo/:id.:format’, :controller => ’…’, :action => ’…’ map.connect ’/foo/:id’, …, :conditions => { :method => :get }

  • Cope with missing content type and length headers. Parse parameters from multipart and urlencoded request bodies only. [Jeremy Kemper]
  • Accept multipart PUT parameters. 5235 [guy.naor@famundo.com]
  • Added interrogation of params[:format] to determine Accept type. If :format is specified and matches a declared extension, like "rss" or "xml", that mime type will be put in front of the accept handler. This means you can link to the same action from different extensions and use that fact to determine output [David Heinemeier Hansson]. Example:

    class WeblogController < ActionController::Base

      def index
    @posts = Post.find :all

    respond_to do |format|
      format.html
      format.xml { render :xml => @posts.to_xml }
      format.rss { render :action => "feed.rxml" }
    end
  end

    end

    # returns HTML when requested by a browser, since the browser # has the HTML mimetype at the top of its priority list Accept: text/html GET /weblog

    # returns the XML Accept: application/xml GET /weblog

    # returns the HTML Accept: application/xml GET /weblog.html

    # returns the XML Accept: text/html GET /weblog.xml

    All this relies on the fact that you have a route that includes .:format.

  • Expanded :method option in FormTagHelper#form_tag, FormHelper#form_for, PrototypeHelper#remote_form_for, PrototypeHelper#remote_form_tag, and PrototypeHelper#link_to_remote to allow for verbs other than GET and POST by automatically creating a hidden form field named _method, which will simulate the other verbs over post [David Heinemeier Hansson]
  • Added :method option to UrlHelper#link_to, which allows for using other verbs than GET for the link. This replaces the :post option, which is now deprecated. Example: link_to "Destroy", person_url(:id => person), :method => :delete [David Heinemeier Hansson]
  • follow_redirect doesn‘t complain about being redirected to the same controller. 5153 [dymo@mk.ukrtelecom.ua]
  • Add layout attribute to response object with the name of the layout that was rendered, or nil if none rendered. [Kevin Clark]
  • Fix NoMethodError when parsing params like &&. [Adam Greenfield]
  • form.text_area handles the :size option just like the original text_area (:size => ‘60x10’ becomes cols="60" rows="10"). [Jeremy Kemper]
  • Excise ingrown code from FormOptionsHelper#options_for_select. 5008 [anonymous]
  • Small fix in routing to allow dynamic routes (broken after [4242]) [Rick Olson]
      map.connect '*path', :controller => 'files', :action => 'show'
  • Use flush between switching from write to syswrite. Closes 4907. [Blair Zajac <blair@orcaware.com>]
  • Allow error_messages_for to report errors for multiple objects, as well as support for customizing the name of the object in the error summary header. Closes 4186. [andrew@redlinesoftware.com, Marcel Molina Jr.]

    error_messages_for :account, :user, :subscription, :object_name => :account

  • Fix assert_redirected_to tests according to real-world usage. Also, don‘t fail if you add an extra :controller option: [Rick Olson]
      redirect_to :action => 'new'
  assert_redirected_to :controller => 'monkeys', :action => 'new'
  • Diff compared routing options. Allow assert_recognizes to take a second arg as a hash to specify optional request method [Rick Olson]
      assert_recognizes({:controller => 'users', :action => 'index'}, 'users')
  assert_recognizes({:controller => 'users', :action => 'create'}, {:path => 'users', :method => :post})
  • Diff compared options with assert_redirected_to [Rick Olson]
  • Add support in routes for semicolon delimited "subpaths", like /books/:id;:action [Jamis Buck]
  • Change link_to_function and button_to_function to (optionally) take an update_page block instead of a JavaScript string. Closes 4804. [zraii@comcast.net, Sam Stephenson]
  • Modify routing so that you can say :require => { :method => :post } for a route, and the route will never be selected unless the request method is POST. Only works for route recognition, not for route generation. [Jamis Buck]
  • Added :add_headers option to verify which merges a hash of name/value pairs into the response‘s headers hash if the prerequisites cannot be satisfied. [Sam Stephenson] ex. verify :only => :speak, :method => :post,
               :render => { :status => 405, :text => "Must be post" },
           :add_headers => { "Allow" => "POST" }

*1.12.5* (August 10th, 2006)

  • Updated security fix

*1.12.4* (August 8th, 2006)

  • Cache CgiRequest#request_parameters so that multiple calls don‘t re-parse multipart data. [Rick Olson]
  • Fixed that remote_form_for can leave out the object parameter and default to the instance variable of the object_name, just like form_for [David Heinemeier Hansson]
  • Added ActionController.filter_parameter_logging that makes it easy to remove passwords, credit card numbers, and other sensitive information from being logged when a request is handled. 1897 [jeremye@bsa.ca.gov]
  • Fixed that real files and symlinks should be treated the same when compiling templates. 5438 [zachary@panandscan.com]
  • Add :status option to send_data and send_file. Defaults to ‘200 OK’. 5243 [Manfred Stienstra <m.stienstra@fngtps.com>]
  • Update documentation for erb trim syntax. 5651 [matt@mattmargolis.net]
  • Short documentation to mention use of Mime::Type.register. 5710 [choonkeat@gmail.com]

*1.12.3* (June 28th, 2006)

  • Fix broken traverse_to_controller. We now: Look for a _controller.rb file under RAILS_ROOT to load. If we find it, we require_dependency it and return the controller it defined. (If none was defined we stop looking.) If we don‘t find it, we look for a .rb file under RAILS_ROOT to load. If we find it, and it loads a constant we keep looking. Otherwise we check to see if a directory of the same name exists, and if it does we create a module for it.

*1.12.2* (June 27th, 2006)

  • Refinement to avoid exceptions in traverse_to_controller.
  • (Hackish) Fix loading of arbitrary files in Ruby‘s load path by traverse_to_controller. [Nicholas Seckar]

*1.12.1* (April 6th, 2006)

  • Fixed that template extensions would be cached development mode 4624 [Stefan Kaes]
  • Update to Prototype 1.5.0_rc0 [Sam Stephenson]
  • Honor skipping filters conditionally for only certain actions even when the parent class sets that filter to conditionally be executed only for the same actions. 4522 [Marcel Molina Jr.]
  • Delegate xml_http_request in integration tests to the session instance. [Jamis Buck]
  • Update the diagnostics template skip the useless ’<controller not set>’ text. [Nicholas Seckar]
  • CHANGED DEFAULT: Don‘t parse YAML input by default, but keep it available as an easy option [David Heinemeier Hansson]
  • Add additional autocompleter options [aballai, Thomas Fuchs]
  • Fixed fragment caching of binary data on Windows 4493 [bellis@deepthought.org]
  • Applied Prototype $() performance patches (4465, 4477) and updated script.aculo.us [Sam Stephenson, Thomas Fuchs]
  • Added automated timestamping to AssetTagHelper methods for stylesheets, javascripts, and images when Action Controller is run under Rails [David Heinemeier Hansson]. Example:
      image_tag("rails.png") # => '<img alt="Rails" src="/images/rails.png?1143664135" />'

    …to avoid frequent stats (not a problem for most people), you can set RAILS_ASSET_ID in the ENV to avoid stats:

      ENV["RAILS_ASSET_ID"] = "2345"
  image_tag("rails.png") # => '<img alt="Rails" src="/images/rails.png?2345" />'

    This can be used by deployment managers to set the asset id by application revision

*1.12.0* (March 27th, 2006)

  • Add documentation for respond_to. [Jamis Buck]
  • Fixed require of bluecloth and redcloth when gems haven‘t been loaded 4446 [murphy@cYcnus.de]
  • Update to Prototype 1.5.0_pre1 [Sam Stephenson]
  • Change form_for and fields_for so that the second argument is not required [Dave Thomas]
      <% form_for :post, @post, :url => { :action => 'create' } do |f| -%>

    becomes…

      <% form_for :post, :url => { :action => 'create' } do |f| -%>
  • Update to script.aculo.us 1.6 [Thomas Fuchs]
  • Enable application/x-yaml processing by default [Jamis Buck]
  • Fix double url escaping of remote_function. Add :escape => false option to ActionView‘s url_for. [Nicholas Seckar]
  • Add :script option to in_place_editor to support evalScripts (closes 4194) [Cody Fauser]
  • Fix mixed case enumerable methods in the JavaScript Collection Proxy (closes 4314) [Cody Fauser]
  • Undo accidental escaping for mail_to; add regression test. [Nicholas Seckar]
  • Added nicer message for assert_redirected_to (closes 4294) [court3nay]
      assert_redirected_to :action => 'other_host', :only_path => false

    when it was expecting…

      redirected_to :action => 'other_host', :only_path => true, :host => 'other.test.host'

    gives the error message…

      response is not a redirection to all of the options supplied (redirection is <{:only_path=>false, :host=>"other.test.host", :action=>"other_host"}>), difference: <{:only_path=>"true", :host=>"other.test.host"}>
  • Change url_for to escape the resulting URLs when called from a view. [Nicholas Seckar, coffee2code]
  • Added easy support for testing file uploads with fixture_file_upload 4105 [turnip@turnipspatch.com]. Example:
      # Looks in Test::Unit::TestCase.fixture_path + '/files/spongebob.png'
  post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')
  • Fixed UrlHelper#current_page? to behave even when url-escaped entities are present 3929 [jeremy@planetargon.com]
  • Add ability for relative_url_root to be specified via an environment variable RAILS_RELATIVE_URL_ROOT. [isaac@reuben.com, Nicholas Seckar]
  • Fixed link_to "somewhere", :post => true to produce valid XHTML by using the parentnode instead of document.body for the instant form 3007 [Bob Silva]
  • Added :function option to PrototypeHelper#observe_field/observe_form that allows you to call a function instead of submitting an ajax call as the trigger 4268 [jonathan@daikini.com]
  • Make Mime::Type.parse consider q values (if any) [Jamis Buck]
  • XML-formatted requests are typecast according to "type" attributes for :xml_simple [Jamis Buck]
  • Added protection against proxy setups treating requests as local even when they‘re not 3898 [Steve Purcell]
  • Added TestRequest#raw_post that simulate raw_post from CgiRequest 3042 [François Beausoleil]
  • Underscore dasherized keys in formatted requests [Jamis Buck]
  • Add MimeResponds::Responder#any for managing multiple types with identical responses [Jamis Buck]
  • Make the xml_http_request testing method set the HTTP_ACCEPT header [Jamis Buck]
  • Add Verification to scaffolds. Prevent destructive actions using GET [Michael Koziarski]
  • Avoid hitting the filesystem when using layouts by using a File.directory? cache. [Stefan Kaes, Nicholas Seckar]
  • Simplify ActionController::Base#controller_path [Nicholas Seckar]
  • Added simple alert() notifications for RJS exceptions when config.action_view.debug_rjs = true. [Sam Stephenson]
  • Added :content_type option to render, so you can change the content type on the fly [David Heinemeier Hansson]. Example: render :action => "atom.rxml", :content_type => "application/atom+xml"
  • CHANGED DEFAULT: The default content type for .rxml is now application/xml instead of type/xml, see www.xml.com/pub/a/2004/07/21/dive.html for reason [David Heinemeier Hansson]
  • Added option to render action/template/file of a specific extension (and here by template type). This means you can have multiple templates with the same name but a different extension [David Heinemeier Hansson]. Example:
      class WeblogController < ActionController::Base
    def index
      @posts = Post.find :all

      respond_to do |type|
        type.html # using defaults, which will render weblog/index.rhtml
        type.xml  { render :action => "index.rxml" }
        type.js   { render :action => "index.rjs" }
      end
    end
  end
  • Added better support for using the same actions to output for different sources depending on the Accept header [David Heinemeier Hansson]. Example:
      class WeblogController < ActionController::Base
    def create
      @post = Post.create(params[:post])

      respond_to do |type|
        type.js   { render }  # renders create.rjs
        type.html { redirect_to :action => "index" }
        type.xml  do
          headers["Location"] = url_for(:action => "show", :id => @post)
          render(:nothing, :status => "201 Created")
        end
      end
    end
  end
  • Added Base#render(:xml => xml) that works just like Base#render(:text => text), but sets the content-type to text/xml and the charset to UTF-8 [David Heinemeier Hansson]
  • Integration test‘s url_for now runs in the context of the last request (if any) so after post /products/show/1 url_for :action => ‘new’ will yield /product/new [Tobias Lütke]
  • Re-added mixed-in helper methods for the JavascriptGenerator. Moved JavascriptGenerators methods to a module that is mixed in after the helpers are added. Also fixed that variables set in the enumeration methods like collect are set correctly. Documentation added for the enumeration methods [Rick Olson]. Examples:
      page.select('#items li').collect('items') do |element|
    element.hide
  end
  # => var items = $$('#items li').collect(function(value, index) { return value.hide(); });
  • Added plugin support for parameter parsers, which allows for better support for REST web services. By default, posts submitted with the application/xml content type is handled by creating a XmlSimple hash with the same name as the root element of the submitted xml. More handlers can easily be registered like this:
      # Assign a new param parser to a new content type
  ActionController::Base.param_parsers['application/atom+xml'] = Proc.new do |data|
    node = REXML::Document.new(post)
   { node.root.name => node.root }
  end

  # Assign the default XmlSimple to a new content type
  ActionController::Base.param_parsers['application/backpack+xml'] = :xml_simple

Default YAML web services were retired, ActionController::Base.param_parsers carries an example which shows how to get this functionality back. As part of this new plugin support, request.[formatted_post?, xml_post?, yaml_post? and post_format] were all deprecated in favor of request.content_type [Tobias Lütke]

  • Fixed Effect.Appear in effects.js to work with floats in Safari 3524, 3813, 3044 [Thomas Fuchs]
  • Fixed that default image extension was not appended when using a full URL with AssetTagHelper#image_tag 4032, 3728 [rubyonrails@beautifulpixel.com]
  • Added that page caching will only happen if the response code is less than 400 4033 [g.bucher@teti.ch]
  • Add ActionController::IntegrationTest to allow high-level testing of the way the controllers and routes all work together [Jamis Buck]
  • Added support to AssetTagHelper#javascript_include_tag for having :defaults appear anywhere in the list, so you can now make one call ala javascript_include_tag(:defaults, "my_scripts") or javascript_include_tag("my_scripts", :defaults) depending on how you want the load order 3506 [Bob Silva]
  • Added support for visual effects scoped queues to the visual_effect helper 3530 [Abdur-Rahman Advany]
  • Added .rxml (and any non-rhtml template, really) supportfor CaptureHelper#content_for and CaptureHelper#capture 3287 [Brian Takita]
  • Added script.aculo.us drag and drop helpers to RJS [Thomas Fuchs]. Examples:
      page.draggable 'product-1'
  page.drop_receiving 'wastebasket', :url => { :action => 'delete' }
  page.sortable 'todolist', :url => { action => 'change_order' }
  • Fixed that form elements would strip the trailing [] from the first parameter 3545 [ruby@bobsilva.com]
  • During controller resolution, update the NameError suppression to check for the expected constant. [Nicholas Seckar]
  • Update script.aculo.us to V1.5.3 [Thomas Fuchs]
  • Added various InPlaceEditor options, 3746, 3891, 3896, 3906 [Bill Burcham, ruairi, sl33p3r]
  • Added :count option to pagination that‘ll make it possible for the ActiveRecord::Base.count call to using something else than * for the count. Especially important for count queries using DISTINCT 3839 [Stefan Kaes]
  • Update script.aculo.us to V1.5.2 [Thomas Fuchs]
  • Added element and collection proxies to RJS [David Heinemeier Hansson]. Examples:
      page['blank_slate']                  # => $('blank_slate');
  page['blank_slate'].show             # => $('blank_slate').show();
  page['blank_slate'].show('first').up # => $('blank_slate').show('first').up();

  page.select('p')                      # => $$('p');
  page.select('p.welcome b').first      # => $$('p.welcome b').first();
  page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide();
  • Add JavaScriptGenerator#replace for replacing an element‘s "outer HTML". 3246 [tom@craz8.com, Sam Stephenson]
  • Remove over-engineered form_for code for a leaner implementation. [Nicholas Seckar]
  • Document form_for‘s :html option. [Nicholas Seckar]
  • Major components cleanup and speedup. 3527 [Stefan Kaes]
  • Fix problems with pagination and :include. [Kevin Clark]
  • Add ActiveRecordTestCase for testing AR integration. [Kevin Clark]
  • Add Unit Tests for pagination [Kevin Clark]
  • Add :html option for specifying form tag options in form_for. [Sam Stephenson]
  • Replace dubious controller parent class in filter docs. 3655, 3722 [info@rhalff.com, eigentone@gmail.com]
  • Don‘t interpret the :value option on text_area as an html attribute. Set the text_area‘s value. 3752 [gabriel@gironda.org]
  • Fix remote_form_for creates a non-ajax form. [Rick Olson]
  • Don‘t let arbitrary classes match as controllers — a potentially dangerous bug. [Nicholas Seckar]
  • Fix Routing tests. Fix routing where failing to match a controller would prevent the rest of routes from being attempted. [Nicholas Seckar]
  • Add :builder => option to form_for and friends. [Nicholas Seckar, Rick Olson]
  • Fix controller resolution to avoid accidentally inheriting a controller from a parent module. [Nicholas Seckar]
  • Set sweeper‘s @controller to nil after a request so that the controller may be collected between requests. [Nicholas Seckar]
  • Subclasses of ActionController::Caching::Sweeper should be Reloadable. [Rick Olson]
  • Document the :xhr option for verifications. 3666 [leeo]
  • Added :only and :except controls to skip_before/after_filter just like for when you add filters [David Heinemeier Hansson]
  • Ensure that the instance variables are copied to the template when performing render :update. [Nicholas Seckar]
  • Add the ability to call JavaScriptGenerator methods from helpers called in update blocks. [Sam Stephenson] Example: module ApplicationHelper
      def update_time
    page.replace_html 'time', Time.now.to_s(:db)
    page.visual_effect :highlight, 'time'
  end

    end

    class UserController < ApplicationController

      def poll
    render :update { |page| page.update_time }
  end

    end

  • Add render(:update) to ActionView::Base. [Sam Stephenson]
  • Fix render(:update) to not render layouts. [Sam Stephenson]
  • Fixed that SSL would not correctly be detected when running lighttpd/fcgi behind lighttpd w/mod_proxy 3548 [Steve Purcell]
  • Added the possibility to specify atomatic expiration for the memcachd session container 3571 [Stefan Kaes]
  • Change layout discovery to take into account the change in semantics with File.join and nil arguments. [Marcel Molina Jr.]
  • Raise a RedirectBackError if redirect_to :back is called when there‘s no HTTP_REFERER defined 3049 [Kevin Clark]
  • Treat timestamps like datetimes for scaffolding purposes 3388 [Maik Schmidt]
  • Fix IE bug with link_to "something", :post => true 3443 [Justin Palmer]
  • Extract Test::Unit::TestCase test process behavior into an ActionController::TestProcess module. [Sam Stephenson]
  • Pass along blocks from render_to_string to render. [Sam Stephenson]
  • Add render :update for inline RJS. [Sam Stephenson] Example: class UserController < ApplicationController
      def refresh
    render :update do |page|
      page.replace_html  'user_list', :partial => 'user', :collection => @users
      page.visual_effect :highlight, 'user_list'
    end
  end

    end

  • allow nil objects for error_messages_for [Michael Koziarski]
  • Refactor human_size to exclude decimal place if it is zero. [Marcel Molina Jr.]
  • Update to Prototype 1.5.0_pre0 [Sam Stephenson]
  • Automatically discover layouts when a controller is namespaced. 2199, 3424 [me@jonnii.com rails@jeffcole.net Marcel Molina Jr.]
  • Add support for multiple proxy servers to CgiRequest#host [gaetanot@comcast.net]
  • Documentation typo fix. 2367 [Blair Zajac]
  • Remove Upload Progress. 2871 [Sean Treadway]
  • Fix typo in function name mapping in auto_complete_field. 2929 3446 [doppler@gmail.com phil.ross@gmail.com]
  • Allow auto-discovery of third party template library layouts. [Marcel Molina Jr.]
  • Have the form builder output radio button, not check box, when calling the radio button helper. 3331 [LouisStAmour@gmail.com]
  • Added assignment of the Autocompleter object created by JavaScriptMacroHelper#auto_complete_field to a local javascript variables [David Heinemeier Hansson]
  • Added :on option for PrototypeHelper#observe_field that allows you to specify a different callback hook to have the observer trigger on [David Heinemeier Hansson]
  • Added JavaScriptHelper#button_to_function that works just like JavaScriptHelper#link_to_function but uses a button instead of a href [David Heinemeier Hansson]
  • Added that JavaScriptHelper#link_to_function will honor existing :onclick definitions when adding the function call [David Heinemeier Hansson]
  • Added :disable_with option to FormTagHelper#submit_tag to allow for easily disabled submit buttons with different text [David Heinemeier Hansson]
  • Make auto_link handle nil by returning quickly if blank? [Scott Barron]
  • Make auto_link match urls with a port number specified. [Marcel Molina Jr.]
  • Added support for toggling visual effects to ScriptaculousHelper::visual_effect, 3323. [Thomas Fuchs]
  • Update to script.aculo.us to 1.5.0 rev. 3343 [Thomas Fuchs]
  • Added :select option for JavaScriptMacroHelper#auto_complete_field that makes it easier to only use part of the auto-complete suggestion as the value for insertion [Thomas Fuchs]
  • Added delayed execution of Javascript from within RJS 3264 [devslashnull@gmail.com]. Example:
      page.delay(20) do
    page.visual_effect :fade, 'notice'
  end
  • Add session ID to default logging, but remove the verbose description of every step [David Heinemeier Hansson]
  • Add the following RJS methods: [Sam Stephenson]
      * alert - Displays an alert() dialog
  * redirect_to - Changes window.location.href to simulate a browser redirect
  * call - Calls a JavaScript function
  * assign - Assigns to a JavaScript variable
  * << - Inserts an arbitrary JavaScript string
  • Fix incorrect documentation for form_for [Nicholas Seckar]
  • Don‘t include a layout when rendering an rjs template using render‘s :template option. [Marcel Molina Jr.]

*1.1.2* (December 13th, 2005)

  • Become part of Rails 1.0
  • Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) [Thomas Fuchs]
  • Update to Prototype 1.4.0 final [Sam Stephenson]
  • Added form_remote_for (form_for meets form_remote_tag) [David Heinemeier Hansson]
  • Update to script.aculo.us 1.5.0_rc6
  • More robust relative url root discovery for SCGI compatibility. This solves the ‘SCGI routes problem’ — you no longer need to prefix all your routes with the name of the SCGI mountpoint. 3070 [Dave Ringoen]
  • Fix docs for text_area_tag. 3083. [Christopher Cotton]
  • Change form_for and fields_for method signatures to take object name and object as separate arguments rather than as a Hash. [David Heinemeier Hansson]
  • Introduce :selected option to the select helper. Allows you to specify a selection other than the current value of object.method. Specify :selected => nil to leave all options unselected. 2991 [Jonathan Viney <jonathan@bluewire.net.nz>]
  • Initialize @optional in routing code to avoid warnings about uninitialized access to an instance variable. [Nicholas Seckar]
  • Make ActionController‘s render honor the :locals option when rendering a :file. 1665. [Emanuel Borsboom, Marcel Molina Jr.]
  • Allow assert_tag(:conditions) to match the empty string when a tag has no children. Closes 2959. [Jamis Buck]
  • Update html-scanner to handle CDATA sections better. Closes 2970. [Jamis Buck]
  • Don‘t put flash in session if sessions are disabled. [Jeremy Kemper]
  • Strip out trailing &_= for raw post bodies. Closes 2868. [Sam Stephenson]
  • Pass multiple arguments to Element.show and Element.hide in JavaScriptGenerator instead of using iterators. [Sam Stephenson]
  • Improve expire_fragment documentation. 2966 [court3nay]
  • Correct docs for automatic layout assignment. 2610. [Charles M. Gerungan]
  • Always create new AR sessions rather than trying too hard to avoid database traffic. 2731 [Jeremy Kemper]
  • Update to Prototype 1.4.0_rc4. Closes 2943 (old Array.prototype.reverse behavior can be obtained by passing false as an argument). [Sam Stephenson]
  • Use Element.update(‘id’, ‘html’) instead of $(‘id’).innerHTML = ‘html’ in JavaScriptGenerator#replace_html so that script tags are evaluated. [Sam Stephenson]
  • Make rjs templates always implicitly skip out on layouts. [Marcel Molina Jr.]
  • Correct length for the truncate text helper. 2913 [Stefan Kaes]
  • Update to Prototype 1.4.0_rc3. Closes 1893, 2505, 2550, 2748, 2783. [Sam Stephenson]
  • Add support for new rjs templates which wrap an update_page block. [Marcel Molina Jr.]
  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]
  • Correct time_zone_options_for_select docs. 2892 [pudeyo@rpi.com]
  • Remove the unused, slow response_dump and session_dump variables from error pages. 1222 [lmarlow]
  • Performance tweaks: use Set instead of Array to speed up prototype helper include? calls. Avoid logging code if logger is nil. Inline commonly-called template presence checks. 2880, 2881, 2882, 2883 [Stefan Kaes]
  • MemCache store may be given multiple addresses. 2869 [Ryan Carver <ryan@fivesevensix.com>]
  • Handle cookie parsing irregularity for certain Nokia phones. 2530 [zaitzow@gmail.com]
  • Added PrototypeHelper::JavaScriptGenerator and PrototypeHelper#update_page for easily modifying multiple elements in an Ajax response. [Sam Stephenson] Example:
      update_page do |page|
    page.insert_html :bottom, 'list', '<li>Last item</li>'
    page.visual_effect :highlight, 'list'
    page.hide 'status-indicator', 'cancel-link'
  end

    generates the following JavaScript:

      new Insertion.Bottom("list", "<li>Last item</li>");
  new Effect.Highlight("list");
  ["status-indicator", "cancel-link"].each(Element.hide);
  • Refactored JavaScriptHelper into PrototypeHelper and ScriptaculousHelper [Sam Stephenson]
  • Update to latest script.aculo.us version (as of [3031])
  • Updated docs for in_place_editor, fixes a couple bugs and offers extended support for external controls [Justin Palmer]
  • Update documentation for render :file. 2858 [Tom Werner]
  • Only include builtin filters whose filenames match /^[a-z][a-z_]*_helper.rb$/ to avoid including operating system metadata such as ._foo_helper.rb. 2855 [court3nay]
  • Added FormHelper#form_for and FormHelper#fields_for that makes it easier to work with forms for single objects also if they don‘t reside in instance variables [David Heinemeier Hansson]. Examples:

    <% form_for :person, @person, :url => { :action => "update" } do |f| %>

      First name: <%= f.text_field :first_name %>
  Last name : <%= f.text_field :last_name %>
  Biography : <%= f.text_area :biography %>
  Admin?    : <%= f.check_box :admin %>

    <% end %>

    <% form_for :person, person, :url => { :action => "update" } do |person_form| %>

      First name: <%= person_form.text_field :first_name %>
  Last name : <%= person_form.text_field :last_name %>

  <% fields_for :permission => person.permission do |permission_fields| %>
    Admin?  : <%= permission_fields.check_box :admin %>
  <% end %>

    <% end %>

  • options_for_select allows any objects which respond_to? :first and :last rather than restricting to Array and Range. 2824 [Jacob Robbins <jrobbins@cmj.com>, Jeremy Kemper]
  • The auto_link text helper accepts an optional block to format the link text for each url and email address. Example: auto_link(post.body) { |text| truncate(text, 10) } [Jeremy Kemper]
  • assert_tag uses exact matches for string conditions, instead of partial matches. Use regex to do partial matches. 2799 [Jamis Buck]
  • CGI::Session::ActiveRecordStore.data_column_name = ‘foobar’ to use a different session data column than the ‘data’ default. [nbpwie102@sneakemail.com]
  • Do not raise an exception when default helper is missing; log a debug message instead. It‘s nice to delete empty helpers. [Jeremy Kemper]
  • Controllers with acronyms in their names (e.g. PDFController) require the correct default helper (PDFHelper in file pdf_helper.rb). 2262 [jeff@opendbms.com]

*1.11.0* (November 7th, 2005)

  • Added request as instance method to views, so you can do <%= request.env["HTTP_REFERER"] %>, just like you can already access response, session, and the likes [David Heinemeier Hansson]
  • Fix conflict with assert_tag and Glue gem 2255 [david.felstead@gmail.com]
  • Add documentation to assert_tag indicating that it only works with well-formed XHTML 1937, 2570 [Jamis Buck]
  • Added action_pack.rb stub so that ActionPack::Version loads properly [Sam Stephenson]
  • Added short-hand to assert_tag so assert_tag :tag => "span" can be written as assert_tag "span" [David Heinemeier Hansson]
  • Added skip_before_filter/skip_after_filter for easier control of the filter chain in inheritance hierachies [David Heinemeier Hansson]. Example:
      class ApplicationController < ActionController::Base
    before_filter :authenticate
  end

  class WeblogController < ApplicationController
    # will run the :authenticate filter
  end

  class SignupController < ActionController::Base
    # will not run the :authenticate filter
    skip_before_filter :authenticate
  end
  • Added redirect_to :back as a short-hand for redirect_to(request.env["HTTP_REFERER"]) [David Heinemeier Hansson]
  • Change javascript_include_tag :defaults to not use script.aculo.us loader, which facilitates the use of plugins for future script.aculo.us and third party javascript extensions, and provide register_javascript_include_default for plugins to specify additional JavaScript files to load. Removed slider.js and builder.js from actionpack. [Thomas Fuchs]
  • Fix problem where redirecting components can cause an infinite loop [Rick Olson]
  • Added support for the queue option on visual_effect [Thomas Fuchs]
  • Update script.aculo.us to V1.5_rc4 [Thomas Fuchs]
  • Fix that render :text didn‘t interpolate instance variables 2629, 2626 [Stefan Kaes]
  • Fix line number detection and escape RAILS_ROOT in backtrace Regexp [Nicholas Seckar]
  • Fixed document.getElementsByClassName from Prototype to be speedy again [Sam Stephenson]
  • Recognize ./#{RAILS_ROOT} as RAILS_ROOT in error traces [Nicholas Seckar]
  • Remove ARStore session fingerprinting [Nicholas Seckar]
  • Fix obscure bug in ARStore [Nicholas Seckar]
  • Added TextHelper#strip_tags for removing HTML tags from a string (using HTMLTokenizer) 2229 [marcin@junkheap.net]
  • Added a reader for flash.now, so it‘s possible to do stuff like flash.now[:alert] ||= ‘New if not set’ 2422 [Caio Chassot]

*1.10.2* (October 26th, 2005)

  • Reset template variables after using render_to_string [Stefan Kaes]
  • Expose the session model backing CGI::Session
  • Abbreviate RAILS_ROOT in traces

*1.10.1* (October 19th, 2005)

  • Update error trace templates [Nicholas Seckar]
  • Stop showing generated routing code in application traces [Nicholas Seckar]

*1.10.0* (October 16th, 2005)

  • Make string-keys locals assigns optional. Add documentation describing depreciated state [Stefan Kaes]
  • Improve line number detection for template errors [Nicholas Seckar]
  • Update/clean up documentation (rdoc)
  • Upgrade to Prototype 1.4.0_rc0 [Sam Stephenson]
  • Added assert_vaild. Reports the proper AR error messages as fail message when the passed record is invalid [Tobias Lütke]
  • Add temporary support for passing locals to render using string keys [Nicholas Seckar]
  • Clean up error pages by providing better backtraces [Nicholas Seckar]
  • Raise an exception if an attempt is made to insert more session data into the ActiveRecordStore data column than the column can hold. 2234. [justin@textdrive.com]
  • Removed references to assertions.rb from actionpack assert‘s backtraces. Makes error reports in functional unit tests much less noisy. [Tobias Lütke]
  • Updated and clarified documentation for JavaScriptHelper to be more concise about the various options for including the JavaScript libs. [Thomas Fuchs]
  • Hide "Retry with Breakpoint" button on error pages until feature is functional. [David Heinemeier Hansson]
  • Fix Request#host_with_port to use the standard port when Rails is behind a proxy. [Nicholas Seckar]
  • Escape query strings in the href attribute of URLs created by url_helper. 2333 [Michael Schuerig <michael@schuerig.de>]
  • Improved line number reporting for template errors [Nicholas Seckar]
  • Added :locals support for render :inline 2463 [mdabney@cavoksolutions.com]
  • Unset the X-Requested-With header when using the xhr wrapper in functional tests so that future requests aren‘t accidentally xhr‘ed 2352 [me@julik.nl, Sam Stephenson]
  • Unescape paths before writing cache to file system. 1877. [Damien Pollet]
  • Wrap javascript_tag contents in a CDATA section and add a cdata_section method to TagHelper 1691 [Michael Schuerig, Sam Stephenson]
  • Misc doc fixes (typos/grammar/etc). 2445. [coffee2code]
  • Speed improvement for session_options. 2287. [Stefan Kaes]
  • Make cacheing binary files friendly with Windows. 1975. [Rich Olson]
  • Convert boolean form options form the tag_helper. 809. [Michael Schuerig <michael@schuerig.de>]
  • Fixed that an instance variable with the same name as a partial should be implicitly passed as the partial :object 2269 [court3nay]
  • Update Prototype to V1.4.0_pre11, script.aculo.us to [2502] [Thomas Fuchs]
  • Make assert_tag :children count appropriately. Closes 2181. [jamie@bravenet.com]
  • Forced newer versions of RedCloth to use hard breaks [David Heinemeier Hansson]
  • Added new scriptaculous options for auto_complete_field 2343 [Manfred Stienstra]
  • Don‘t prepend the asset host if the string is already a fully-qualified URL
  • Updated to script.aculo.us V1.5.0_rc2 and Prototype to V1.4.0_pre7 [Thomas Fuchs]
  • Undo condition change made in [2345] to prevent normal parameters arriving as StringIO.
  • Tolerate consecutive delimiters in query parameters. 2295 [darashi@gmail.com]
  • Streamline render process, code cleaning. Closes 2294. [skae]
  • Keep flash after components are rendered. 2291 [Rick Olson, Scott]
  • Shorten IE file upload path to filename only to match other browsers. 1507 [court3nay]
  • Fix open/save dialog in IE not opening files send with send_file/send_data, 2279 [Thomas Fuchs]
  • Fixed that auto_discovery_link_tag couldn‘t take a string as the URL [David Heinemeier Hansson]
  • Fixed problem with send_file and WEBrick using stdout 1812 [David Heinemeier Hansson]
  • Optimized tag_options to not sort keys, which is no longer necessary when assert_dom_equal and friend is available 1995 [skae]
  • Added assert_dom_equal and assert_dom_not_equal to compare tags generated by the helpers in an order-indifferent manner 1995 [skae]
  • Fixed that Request#domain caused an exception if the domain header wasn‘t set in the original http request 1795 [Michael Koziarski]
  • Make the truncate() helper multi-byte safe (assuming $KCODE has been set to something other than "NONE") 2103
  • Add routing tests from 1945 [ben@groovie.org]
  • Add a routing test case covering 2101 [Nicholas Seckar]
  • Cache relative_url_root for all webservers, not just Apache 2193 [skae]
  • Speed up cookie use by decreasing string copying 2194 [skae]
  • Fixed access to "Host" header with requests made by crappy old HTTP/1.0 clients 2124 [Marcel Molina Jr.]
  • Added easy assignment of fragment cache store through use of symbols for included stores (old way still works too)

    Before:

      ActionController::Base.fragment_cache_store =
    ActionController::Base::Caching::Fragments::FileStore.new("/path/to/cache/directory")

    After:

      ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"
  • Added ActionController::Base.session_store=, session_store, and session_options to make it easier to tweak the session options (instead of going straight to ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS)
  • Added TextHelper#cycle to cycle over an array of values on each hit (useful for alternating row colors etc) 2154 [dave-ml@dribin.org]
  • Ensure that request.path never returns nil. Closes 1675 [Nicholas Seckar]
  • Add ability to specify Route Regexps for controllers. Closes 1917. [Sebastian Kanthak]
  • Provide Named Route‘s hash methods as helper methods. Closes 1744. [Nicholas Seckar, Steve Purcell]
  • Added :multipart option to ActiveRecordHelper#form to make it possible to add file input fields 2034 [jstirk@oobleyboo.com]
  • Moved auto-completion and in-place editing into the Macros module and their helper counterparts into JavaScriptMacrosHelper
  • Added in-place editing support in the spirit of auto complete with ActionController::Base.in_place_edit_for, JavascriptHelper#in_place_editor_field, and Javascript support from script.aculo.us 2038 [Jon Tirsen]
  • Added :disabled option to all data selects that‘ll make the elements inaccessible for change 2167, 253 [eigentone]
  • Fixed that TextHelper#auto_link_urls would include punctuation in the links 2166, 1671 [eigentone]
  • Fixed that number_to_currency(1000, {:precision => 0})) should return "$1,000", instead of "$1,000." 2122 [sd@notso.net]
  • Allow link_to_remote to use any DOM-element as the parent of the form elements to be submitted 2137 [erik@ruby-lang.nl]. Example:
      <tr id="row023">
    <td><input name="foo"/></td>
    <td><input name="bar"/></td>
    <td><%= link_to_remote 'Save', :update => "row023",
          :submit => "row023", :url => {:action => 'save_row'} %></td>
  </tr>
  • Fixed that render :partial would fail when :object was a Hash (due to backwards compatibility issues) 2148 [Sam Stephenson]
  • Fixed JavascriptHelper#auto_complete_for to only include unique items 2153 [Thomas Fuchs]
  • Fixed all AssetHelper methods to work with relative paths, such that javascript_include_tag(‘stdlib/standard’) will look in /javascripts/stdlib/standard instead of ’/stdlib/standard/’ 1963
  • Avoid extending view instance with helper modules each request. Closes 1979
  • Performance improvements to CGI methods. Closes 1980 [Stefan Kaes]
  • Added :post option to UrlHelper#link_to that makes it possible to do POST requests through normal ahref links using Javascript
  • Fixed overwrite_params
  • Added ActionController::Base.benchmark and ActionController::Base.silence to allow for easy benchmarking and turning off the log
  • Updated vendor copy of html-scanner to support better xml parsing
  • Added :popup option to UrlHelper#link_to 1996 [gabriel.gironda@gmail.com]. Examples:
      link_to "Help", { :action => "help" }, :popup => true
  link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600']
  • Drop trailing \000 if present on RAW_POST_DATA (works around bug in Safari Ajax implementation) 918
  • Fix observe_field to fall back to event-based observation if frequency <= 0 1916 [Michael Schubert]
  • Allow use of the :with option for submit_to_remote 1936 [jon@instance-design.co.uk]
  • AbstractRequest#domain returns nil when host is an ip address 2012 [Kevin Clark]
  • ActionController documentation update 2051 [François Beausoleil]
  • Yield @content_for_ variables to templates 2058 [Sam Stephenson]
  • Make rendering an empty partial collection behave like :nothing => true 2080 [Sam Stephenson]
  • Add option to specify the singular name used by pagination.
  • Use string key to obtain action value. Allows indifferent hashes to be disabled.
  • Added ActionView::Base.cache_template_loading back.
  • Rewrote compiled templates to decrease code complexity. Removed template load caching in favour of compiled caching. Fixed template error messages. [Nicholas Seckar]
  • Fix Routing to handle :some_param => nil better. [Nicholas Seckar, Luminas]
  • Add support for :include with pagination (subject to existing constraints for :include with :limit and :offset) 1478 [Michael Schubert]
  • Prevent the benchmark module from blowing up if a non-HTTP/1.1 request is processed
  • Added :use_short_month option to select_month helper to show month names as abbreviations
  • Make link_to escape the javascript in the confirm option 1964 [nicolas.pouillard@gmail.com]
  • Make assert_redirected_to properly check URL‘s passed as strings 1910 [Scott Barron]
  • Make sure :layout => false is always used when rendering inside a layout
  • Use raise instead of assert_not_nil in Test::Unit::TestCase#process to ensure that the test variables (controller, request, response) have been set
  • Make sure assigns are built for every request when testing 1866
  • Allow remote_addr to be queried on TestRequest 1668
  • Fixed bug when a partial render was passing a local with the same name as the partial
  • Improved performance of test app req/sec with ~10% refactoring the render method 1823 [Stefan Kaes]
  • Improved performance of test app req/sec with 5-30% through a series of Action Pack optimizations 1811 [Stefan Kaes]
  • Changed caching/expiration/hit to report using the DEBUG log level and errors to use the ERROR log level instead of both using INFO
  • Added support for per-action session management 1763
  • Improved rendering speed on complicated templates by up to 100% (the more complex the templates, the higher the speedup) 1234 [Stefan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that.
  • Added options hash as third argument to FormHelper#input, so you can do input(‘person’, ‘zip’, :size=>10) 1719 [jeremye@bsa.ca.gov]
  • Added Base#expires_in(seconds)/Base#expires_now to control HTTP content cache headers 1755 [Thomas Fuchs]
  • Fixed line number reporting for Builder template errors 1753 [piotr]
  • Fixed assert_routing so that testing controllers in modules works as expected [Nicholas Seckar, Rick Olson]
  • Fixed bug with :success/:failure callbacks for the JavaScriptHelper methods 1730 [court3nay/Thomas Fuchs]
  • Added named_route method to RouteSet instances so that RouteSet instance methods do not prevent certain names from being used. [Nicholas Seckar]
  • Fixed routes so that routes which do not specify :action in the path or in the requirements have a default of :action => ‘index’, In addition, fixed url generation so that :action => ‘index’ does not need to be provided for such urls. [Nicholas Seckar, Markjuh]
  • Worked around a Safari bug where it wouldn‘t pass headers through if the response was zero length by having render :nothing return ’ ’ instead of ’’
  • Fixed Request#subdomains to handle "foo.foo.com" correctly

*1.9.1* (11 July, 2005)

  • Fixed that auto_complete_for didn‘t force the input string to lower case even as the db comparison was
  • Fixed that Action View should always use the included Builder, never attempt to require the gem, to ensure compatibility
  • Added that nil options are not included in tags, so tag("p", :ignore => nil) now returns <p /> not <p ignore="" /> but that tag("p", :ignore => "") still includes it 1465 [Michael Schuerig]
  • Fixed that UrlHelper#link_to_unless/link_to_if used html_escape on the name if no link was to be applied. This is unnecessary and breaks its use with images 1649 [joergd@pobox.com]
  • Improved error message for DoubleRenderError
  • Fixed routing to allow for testing of *path components 1650 [Nicholas Seckar]
  • Added :handle as an option to sortable_element to restrict the drag handle to a given class 1642 [thejohnny]
  • Added a bunch of script.aculo.us features 1644, 1677, 1695 [Thomas Fuchs]
    • Effect.ScrollTo, to smoothly scroll the page to an element
    • Better Firefox flickering handling on SlideUp/SlideDown
    • Removed a possible memory leak in IE with draggables
    • Added support for cancelling dragging my hitting ESC
    • Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js (this makes it possible to call sortable_element on the same element more than once, e.g. in AJAX returns that modify the sortable element. all current sortable ‘stuff’ on the element will be discarded and the sortable will be rebuilt)
    • Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances)
    • Removed circular references from element to prevent memory leaks (still not completely gone in IE)
    • Changes to class extension in effects.js
    • Make Effect.Highlight restore any previously set background color when finishing (makes effect work with CSS classes that set a background color)
    • Fixed myriads of memory leaks in IE and Gecko-based browsers [David Zülke]
    • Added incremental and local autocompleting and loads of documentation to controls.js [Ivan Krstic]
    • Extended the auto_complete_field helper to accept tokens option
    • Changed object extension mechanism to favor Object.extend to make script.aculo.us easily adaptable to support 3rd party libs like IE7.js [David Zülke]
  • Fixed that named routes didn‘t use the default values for action and possible other parameters 1534 [Nicholas Seckar]
  • Fixed JavascriptHelper#visual_effect to use camelize such that :blind_up will work 1639 [pelletierm@eastmedia.net]
  • Fixed that a SessionRestoreError was thrown if a model object was placed in the session that wasn‘t available to all controllers. This means that it‘s no longer necessary to use the ‘model :post’ work-around in ApplicationController to have a Post model in your session.

*1.9.0* (6 July, 2005)

  • Added logging of the request URI in the benchmark statement (makes it easy to grep for slow actions)
  • Added javascript_include_tag :defaults shortcut that‘ll include all the default javascripts included with Action Pack (prototype, effects, controls, dragdrop)
  • Cache several controller variables that are expensive to calculate 1229 [Stefan Kaes]
  • The session class backing CGI::Session::ActiveRecordStore may be replaced with any class that duck-types with a subset of Active Record. See docs for details 1238 [Stefan Kaes]
  • Fixed that hashes was not working properly when passed by GET to lighttpd 849 [Nicholas Seckar]
  • Fixed assert_template nil will be true when no template was rendered 1565 [maceywj@telus.net]
  • Added :prompt option to FormOptions#select (and the users of it, like FormOptions#select_country etc) to create "Please select" style descriptors 1181 [Michael Schuerig]
  • Added JavascriptHelper#update_element_function, which returns a Javascript function (or expression) that‘ll update a DOM element according to the options passed 933 [mortonda@dgrmm.net]. Examples:
      <%= update_element_function("products", :action => :insert, :position => :bottom, :content => "<p>New product!</p>") %>

  <% update_element_function("products", :action => :replace, :binding => binding) do %>
    <p>Product 1</p>
    <p>Product 2</p>
  <% end %>
  • Added :field_name option to DateHelper#select_(year|month|day) to deviate from the year/month/day defaults 1266 [Marcel Molina Jr.]
  • Added JavascriptHelper#draggable_element and JavascriptHelper#drop_receiving_element to facilitate easy dragging and dropping through the script.aculo.us libraries 1578 [Thomas Fuchs]
  • Added that UrlHelper#mail_to will now also encode the default link title 749 [f.svehla@gmail.com]
  • Removed the default option of wrap=virtual on FormHelper#text_area to ensure XHTML compatibility 1300 [thomas@columbus.rr.com]
  • Adds the ability to include XML CDATA tags using Builder 1563 [Josh Knowles]. Example:
      xml.cdata! "some text" # => <![CDATA[some text]]>
  • Added evaluation of <SCRIPT> blocks in content returned to Ajax calls 1577 [Thomas Fuchs/court3nay/Sean Treadway]
  • Directly generate paths with a leading slash instead of tacking it on later. 1543 [Nicholas Seckar]
  • Fixed errant parameter modification in functional tests. 1542 [Nicholas Seckar]
  • Routes fail with leading slash 1540 [Nicholas Seckar]
  • Added support for graceful error handling of Ajax calls 1217 [Jamis Buck/Thomas Fuchs]. Example:
      link_to_remote(
    "test",
    :url => { :action => "faulty" },
    :update => { :success => "good", :failure => "bad" },
    403 => "alert('Forbidden- got ya!')",
    404 => "alert('Nothing there...?')",
    :failure => "alert('Unkown error ' + request.status)")
  • Attempt to explicitly flush the output at the end of CgiProcess#out
  • Fixed assert_redirected_to to handle absolute controller paths properly 1472 [Rick Olson/Nicholas Seckar]
  • Added event-based observations when frequency is not set on observe_field/form 1474 [flash@vanklinkenbergsoftware.nl]
  • Added script.aculo.us Javascripts (controls.js, dragdrop.js, effects.js) (NEEDS MORE DESCRIPTION) 1509 [Thomas Fuchs]
  • Fixed prototype to consider all fields it doesn‘t know as text (such as Safari‘s search) just like the browser in its serialization 1497 [Sean Treadway]
  • Improved performance of Routes generation by a factor of 5 1434 [Nicholas Seckar]
  • Added named routes (NEEDS BETTER DESCRIPTION) 1434 [Nicholas Seckar]
  • Improved AbstractRequest documentation 1483 [court3nay]
  • Added ActionController::Base.allow_concurrency to control whether the application is thread-safe, so multi-threaded servers like WEBrick knows whether to apply a mutex around the performance of each action. Turned off by default. EXPERIMENTAL FEATURE.
  • Added TextHelper#word_wrap(text, line_length = 80) 1449 [tuxie@dekadance.se]
  • Added a fall-through action for form_remote_tag that‘ll be used in case Javascript is unavailable 1459 [Scott Barron]. Example:
      form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") }
  • Added :xhr => true/false option to verify so you can ensure that a request is coming from an Ajax call or not 1464 [Thomas Fuchs]
  • Added tag_options as a third parameter to AssetHelper#auto_discovery_link_tag to control options like the title of the link 1430 [Kevin Clark]
  • Added option to pass in parameters to CaptureHelper#capture, so you can create more advanced view helper methods 1466 [duane.johnson@gmail.com]. Example:
      <% show_calendar(:year => 2005, :month => 6) do |day, options| %>
    <% options[:bgcolor] = '#dfd' if 10..15.include? day %>
    [<%= day %>]
  <% end %>
  • Changed the default name of the input tag generated by FormTagHelper#submit_tag from "submit" to "commit" so it doesn‘t clash with form.submit() calls in Javascript 1271
  • Fixed relative urls support for lighttpd 1048 [Nicholas Seckar/maznawak@nerim.net]
  • Correct distance_of_time_in_words for integer arguments and make the second arg optional, treating the first arg as a duration in seconds. 1458 [madrobby <thomas@fesch.at>]
  • Fixed query parser to deal gracefully with equal signs inside keys and values 1345 [gorou]. Example: /?sig=abcdef=:foobar=&x=y will pass now.
  • Added Cuba to country list 1351 [todd]
  • Fixed radio_button to work with numeric values 1352 [demetrius]
  • Added :extension option to NumberHelper#number_to_phone 1361 [delynnb]
  • Added button_to as a form-based solution to deal with harmful actions that should be hidden behind POSTs. This makes it just as easy as link_to to create a safe trigger for actions like destroy, although it‘s limited by being a block element, the fixed look, and a no-no inside other forms. 1371 [tom@moertel.com]
  • Fixed image_tag so an exception is not thrown just because the image is missing and alt value can‘t be generated 1395 [Marcel Molina Jr.]
  • Added a third parameter to TextHelper#auto_link called href_options for specifying additional tag options on the links generated 1401 [tyler.kovacs@gmail.com]. Example: auto_link(text, :all, { :target => "_blank" }) to have all the generated links open in a new window.
  • Fixed TextHelper#highlight to return the text, not nil, if the phrase is blank 1409 [Patrick Lenz]
  • Fixed TagHelper such that :name and ‘name’ keys in the options doesn‘t result in two attributes 1455 [take_tk]
  • Ensure that helpers are only available to the controllers where they are defined and their subclasses. 1394 [kdole@tamu.edu]
  • render("foo/bar") works with a layout again
  • Fixed double-singularization on scaffolded pagination call (Address would be turned into Addres) 1216, 1404 [nilsga]
  • Removed the require hack used by functional testing to work around an earlier bug in rake.
  • Allow distance_of_time_in_words to work with any value that responds to to_time (like dates) 969
  • Support :render option for :verify 1440 [Tobias Lütke]
  • Updated vendor copy of html-scanner lib to 0.5.2, for bug fixes and optimizations. The :content option may be used as expected—to find a tag whose textual content is a particular value—in assert_tag, now.
  • Changed test requests to come from 0.0.0.0 instead of 127.0.0.1 such that they don‘t trigger debugging screens on exceptions, but instead call rescue_action_in_public
  • Modernize scaffolding to match the generator: use the new render method and change style from the warty @params["id"] to the sleek params[:id]. 1367
  • Include :id in the action generated by the form helper method. Then, for example, the controller can do Model.find(params[:id]) for both edit and update actions. Updated scaffolding to take advantage. 1367
  • Add assertions with friendly messages to TestCase#process to ensure that @controller, @request, and @response are set. 1367
  • Arrays, hashes sent via multipart posts are converted to strings 1032 [dj@omelia.org, me@julik.nl]
  • render(:layout => true) is a synonym for render(:layout => nil)
  • Make sure the benchmarking render method always returns the output of the render.
  • render(:action), render(:template) and render() are the only three calls that default to using a layout. All other render calls assume :layout => false. This also fixes send_file, which was applying a layout if one existed for the current action.
  • verify with :redirect_to won‘t redirect if a redirect or render has already been performed 1350
  • render(:partial => true) is identical to the behavior of the deprecated render_partial()
  • Fixed render(:partial => "…") to use an empty Hash for the local assigns 1365
  • Fixed Caching::Fragments::FileStore.delete to not raise an exception if the delete fails.
  • Deprecated all render_* methods in favor of consolidating all rendering behavior in Base#render(options). This enables more natural use of combining options, such as layouts. Examples:
      +---------------------------------------------------------------+-------------------------------------------------------+
  | BEFORE                                                        | AFTER                                                 |
  +---------------------------------------------------------------+-------------------------------------------------------+
  | render_with_layout "weblog/show", "200 OK", "layouts/dialog"  | render :action => "show", :layout => "dialog"         |
  | render_without_layout "weblog/show"                           | render :action => "show", :layout => false            |
  | render_action "error", "404 Not Found"                        | render :action => "error", :status => "404 Not Found" |
  | render_template "xml.div('stuff')", "200 OK", :rxml           | render :inline => "xml.div('stuff')", :type => :rxml  |
  | render_text "hello world!"                                    | render :text => "hello world!"                        |
  | render_partial_collection "person", @people, nil, :a => 1     | render :partial => "person", :collection => @people,  |
  |                                                               |        :locals => { :a => 1 }                         |
  +---------------------------------------------------------------+-------------------------------------------------------+
  • Deprecated redirect_to_path and redirect_to_url in favor of letting redirect_to do the right thing when passed either a path or url.
  • Fixed use of an integer as return code for renders, so render_text "hello world", 404 now works 1327
  • Fixed assert_redirect_to to work with redirect_to_path 869 [Nicholas Seckar]
  • Fixed escaping of :method option in remote_form_tag 1218 [Rick Olson]
  • Added Serbia and Montenegro to the country_select 1239 [todd@robotcoop.com]
  • Fixed Request#remote_ip in testing 1251 [Jeremy Kemper]
  • Fixed that compute_public_path should recognize external URLs, so image_tag(" [image] ") is not prefixed with the relative url path 1254 [victor-ronr-trac@carotena.net]
  • Added support for descending year values in DateHelper#select_year, like select_year(Date.today, :start_year => 2005, :end_year => 1900), which would count down from 2005 to 1900 instead of the other way 1274 [nwoods@mail.com]
  • Fixed that FormHelper#checkbox should return a checked checkbox if the value is the same as checked_value 1286 [Florian Weber]
  • Fixed Form.disable in Prototype 1317 [Wintermute]
  • Added accessors to logger, params, response, session, flash, and headers from the view, so you can write <% logger.info "stuff" %> instead of <% @logger.info "others" %> — more consistent with the preferred way of accessing these attributes and collections from the controller
  • Added support for POST data in form of YAML or XML, which is controller through the Content-Type header. Example request:
      Content-Type: application/xml
  <request><item><content>HelloWorld</content></item></request>

    …is the same as:

      Content-Type: application/x-yaml
  ---
  item:
    content: HelloWorld

    …is the same as:

      item[content]=HelloWorld

    Which in the end turns into { "item" => { "content" => "HelloWorld" } }. This makes it a lot easier to publish REST web services on top of your regular actions (as they won‘t care).

    Example Curl call:

      curl -H 'Content-Type: application/xml' -d '<request><item><content>KillMeMore</content></item></request>' http://www.example.com/service

    You can query to find out whether a given request came through as one of these types with:

      - request.post_format? (:url_encoded, :xml or :yaml)
  - request.formatted_post? (for either xml or yaml)
  - request.xml_post?
  - request.yaml_post?
  • Added bundling of XmlSimple by Maik Schmidt
  • Fixed that render_partial_collection should always return a string (and not sometimes an array, despite <%= %> not caring)
  • Added TextHelper#sanitize that can will remove any Javascript handlers, blocks, and forms from an input of HTML. This allows for use of HTML on public sites, but still be free of XSS issues. 1277 [Jamis Buck]
  • Fixed the HTML scanner used by assert_tag where a infinite loop could be caused by a stray less-than sign in the input 1270 [Jamis Buck]
  • Added functionality to assert_tag, so you can now do tests on the siblings of a node, to assert that some element comes before or after the element in question, or just to assert that some element exists as a sibling 1226 [Jamis Buck]
  • Added better error handling for regexp caching expiration
  • Fixed handling of requests coming from unknown HTTP methods not to kill the server
  • Added that both AssetHelper#stylesheet_link_tag and AssetHelper#javascript_include_tag now accept an option hash as the last parameter, so you can do stuff like: stylesheet_link_tag "style", :media => "all"
  • Added FormTagHelper#image_submit_tag for making submit buttons that uses images
  • Added ActionController::Base.asset_host that will then be used by all the asset helpers. This enables you to easily offload static content like javascripts and images to a separate server tuned just for that.
  • Fixed action/fragment caching using the filestore when a directory and a file wanted to use the same name. Now there‘s a .cache prefix that sidesteps the conflict 1188 [imbcmdth@hotmail.com]
  • Fixed missing id uniqueness in FormTag#radio_button 1207 [Jarkko Laine]
  • Fixed assert_redirected_to to work with :only_path => false 1204 [Alisdair McDiarmid]
  • Fixed render_partial_collection to output an empty string instead of nil when handed an empty array 1202 [Ryan Carver]
  • Improved the speed of regular expression expirations for caching by a factor of 10 1221 [Jamis Buck]
  • Removed dumping of template assigns on the rescue page as it would very easily include a ton of data making page loads take seconds (and the information was rarely helpful) 1222
  • Added BenchmarkHelper that can measure the execution time of a block in a template and reports the result to the log. Example:
      <% benchmark "Notes section" do %>
    <%= expensive_notes_operation %>
  <% end %>

 Will add something like "Notes section (0.345234)" to the log.
  • Added ActionController::Caching::Sweeper as an improved an easier to use sweeper. The new sweepers work on a single-step approach instead of two-steps like the old ones. Before
      def after_save(record)
    @list = record.is_a?(List) ? record : record.list
  end

  def filter(controller)
    controller.expire_page(:controller => "lists", :action => %w( show public feed ), :id => @list.id)
    controller.expire_action(:controller => "lists", :action => "all")
    @list.shares.each { |share| controller.expire_page(:controller => "lists", :action => "show", :id => share.url_key) }
  end

    ..after:

      def after_save(record)
    list = record.is_a?(List) ? record : record.list
    expire_page(:controller => "lists", :action => %w( show public feed ), :id => list.id)
    expire_action(:controller => "lists", :action => "all")
    list.shares.each { |share| expire_page(:controller => "lists", :action => "show", :id => share.url_key) }
  end

    The new sweepers can also observe on the actions themselves by implementing methods according to (before|after)_$controller_$action. Example of a callback that‘ll be called after PagesController#update_title has been performed:

        def after_pages_update_title
      expire_fragment(%r{pages/#{controller.assigns["page"].id}/.*})
    end

    Note that missing_method is delegated to the controller instance, which is assigned in a before filter. This means that you can call expire_fragment instead of @controller.expire_fragment.

  • Added that Fragments#expire_fragment now accepts as a regular expression as the name thereby deprecating expire_matched_fragments
  • Fixed that fragments shouldn‘t use the current host and the path as part of the key like pages does
  • Added conditions to around_filters just like before_filter and after_filter

*1.8.1* (20th April, 2005)

  • Added xml_http_request/xhr method for simulating XMLHttpRequest in functional tests 1151 [Sam Stephenson]. Example:
      xhr :post, :index
  • Fixed that Ajax.Base.options.asynchronous wasn‘t being respected in Ajax.Request (thanks Jon Casey)
  • Fixed that :get, :post, and the others should take a flash array as the third argument just like process 1144 [rails@cogentdude.com]
  • Fixed a problem with Flash.now
  • Fixed stringification on all assigned hashes. The sacrifice is that assigns[:person] won‘t work in testing. Instead assigns["person"] or assigns(:person) must be used. In other words, the keys of assigns stay strings but we‘ve added a method-based accessor to appease the need for symbols.
  • Fixed that rendering a template would require a connection to the database 1146

*1.8.0* (19th April, 2005)

  • Added assert_tag and assert_no_tag as a much improved alternative to the deprecated assert_template_xpath_match 1126 [Jamis Buck]
  • Deprecated the majority of all the testing assertions and replaced them with a much smaller core and access to all the collections the old assertions relied on. That way the regular test/unit assertions can be used against these. Added documentation about how to use it all.
  • Added a wide range of new Javascript effects:
      * Effect.Puff zooms the element out and makes it smoothly transparent at the same time, giving a "puff" illusion #996 [thomas@fesch.at]
    After the animation is completed, the display property will be set to none.
    This effect will work on relative and absolute positioned elements.

  * Effect.Appear as the opposite of Effect.Fade #990 [thomas@fesch.at]
    You should return elements with style="display:none;" or a like class for this to work best and have no chance of flicker.

  * Effect.Squish for scaling down an element and making it disappear at the end #972 [thomas@fesch.at]

  * Effect.Scale for smoothly scaling images or text up and down #972 [thomas@fesch.at]

  * Effect.Fade which smoothly turns opacity from 100 to 0 and then hides the element #960 [thomas@fesch.at]
  • Added Request#xml_http_request? (and an alias xhr?) to that‘ll return true when the request came from one of the Javascript helper methods (Ajax). This can be used to give one behavior for modern browsers supporting Ajax, another to old browsers 1127 [Sam Stephenson]
  • Changed render_partial to take local assigns as the second parameter instead of an explicit object and then the assigns. So the API changes from:
      <%= render_partial "account", person, "rules" => regulations.rules %>

    …to:

      <%= render_partial "account", :account => person, :rules => regulations.rules %>

    The old API will still work, though, and render_partial "account" will still assume :account => @account.

  • Added support for web servers that use PATH_INFO instead of REQUEST_URI like IIS 1014 [BradG/Nicholas Seckar]
  • Added graceful handling of PUT, DELETE, and OPTIONS requests for a complete coverage of REST functionality 1136 [Josh Knowles]
  • Fixed that you can now pass an alternative :href option to link_to_function/remote in order to point to somewhere other than # if the javascript fails or is turned off. You can do the same with form_remote_tag by passing in :action. 1113 [Sam Stephenson]
  • Fixed DateHelper to return values on the option tags such that they‘ll work properly in IE with form_remote_tag 1024 [Scott Raymond]
  • Fixed FormTagHelper#check_box to respect checked 1049 [DelynnB]
  • Added that render_partial called from a controller will use the action name as default 828 [Dan Peterson]
  • Added Element.toggle, Element.show, and Element.hide to the prototype javascript library. Toggle.display has been deprecated, but will still work 992 [Lucas Carlson]
  • Added that deleting a cookie should not just set it to an empty string but also instantly expire it 1118 [todd@robotcoop.com]
  • Added AssetTagHelper#image_path, AssetTagHelper#javascript_path, and AssetTagHelper#stylesheet_path 1110 [Larry Halff]
  • Fixed url_for(nil) in functional tests 1116 [Alisdair McDiarmid]
  • Fixed error handling of broken layouts 1115 [Michael Schubert]
  • Added submit_to_remote that allows you to trigger an Ajax form submition at the click of the submission button, which allows for multiple targets in a single form through the use of multiple submit buttons 930 [yrashk@gmail.com]
  • Fixed pagination to work with joins 1034 [scott@sigkill.org]
  • Fixed that *rest parameter in map.connect couldn‘t accept an empty list 1037 [Dee Zsombor]
  • Added :confirm option to link_to_remote just like link_to has 1082 [yrashk@fp.org.ua]
  • Added minute_step as an option to select_minute (and the helpers that use it) to jump in larger increments than just 1 minute. At 15, it would return 0, 15, 30, 45 options 1085 [ordwaye@evergreen.edu]
  • Fixed that an exception would be thrown when an empty form was submitted 1090 [jan@ulbrich-boerwang.de]
  • Moved TextHelper#human_size to NumberHelper#number_to_human_size, but kept an deprecated alias to the old method name
  • Fixed that the content-type for some browsers could include an additional \r which made wonky things happen 1067 [Thomas Fuchs]
  • Fixed that radio buttons shouldn‘t have a default size attribute 1074 [hendrik@mans.de]
  • Added ActionView::Helpers::InstanceTag::DEFAULT_RADIO_OPTIONS that contains a hash of default options for radio buttons 1074 [hendrik@mans.de]
  • Fixed that in some circumstances controllers outside of modules may have hidden ones inside modules. For example, admin/content might have been hidden by /content. 1075 [Nicholas Seckar]
  • Added JavascriptHelper#periodically_call_remote in order to create areas of a page that update automatically at a set interval 945 [Jon Tirsen]
  • Fixed Cache#expire_matched_fragments that couldn‘t recognize the difference between string and url_for options 1030 [Stefan Kaes]
  • Added simulation of @request.request_uri in functional tests 1038 [Jamis Buck]
  • Fixed autolinking to work better in more cases 1013 [Jamis Buck]
  • Added the possible of using symbols in form helpers that relate to instance variables like text_field :account, :name in addition to text_field "account", "name"’
  • Fixed javascript_include_tag to output type instead of language and conform to XHTML 1018 [Rick Olson]
  • Added NumberHelper for common string representations like phone number, currency, and percentage 1015 [DeLynn]
  • Added pagination for scaffolding (10 items per page) 964 [mortonda@dgrmm.net]
  • Added assert_no_cookie and fixed assert_cookie_equal to deal with non-existing cookies 979 [Jeremy Kemper]
  • Fixed :overwrite_param so it doesn‘t delete but reject elements from @request.parameters 982 [raphinou@yahoo.com]
  • Added :method option to verify for ensuring that either GET, POST, etc is allowed 984 [Jamis Buck]
  • Added options to set cc, bcc, subject, and body for UrlHelper#mail_to 966 [DeLynn]
  • Fixed include_blank for select_hour/minute/second 527 [edward@debian.org]
  • Improved the message display on the exception handler pages 963 [Johan Sorensen]
  • Fixed that on very rare occasions, webrick would raise a NoMethodError: private method ‘split’ called for nil 1001 [Flurin Egger]
  • Fixed problem with page caching 958 [Rick Olson]

*1.7.0* (27th March, 2005)

  • Added ActionController::Base.page_cache_extension for setting the page cache file extension (the default is .html) 903 [Andreas]
  • Fixed "bad environment variable value" exception caused by Safari, Apache, and Ajax calls 918
  • Fixed that pagination_helper would ignore :params 947 [Sebastian Kanthak]
  • Added :owerwrite_params back to url_for and friends — it was AWL since the introduction of Routes 921 [raphinou]
  • Added :position option to link_to_remote/form_remote_tag that can be either :before, :top, :bottom, or :after and specifies where the return from the method should be inserted 952 [Matthew McCray/Sam Stephenson]
  • Added Effect.Highlight to prototype.js to do Yellow Fade Technique (of 37signals’ fame) on any container 952 [Sam Stephenson/court3nay]
  • Added include_seconds option as the third parameter to distance_of_time_in_words which will render "less than a minute" in higher resolution ("less than 10 seconds" etc) 944 [thomas@fesch.at]
  • Added fourth option to process in test cases to specify the content of the flash 949 [Jamis Buck]
  • Added Verifications that allows you to specify preconditions to actions in form of statements like verify :only => :update_post, :params => "admin_privileges", :redirect_to => { :action => "settings" }, which ensure that the update_post action is only called if admin_privileges is available as a parameter — otherwise the user is redirected to settings. 897 [Jamis Buck]
  • Fixed Form.Serialize for the JavascriptHelper to also seriliaze password fields 934 [dweitzman@gmail.com]
  • Added JavascriptHelper#escape_javascript as a public method (was private) and made it escape both single and double quotes and new lines 940 [mortonda@dgrmm.net]
  • Added trailing_slash option to url_for, so you can generate urls ending in a slash. Note that is currently not recommended unless you need it for special reasons since it breaks caching 937 [stian@grytoyr.net]
  • Added expire_matched_fragments(regular_expression) to clear out a lot of fragment caches at once 927 [Rick Olson]
  • Fixed the problems with : and ? in file names for fragment caches on Windows 927 [Rick Olson]
  • Added TextHelper#human_size for formatting file sizes, like human_size(1234567) => 1.2 MB 943 [thomas@fesch.at]
  • Fixed link_to :confirm 936 [Nicholas Seckar]
  • Improved error reporting especially around never shallowing exceptions. Debugging helpers should be much easier now 980 [Nicholas Seckar]
  • Fixed Toggle.display in prototype.js 902 [Lucas Carlson]

*1.6.0* (22th March, 2005)

  • Added a JavascriptHelper and accompanying prototype.js library that opens the world of Ajax to Action Pack with a large array of options for dynamically interacting with an application without reloading the page 884 [Sam Stephenson/David]
  • Added pagination support through both a controller and helper add-on 817 [Sam Stephenson]
  • Fixed routing and helpers to make Rails work on non-vhost setups 826 [Nicholas Seckar/Tobias Lütke]
  • Added a much improved Flash module that allows for finer-grained control on expiration and allows you to flash the current action 839 [Caio Chassot]. Example of flash.now:
      class SomethingController < ApplicationController
    def save
      ...
      if @something.save
        # will redirect, use flash
        flash[:message] = 'Save successful'
        redirect_to :action => 'list'
      else
        # no redirect, message is for current action, use flash.now
        flash.now[:message] = 'Save failed, review'
        render_action 'edit'
      end
    end
  end
  • Added to_param call for parameters when composing an url using url_for from something else than strings 812 [Sam Stephenson]. Example:
      class Page
    def initialize(number)
      @number = number
    end
    # ...
    def to_param
      @number.to_s
    end
  end

    You can now use instances of Page with url_for:

      class BarController < ApplicationController
    def baz
      page = Page.new(4)
      url = url_for :page => page # => "http://foo/bar/baz?page=4"
    end
  end
  • Fixed form helpers to query Model#id_before_type_cast instead of Model#id as a temporary workaround for Ruby 1.8.2 warnings 818 [DeLynn B]
  • Fixed TextHelper#markdown to use blank? instead of empty? so it can deal with nil strings passed 814 [Johan Sörensen]
  • Added TextHelper#simple_format as a non-dependency text presentation helper 814 [Johan Sörensen]
  • Added that the html options disabled, readonly, and multiple can all be treated as booleans. So specifying disabled => :true will give disabled="disabled". 809 [mindel]
  • Added path collection syntax for Routes that will gobble up the rest of the url and pass it on to the controller 830 [rayners]. Example:
      map.connect 'categories/*path_info', :controller => 'categories', :action => 'show'

    A request for /categories/top-level-cat, would give @params[:path_info] with "top-level-cat". A request for /categories/top-level-cat/level-1-cat, would give @params[:path_info] with "top-level-cat/level-1-cat" and so forth.

    The @params[:path_info] return is really an array, but where to_s has been overwritten to do join("/").

  • Fixed options_for_select on selected line issue 624 [Florian Weber]
  • Added CaptureHelper with CaptureHelper#capture and CaptureHelper#content_for. See documentation in helper 837 [Tobias Lütke]
  • Fixed :anchor use in url_for 821 [Nicholas Seckar]
  • Removed the reliance on PATH_INFO as it was causing problems for caching and inhibited the new non-vhost support 822 [Nicholas Seckar]
  • Added assigns shortcut for @response.template.assigns to controller test cases [Jeremy Kemper]. Example:

    Before:

      def test_list
    assert_equal 5, @response.template.assigns['recipes'].size
    assert_equal 8, @response.template.assigns['categories'].size
  end

    After:

      def test_list
    assert_equal 5, assigns(:recipes).size
    assert_equal 8, assigns(:categories).size
  end
  • Added TagHelper#image_tag and deprecated UrlHelper#link_image_to (recommended approach is to combine image_tag and link_to instead)
  • Fixed textilize to be resilient to getting nil parsed (by using Object#blank? instead of String#empty?)
  • Fixed that the :multipart option in FormTagHelper#form_tag would be ignored [Yonatan Feldman]

*1.5.1* (7th March, 2005)

  • Fixed that the routes.rb file wouldn‘t be found on symlinked setups due to File.expand_path 793 [piotr@t-p-l.com]
  • Changed ActiveRecordStore to use Marshal instead of YAML as the latter proved troublesome in persisting circular dependencies. Updating existing applications MUST clear their existing session table from data to start using this updated store 739 [Jamis Buck]
  • Added shortcut :id assignment to render_component and friends (before you had to go through :params) 784 [Lucas Carlson]
  • Fixed that map.connect should convert arguments to strings 780 [Nicholas Seckar]
  • Added UrlHelper#link_to_if/link_to_unless to enable other conditions that just link_to_unless_current 757 [mindel]
  • Fixed that single quote was not escaped in a UrlHelper#link_to javascript confirm 549 [Scott Barron]
  • Removed the default border on link_image_to (it broke xhtml strict) — can be specified with :border => 0 517 [?/caleb]
  • Fixed that form helpers would treat string and symbol keys differently in html_options (and possibly create duplicate entries) 112 [Jeremy Kemper]
  • Fixed that broken pipe errors (clients disconnecting in mid-request) could bring down a fcgi process
  • Added the original exception message to session recall errors (so you can see which class wasnt required)
  • Fixed that RAILS_ROOT might not be defined when AP was loaded, so do a late initialization of the ROUTE_FILE 761 [Scott Barron]
  • Fix request.path_info and clear up LoadingModule behavior 754 [Nicholas Seckar]
  • Fixed caching to be aware of extensions (so you can cache files like api.wsdl or logo.png) 734 [Nicholas Seckar]
  • Fixed that Routes would raise NameErrors if a controller component contains characters that are not valid constant names 733 [Nicholas Seckar]
  • Added PATH_INFO access from the request that allows urls like the following to be interpreted by rails: www.example.com/dispatcher.cgi/controller/action — that makes it possible to use rails as a CGI under lighttpd and would also allow (for example) Rublog to be ported to rails without breaking existing links to Rublog-powered blogs. 728 [Jamis Buck]
  • Fixed that caching the root would result in .html not index.html 731, 734 [alisdair/Nicholas Seckar]

*1.5.0* (24th February, 2005)

  • Added Routing as a replacement for mod_rewrite pretty urls [Nicholas Seckar]. Read more in ActionController::Base.url_for and on manuals.rubyonrails.com/read/book/9
  • Added components that allows you to call other actions for their rendered response while execution another action. You can either delegate the entire response rendering or you can mix a partial response in with your other content. Read more on manuals.rubyonrails.com/read/book/14

* Fixed that proxy IPs do not follow all RFC1918 nets 251 [caleb@aei-tech.com]

  • Added Base#render_to_string to parse a template and get the result back as a string 479
  • Fixed that send_file/data can work even if render* has been called before in action processing to render the content of a file to be send for example 601
  • Added FormOptionsHelper#time_zone_select and FormOptionsHelper#time_zone_options_for_select to work with the new value object TimeZone in Active Support 688 [Jamis Buck]
  • Added FormHelper#file_field and FormTagHelper#file_field_tag for creating file upload fields
  • Added :order option for date_select that allows control over the order in which the date dropdowns is used and which of them should be used 619 [Tim Bates]. Examples:
      date_select("post", "written_on", :order => [:day, :month, :year])
  date_select("user", "birthday",   :order => [:month, :day])
  • Added ActionView::Base.register_template_handler for easy integration of an alternative template language to ERb and Builder. See test/controller/custom_handler_test.rb for a usage example 656 [Jamis Buck]
  • Added AssetTagHelper that provides methods for linking a HTML page together with other assets, such as javascripts, stylesheets, and feeds.
  • Added FormTagHelper that provides a number of methods for creating form tags that doesn‘t rely on conventions with an object assigned to the template like FormHelper does. With the FormTagHelper, you provide the names and values yourself.
  • Added Afghanistan, Iran, and Iraq to the countries list used by FormOptions#country_select and FormOptions#country_options_for_select
  • Renamed link_to_image to link_image_to (since thats what it actually does) — kept alias for the old method name
  • Fixed textilize for RedCloth3 to keep doing hardbreaks
  • Fixed that assert_template_xpath_matches did not indicate when a path was not found 658 [Eric Hodel]
  • Added TextHelper#auto_link to turn email addresses and urls into ahrefs
  • Fixed that on validation errors, scaffold couldn‘t find template 654 [mindel]
  • Added Base#hide_action(*names) to hide public methods from a controller that would otherwise have been callable through the URL. For the majority of cases, its preferred just to make the methods you don‘t want to expose protected or private (so they‘ll automatically be hidden) — but if you must have a public method, this is a way to make it uncallable. Base#hidden_actions retrieve the list of all hidden actions for the controller 644 [Nicholas Seckar]
  • Fixed that a bunch of methods from ActionController::Base was accessible as actions (callable through a URL) when they shouldn‘t have been 644 [Nicholas Seckar]
  • Added UrlHelper#current_page?(options) method to check if the url_for options passed corresponds to the current page
  • Fixed https handling on other ports than 443 [Alan Gano]
  • Added follow_redirect method for functional tests that‘ll get-request the redirect that was made. Example:
      def test_create_post
    post :create, "post" => { "title" => "Exciting!" }
    assert_redirected_to :action => "show"

    follow_redirect
    assert_rendered_file "post/show"
  end

    Limitation: Only works for redirects to other actions within the same controller.

  • Fixed double requiring of models with the same name as the controller
  • Fixed that query params could be forced to nil on a POST due to the raw post fix 562 [moriq@moriq.com]
  • Fixed that cookies shouldn‘t be frozen in TestRequest 571 [Eric Hodel]

*1.4.0* (January 25th, 2005)

  • Fixed problems with ActiveRecordStore under the development environment in Rails
  • Fixed the ordering of attributes in the xml-decleration of Builder 540 [woeye]
  • Added @request.raw_post as a convenience access to @request.env[‘RAW_POST_DATA’] 534 [Tobias Lütke]
  • Added support for automatic id-based indexing for lists of items 532 [dblack]. Example:
      <% @students.each do |@student| %>
    <%= text_field "student[]", "first_name", :size => "20" %>
    <%= text_field "student[]", "last_name" %>
    <%= text_field "student[]", "grade", :size => "5" %>
  <% end %>

    …would produce, for say David Black with id 123 and a grace of C+:

      <input id="student_123_first_name" name="student[123][first_name]" size="20"     size="30" type="text" value="David" />
  <input id="student_123_last_name" name="student[123][last_name]" size="30"  type="text" value="Black" />
  <input id="student_123_grade" name="student[123][grade]" size="5" type="text"  value="C+" />
  • Added :application_prefix to url_for and friends that makes it easier to setup Rails in non-vhost environments 516 [Jamis Buck]
  • Added :encode option to mail_to that‘ll allow you to masquarede the email address behind javascript or hex encoding 494 [Lucas Carlson]
  • Fixed that the content-header was being set to application/octet_stream instead of application/octet-stream on send_date/file [Alexey]
  • Removed the need for passing the binding when using CacheHelper#cache
  • Added TestResponse#binary_content that‘ll return as a string the data sent through send_data/send_file for testing 500 [Alexey]
  • Added @request.env[‘RAW_POST_DATA’] for people who need access to the data before Ruby‘s CGI has parsed it 505 [Jeremy Kemper]
  • Fixed that a default fragment store wan‘t being set to MemoryStore as intended.
  • Fixed that all redirect and render calls now return true, so you can use the pattern of "do and return". Example:
      def show
    redirect_to(:action => "login") and return unless @person.authenticated?
    render_text "I won't happen unless the person is authenticated"
  end
  • Added that renders and redirects called in before_filters will have the same effect as returning false: stopping the chain. Example:
      class WeblogController
    before_filter { |c| c.send(:redirect_to_url("http://www.farfaraway.com")}) }

    def hello
      render_text "I will never be called"
    end
  end
  • Added that only one render or redirect can happen per action. The first call wins and subsequent calls are ignored. Example:
      def do_something
    redirect_to :action => "elsewhere"
    render_action "overthere"
  end

    Only the redirect happens. The rendering call is simply ignored.

*1.3.1* (January 18th, 2005)

  • Fixed a bug where cookies wouldn‘t be set if a symbol was used instead of a string as the key
  • Added assert_cookie_equal to assert the contents of a named cookie
  • Fixed bug in page caching that prevented it from working at all

*1.3.0* (January 17th, 2005)

  • Added an extensive caching module that offers three levels of granularity (page, action, fragment) and a variety of stores. Read more in ActionController::Caching.
  • Added the option of passing a block to ActiveRecordHelper#form in order to add more to the auto-generated form 469 [dom@sisna.com]
      form("entry", :action => "sign") do |form|
    form << content_tag("b", "Department")
    form << collection_select("department", "id", @departments, "id", "name")
  end
  • Added arrays as a value option for params in url_for and friends 467 [Eric Anderson]. Example:
      url_for(:controller => 'user', :action => 'delete', :params => { 'username' =>  %( paul john steve ) } )
  # => /user/delete?username[]=paul&username[]=john&username[]=steve
  • Fixed that controller tests can now assert on the use of cookies 466 [Alexey]
  • Fixed that send_file would "remember" all the files sent by adding to the headers again and again 458 [Jeremy Kemper]
  • Fixed url rewriter confusion when the controller or action name was a substring of the controller_prefix or action_prefix
  • Added conditional layouts like layout "weblog_standard", :except => :rss 452 [Marcel Molina Jr.]
  • Fixed that MemCacheStore wasn‘t included by default and added default MemCache object pointing to localhost 447 [Lucas Carlson]
  • Added fourth argument to render_collection_of_partials that allows you to specify local_assigns — just like render_partial 432 [Ryan Davis]
  • Fixed that host would choke when cgi.host returned nil 432 [Tobias Lütke]
  • Added that form helpers now take an index option 448 [Tim Bates]

    Example:

      text_field "person", "name", "index" => 3

    Becomes:

      <input type="text" name="person[3][name]" id="person_3_name" value="<%= @person.name %>" />
  • Fixed three issues with retrying breakpoints 417 [Florian Gross]
    1. Don‘t screw up pages that use multiple values for the same parameter (?foo=bar&foo=qux was converted to ?foo=barqux)
    2. Don‘t screw up all forms when you click the "Retry with Breakpoint" link multiple times instead of reloading (This caused the parameters to be added multiple times for GET forms leading to trouble.)
    3. Don‘t add ?BP-RETRY=1 multiple times
  • Added that all renders and redirects now return false, so they can be used as the last line in before_filters to stop execution.

    Before:

      def authenticate
    unless @session[:authenticated]
      redirect_to :controller => "account", :action => "login"
      return false
    end
  end

    After:

      def authenticate
    redirect_to(:controller => "account", :action => "login") unless @session[:authenticated]
  end
  • Added conditional filters 431 [Marcel Molina Jr.]. Example:
      class JournalController < ActionController::Base
    # only require authentication if the current action is edit or delete
    before_filter :authorize, :only_on => [ :edit, :delete ]

    private
      def authorize
        # redirect to login unless authenticated
      end
  end
  • Added Base#render_nothing as a cleaner way of doing render_text "" when you‘re not interested in returning anything but an empty response.
  • Added the possibility of passing nil to UrlHelper#link_to to use the link itself as the name

*1.2.0* (January 4th, 2005)

  • Added MemCacheStore for storing session data in Danga‘s MemCache system [Bob Cottrell] Depends on: MemCached server (www.danga.com/memcached/), MemCache client (raa.ruby-lang.org/project/memcache/)
  • Added thread-safety to the DRbStore 66, 389 [Ben Stiglitz]
  • Added DateHelper#select_time and DateHelper#select_second 373 [Scott Baron]
  • Added :host and :protocol options to url_for and friends to redirect to another host and protocol than the current.
  • Added class declaration for the MissingFile exception 388 [Kent Sibilev]
  • Added "short hypertext note with a hyperlink to the new URI(s)" to redirects to fulfill compliance with RFC 2616 (HTTP/1.1) section 10.3.3 397 [Tim Bates]
  • Added second boolean parameter to Base.redirect_to_url and Response#redirect to control whether the redirect is permanent or not (301 vs 302) 375 [Hodel]
  • Fixed redirects when the controller and action is named the same. Still haven‘t fixed same controller, module, and action, though 201 [Josh Peek]
  • Fixed problems with running multiple functional tests in Rails under 1.8.2 by including hack for test/unit weirdness
  • Fixed that @request.remote_ip didn‘t work in the test environment 369 [Bruno Mattarollo]

*1.1.0*

  • Added search through session to clear out association caches at the end of each request. This makes it possible to place Active Record objects in the session without worrying about stale data in the associations (the main object is still subject to caching, naturally) 347 [Tobias Lütke]
  • Added more informative exception when using helper :some_helper and the helper requires another file that fails, you‘ll get an error message tells you what file actually failed to load, rather than falling back on assuming it was the helper file itself 346 [dblack]
  • Added use of *_before_type_cast for all input and text fields. This is helpful for getting "100,000" back on a integer-based validation where the value would normally be "100".
  • Added Request#port_string to get something like ":8080" back on 8080 and "" on 80 (or 443 with https).
  • Added Request#domain (returns string) and Request#subdomains (returns array).
  • Added POST support for the breakpoint retries, so form processing that raises an exception can be retried with the original request [Florian Gross]
  • Fixed regression with Base#reset_session that wouldn‘t use the DEFAULT_SESSION_OPTIONS [adam@the-kramers.net]
  • Fixed error rendering of rxml documents to not just swallow the exception and return 0 (still not guessing the right line, but hey)
  • Fixed that textilize and markdown would instantiate their engines even on empty strings. This also fixes 333 [Ulysses]
  • Fixed UrlHelper#link_to_unless so it doesn‘t care if the id is a string or fixnum [Ryan Davis]

*1.0.1*

  • Fixed a bug that would cause an ApplicationController to require itself three times and hence cause filters to be run three times [evl]

*1.0*

  • Added that controllers will now attempt to require a model dependency with their name and in a singular attempt for their name. So both PostController and PostsController will automatically have the post.rb model required. If no model is found, no error is raised, as it is then expected that no match is available and the programmer will have included his own models.
  • Fixed DateHelper#date_select so that you can pass include_blank as an option even if you don‘t use start_year and end_year 59 [what-a-day]
  • Added that controllers will now search for a layout in $template_root/layouts/$controller_name.r(html|xml), so PostsController will look for layouts/posts.rhtml or layouts/posts.rxml and automatically configure this layout if found 307 [Marcel Molina Jr.]
  • Added FormHelper#radio_button to work with radio buttons like its already possible with check boxes [Michael Koziarski]
  • Added TemplateError#backtrace that makes it much easier to debug template errors from unit and functional tests
  • Added display of error messages with scaffolded form pages
  • Added option to ERB templates to swallow newlines by using <% if something -%> instead of just <% if something %>. Example:
      class SomeController < ApplicationController
  <% if options[:scaffold] %>
    scaffold :<%= singular_name %>
  <% end %>
    helper :post

    …produces this on post as singular_name:

      class SomeController < ApplicationController

    scaffold :post

    helper :post

    …where as:

      class SomeController < ApplicationController
  <% if options[:scaffold] -%>
    scaffold :<%= singular_name %>
  <% end -%>
    helper :post

    …produces:

      class SomeController < ApplicationController
    scaffold :post
    helper :post

    [This undocumented gem for ERb was uncovered by bitsweat]

  • Fixed CgiRequest so that it‘ll now accept session options with Symbols as keys (as the documentation points out) [Suggested by Andreas]
  • Added that render_partial will always by default include a counter with value 1 unless there is a counter passed in via the local_assigns hash that overrides it. As a result, render_collection_of_partials can still be written in terms of render_partial and partials that make use of a counter can be called without problems from both render_collection_of_partials as well as render_partial 295 [Marcel Molina Jr.]
  • Fixed CgiRequest#out to fall back to write if $stdout doesn‘t have syswrite [Jeremy Kemper]
  • Fixed all helpers so that they use XHTML compliant double quotes for values instead of single quotes [htonl/Jeremy Kemper]
  • Added link_to_image(src, options = {}, html_options = {}). Documentation:
      Creates a link tag to the image residing at the +src+ using an URL created by the set of +options+. See the valid options in
  link:classes/ActionController/Base.html#M000021. It's also possible to pass a string instead of an options hash to
  get a link tag that just points without consideration. The <tt>html_options</tt> works jointly for the image and ahref tag by
  letting the following special values enter the options on the image and the rest goes to the ahref:

  ::alt: If no alt text is given, the file name part of the +src+ is used (capitalized and without the extension)
  ::size: Supplied as "XxY", so "30x45" becomes width="30" and height="45"
  ::align: Sets the alignment, no special features

  The +src+ can be supplied as a...
  * full path, like "/my_images/image.gif"
  * file name, like "rss.gif", that gets expanded to "/images/rss.gif"
  * file name without extension, like "logo", that gets expanded to "/images/logo.png"
  • Fixed to_input_field_tag so it no longer explicitly uses InstanceTag.value if value was specified in the options hash [evl]
  • Added the possibility of having validate be protected for assert_(in)valid_column 263 [Tobias Lütke]
  • Added that ActiveRecordHelper#form now calls url_for on the :action option.
  • Added all the HTTP methods as alternatives to the generic "process" for functional testing 276 [Tobias Lütke]. Examples:
      # Calls Controller#miletone with a GET request
  process :milestone

  # Calls Controller#miletone with a POST request that has parameters
  post :milestone, { "name" => "David" }

  # Calls Controller#milestone with a HEAD request that has both parameters and session data
  head :milestone, { "id" => 1 }, { "user_id" => 23 }

    This is especially useful for testing idiomatic REST web services.

  • Added proper handling of HEAD requests, so that content isn‘t returned (Request#head? added as well) 277 [Eric Hodel]
  • Added indifference to whether @headers["Content-Type"], @headers["Content-type"], or @headers["content-type"] is used.
  • Added TestSession#session_id that returns an empty string to make it easier to functional test applications that doesn‘t use cookie-based sessions 275 [jcf]
  • Fixed that cached template loading would still check the file system to see if the file existed 258 [Andreas Schwarz]
  • Added options to tailor header tag, div id, and div class on ActiveRecordHelper#error_messages_for [Josh Peek]
  • Added graceful handling of non-alphanumeric names and misplaced brackets in input parameters [Jeremy Kemper]
  • Added a new container for cookies that makes them more intuative to use. The old methods of cookie and @cookies have been deprecated.

    Examples for writing:

      cookies["user_name"] = "david" # => Will set a simple session cookie
  cookies["login"] = { "value" => "XJ-122", "expires" => Time.now + 360} # => Will set a cookie that expires in 1 hour

    Examples for reading:

      cookies["user_name"] # => "david"
  cookies.size         # => 2

    Read more in ActionController::Cookies

    NOTE: If you were using the old accessor (cookies instead of @cookies), this could potentially break your code — if you expect a full cookie object!

  • Added the opportunity to defined method_missing on a controller which will handle all requests for actions not otherwise defined 223 [timb]
  • Fixed AbstractRequest#remote_ip for users going through proxies - Patch 228 [Eric Hodel]
  • Added Request#ssl? which is shorthand for @request.protocol == "https://"
  • Added the choice to call form_tag with no arguments (resulting in a form posting to current action) [Jeremy Kemper]
  • Upgraded to Builder 1.2.1
  • Added :module as an alias for :controller_prefix to url_for and friends, so you can do redirect_to(:module => "shop", :controller => "purchases") and go to /shop/purchases/
  • Added support for controllers in modules through @params["module"].
  • Added reloading for dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use those environments for development. This is turned on by default, but can be turned off with ActionController::Base.reload_dependencies = false in production environments.

    NOTE: This will only have an effect if you use the new model, service, and observer class methods to mark dependencies. All libraries loaded through require will be "forever" cached. You can, however, use ActionController::Base.load_or_require("library") to get this behavior outside of the new dependency style.

  • Added that controllers will automatically require their own helper if possible. So instead of doing:
      class MsgController < ApplicationController
    helper :msg
  end

    …you can just do:

      class MsgController < ApplicationController
  end
  • Added dependencies_on(layer) to query the dependencies of a controller. Examples:
      MsgController.dependencies_on(:model)    # => [ :post, :comment, :attachment ]
  MsgController.dependencies_on(:service)  # => [ :notification_service ]
  MsgController.dependencies_on(:observer) # => [ :comment_observer ]
  • Added a new dependency model with the class methods model, service, and observer. Example:
      class MsgController < ApplicationController
    model    :post, :comment, :attachment
    service  :notification_service
    observer :comment_observer
  end

    These new "keywords" remove the need for explicitly calling ‘require’ in most cases. The observer method even instantiates the observer as well as requiring it.

  • Fixed that link_to would escape & in the url again after url_for already had done so

*0.9.5* (28)

  • Added helper_method to designate that a given private or protected method you should available as a helper in the view. [Jeremy Kemper]
  • Fixed assert_rendered_file so it actually verifies if that was the rendered file [htonl]
  • Added the option for sharing partial spacer templates just like partials themselves [radsaq]
  • Fixed that Russia was named twice in country_select [alexey]
  • Fixed request_origin to use remote_ip instead of remote_addr [Jeremy Kemper]
  • Fixed link_to breakage when nil was passed for html_options [alexey]
  • Fixed redirect_to on a virtual server setup with apache with a port other than the default where it would forget the port number [seanohalpin]
  • Fixed that auto-loading webrick on Windows would cause file uploads to fail [Jeremy Kemper]
  • Fixed issues with sending files on WEBrick by setting the proper binmode [Jeremy Kemper]
  • Added send_data as an alternative to send_file when the stream is not read off the filesystem but from a database or generated live [Jeremy Kemper]
  • Added a new way to include helpers that doesn‘t require the include hack and can go without the explicit require. [Jeremy Kemper]

    Before:

      module WeblogHelper
    def self.included(controller) #:nodoc:
      controller.ancestors.include?(ActionController::Base) ? controller.add_template_helper(self) : super
    end
  end

  require 'weblog_helper'
  class WeblogController < ActionController::Base
    include WeblogHelper
  end

    After:

      module WeblogHelper
  end

  class WeblogController < ActionController::Base
    helper :weblog
  end
  • Added a default content-type of "text/xml" to .rxml renders [Ryan Platte]
  • Fixed that when /controller/index was requested by the browser, url_for would generates wrong URLs [Ryan Platte]
  • Fixed a bug that would share cookies between users when using FastCGI and mod_ruby [The Robot Co-op]
  • Added an optional third hash parameter to the process method in functional tests that takes the session data to be used [alexey]
  • Added UrlHelper#mail_to to make it easier to create mailto: style ahrefs
  • Added better error messages for layouts declared with the .rhtml extension (which they shouldn‘t) [geech]
  • Added another case to DateHelper#distance_in_minutes to return "less than a minute" instead of "0 minutes" and "1 minute" instead of "1 minutes"
  • Added a hidden field to checkboxes generated with FormHelper#check_box that will make sure that the unchecked value (usually 0) is sent even if the checkbox is not checked. This relieves the controller from doing custom checking if the checkbox wasn‘t checked. BEWARE: This might conflict with your run-on-the-mill work-around code. [Tobias Lütke]
  • Fixed error_message_on to just use the first if more than one error had been added [Marcel Molina Jr.]
  • Fixed that URL rewriting with /controller/ was working but /controller was not and that you couldn‘t use :id on index [geech]
  • Fixed a bug with link_to where the :confirm option wouldn‘t be picked up if the link was a straight url instead of an option hash
  • Changed scaffolding of forms to use <label> tags instead of <b> to please W3C [evl]
  • Added DateHelper#distance_of_time_in_words_to_now(from_time) that works like distance_of_time_in_words, but where to_time is fixed to Time.now.
  • Added assert_flash_equal(expected, key, message), assert_session_equal(expected, key, message), assert_assigned_equal(expected, key, message) to test the contents of flash, session, and template assigns.
  • Improved the failure report on assert_success when the action triggered a redirection [alexey].
  • Added "markdown" to accompany "textilize" as a TextHelper method for converting text to HTML using the Markdown syntax. BlueCloth must be installed in order for this method to become available.
  • Made sure that an active session exists before we attempt to delete it [Samuel]
  • Changed link_to with Javascript confirmation to use onclick instead of onClick for XHTML validity [Scott Barron]

*0.9.0 (43)*

  • Added support for Builder-based templates for files with the .rxml extension. These new templates are an alternative to ERb that are especially useful for generating XML content, such as this RSS example from Basecamp:
      xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
    xml.channel do
      xml.title(@feed_title)
      xml.link(@url)
      xml.description "Basecamp: Recent items"
      xml.language "en-us"
      xml.ttl "40"

      for item in @recent_items
        xml.item do
          xml.title(item_title(item))
          xml.description(item_description(item)) if item_description(item)
          xml.pubDate(item_pubDate(item))
          xml.guid(@person.firm.account.url + @recent_items.url(item))
          xml.link(@person.firm.account.url + @recent_items.url(item))

          xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
        end
      end
    end
  end

  ...which will generate something like:

  <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
      <title>Web Site Redesign</title>
      <link>http://www.basecamphq.com/clients/travelcenter/1/</link>
      <description>Basecamp: Recent items</description>
      <language>en-us</language>
      <ttl>40</ttl>
      <item>
        <title>Post: don't you know</title>
        <description>&amp;lt;p&amp;gt;deeper and down&amp;lt;/p&amp;gt;</description>
        <pubDate>Fri, 20 Aug 2004 21:13:50 CEST</pubDate>
        <guid>http://www.basecamphq.com/clients/travelcenter/1/msg/assets/96976/comments</guid>
        <link>http://www.basecamphq.com/clients/travelcenter/1/msg/assets/96976/comments</link>
        <dc:creator>David H. Heinemeier</dc:creator>
      </item>
      <item>
        <title>Milestone completed: Design Comp 2</title>
        <pubDate>Mon,  9 Aug 2004 14:42:06 CEST</pubDate>
        <guid>http://www.basecamphq.com/clients/travelcenter/1/milestones/#49</guid>
        <link>http://www.basecamphq.com/clients/travelcenter/1/milestones/#49</link>
      </item>
    </channel>
  </rss>

    The "xml" local variable is automatically available in .rxml templates. You construct the template by calling a method with the name of the tag you want. Options for the tag can be specified as a hash parameter to that method.

    Builder-based templates can be mixed and matched with the regular ERb ones. The only thing that differentiates them is the extension. No new methods have been added to the public interface to handle them.

    Action Pack ships with a version of Builder, but it will use the RubyGems version if you have one installed.

    Read more about Builder on: onestepback.org/index.cgi/Tech/Ruby/StayingSimple.rdoc

    [Builder is created by Jim Weirich]

  • Added much improved support for functional testing [what-a-day].
      # Old style
  def test_failing_authenticate
    @request.request_uri = "/login/authenticate"
    @request.action = "authenticate"
    @request.request_parameters["user_name"] = "nop"
    @request.request_parameters["password"]  = ""

    response = LoginController.process_test(@request)

    assert_equal "The username and/or password you entered is invalid.", response.session["flash"]["alert"]
    assert_equal "http://37signals.basecamp.com/login/", response.headers["location"]
  end

  # New style
  def test_failing_authenticate
    process :authenticate, "user_name" => "nop", "password" => ""
    assert_flash_has 'alert'
    assert_redirected_to :action => "index"
  end

    See a full example on codepaste.org/view/paste/334

  • Increased performance by up to 100% with a revised cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below. It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on: groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14
  • Added caching for compiled ERb templates. On Basecamp, it gave between 8.5% and 71% increase in performance [Andreas Schwarz].
  • Added implicit counter variable to render_collection_of_partials [Marcel Molina Jr.]. From the docs:
      <%= render_collection_of_partials "ad", @advertisements %>

  This will render "advertiser/_ad.rhtml" and pass the local variable +ad+ to the template for display. An iteration counter
  will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
  example above, the template would be fed +ad_counter+.
  • Fixed problems with two sessions being maintained on reset_session that would particularly screw up ActiveRecordStore.
  • Fixed reset_session to start an entirely new session instead of merely deleting the old. So you can now safely access @session after calling reset_ression and expect it to work.
  • Added @request.get?, @request.post?, @request.put?, @request.delete? as convenience query methods for @request.method [geech]
  • Added @request.method that‘ll return a symbol representing the HTTP method, such as :get, :post, :put, :delete [geech]
  • Changed @request.remote_ip and @request.host to work properly even when a proxy is in front of the application [geech]
  • Added JavaScript confirm feature to link_to. Documentation:
      The html_options have a special feature for creating javascript confirm alerts where if you pass
  :confirm => 'Are you sure?', the link will be guarded with a JS popup asking that question.
  If the user accepts, the link is processed, otherwise not.
  • Added link_to_unless_current as a UrlHelper method [Sam Stephenson]. Documentation:
      Creates a link tag of the given +name+ using an URL created by the set of +options+, unless the current
  controller, action, and id are the same as the link's, in which case only the name is returned (or the
  given block is yielded, if one exists). This is useful for creating link bars where you don't want to link
  to the page currently being viewed.
  • Fixed that UrlRewriter (the driver for url_for, link_to, etc) would blow up when the anchor was an integer [alexey]
  • Added that layouts defined with no directory defaults to layouts. So layout "weblog/standard" will use weblog/standard (as always), but layout "standard" will use layouts/standard.
  • Fixed that partials (or any template starting with an underscore) was publically viewable [Marten]
  • Added HTML escaping to text_area helper.
  • Added :overwrite_params to url_for and friends to keep the parameters as they were passed to the current action and only overwrite a subset. The regular :params will clear the slate so you need to manually add in existing parameters if you want to reuse them. [raphinou]
  • Fixed scaffolding problem with composite named objects [Moo Jester]
  • Added the possibility for shared partials. Example:
      <%= render_partial "advertisement/ad", ad %>

    This will render the partial "advertisement/_ad.rhtml" regardless of which controller this is being called from.

    [Jacob Fugal]

  • Fixed crash when encountering forms that have empty-named fields [James Prudente]
  • Added check_box form helper method now accepts true/false as well as 1/0 [what-a-day]
  • Fixed the lacking creation of all directories with install.rb [Dave Steinberg]
  • Fixed that date_select returns valid XHTML selected options [Andreas Schwarz]
  • Fixed referencing an action with the same name as a controller in url_for [what-a-day]
  • Fixed the destructive nature of Base#attributes= on the argument [Kevin Watt]
  • Changed ActionControllerError to decent from StandardError instead of Exception. It can now be caught by a generic rescue.
  • Added SessionRestoreError that is raised when a session being restored holds objects where there is no class available.
  • Added block as option for inline filters. So what used to be written as:
      before_filter Proc { |controller| return false if controller.params["stop_action"] }

    …can now be as:

      before_filter { |controller| return false if controller.params["stop_action"] }

    [Jeremy Kemper]

  • Made the following methods public (was protected): url_for, controller_class_name, controller_name, action_name This makes it easier to write filters without cheating around the encapsulation with send.
  • ActionController::Base#reset_session now sticks even if you access @session afterwards [Kent Sibilev]
  • Improved the exception logging so the log file gets almost as much as in-browser debugging.
  • Changed base class setup from AbstractTemplate/ERbTemplate to ActionView::Base. This change should be harmless unless you were accessing Action View directly in which case you now need to reference the Base class.\
  • Added that render_collection_of_partials returns nil if the collection is empty. This makes showing a “no items” message easier. For example: <%= render_collection_of_partials("message", @messages) || "No messages found." %> [Sam Stephenson]
  • Added :month_before_year as an option to date_select to get the month select before the year. Especially useful for credit card forms.
  • Added :add_month_numbers to select_month to get options like "3 - March".
  • Removed Base.has_active_layout? as it couldn‘t answer the question without the instance. Use Base#active_layout instead.
  • Removed redundant call to update on ActionController::Base#close_session [Andreas Schwarz]
  • Fixed that DRb Store accidently started its own server (instead of just client) [Andreas]
  • Fixed strip_links so it now works across multiple lines [Chad Fowler]
  • Fixed the TemplateError exception to show the proper trace on to_s (useful for unit test debugging)
  • Implemented class inheritable attributes without eval [Caio Chassot]
  • Made TextHelper#concat accept binding as it would otherwise not work
  • The FormOptionsHelper will now call to_s on the keys and values used to generate options

*0.8.5*

  • Introduced passing of locally scoped variables between templates:
      You can pass local variables to sub templates by using a hash of with the variable
  names as keys and the objects as values:

    <%= render "shared/header", { "headline" => "Welcome", "person" => person } %>

  These can now be accessed in shared/header with:

    Headline: <%= headline %>
    First name: <%= person.first_name %>
  • Introduced the concept of partials as a certain type of sub templates:
      There's also a convenience method for rendering sub templates within the current
  controller that depends on a single object (we call this kind of sub templates for
  partials). It relies on the fact that partials should follow the naming convention
  of being prefixed with an underscore -- as to separate them from regular templates
  that could be rendered on their own. In the template for Advertiser#buy, we could have:

    <% for ad in @advertisements %>
      <%= render_partial "ad", ad %>
    <% end %>

  This would render "advertiser/_ad.rhtml" and pass the local variable +ad+
  for the template to display.

  == Rendering a collection of partials

  The example of partial use describes a familar pattern where a template needs
  to iterate over a array and render a sub template for each of the elements.
  This pattern has been implemented as a single method that accepts an array and
  renders a partial by the same name of as the elements contained within. So the
  three-lined example in "Using partials" can be rewritten with a single line:

    <%= render_collection_of_partials "ad", @advertisements %>

  So this will render "advertiser/_ad.rhtml" and pass the local variable +ad+ for
  the template to display.
  • Improved send_file by allowing a wide range of options to be applied [Jeremy Kemper]:
      Sends the file by streaming it 4096 bytes at a time. This way the
  whole file doesn't need to be read into memory at once.  This makes
  it feasible to send even large files.

  Be careful to sanitize the path parameter if it coming from a web
  page.  send_file(@params['path'] allows a malicious user to
  download any file on your server.

  Options:
  * <tt>:filename</tt> - specifies the filename the browser will see.
    Defaults to File.basename(path).
  * <tt>:type</tt> - specifies an HTTP content type.
    Defaults to 'application/octet-stream'.
  * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
    Valid values are 'inline' and 'attachment' (default).
  * <tt>:buffer_size</tt> - specifies size (in bytes) of the buffer used to stream
    the file.  Defaults to 4096.

  The default Content-Type and Content-Disposition headers are
  set to download arbitrary binary files in as many browsers as
  possible.  IE versions 4, 5, 5.5, and 6 are all known to have
  a variety of quirks (especially when downloading over SSL).

  Simple download:
    send_file '/path/to.zip'

  Show a JPEG in browser:
    send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'

  Read about the other Content-* HTTP headers if you'd like to
  provide the user with more information (such as Content-Description).
  http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11

  Also be aware that the document may be cached by proxies and browsers.
  The Pragma and Cache-Control headers declare how the file may be cached
  by intermediaries.  They default to require clients to validate with
  the server before releasing cached responses.  See
  http://www.mnot.net/cache_docs/ for an overview of web caching and
  http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
  for the Cache-Control header spec.
  • Added pluralize method to the TextHelper that makes it easy to get strings like "1 message", "3 messages"
  • Added proper escaping for the rescues [Andreas Schwarz]
  • Added proper escaping for the option and collection tags [Andreas Schwarz]
  • Fixed NaN errors on benchmarking [Jim Weirich]
  • Fixed query string parsing for URLs that use the escaped versions of & or ; as part of a key or value
  • Fixed bug with custom Content-Type headers being in addition to rather than instead of the default header. (This bug didn‘t matter with neither CGI or mod_ruby, but FCGI exploded on it) [With help from Ara T. Howard]

*0.8.0*

  • Added select, collection_select, and country_select to make it easier for Active Records to set attributes through drop-down lists of options. Example:
      <%= select "person", "gender", %w( Male Female ) %>

    …would give the following:

      <select name="person[gender]" id="person_gender"><option>Male</option><option>Female</option></select>
  • Added an option for getting multiple values on a single form name into an array instead of having the last one overwrite. This is especially useful for groups of checkboxes, which can now be written as:
      <input type="checkbox" name="rights[]" value="CREATE" />
  <input type="checkbox" name="rights[]" value="UPDATE" />
  <input type="checkbox" name="rights[]" value="DELETE" />

    …and retrieved in the controller action with:

      @params["rights"] # => [ "CREATE", "UPDATE", "DELETE" ]

    The old behavior (where the last one wins, "DELETE" in the example) is still available. Just don‘t add "[]" to the end of the name. [Scott Baron]

  • Added send_file which uses the new render_text block acceptance to make it feasible to send large files. The files is sent with a bunch of voodoo HTTP headers required to get arbitrary files to download as expected in as many browsers as possible (eg, IE hacks). Example:

    def play_movie

      send_file "/movies/that_movie.avi"

    end

    [Jeremy Kemper]

  • render_text now accepts a block for deferred rendering. Useful for streaming large files, displaying a “please wait” message during a complex search, etc. Streaming example:
      render_text do |response|
    File.open(path, 'rb') do |file|
      while buf = file.read(1024)
        print buf
      end
    end
  end

    [Jeremy Kemper]

  • Added a new Tag Helper that can generate generic tags programmatically insted of through HTML. Example:
      tag("br", "clear" => "all") => <br clear="all" />

    …that‘s usually not terribly interesting (unless you have a lot of options already in a hash), but it gives way for more specific tags, like the new form tag:

      form_tag({ :controller => "weblog", :action => "update" }, { :multipart => "true", "style" => "width: 200px"}) =>
    <form action="/weblog/update" enctype="multipart/formdata" style="width: 200px">

    There‘s even a "pretty" version for people who don‘t like to open tags in code and close them in HTML:

      <%= start_form_tag :action => "update" %>
    # all the input fields
  <%= end_form_tag %>

    (end_form_tag just returns "</form>")

  • The selected parameter in options_for_select may now also an array of values to be selected when using a multiple select. Example:
      options_for_select([ "VISA", "Mastercard", "Discover" ], ["VISA", "Discover"]) =>
    <option selected>VISA</option>\n<option>Mastercard</option>\n<option selected>Discover</option>

    [Scott Baron]

  • Changed the URL rewriter so controller_prefix and action_prefix can be used in isolation. You can now do:
      url_for(:controller_prefix => "clients")

    …or:

      url_for(:action_prefix => "category/messages")

    Neither would have worked in isolation before (:controller_prefix required a :controller and :action_prefix required an :action)

  • Started process of a cleaner separation between Action Controller and ERb-based Action Views by introducing an abstract base class for views. And Amita adapter could be fitted in more easily now.
  • The date helper methods date_select and datetime_select now also use the field error wrapping (div with class fieldWithErrors by default).
  • The date helper methods date_select and datetime_select can now discard selects
  • Added option on AbstractTemplate to specify a different field error wrapping. Example:
      ActionView::AbstractTemplate.field_error_proc = Proc.new do |html, instance|
    "<p>#{instance.method_name + instance.error_message}</p><div style='background-color: red'>#{html}</div>"
  end

    …would give the following on a Post#title (text field) error:

      <p>Title can't be empty</p>
  <div style='background-color: red'>
    <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
  </div>
  • The UrlHelper methods url_for and link_to will now by default only return paths, not complete URIs. That should make it easier to fit a Rails application behind a proxy or load-balancer. You can overwrite this by passing :only_path => false as part of the options. [Suggested by U235]
  • Fixed bug with having your own layout for use with scaffolding [Kevin Radloff]
  • Fixed bug where redirect_to_path didn‘t append the port on non-standard ports [dhawkins]
  • Scaffolding plays nicely with single-table inheritance (LoadErrors are caught) [Jeremy Kemper]
  • Scaffolding plays nice with plural models like Category/categories [Jeremy Kemper]
  • Fixed missing suffix appending in scaffolding [Kevin Radloff]

*0.7.9*

  • The "form" method now present boolean fields from PostgreSQL as drop-down menu. [Scott]
  • Scaffolding now automatically attempts to require the class that‘s being scaffolded.
  • Scaffolding will use the current active layout, instead of its own, if one has been specified. Example:
      class WeblogController < ActionController::Base
    layout "layouts/weblog"
    scaffold :post
  end

    [Suggested by Scott]

  • Changed url_for (and all the that drives, like redirect_to, link_to, link_for) so you can pass it a symbol instead of a hash. This symbol is a method reference which is then called to calculate the url. Example:
      class WeblogController < ActionController::Base
    def update
      # do some update
      redirect_to :dashboard_url
    end

    protected
      def dashboard_url
        if @project.active?
          url_for :controller => "project", :action => "dashboard"
        else
          url_for :controller => "account", :action => "dashboard"
        end
      end
  end
  • Added default_url_options to specialize behavior for all url_for (and friends) calls:
      Overwrite to implement a number of default options that all url_for-based methods will use.
  The default options should come in form of a hash, just like the one you would use for
  url_for directly. Example:

    def default_url_options(options)
      { :controller_prefix => @project.active? ? "projects/" : "accounts/" }
    end

  As you can infer from the example, this is mostly useful for situations where you want to
  centralize dynamic dissions about the urls as they stem from the business domain. Please note
  that any individual url_for call can always override the defaults set by this method.
  • Changed url_for so that an "id" passed in the :params is not treated special. You need to use the dedicated :id to get the special auto path-params treatment. Considering the url localhost:81/friends/list
      url_for(:action => "show", :params => { "id" => 5 })
    ...used to give http://localhost:81/friends/show/5
    ......now gives http://localhost:81/friends/show?id=5

  If you want the automated id behavior, do:

  url_for(:action => "show", :id => 5 )
    ....which gives http://localhost:81/friends/show/5
  • Fixed problem with anchor being inserted before path parameters with url_for (and friends)

*0.7.8*

  • Fixed session bug where you couldn‘t store any objects that didn‘t exist in the standard library (such as Active Record objects).
  • Added reset_session method for Action Controller objects to clear out all objects in the session.
  • Fixed that exceptions raised during filters are now also caught by the default rescues
  • Added new around_filter for doing before and after filtering with a single object [Florian Weber]:
      class WeblogController < ActionController::Base
    around_filter BenchmarkingFilter.new

    # Before this action is performed, BenchmarkingFilter#before(controller) is executed
    def index
    end
    # After this action has been performed, BenchmarkingFilter#after(controller) is executed
  end

  class BenchmarkingFilter
    def initialize
      @runtime
    end

    def before
      start_timer
    end

    def after
      stop_timer
      report_result
    end
  end
  • Added the options for specifying a different name and id for the form helper methods than what is guessed [Florian Weber]:
      text_field "post", "title"
    ...just gives: <input id="post_title" name="post[title]" size="30" type="text" value="" />

  text_field "post", "title", "id" => "title_for_post", "name" => "first_post_title"
    ...can now give: <input id="title_for_post" name="first_post_title" size="30" type="text" value="" />
  • Added DebugHelper with a single "debug" method for doing pretty dumps of objects in the view (now used in the default rescues to better present the contents of session and template variables)
  • Added note to log about the templates rendered within layouts (before just the layout was shown)
  • Fixed redirects on https setups [Andreas]
  • Fixed scaffolding problem on the edit action when using :suffix => true [Scott]
  • Fixed scaffolding problem where implementing list.rhtml wouldn‘t work for the index action
  • URLs generated now uses &amp; instead of just & so pages using it can validate with W3C [Spotted by Andreas]

*0.7.7*

  • Fixed bug in CGI extension that prevented multipart forms from working

*0.7.6*

  • Included ERB::Util so all templates can easily escape HTML content with <%=h @person.content %>
  • All requests are now considered local by default, so everyone will be exposed to detailed debugging screens on errors. When the application is ready to go public, set ActionController::Base.consider_all_requests_local to false, and implement the protected method local_request? in the controller to determine when debugging screens should be shown.
  • Fixed three bugs with the url_for/redirect_to/link_to handling. Considering the url localhost:81/friends/show/1
      url_for(:action => "list")
    ...used to give http://localhost:81/friends/list/1
    ......now gives http://localhost:81/friends/list

  url_for(:controller => "friends", :action => "destroy", :id => 5)
    ...used to give http://localhost:81/friends/destroy
    ......now gives http://localhost:81/friends/destroy/5

    Considering the url localhost:81/teachers/show/t

      url_for(:action => "list", :id => 5)
    ...used to give http://localhost:81/5eachers/list/t
    ......now gives http://localhost:81/teachers/list/5

    [Reported by David Morton & Radsaq]

  • Logs exception to logfile in addition to showing them for local requests
  • Protects the eruby load behind a begin/rescue block. eRuby is not required to run ActionController.
  • Fixed install.rb to also install clean_logger and the templates
  • Added ActiveRecordStore as a session option. Read more in lib/action_controller/session/active_record_store.rb [Tim Bates]
  • Change license to MIT License (and included license file in package)
  • Application error page now returns status code 500 instead of 200
  • Fixed using Procs as layout handlers [Florian Weber]
  • Fixed bug with using redirects ports other than 80
  • Added index method that calls list on scaffolding

*0.7.5*

  • First public release


Class: ActionView::Base

Class | ActionView::Base
In: | vendor/rails/actionpack/lib/action_view/base.rb vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb vendor/rails/actionpack/lib/action_view/test_case.rb
Parent: | Object

Action View templates can be written in three ways. If the template file has a .erb (or .rhtml) extension then it uses a mixture of ERb (included in Ruby) and HTML. If the template file has a .builder (or .rxml) extension then Jim Weirich‘s Builder::XmlMarkup library is used. If the template file has a .rjs extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.

ERb

You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the following loop for names:

  <b>Names of all the people</b>
  <% for person in @people %>
    Name: <%= person.name %><br/>
  <% end %>

The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this is not just a usage suggestion. Regular output functions like print or puts won‘t work with ERb templates. So this would be wrong:

  Hi, Mr. <% puts "Frodo" %>

If you absolutely must write from within a function, you can use the TextHelper#concat.

<%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>.

Using sub templates

Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):

  <%= render "shared/header" %>
  Something really specific and terrific
  <%= render "shared/footer" %>

As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the result of the rendering. The output embedding writes it to the current template.

But you don‘t have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance variables defined using the regular embedding tags. Like this:

  <% @page_title = "A Wonderful Hello" %>
  <%= render "shared/header" %>

Now the header can pick up on the @page_title variable and use it for outputting a title tag:

  <title><%= @page_title %></title>

Passing local variables to sub templates

You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:

  <%= render "shared/header", { :headline => "Welcome", :person => person } %>

These can now be accessed in shared/header with:

  Headline: <%= headline %>
  First name: <%= person.first_name %>

If you need to find out whether a certain local variable has been assigned a value in a particular render call, you need to use the following pattern:

  <% if local_assigns.has_key? :headline %>
    Headline: <%= headline %>
  <% end %>

Testing using defined? headline will not work. This is an implementation restriction.

Template caching

By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file‘s modification time and recompile it.

Builder

Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object named xml is automatically made available to templates with a .builder extension.

Here are some basic examples:

  xml.em("emphasized")                              # => <em>emphasized</em>
  xml.em { xml.b("emph & bold") }                   # => <em><b>emph &amp; bold</b></em>
  xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
  xml.target("name"=>"compile", "option"=>"fast")   # => <target option="fast" name="compile"\>
                                                    # NOTE: order of attributes is not specified.

Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:

  xml.div {
    xml.h1(@person.name)
    xml.p(@person.bio)
  }

would produce something like:

  <div>
    <h1>David Heinemeier Hansson</h1>
    <p>A product of Danish Design during the Winter of '79...</p>
  </div>

A full-length RSS example actually used on Basecamp:

  xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
    xml.channel do
      xml.title(@feed_title)
      xml.link(@url)
      xml.description "Basecamp: Recent items"
      xml.language "en-us"
      xml.ttl "40"

      for item in @recent_items
        xml.item do
          xml.title(item_title(item))
          xml.description(item_description(item)) if item_description(item)
          xml.pubDate(item_pubDate(item))
          xml.guid(@person.firm.account.url + @recent_items.url(item))
          xml.link(@person.firm.account.url + @recent_items.url(item))

          xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
        end
      end
    end
  end

More builder documentation can be found at builder.rubyforge.org.

JavaScriptGenerator

JavaScriptGenerator templates end in .rjs. Unlike conventional templates which are used to render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax and make updates to the page where the request originated from.

An instance of the JavaScriptGenerator object named page is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.

When an .rjs action is called with link_to_remote, the generated JavaScript is automatically evaluated. Example:

  link_to_remote :url => {:action => 'delete'}

The subsequently rendered delete.rjs might look like:

  page.replace_html  'sidebar', :partial => 'sidebar'
  page.remove        "person-#{@person.id}"
  page.visual_effect :highlight, 'user-list'

This refreshes the sidebar, removes a person element and highlights the user list.

See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.

Methods

cache_template_loading? new process_view_paths template template_format view_paths= with_template

Included Modules

Helpers Partials ::ERB::Util CompiledTemplates

Classes and Modules

Class ActionView::Base::ProxyModule

External Aliases

initialize -> initialize_without_template_tracking

Attributes

assigns | [RW]
base_path | [RW]
controller | [RW]
helpers | [R]
output_buffer | [RW]
template_extension | [RW]
template_format | [W]
view_paths | [R]

Public Class methods

cache_template_loading?()

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 190
190:     def self.cache_template_loading?
191:       ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading)
192:     end
new(*args)

[Source]

   # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 6
6:     def initialize(*args)
7:       @_rendered = { :template => nil, :partials => Hash.new(0) }
8:       initialize_without_template_tracking(*args)
9:     end
process_view_paths(value)

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 204
204:     def self.process_view_paths(value)
205:       ActionView::PathSet.new(Array(value))
206:     end

Public Instance methods

template()

Access the current template being rendered. Returns a ActionView::Template object.

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 290
290:     def template
291:       @_current_render
292:     end
template_format()

The format to be used when choosing between multiple templates with the same name but differing formats. See +Request#template_format+ for more details.

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 278
278:     def template_format
279:       if defined? @template_format
280:         @template_format
281:       elsif controller && controller.respond_to?(:request)
282:         @template_format = controller.request.template_format.to_sym
283:       else
284:         @template_format = :html
285:       end
286:     end
view_paths=(paths)

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 234
234:     def view_paths=(paths)
235:       @view_paths = self.class.process_view_paths(paths)
236:       # we might be using ReloadableTemplates, so we need to let them know this a new request
237:       @view_paths.load!
238:     end
with_template(current_template) {|| ...}

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 299
299:     def with_template(current_template)
300:       last_template, self.template = template, current_template
301:       yield
302:     ensure
303:       self.template = last_template
304:     end


Class: ActionView::Base::ProxyModule

Class | ActionView::Base::ProxyModule
In: | vendor/rails/actionpack/lib/action_view/base.rb
Parent: | Module

Methods

include new

Public Class methods

new(receiver)

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 211
211:       def initialize(receiver)
212:         @receiver = receiver
213:       end

Public Instance methods

include(*args)

[Source]

     # File vendor/rails/actionpack/lib/action_view/base.rb, line 215
215:       def include(*args)
216:         super(*args)
217:         @receiver.extend(*args)
218:       end


Module: ActionView::Helpers::ActiveRecordHelper

Module | ActionView::Helpers::ActiveRecordHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb

The Active Record Helper makes it easier to create forms for records kept in instance variables. The most far-reaching is the form method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. In that case, it‘s better to use the input method and the specialized form methods in classes/ActionView/Helpers/FormHelper.html

Methods

error_message_on error_messages_for form input

Public Instance methods

error_message_on(object, method, *args)

Returns a string containing the error message attached to the method on the object if one exists. This error message is wrapped in a DIV tag, which can be extended to include a :prepend_text and/or :append_text (to properly explain the error), and a :css_class to style it accordingly. object should either be the name of an instance variable or the actual object. The method can be passed in either as a string or a symbol. As an example, let‘s say you have a model @post that has an error message on the title attribute:

  <%= error_message_on "post", "title" %>
  # => <div class="formError">can't be empty</div>

  <%= error_message_on @post, :title %>
  # => <div class="formError">can't be empty</div>

  <%= error_message_on "post", "title",
      :prepend_text => "Title simply ",
      :append_text => " (or it won't work).",
      :css_class => "inputError" %>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb, line 109
109:       def error_message_on(object, method, *args)
110:         options = args.extract_options!
111:         unless args.empty?
112:           ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' +
113:             'prepend_text, append_text, and css_class arguments', caller)
114:
115:           options[:prepend_text] = args[0] || ''
116:           options[:append_text] = args[1] || ''
117:           options[:css_class] = args[2] || 'formError'
118:         end
119:         options.reverse_merge!(:prepend_text => '', :append_text => '', :css_class => 'formError')
120:
121:         if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
122:           (errors = obj.errors.on(method))
123:           content_tag("div",
124:             "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.is_a?(Array) ? errors.first : errors)}#{options[:append_text]}",
125:             :class => options[:css_class]
126:           )
127:         else
128:           ''
129:         end
130:       end
error_messages_for(*params)

Returns a string with a DIV containing all of the error messages for the objects located as instance variables by the names given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are provided.

This DIV can be tailored by the following options:

  • :header_tag - Used for the header of the error div (default: "h2").
  • :id - The id of the error div (default: "errorExplanation").
  • :class - The class of the error div (default: "errorExplanation").
  • :object - The object (or array of objects) for which to display errors, if you need to escape the instance variable convention.
  • :object_name - The object name to use in the header, or any text that you prefer. If :object_name is not set, the name of the first object will be used.
  • :header_message - The message in the header of the error div. Pass nil or an empty string to avoid the header message altogether. (Default: "X errors prohibited this object from being saved").
  • :message - The explanation message after the header message and before the error list. Pass nil or an empty string to avoid the explanation message altogether. (Default: "There were problems with the following fields:").

To specify the display for one object, you simply provide its name as a parameter. For example, for the @user model:

  error_messages_for 'user'

To specify more than one object, you simply list them; optionally, you can add an extra :object_name parameter, which will be the name used in the header message:

  error_messages_for 'user_common', 'user', :object_name => 'user'

If the objects cannot be located as instance variables, you can add an extra :object parameter which gives the actual object (or array of objects to use):

  error_messages_for 'user', :object => @question.user

NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what you need is significantly different from the default presentation, it makes plenty of sense to access the object.errors instance yourself and set it up. View the source of this method to see how easy it is.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb, line 170
170:       def error_messages_for(*params)
171:         options = params.extract_options!.symbolize_keys
172:
173:         if object = options.delete(:object)
174:           objects = [object].flatten
175:         else
176:           objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
177:         end
178:
179:         count  = objects.inject(0) {|sum, object| sum + object.errors.count }
180:         unless count.zero?
181:           html = {}
182:           [:id, :class].each do |key|
183:             if options.include?(key)
184:               value = options[key]
185:               html[key] = value unless value.blank?
186:             else
187:               html[key] = 'errorExplanation'
188:             end
189:           end
190:           options[:object_name] ||= params.first
191:
192:           I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale|
193:             header_message = if options.include?(:header_message)
194:               options[:header_message]
195:             else
196:               object_name = options[:object_name].to_s.gsub('_', ' ')
197:               object_name = I18n.t(object_name, :default => object_name, :scope => [:activerecord, :models], :count => 1)
198:               locale.t :header, :count => count, :model => object_name
199:             end
200:             message = options.include?(:message) ? options[:message] : locale.t(:body)
201:             error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, ERB::Util.html_escape(msg)) } }.join
202:
203:             contents = ''
204:             contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
205:             contents << content_tag(:p, message) unless message.blank?
206:             contents << content_tag(:ul, error_messages)
207:
208:             content_tag(:div, contents, html)
209:           end
210:         else
211:           ''
212:         end
213:       end
form(record_name, options = {}) {|contents if block_given?| ...}

Returns an entire form with all needed input tags for a specified Active Record object. For example, if @post has attributes named title of type VARCHAR and body of type TEXT then

  form("post")

would yield a form like the following (modulus formatting):

  <form action='/posts/create' method='post'>
    <p>
      <label for="post_title">Title</label><br />
      <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
    </p>
    <p>
      <label for="post_body">Body</label><br />
      <textarea cols="40" id="post_body" name="post[body]" rows="20"></textarea>
    </p>
    <input name="commit" type="submit" value="Create" />
  </form>

It‘s possible to specialize the form builder by using a different action name and by supplying another block renderer. For example, if @entry has an attribute message of type VARCHAR then

  form("entry",
    :action => "sign",
    :input_block => Proc.new { |record, column|
      "#{column.human_name}: #{input(record, column.name)}<br />"
  })

would yield a form like the following (modulus formatting):

  <form action="/entries/sign" method="post">
    Message:
    <input id="entry_message" name="entry[message]" size="30" type="text" /><br />
    <input name="commit" type="submit" value="Sign" />
  </form>

It‘s also possible to add additional content to the form by giving it a block, such as:

  form("entry", :action => "sign") do |form|
    form << content_tag("b", "Department")
    form << collection_select("department", "id", @departments, "id", "name")
  end

The following options are available:

  • :action - The action used when submitting the form (default: create if a new record, otherwise update).
  • :input_block - Specialize the output using a different block, see above.
  • :method - The method used when submitting the form (default: post).
  • :multipart - Whether to change the enctype of the form to "multipart/form-data", used when uploading a file (default: false).
  • :submit_value - The text of the submit button (default: "Create" if a new record, otherwise "Update").

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb, line 75
75:       def form(record_name, options = {})
76:         record = instance_variable_get("@#{record_name}")
77:
78:         options = options.symbolize_keys
79:         options[:action] ||= record.new_record? ? "create" : "update"
80:         action = url_for(:action => options[:action], :id => record)
81:
82:         submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize
83:
84:         contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil)
85:         contents << hidden_field(record_name, :id) unless record.new_record?
86:         contents << all_input_tags(record, record_name, options)
87:         yield contents if block_given?
88:         contents << submit_tag(submit_value)
89:         contents << '</form>'
90:       end
input(record_name, method, options = {})

Returns a default input tag for the type of object returned by the method. For example, if @post has an attribute title mapped to a VARCHAR column that holds "Hello World":

  input("post", "title")
  # => <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb, line 21
21:       def input(record_name, method, options = {})
22:         InstanceTag.new(record_name, method, self).to_tag(options)
23:       end


Module: ActionView::Helpers::AssetTagHelper

Module | ActionView::Helpers::AssetTagHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb

This module provides methods for generating HTML that links views to assets such as images, javascripts, stylesheets, and feeds. These methods do not verify the assets exist before linking to them:

  image_tag("rails.png")
  # => <img alt="Rails src="/images/rails.png?1230601161" />
  stylesheet_link_tag("application")
  # => <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />

Using asset hosts

By default, Rails links to these assets on the current host in the public folder, but you can direct Rails to link to assets from a dedicated asset server by setting ActionController::Base.asset_host in the application configuration, typically in config/environments/production.rb. For example, you‘d define assets.example.com to be your asset host this way:

  ActionController::Base.asset_host = "assets.example.com"

Helpers take that into account:

  image_tag("rails.png")
  # => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />
  stylesheet_link_tag("application")
  # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />

Browsers typically open at most two simultaneous connections to a single host, which means your assets often have to wait for other assets to finish downloading. You can alleviate this by using a %d wildcard in the asset_host. For example, "assets%d.example.com". If that wildcard is present Rails distributes asset requests among the corresponding four hosts "assets0.example.com", …, "assets3.example.com". With this trick browsers will open eight simultaneous connections rather than two.

  image_tag("rails.png")
  # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
  stylesheet_link_tag("application")
  # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />

To do this, you can either setup four actual hosts, or you can use wildcard DNS to CNAME the wildcard to a single asset host. You can read more about setting up your DNS CNAME records from your ISP.

Note: This is purely a browser performance optimization and is not meant for server load balancing. See www.die.net/musings/page_load_time/ for background.

Alternatively, you can exert more control over the asset host by setting asset_host to a proc like this:

  ActionController::Base.asset_host = Proc.new { |source|
    "http://assets#{rand(2) + 1}.example.com"
  }
  image_tag("rails.png")
  # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
  stylesheet_link_tag("application")
  # => <link href="http://assets1.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />

The example above generates "assets1.example.com" and "assets2.example.com" randomly. This option is useful for example if you need fewer/more than four hosts, custom host names, etc.

As you see the proc takes a source parameter. That‘s a string with the absolute path of the asset with any extensions and timestamps in place, for example "/images/rails.png?1230601161".

   ActionController::Base.asset_host = Proc.new { |source|
     if source.starts_with?('/images')
       "http://images.example.com"
     else
       "http://assets.example.com"
     end
   }
  image_tag("rails.png")
  # => <img alt="Rails" src="http://images.example.com/images/rails.png?1230601161" />
  stylesheet_link_tag("application")
  # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />

Alternatively you may ask for a second parameter request. That one is particularly useful for serving assets from an SSL-protected page. The example proc below disables asset hosting for HTTPS connections, while still sending assets for plain HTTP requests from asset hosts. If you don‘t have SSL certificates for each of the asset hosts this technique allows you to avoid warnings in the client about mixed media.

  ActionController::Base.asset_host = Proc.new { |source, request|
    if request.ssl?
      "#{request.protocol}#{request.host_with_port}"
    else
      "#{request.protocol}assets.example.com"
    end
  }

You can also implement a custom asset host object that responds to call and takes either one or two parameters just like the proc.

  config.action_controller.asset_host = AssetHostingWithMinimumSsl.new(
    "http://asset%d.example.com", "https://asset1.example.com"
  )

Using asset timestamps

By default, Rails appends asset‘s timestamps to all asset paths. This allows you to set a cache-expiration date for the asset far into the future, but still be able to instantly invalidate it by simply updating the file (and hence updating the timestamp, which then updates the URL as the timestamp is part of that, which in turn busts the cache).

It‘s the responsibility of the web server you use to set the far-future expiration date on cache assets that you need to take advantage of this feature. Here‘s an example for Apache:

  # Asset Expiration
  ExpiresActive On
  <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
    ExpiresDefault "access plus 1 year"
  </FilesMatch>

Also note that in order for this to work, all your application servers must return the same timestamps. This means that they must have their clocks synchronized. If one of them drifts out of sync, you‘ll see different timestamps at random and the cache won‘t work. In that case the browser will request the same assets over and over again even thought they didn‘t change. You can use something like Live HTTP Headers for Firefox to verify that the cache is indeed working.

Methods

auto_discovery_link_tag cache_asset_timestamps cache_asset_timestamps= image_path image_tag javascript_include_tag javascript_path path_to_image path_to_javascript path_to_stylesheet register_javascript_expansion register_javascript_include_default register_stylesheet_expansion stylesheet_link_tag stylesheet_path

Constants

ASSETS_DIR | = | defined?(Rails.public_path) ? Rails.public_path : "public"
JAVASCRIPTS_DIR | = | "#{ASSETS_DIR}/javascripts"
STYLESHEETS_DIR | = | "#{ASSETS_DIR}/stylesheets"
JAVASCRIPT_DEFAULT_SOURCES | = | ['prototype', 'effects', 'dragdrop', 'controls'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)

Public Class methods

cache_asset_timestamps()

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 495
495:       def self.cache_asset_timestamps
496:         @@cache_asset_timestamps
497:       end
cache_asset_timestamps=(value)

You can enable or disable the asset tag timestamps cache. With the cache enabled, the asset tag helper methods will make fewer expense file system calls. However this prevents you from modifying any asset files while the server is running.

  ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 505
505:       def self.cache_asset_timestamps=(value)
506:         @@cache_asset_timestamps = value
507:       end
register_javascript_expansion(expansions)

Register one or more javascript files to be included when symbol is passed to javascript_include_tag. This method is typically intended to be called from plugin initialization to register javascript files that the plugin installed in public/javascripts.

  ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]

  javascript_include_tag :monkey # =>
    <script type="text/javascript" src="/javascripts/head.js"></script>
    <script type="text/javascript" src="/javascripts/body.js"></script>
    <script type="text/javascript" src="/javascripts/tail.js"></script>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 302
302:       def self.register_javascript_expansion(expansions)
303:         @@javascript_expansions.merge!(expansions)
304:       end
register_javascript_include_default(*sources)

Register one or more additional JavaScript files to be included when javascript_include_tag :defaults is called. This method is typically intended to be called from plugin initialization to register additional .js files that the plugin installed in public/javascripts.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 327
327:       def self.register_javascript_include_default(*sources)
328:         @@javascript_expansions[:defaults].concat(sources)
329:       end
register_stylesheet_expansion(expansions)

Register one or more stylesheet files to be included when symbol is passed to stylesheet_link_tag. This method is typically intended to be called from plugin initialization to register stylesheet files that the plugin installed in public/stylesheets.

  ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]

  stylesheet_link_tag :monkey # =>
    <link href="/stylesheets/head.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/body.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/tail.css"  media="screen" rel="stylesheet" type="text/css" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 319
319:       def self.register_stylesheet_expansion(expansions)
320:         @@stylesheet_expansions.merge!(expansions)
321:       end

Public Instance methods

auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})

Returns a link tag that browsers and news readers can use to auto-detect an RSS or ATOM feed. The type can either be :rss (default) or :atom. Control the link options in url_for format using the url_options. You can modify the LINK tag itself in tag_options.

Options

  • :rel - Specify the relation of this link, defaults to "alternate"
  • :type - Override the auto-generated mime type
  • :title - Specify the title of the link, defaults to the type

Examples

 auto_discovery_link_tag # =>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
 auto_discovery_link_tag(:atom) # =>
    <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" />
 auto_discovery_link_tag(:rss, {:action => "feed"}) # =>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" />
 auto_discovery_link_tag(:rss, {:action => "feed"}, {:title => "My RSS"}) # =>
    <link rel="alternate" type="application/rss+xml" title="My RSS" href="http://www.currenthost.com/controller/feed" />
 auto_discovery_link_tag(:rss, {:controller => "news", :action => "feed"}) # =>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/news/feed" />
 auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "Example RSS"}) # =>
    <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 162
162:       def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
163:         tag(
164:           "link",
165:           "rel"   => tag_options[:rel] || "alternate",
166:           "type"  => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s,
167:           "title" => tag_options[:title] || type.to_s.upcase,
168:           "href"  => url_options.is_a?(Hash) ? url_for(url_options.merge(:only_path => false)) : url_options
169:         )
170:       end
image_path(source)

Computes the path to an image asset in the public images directory. Full paths from the document root will be passed through. Used internally by image_tag to build the image path.

Examples

  image_path("edit")                                         # => /images/edit
  image_path("edit.png")                                     # => /images/edit.png
  image_path("icons/edit.png")                               # => /images/icons/edit.png
  image_path("/icons/edit.png")                              # => /icons/edit.png
  image_path("http://www.railsapplication.com/img/edit.png") # => http://www.railsapplication.com/img/edit.png

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 439
439:       def image_path(source)
440:         compute_public_path(source, 'images')
441:       end
image_tag(source, options = {})

Returns an html image tag for the source. The source can be a full path or a file that exists in your public images directory.

Options

You can add HTML attributes using the options. The options supports three additional keys for convenience and conformance:

  • :alt - If no alt text is given, the file name part of the source is used (capitalized and without the extension)
  • :size - Supplied as "{Width}x{Height}", so "30x45" becomes width="30" and height="45". :size will be ignored if the value is not in the correct format.
  • :mouseover - Set an alternate image to be used when the onmouseover event is fired, and sets the original image to be replaced onmouseout. This can be used to implement an easy image toggle that fires on onmouseover.

Examples

 image_tag("icon")  # =>
   <img src="/images/icon" alt="Icon" />
 image_tag("icon.png")  # =>
   <img src="/images/icon.png" alt="Icon" />
 image_tag("icon.png", :size => "16x10", :alt => "Edit Entry")  # =>
   <img src="/images/icon.png" width="16" height="10" alt="Edit Entry" />
 image_tag("/icons/icon.gif", :size => "16x16")  # =>
   <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
 image_tag("/icons/icon.gif", :height => '32', :width => '32') # =>
   <img alt="Icon" height="32" src="/icons/icon.gif" width="32" />
 image_tag("/icons/icon.gif", :class => "menu_icon") # =>
   <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
 image_tag("mouse.png", :mouseover => "/images/mouse_over.png") # =>
   <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />
 image_tag("mouse.png", :mouseover => image_path("mouse_over.png")) # =>
   <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 477
477:       def image_tag(source, options = {})
478:         options.symbolize_keys!
479:
480:         options[:src] = path_to_image(source)
481:         options[:alt] ||= File.basename(options[:src], '.*').split('.').first.to_s.capitalize
482:
483:         if size = options.delete(:size)
484:           options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
485:         end
486:
487:         if mouseover = options.delete(:mouseover)
488:           options[:onmouseover] = "this.src='#{image_path(mouseover)}'"
489:           options[:onmouseout]  = "this.src='#{image_path(options[:src])}'"
490:         end
491:
492:         tag("img", options)
493:       end
javascript_include_tag(*sources)

Returns an html script tag for each of the sources provided. You can pass in the filename (.js extension is optional) of javascript files that exist in your public/javascripts directory for inclusion into the current page or you can pass the full path relative to your document root. To include the Prototype and Scriptaculous javascript libraries in your application, pass :defaults as the source. When using :defaults, if an application.js file exists in your public javascripts directory, it will be included as well. You can modify the html attributes of the script tag by passing a hash as the last argument.

Examples

  javascript_include_tag "xmlhr" # =>
    <script type="text/javascript" src="/javascripts/xmlhr.js"></script>

  javascript_include_tag "xmlhr.js" # =>
    <script type="text/javascript" src="/javascripts/xmlhr.js"></script>

  javascript_include_tag "common.javascript", "/elsewhere/cools" # =>
    <script type="text/javascript" src="/javascripts/common.javascript"></script>
    <script type="text/javascript" src="/elsewhere/cools.js"></script>

  javascript_include_tag "http://www.railsapplication.com/xmlhr" # =>
    <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script>

  javascript_include_tag "http://www.railsapplication.com/xmlhr.js" # =>
    <script type="text/javascript" src="http://www.railsapplication.com/xmlhr.js"></script>

  javascript_include_tag :defaults # =>
    <script type="text/javascript" src="/javascripts/prototype.js"></script>
    <script type="text/javascript" src="/javascripts/effects.js"></script>
    ...
    <script type="text/javascript" src="/javascripts/application.js"></script>
  • = The application.js file is only referenced if it exists

Though it‘s not really recommended practice, if you need to extend the default JavaScript set for any reason (e.g., you‘re going to be using a certain .js file in every action), then take a look at the register_javascript_include_default method.

You can also include all javascripts in the javascripts directory using :all as the source:

  javascript_include_tag :all # =>
    <script type="text/javascript" src="/javascripts/prototype.js"></script>
    <script type="text/javascript" src="/javascripts/effects.js"></script>
    ...
    <script type="text/javascript" src="/javascripts/application.js"></script>
    <script type="text/javascript" src="/javascripts/shop.js"></script>
    <script type="text/javascript" src="/javascripts/checkout.js"></script>

Note that the default javascript files will be included first. So Prototype and Scriptaculous are available to all subsequently included files.

If you want Rails to search in all the subdirectories under javascripts, you should explicitly set :recursive:

  javascript_include_tag :all, :recursive => true

Caching multiple javascripts into one

You can also cache multiple javascripts into one file, which requires less HTTP connections to download and can better be compressed by gzip (leading to faster transfers). Caching will only happen if ActionController::Base.perform_caching is set to true (which is the case by default for the Rails production environment, but not for the development environment).

Examples

  javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is false =>
    <script type="text/javascript" src="/javascripts/prototype.js"></script>
    <script type="text/javascript" src="/javascripts/effects.js"></script>
    ...
    <script type="text/javascript" src="/javascripts/application.js"></script>
    <script type="text/javascript" src="/javascripts/shop.js"></script>
    <script type="text/javascript" src="/javascripts/checkout.js"></script>

  javascript_include_tag :all, :cache => true # when ActionController::Base.perform_caching is true =>
    <script type="text/javascript" src="/javascripts/all.js"></script>

  javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is false =>
    <script type="text/javascript" src="/javascripts/prototype.js"></script>
    <script type="text/javascript" src="/javascripts/cart.js"></script>
    <script type="text/javascript" src="/javascripts/checkout.js"></script>

  javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when ActionController::Base.perform_caching is true =>
    <script type="text/javascript" src="/javascripts/shop.js"></script>

The :recursive option is also available for caching:

  javascript_include_tag :all, :cache => true, :recursive => true

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 273
273:       def javascript_include_tag(*sources)
274:         options = sources.extract_options!.stringify_keys
275:         cache   = options.delete("cache")
276:         recursive = options.delete("recursive")
277:
278:         if ActionController::Base.perform_caching && cache
279:           joined_javascript_name = (cache == true ? "all" : cache) + ".js"
280:           joined_javascript_path = File.join(JAVASCRIPTS_DIR, joined_javascript_name)
281:
282:           write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive)) unless File.exists?(joined_javascript_path)
283:           javascript_src_tag(joined_javascript_name, options)
284:         else
285:           expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
286:         end
287:       end
javascript_path(source)

Computes the path to a javascript asset in the public javascripts directory. If the source filename has no extension, .js will be appended. Full paths from the document root will be passed through. Used internally by javascript_include_tag to build the script path.

Examples

  javascript_path "xmlhr" # => /javascripts/xmlhr.js
  javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js
  javascript_path "/dir/xmlhr" # => /dir/xmlhr.js
  javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr.js
  javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 183
183:       def javascript_path(source)
184:         compute_public_path(source, 'javascripts', 'js')
185:       end
path_to_image(source)

Alias for image_path

path_to_javascript(source)

Alias for javascript_path

path_to_stylesheet(source)

Alias for stylesheet_path

stylesheet_link_tag(*sources)

Returns a stylesheet link tag for the sources specified as arguments. If you don‘t specify an extension, .css will be appended automatically. You can modify the link attributes by passing a hash as the last argument.

Examples

  stylesheet_link_tag "style" # =>
    <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "style.css" # =>
    <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "http://www.railsapplication.com/style.css" # =>
    <link href="http://www.railsapplication.com/style.css" media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "style", :media => "all" # =>
    <link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "style", :media => "print" # =>
    <link href="/stylesheets/style.css" media="print" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "random.styles", "/css/stylish" # =>
    <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />
    <link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />

You can also include all styles in the stylesheets directory using :all as the source:

  stylesheet_link_tag :all # =>
    <link href="/stylesheets/style1.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/styleB.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />

If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set :recursive:

  stylesheet_link_tag :all, :recursive => true

Caching multiple stylesheets into one

You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be compressed by gzip (leading to faster transfers). Caching will only happen if ActionController::Base.perform_caching is set to true (which is the case by default for the Rails production environment, but not for the development environment). Examples:

Examples

  stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is false =>
    <link href="/stylesheets/style1.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/styleB.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag :all, :cache => true # when ActionController::Base.perform_caching is true =>
    <link href="/stylesheets/all.css"  media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is false =>
    <link href="/stylesheets/shop.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/cart.css"  media="screen" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" type="text/css" />

  stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when ActionController::Base.perform_caching is true =>
    <link href="/stylesheets/payment.css"  media="screen" rel="stylesheet" type="text/css" />

The :recursive option is also available for caching:

  stylesheet_link_tag :all, :cache => true, :recursive => true

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 413
413:       def stylesheet_link_tag(*sources)
414:         options = sources.extract_options!.stringify_keys
415:         cache   = options.delete("cache")
416:         recursive = options.delete("recursive")
417:
418:         if ActionController::Base.perform_caching && cache
419:           joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
420:           joined_stylesheet_path = File.join(STYLESHEETS_DIR, joined_stylesheet_name)
421:
422:           write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive)) unless File.exists?(joined_stylesheet_path)
423:           stylesheet_tag(joined_stylesheet_name, options)
424:         else
425:           expand_stylesheet_sources(sources, recursive).collect { |source| stylesheet_tag(source, options) }.join("\n")
426:         end
427:       end
stylesheet_path(source)

Computes the path to a stylesheet asset in the public stylesheets directory. If the source filename has no extension, .css will be appended. Full paths from the document root will be passed through. Used internally by stylesheet_link_tag to build the stylesheet path.

Examples

  stylesheet_path "style" # => /stylesheets/style.css
  stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css
  stylesheet_path "/dir/style.css" # => /dir/style.css
  stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style.css
  stylesheet_path "http://www.railsapplication.com/css/style.js" # => http://www.railsapplication.com/css/style.css

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 346
346:       def stylesheet_path(source)
347:         compute_public_path(source, 'stylesheets', 'css')
348:       end


Module: ActionView::Helpers::AtomFeedHelper

Module | ActionView::Helpers::AtomFeedHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb

Methods

atom_feed

Classes and Modules

Class ActionView::Helpers::AtomFeedHelper::AtomBuilder
Class ActionView::Helpers::AtomFeedHelper::AtomFeedBuilder

Public Instance methods

atom_feed(options = {}) {|AtomFeedBuilder.new(xml, self, options)| ...}

Full usage example:

  config/routes.rb:
    ActionController::Routing::Routes.draw do |map|
      map.resources :posts
      map.root :controller => "posts"
    end

  app/controllers/posts_controller.rb:
    class PostsController < ApplicationController::Base
      # GET /posts.html
      # GET /posts.atom
      def index
        @posts = Post.find(:all)

        respond_to do |format|
          format.html
          format.atom
        end
      end
    end

  app/views/posts/index.atom.builder:
    atom_feed do |feed|
      feed.title("My great blog!")
      feed.updated(@posts.first.created_at)

      for post in @posts
        feed.entry(post) do |entry|
          entry.title(post.title)
          entry.content(post.body, :type => 'html')

          entry.author do |author|
            author.name("DHH")
          end
        end
      end
    end

The options for atom_feed are:

  • :language: Defaults to "en-US".
  • :root_url: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
  • :url: The URL for this feed. Defaults to the current URL.
  • :id: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")}"
  • :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you created the feed. See feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, 2005 is used (as an "I don‘t care" value).
  • :instruct: Hash of XML processing instructions in the form {target => {attribute => value, }} or {target => [{attribute => value, }, ]}

Other namespaces can be added to the root element:

  app/views/posts/index.atom.builder:
    atom_feed({'xmlns:app' => 'http://www.w3.org/2007/app',
        'xmlns:openSearch' => 'http://a9.com/-/spec/opensearch/1.1/'}) do |feed|
      feed.title("My great blog!")
      feed.updated((@posts.first.created_at))
      feed.tag!(openSearch:totalResults, 10)

      for post in @posts
        feed.entry(post) do |entry|
          entry.title(post.title)
          entry.content(post.body, :type => 'html')
          entry.tag!('app:edited', Time.now)

          entry.author do |author|
            author.name("DHH")
          end
        end
      end
    end

The Atom spec defines five elements (content rights title subtitle summary) which may directly contain xhtml content if :type => ‘xhtml’ is specified as an attribute. If so, this helper will take care of the enclosing div and xhtml namespace declaration. Example usage:

   entry.summary :type => 'xhtml' do |xhtml|
     xhtml.p pluralize(order.line_items.count, "line item")
     xhtml.p "Shipped to #{order.address}"
     xhtml.p "Paid by #{order.pay_type}"
   end

atom_feed yields an AtomFeedBuilder instance. Nested elements yield an AtomBuilder instance.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb, line 94
 94:       def atom_feed(options = {}, &block)
 95:         if options[:schema_date]
 96:           options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
 97:         else
 98:           options[:schema_date] = "2005" # The Atom spec copyright date
 99:         end
100:
101:         xml = options[:xml] || eval("xml", block.binding)
102:         xml.instruct!
103:         if options[:instruct]
104:           options[:instruct].each do |target,attrs|
105:             if attrs.respond_to?(:keys)
106:               xml.instruct!(target, attrs)
107:             elsif attrs.respond_to?(:each)
108:               attrs.each { |attr_group| xml.instruct!(target, attr_group) }
109:             end
110:           end
111:         end
112:
113:         feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
114:         feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}
115:
116:         xml.feed(feed_opts) do
117:           xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}")
118:           xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port))
119:           xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url)
120:
121:           yield AtomFeedBuilder.new(xml, self, options)
122:         end
123:       end


Class: ActionView::Helpers::AtomFeedHelper::AtomBuilder

Class | ActionView::Helpers::AtomFeedHelper::AtomBuilder
In: | vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb
Parent: | Object

Methods

new

Constants

XHTML_TAG_NAMES = %w(content rights title subtitle summary).to_set

Public Class methods

new(xml)

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb, line 128
128:         def initialize(xml)
129:           @xml = xml
130:         end


Class: ActionView::Helpers::AtomFeedHelper::AtomFeedBuilder

Class | ActionView::Helpers::AtomFeedHelper::AtomFeedBuilder
In: | vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb
Parent: | AtomBuilder

Methods

entry new updated

Public Class methods

new(xml, view, feed_options = {})

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb, line 160
160:         def initialize(xml, view, feed_options = {})
161:           @xml, @view, @feed_options = xml, view, feed_options
162:         end

Public Instance methods

entry(record, options = {}) {|AtomBuilder.new(@xml)| ...}

Creates an entry tag for a specific record and prefills the id using class and id.

Options:

  • :published: Time first published. Defaults to the created_at attribute on the record if one such exists.
  • :updated: Time of update. Defaults to the updated_at attribute on the record if one such exists.
  • :url: The URL for this entry. Defaults to the polymorphic_url for the record.
  • :id: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb, line 177
177:         def entry(record, options = {})
178:           @xml.entry do
179:             @xml.id(options[:id] || "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}")
180:
181:             if options[:published] || (record.respond_to?(:created_at) && record.created_at)
182:               @xml.published((options[:published] || record.created_at).xmlschema)
183:             end
184:
185:             if options[:updated] || (record.respond_to?(:updated_at) && record.updated_at)
186:               @xml.updated((options[:updated] || record.updated_at).xmlschema)
187:             end
188:
189:             @xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:url] || @view.polymorphic_url(record))
190:
191:             yield AtomBuilder.new(@xml)
192:           end
193:         end
updated(date_or_time = nil)

Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb, line 165
165:         def updated(date_or_time = nil)
166:           @xml.updated((date_or_time || Time.now.utc).xmlschema)
167:         end


Module: ActionView::Helpers::BenchmarkHelper

Module | ActionView::Helpers::BenchmarkHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb

This helper offers a method to measure the execution time of a block in a template.

Methods

benchmark

Public Instance methods

benchmark(message = "Benchmarking", options = {}) {|| ...}

Allows you to measure the execution time of a block in a template and records the result to the log. Wrap this block around expensive operations or possible bottlenecks to get a time reading for the operation. For example, let‘s say you thought your file processing method was taking too long; you could wrap it in a benchmark block.

 <% benchmark "Process data files" do %>
   <%= expensive_files_operation %>
 <% end %>

That would add something like "Process data files (345.2ms)" to the log, which you can then use to compare timings when optimizing your code.

You may give an optional logger level as the :level option. (:debug, :info, :warn, :error); the default value is :info.

 <% benchmark "Low-level files", :level => :debug do %>
   <%= lowlevel_files_operation %>
 <% end %>

Finally, you can pass true as the third argument to silence all log activity inside the block. This is great for boiling down a noisy block to just a single statement:

 <% benchmark "Process data files", :level => :info, :silence => true do %>
   <%= expensive_and_chatty_files_operation %>
 <% end %>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb, line 34
34:       def benchmark(message = "Benchmarking", options = {})
35:         if controller.logger
36:           if options.is_a?(Symbol)
37:             ActiveSupport::Deprecation.warn("use benchmark('#{message}', :level => :#{options}) instead", caller)
38:             options = { :level => options, :silence => false }
39:           else
40:             options.assert_valid_keys(:level, :silence)
41:             options[:level] ||= :info
42:           end
43:
44:           result = nil
45:           ms = Benchmark.ms { result = options[:silence] ? controller.logger.silence { yield } : yield }
46:           controller.logger.send(options[:level], '%s (%.1fms)' % [ message, ms ])
47:           result
48:         else
49:           yield
50:         end
51:       end


Module: ActionView::Helpers::CacheHelper

Module | ActionView::Helpers::CacheHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb

This helper to exposes a method for caching of view fragments. See ActionController::Caching::Fragments for usage instructions.

Methods

cache

Public Instance methods

cache(name = {}, options = nil, &block)

A method for caching fragments of a view rather than an entire action or page. This technique is useful caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See ActionController::Caching::Fragments for more information.

Examples

If you wanted to cache a navigation menu, you could do the following.

  <% cache do %>
    <%= render :partial => "menu" %>
  <% end %>

You can also cache static content…

  <% cache do %>
     <p>Hello users!  Welcome to our website!</p>
  <% end %>

…and static content mixed with RHTML content.

   <% cache do %>
     Topics:
     <%= render :partial => "topics", :collection => @topic_list %>
     <i>Topics listed alphabetically</i>
   <% end %>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb, line 34
34:       def cache(name = {}, options = nil, &block)
35:         @controller.fragment_for(output_buffer, name, options, &block)
36:       end


Module: ActionView::Helpers::CaptureHelper

Module | ActionView::Helpers::CaptureHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb

CaptureHelper exposes methods to let you extract generated markup which can be used in other parts of a template or layout file. It provides a method to capture blocks into variables through capture and a way to capture a block of markup for use in a layout through content_for.

Methods

capture content_for

Public Instance methods

capture(*args, &block)

The capture method allows you to extract part of a template into a variable. You can then use this variable anywhere in your templates or layout.

Examples

The capture method can be used in ERb templates…

  <% @greeting = capture do %>
    Welcome to my shiny new web page!  The date and time is
    <%= Time.now %>
  <% end %>

…and Builder (RXML) templates.

  @timestamp = capture do
    "The current timestamp is #{Time.now}."
  end

You can then use that variable anywhere else. For example:

  <html>
  <head><title><%= @greeting %></title></head>
  <body>
  <b><%= @greeting %></b>
  </body></html>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 33
33:       def capture(*args, &block)
34:         # Return captured buffer in erb.
35:         if block_called_from_erb?(block)
36:           with_output_buffer { block.call(*args) }
37:         else
38:           # Return block result otherwise, but protect buffer also.
39:           with_output_buffer { return block.call(*args) }
40:         end
41:       end
content_for(name, content = nil, &block)

Calling content_for stores a block of markup in an identifier for later use. You can make subsequent calls to the stored content in other templates or the layout by passing the identifier as an argument to yield.

Examples

  <% content_for :not_authorized do %>
    alert('You are not authorized to do that!')
  <% end %>

You can then use yield :not_authorized anywhere in your templates.

  <%= yield :not_authorized if current_user.nil? %>

You can also use this syntax alongside an existing call to yield in a layout. For example:

  <%# This is the layout %>
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>My Website</title>
    <%= yield :script %>
  </head>
  <body>
    <%= yield %>
  </body>
  </html>

And now, we‘ll create a view that has a content_for call that creates the script identifier.

  <%# This is our view %>
  Please login!

  <% content_for :script do %>
    <script type="text/javascript">alert('You are not authorized to view this page!')</script>
  <% end %>

Then, in another view, you could to do something like this:

  <%= link_to_remote 'Logout', :action => 'logout' %>

  <% content_for :script do %>
    <%= javascript_include_tag :defaults %>
  <% end %>

That will place <script> tags for Prototype, Scriptaculous, and application.js (if it exists) on the page; this technique is useful if you‘ll only be using these scripts in a few views.

Note that content_for concatenates the blocks it is given for a particular identifier in order. For example:

  <% content_for :navigation do %>
    <li><%= link_to 'Home', :action => 'index' %></li>
  <% end %>

  <%#  Add some other content, or use a different template: %>

  <% content_for :navigation do %>
    <li><%= link_to 'Login', :action => 'login' %></li>
  <% end %>

Then, in another template or layout, this code would render both links in order:

  <ul><%= yield :navigation %></ul>

Lastly, simple content can be passed as a parameter:

  <% content_for :script, javascript_include_tag(:defaults) %>

WARNING: content_for is ignored in caches. So you shouldn‘t use it for elements that will be fragment cached.

The deprecated way of accessing a content_for block is to use an instance variable named @content_for_#{name_of_the_content_block}. The preferred usage is now <%= yield :footer %>.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb, line 118
118:       def content_for(name, content = nil, &block)
119:         ivar = "@content_for_#{name}"
120:         content = capture(&block) if block_given?
121:         instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
122:         nil
123:       end


Module: ActionView::Helpers::ClassMethods

Module | ActionView::Helpers::ClassMethods
In: | vendor/rails/actionpack/lib/action_view/helpers.rb

Included Modules

SanitizeHelper::ClassMethods


Module: ActionView::Helpers::DateHelper

Module | ActionView::Helpers::DateHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb

The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the select-type methods share a number of common options that are as follows:

  • :prefix - overwrites the default prefix of "date" used for the select names. So specifying "birthday"

would give birthday[month] instead of date[month] if passed to the select_month method.

  • :include_blank - set to true if it should be possible to set an empty date.
  • :discard_type - set to true if you want to discard the type part of the select name. If set to true, the select_month method would use simply "date" (which can be overwritten using :prefix) instead of "date[month]".

Methods

date_select datetime_select distance_of_time_in_words distance_of_time_in_words_to_now select_date select_datetime select_day select_hour select_minute select_month select_second select_time select_year time_ago_in_words time_select

Public Instance methods

date_select(object_name, method, options = {}, html_options = {})

Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by method) on an object assigned to the template (identified by object). You can the output in the options hash.

Options

  • :use_month_numbers - Set to true if you want to use month numbers rather than month names (e.g. "2" instead of "February").
  • :use_short_month - Set to true if you want to use the abbreviated month name instead of the full name (e.g. "Feb" instead of "February").
  • :add_month_number - Set to true if you want to show both, the month‘s number and name (e.g. "2 - February" instead of "February").
  • :use_month_names - Set to an array with 12 month names if you want to customize month names. Note: You can also use Rails’ new i18n functionality for this.
  • :date_separator - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
  • :start_year - Set the start year for the year select. Default is Time.now.year - 5.
  • :end_year - Set the end year for the year select. Default is Time.now.year + 5.
  • :discard_day - Set to true if you don‘t want to show a day select. This includes the day as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the first of the given month in order to not create invalid dates like 31 February.
  • :discard_month - Set to true if you don‘t want to show a month select. This includes the month as a hidden field instead of showing a select field. Also note that this implicitly sets :discard_day to true.
  • :discard_year - Set to true if you don‘t want to show a year select. This includes the year as a hidden field instead of showing a select field.
  • :order - Set to an array containing :day, :month and :year do customize the order in which the select fields are shown. If you leave out any of the symbols, the respective select will not be shown (like when you set :discard_xxx => true. Defaults to the order defined in the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
  • :include_blank - Include a blank option in every select field so it‘s possible to set empty dates.
  • :default - Set a default date if the affected date isn‘t set or is nil.
  • :disabled - Set to true if you want show the select fields as disabled.
  • :prompt - Set to true (for a generic prompt), a prompt string or a hash of prompt strings for :year, :month, :day, :hour, :minute and :second. Setting this option prepends a select option with a generic prompt (Day, Month, Year, Hour, Minute, Seconds) or the given prompt string.

If anything is passed in the html_options hash it will be applied to every select tag in the set.

NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.

Examples

  # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
  date_select("post", "written_on")

  # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
  # with the year in the year drop down box starting at 1995.
  date_select("post", "written_on", :start_year => 1995)

  # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
  # with the year in the year drop down box starting at 1995, numbers used for months instead of words,
  # and without a day select box.
  date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
                                    :discard_day => true, :include_blank => true)

  # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
  # with the fields ordered as day, month, year rather than month, day, year.
  date_select("post", "written_on", :order => [:day, :month, :year])

  # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
  # lacking a year field.
  date_select("user", "birthday", :order => [:month, :day])

  # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
  # which is initially set to the date 3 days from the current date
  date_select("post", "written_on", :default => 3.days.from_now)

  # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
  # that will have a default day of 20.
  date_select("credit_card", "bill_due", :default => { :day => 20 })

  # Generates a date select with custom prompts
  date_select("post", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })

The selects are prepared for multi-parameter assignment to an Active Record object.

Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month choices are valid.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 185
185:       def date_select(object_name, method, options = {}, html_options = {})
186:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_date_select_tag(options, html_options)
187:       end
datetime_select(object_name, method, options = {}, html_options = {})

Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based attribute (identified by method) on an object assigned to the template (identified by object). Examples:

If anything is passed in the html_options hash it will be applied to every select tag in the set.

Examples

  # Generates a datetime select that, when POSTed, will be stored in the post variable in the written_on
  # attribute
  datetime_select("post", "written_on")

  # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
  # post variable in the written_on attribute.
  datetime_select("post", "written_on", :start_year => 1995)

  # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
  # be stored in the trip variable in the departing attribute.
  datetime_select("trip", "departing", :default => 3.days.from_now)

  # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
  # as the written_on attribute.
  datetime_select("post", "written_on", :discard_type => true)

  # Generates a datetime select with a custom prompt. Use :prompt=>true for generic prompts.
  datetime_select("post", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
  datetime_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
  datetime_select("post", "written_on", :prompt => true) # generic prompts for all

The selects are prepared for multi-parameter assignment to an Active Record object.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 262
262:       def datetime_select(object_name, method, options = {}, html_options = {})
263:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options)
264:       end
distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})

Reports the approximate distance in time between two Time or Date objects or integers as seconds. Set include_seconds to true if you want more detailed approximations when distance < 1 min, 29 secs Distances are reported based on the following table:

  0 <-> 29 secs                                                             # => less than a minute
  30 secs <-> 1 min, 29 secs                                                # => 1 minute
  1 min, 30 secs <-> 44 mins, 29 secs                                       # => [2..44] minutes
  44 mins, 30 secs <-> 89 mins, 29 secs                                     # => about 1 hour
  89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs                             # => about [2..24] hours
  23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs                     # => 1 day
  47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs            # => [2..29] days
  29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs   # => about 1 month
  59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec                    # => [2..12] months
  1 yr <-> 2 yrs minus 1 secs                                               # => about 1 year
  2 yrs <-> max time or date                                                # => over [2..X] years

With include_seconds = true and the difference < 1 minute 29 seconds:

  0-4   secs      # => less than 5 seconds
  5-9   secs      # => less than 10 seconds
  10-19 secs      # => less than 20 seconds
  20-39 secs      # => half a minute
  40-59 secs      # => less than a minute
  60-89 secs      # => 1 minute

Examples

  from_time = Time.now
  distance_of_time_in_words(from_time, from_time + 50.minutes)        # => about 1 hour
  distance_of_time_in_words(from_time, 50.minutes.from_now)           # => about 1 hour
  distance_of_time_in_words(from_time, from_time + 15.seconds)        # => less than a minute
  distance_of_time_in_words(from_time, from_time + 15.seconds, true)  # => less than 20 seconds
  distance_of_time_in_words(from_time, 3.years.from_now)              # => over 3 years
  distance_of_time_in_words(from_time, from_time + 60.hours)          # => about 3 days
  distance_of_time_in_words(from_time, from_time + 45.seconds, true)  # => less than a minute
  distance_of_time_in_words(from_time, from_time - 45.seconds, true)  # => less than a minute
  distance_of_time_in_words(from_time, 76.seconds.from_now)           # => 1 minute
  distance_of_time_in_words(from_time, from_time + 1.year + 3.days)   # => about 1 year
  distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => over 4 years

  to_time = Time.now + 6.years + 19.days
  distance_of_time_in_words(from_time, to_time, true)     # => over 6 years
  distance_of_time_in_words(to_time, from_time, true)     # => over 6 years
  distance_of_time_in_words(Time.now, Time.now)           # => less than a minute

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 59
59:       def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})
60:         from_time = from_time.to_time if from_time.respond_to?(:to_time)
61:         to_time = to_time.to_time if to_time.respond_to?(:to_time)
62:         distance_in_minutes = (((to_time - from_time).abs)/60).round
63:         distance_in_seconds = ((to_time - from_time).abs).round
64:
65:         I18n.with_options :locale => options[:locale], :scope => 'datetime.distance_in_words''datetime.distance_in_words' do |locale|
66:           case distance_in_minutes
67:             when 0..1
68:               return distance_in_minutes == 0 ?
69:                      locale.t(:less_than_x_minutes, :count => 1) :
70:                      locale.t(:x_minutes, :count => distance_in_minutes) unless include_seconds
71:
72:               case distance_in_seconds
73:                 when 0..4   then locale.t :less_than_x_seconds, :count => 5
74:                 when 5..9   then locale.t :less_than_x_seconds, :count => 10
75:                 when 10..19 then locale.t :less_than_x_seconds, :count => 20
76:                 when 20..39 then locale.t :half_a_minute
77:                 when 40..59 then locale.t :less_than_x_minutes, :count => 1
78:                 else             locale.t :x_minutes,           :count => 1
79:               end
80:
81:             when 2..44           then locale.t :x_minutes,      :count => distance_in_minutes
82:             when 45..89          then locale.t :about_x_hours,  :count => 1
83:             when 90..1439        then locale.t :about_x_hours,  :count => (distance_in_minutes.to_f / 60.0).round
84:             when 1440..2879      then locale.t :x_days,         :count => 1
85:             when 2880..43199     then locale.t :x_days,         :count => (distance_in_minutes / 1440).round
86:             when 43200..86399    then locale.t :about_x_months, :count => 1
87:             when 86400..525599   then locale.t :x_months,       :count => (distance_in_minutes / 43200).round
88:             when 525600..1051199 then locale.t :about_x_years,  :count => 1
89:             else                      locale.t :over_x_years,   :count => (distance_in_minutes / 525600).round
90:           end
91:         end
92:       end
distance_of_time_in_words_to_now(from_time, include_seconds = false)

Alias for time_ago_in_words

select_date(date = Date.current, options = {}, html_options = {})

Returns a set of html select-tags (one for year, month, and day) pre-selected with the date. It‘s possible to explicitly set the order of the tags using the :order option with an array of symbols :year, :month and :day in the desired order. If you do not supply a Symbol, it will be appended onto the :order passed in.

If anything is passed in the html_options hash it will be applied to every select tag in the set.

Examples

  my_date = Time.today + 6.days

  # Generates a date select that defaults to the date in my_date (six days after today)
  select_date(my_date)

  # Generates a date select that defaults to today (no specified date)
  select_date()

  # Generates a date select that defaults to the date in my_date (six days after today)
  # with the fields ordered year, month, day rather than month, day, year.
  select_date(my_date, :order => [:year, :month, :day])

  # Generates a date select that discards the type of the field and defaults to the date in
  # my_date (six days after today)
  select_date(my_date, :discard_type => true)

  # Generates a date select that defaults to the date in my_date,
  # which has fields separated by '/'
  select_date(my_date, :date_separator => '/')

  # Generates a date select that defaults to the datetime in my_date (six days after today)
  # prefixed with 'payday' rather than 'date'
  select_date(my_date, :prefix => 'payday')

  # Generates a date select with a custom prompt. Use :prompt=>true for generic prompts.
  select_date(my_date, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
  select_date(my_date, :prompt => {:hour => true}) # generic prompt for hours
  select_date(my_date, :prompt => true) # generic prompts for all

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 351
351:       def select_date(date = Date.current, options = {}, html_options = {})
352:         DateTimeSelector.new(date, options, html_options).select_date
353:       end
select_datetime(datetime = Time.current, options = {}, html_options = {})

Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the datetime. It‘s also possible to explicitly set the order of the tags using the :order option with an array of symbols :year, :month and :day in the desired order. If you do not supply a Symbol, it will be appended onto the :order passed in. You can also add :date_separator, :datetime_separator and :time_separator keys to the options to control visual display of the elements.

If anything is passed in the html_options hash it will be applied to every select tag in the set.

Examples

  my_date_time = Time.now + 4.days

  # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
  select_datetime(my_date_time)

  # Generates a datetime select that defaults to today (no specified datetime)
  select_datetime()

  # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
  # with the fields ordered year, month, day rather than month, day, year.
  select_datetime(my_date_time, :order => [:year, :month, :day])

  # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
  # with a '/' between each date field.
  select_datetime(my_date_time, :date_separator => '/')

  # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
  # with a date fields separated by '/', time fields separated by '' and the date and time fields
  # separated by a comma (',').
  select_datetime(my_date_time, :date_separator => '/', :time_separator => '', :datetime_separator => ',')

  # Generates a datetime select that discards the type of the field and defaults to the datetime in
  # my_date_time (four days after today)
  select_datetime(my_date_time, :discard_type => true)

  # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
  # prefixed with 'payday' rather than 'date'
  select_datetime(my_date_time, :prefix => 'payday')

  # Generates a datetime select with a custom prompt. Use :prompt=>true for generic prompts.
  select_datetime(my_date_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
  select_datetime(my_date_time, :prompt => {:hour => true}) # generic prompt for hours
  select_datetime(my_date_time, :prompt => true) # generic prompts for all

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 310
310:       def select_datetime(datetime = Time.current, options = {}, html_options = {})
311:         DateTimeSelector.new(datetime, options, html_options).select_datetime
312:       end
select_day(date, options = {}, html_options = {})

Returns a select tag with options for each of the days 1 through 31 with the current day selected. The date can also be substituted for a hour number. Override the field name using the :field_name option, ‘day’ by default.

Examples

  my_date = Time.today + 2.days

  # Generates a select field for days that defaults to the day for the date in my_date
  select_day(my_time)

  # Generates a select field for days that defaults to the number given
  select_day(5)

  # Generates a select field for days that defaults to the day for the date in my_date
  # that is named 'due' rather than 'day'
  select_day(my_time, :field_name => 'due')

  # Generates a select field for days with a custom prompt.  Use :prompt => true for a
  # generic prompt.
  select_day(5, :prompt => 'Choose day')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 488
488:       def select_day(date, options = {}, html_options = {})
489:         DateTimeSelector.new(date, options, html_options).select_day
490:       end
select_hour(datetime, options = {}, html_options = {})

Returns a select tag with options for each of the hours 0 through 23 with the current hour selected. The hour can also be substituted for a hour number. Override the field name using the :field_name option, ‘hour’ by default.

Examples

  my_time = Time.now + 6.hours

  # Generates a select field for hours that defaults to the hour for the time in my_time
  select_hour(my_time)

  # Generates a select field for hours that defaults to the number given
  select_hour(13)

  # Generates a select field for hours that defaults to the minutes for the time in my_time
  # that is named 'stride' rather than 'second'
  select_hour(my_time, :field_name => 'stride')

  # Generates a select field for hours with a custom prompt.  Use :prompt => true for a
  # generic prompt.
  select_hour(13, :prompt =>'Choose hour')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 463
463:       def select_hour(datetime, options = {}, html_options = {})
464:         DateTimeSelector.new(datetime, options, html_options).select_hour
465:       end
select_minute(datetime, options = {}, html_options = {})

Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected. Also can return a select tag with options by minute_step from 0 through 59 with the 00 minute selected. The minute can also be substituted for a minute number. Override the field name using the :field_name option, ‘minute’ by default.

Examples

  my_time = Time.now + 6.hours

  # Generates a select field for minutes that defaults to the minutes for the time in my_time
  select_minute(my_time)

  # Generates a select field for minutes that defaults to the number given
  select_minute(14)

  # Generates a select field for minutes that defaults to the minutes for the time in my_time
  # that is named 'stride' rather than 'second'
  select_minute(my_time, :field_name => 'stride')

  # Generates a select field for minutes with a custom prompt.  Use :prompt=>true for a
  # generic prompt.
  select_minute(14, :prompt => 'Choose minutes')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 438
438:       def select_minute(datetime, options = {}, html_options = {})
439:         DateTimeSelector.new(datetime, options, html_options).select_minute
440:       end
select_month(date, options = {}, html_options = {})

Returns a select tag with options for each of the months January through December with the current month selected. The month names are presented as keys (what‘s shown to the user) and the month numbers (1-12) are used as values (what‘s submitted to the server). It‘s also possible to use month numbers for the presentation instead of names — set the :use_month_numbers key in options to true for this to happen. If you want both numbers and names, set the :add_month_numbers key in options to true. If you would prefer to show month names as abbreviations, set the :use_short_month key in options to true. If you want to use your own month names, set the :use_month_names key in options to an array of 12 month names. Override the field name using the :field_name option, ‘month’ by default.

Examples

  # Generates a select field for months that defaults to the current month that
  # will use keys like "January", "March".
  select_month(Date.today)

  # Generates a select field for months that defaults to the current month that
  # is named "start" rather than "month"
  select_month(Date.today, :field_name => 'start')

  # Generates a select field for months that defaults to the current month that
  # will use keys like "1", "3".
  select_month(Date.today, :use_month_numbers => true)

  # Generates a select field for months that defaults to the current month that
  # will use keys like "1 - January", "3 - March".
  select_month(Date.today, :add_month_numbers => true)

  # Generates a select field for months that defaults to the current month that
  # will use keys like "Jan", "Mar".
  select_month(Date.today, :use_short_month => true)

  # Generates a select field for months that defaults to the current month that
  # will use keys like "Januar", "Marts."
  select_month(Date.today, :use_month_names => %w(Januar Februar Marts ...))

  # Generates a select field for months with a custom prompt.  Use :prompt => true for a
  # generic prompt.
  select_month(14, :prompt => 'Choose month')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 530
530:       def select_month(date, options = {}, html_options = {})
531:         DateTimeSelector.new(date, options, html_options).select_month
532:       end
select_second(datetime, options = {}, html_options = {})

Returns a select tag with options for each of the seconds 0 through 59 with the current second selected. The second can also be substituted for a second number. Override the field name using the :field_name option, ‘second’ by default.

Examples

  my_time = Time.now + 16.minutes

  # Generates a select field for seconds that defaults to the seconds for the time in my_time
  select_second(my_time)

  # Generates a select field for seconds that defaults to the number given
  select_second(33)

  # Generates a select field for seconds that defaults to the seconds for the time in my_time
  # that is named 'interval' rather than 'second'
  select_second(my_time, :field_name => 'interval')

  # Generates a select field for seconds with a custom prompt.  Use :prompt=>true for a
  # generic prompt.
  select_minute(14, :prompt => 'Choose seconds')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 412
412:       def select_second(datetime, options = {}, html_options = {})
413:         DateTimeSelector.new(datetime, options, html_options).select_second
414:       end
select_time(datetime = Time.current, options = {}, html_options = {})

Returns a set of html select-tags (one for hour and minute) You can set :time_separator key to format the output, and the :include_seconds option to include an input for seconds.

If anything is passed in the html_options hash it will be applied to every select tag in the set.

Examples

  my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds

  # Generates a time select that defaults to the time in my_time
  select_time(my_time)

  # Generates a time select that defaults to the current time (no specified time)
  select_time()

  # Generates a time select that defaults to the time in my_time,
  # which has fields separated by ':'
  select_time(my_time, :time_separator => ':')

  # Generates a time select that defaults to the time in my_time,
  # that also includes an input for seconds
  select_time(my_time, :include_seconds => true)

  # Generates a time select that defaults to the time in my_time, that has fields
  # separated by ':' and includes an input for seconds
  select_time(my_time, :time_separator => ':', :include_seconds => true)

  # Generates a time select with a custom prompt. Use :prompt=>true for generic prompts.
  select_time(my_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
  select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
  select_time(my_time, :prompt => true) # generic prompts for all

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 387
387:       def select_time(datetime = Time.current, options = {}, html_options = {})
388:         DateTimeSelector.new(datetime, options, html_options).select_time
389:       end
select_year(date, options = {}, html_options = {})

Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius can be changed using the :start_year and :end_year keys in the options. Both ascending and descending year lists are supported by making :start_year less than or greater than :end_year. The date can also be substituted for a year given as a number. Override the field name using the :field_name option, ‘year’ by default.

Examples

  # Generates a select field for years that defaults to the current year that
  # has ascending year values
  select_year(Date.today, :start_year => 1992, :end_year => 2007)

  # Generates a select field for years that defaults to the current year that
  # is named 'birth' rather than 'year'
  select_year(Date.today, :field_name => 'birth')

  # Generates a select field for years that defaults to the current year that
  # has descending year values
  select_year(Date.today, :start_year => 2005, :end_year => 1900)

  # Generates a select field for years that defaults to the year 2006 that
  # has ascending year values
  select_year(2006, :start_year => 2000, :end_year => 2010)

  # Generates a select field for years with a custom prompt.  Use :prompt => true for a
  # generic prompt.
  select_year(14, :prompt => 'Choose year')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 561
561:       def select_year(date, options = {}, html_options = {})
562:         DateTimeSelector.new(date, options, html_options).select_year
563:       end
time_ago_in_words(from_time, include_seconds = false)

Like distance_of_time_in_words, but where to_time is fixed to Time.now.

Examples

  time_ago_in_words(3.minutes.from_now)       # => 3 minutes
  time_ago_in_words(Time.now - 15.hours)      # => 15 hours
  time_ago_in_words(Time.now)                 # => less than a minute

  from_time = Time.now - 3.days - 14.minutes - 25.seconds     # => 3 days

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 102
102:       def time_ago_in_words(from_time, include_seconds = false)
103:         distance_of_time_in_words(from_time, Time.now, include_seconds)
104:       end
time_select(object_name, method, options = {}, html_options = {})

Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a specified time-based attribute (identified by method) on an object assigned to the template (identified by object). You can include the seconds with :include_seconds.

This method will also generate 3 input hidden tags, for the actual year, month and day unless the option :ignore_date is set to true.

If anything is passed in the html_options hash it will be applied to every select tag in the set.

Examples

  # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute
  time_select("post", "sunrise")

  # Creates a time select tag that, when POSTed, will be stored in the order variable in the submitted
  # attribute
  time_select("order", "submitted")

  # Creates a time select tag that, when POSTed, will be stored in the mail variable in the sent_at attribute
  time_select("mail", "sent_at")

  # Creates a time select tag with a seconds field that, when POSTed, will be stored in the post variables in
  # the sunrise attribute.
  time_select("post", "start_time", :include_seconds => true)

  # Creates a time select tag with a seconds field that, when POSTed, will be stored in the entry variables in
  # the submission_time attribute.
  time_select("entry", "submission_time", :include_seconds => true)

  # You can set the :minute_step to 15 which will give you: 00, 15, 30 and 45.
  time_select 'game', 'game_time', {:minute_step => 15}

  # Creates a time select tag with a custom prompt. Use :prompt => true for generic prompts.
  time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
  time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
  time_select("post", "written_on", :prompt => true) # generic prompts for all

The selects are prepared for multi-parameter assignment to an Active Record object.

Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month choices are valid.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb, line 229
229:       def time_select(object_name, method, options = {}, html_options = {})
230:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_time_select_tag(options, html_options)
231:       end


Module: ActionView::Helpers::DebugHelper

Module | ActionView::Helpers::DebugHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb

Provides a set of methods for making it easier to debug Rails objects.

Methods

debug

Public Instance methods

debug(object)

Returns a YAML representation of object wrapped with <pre> and </pre>. If the object cannot be converted to YAML using to_yaml, inspect will be called instead. Useful for inspecting an object at the time of rendering.

Example

  @user = User.new({ :username => 'testing', :password => 'xyz', :age => 42}) %>
  debug(@user)
  # =>
  <pre class='debug_dump'>--- !ruby/object:User
  attributes:
  &nbsp; updated_at:
  &nbsp; username: testing

  &nbsp; age: 42
  &nbsp; password: xyz
  &nbsp; created_at:
  attributes_cache: {}

  new_record: true
  </pre>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb, line 27
27:       def debug(object)
28:         begin
29:           Marshal::dump(object)
30:           "<pre class='debug_dump'>#{h(object.to_yaml).gsub("  ", "&nbsp; ")}</pre>"
31:         rescue Exception => e  # errors from Marshal or YAML
32:           # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
33:           "<code class='debug_dump'>#{h(object.inspect)}</code>"
34:         end
35:       end


Module: ActionView::Helpers::FormHelper

Module | ActionView::Helpers::FormHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb

Form helpers are designed to make working with models much easier compared to using just standard HTML elements by providing a set of methods for creating forms based on your models. This helper generates the HTML for forms, providing a method for each sort of input (e.g., text, password, select, and so on). When the form is submitted (i.e., when the user hits the submit button or form.submit is called via JavaScript), the form inputs will be bundled into the params object and passed back to the controller.

There are two types of form helpers: those that specifically work with model attributes and those that don‘t. This helper deals with those that work with model attributes; to see an example of form helpers that don‘t work with model attributes, check the ActionView::Helpers::FormTagHelper documentation.

The core method of this helper, form_for, gives you the ability to create a form for a model instance; for example, let‘s say that you have a model Person and want to create a new instance of it:

    # Note: a @person variable will have been created in the controller.
    # For example: @person = Person.new
    <% form_for :person, @person, :url => { :action => "create" } do |f| %>
      <%= f.text_field :first_name %>
      <%= f.text_field :last_name %>
      <%= submit_tag 'Create' %>
    <% end %>

The HTML generated for this would be:

    <form action="/persons/create" method="post">
      <input id="person_first_name" name="person[first_name]" size="30" type="text" />
      <input id="person_last_name" name="person[last_name]" size="30" type="text" />
      <input name="commit" type="submit" value="Create" />
    </form>

If you are using a partial for your form fields, you can use this shortcut:

    <% form_for :person, @person, :url => { :action => "create" } do |f| %>
      <%= render :partial => f %>
      <%= submit_tag 'Create' %>
    <% end %>

This example will render the people/_form partial, setting a local variable called form which references the yielded FormBuilder. The params object created when this form is submitted would look like:

    {"action"=>"create", "controller"=>"persons", "person"=>{"first_name"=>"William", "last_name"=>"Smith"}}

The params hash has a nested person value, which can therefore be accessed with params[:person] in the controller. If were editing/updating an instance (e.g., Person.find(1) rather than Person.new in the controller), the objects attribute values are filled into the form (e.g., the person_first_name field would have that person‘s first name in it).

If the object name contains square brackets the id for the object will be inserted. For example:

  <%= text_field "person[]", "name" %>

…will generate the following ERb.

  <input type="text" id="person_<%= @person.id %>_name" name="person[<%= @person.id %>][name]" value="<%= @person.name %>" />

If the helper is being used to generate a repetitive sequence of similar form elements, for example in a partial used by render_collection_of_partials, the index option may come in handy. Example:

  <%= text_field "person", "name", "index" => 1 %>

…becomes…

  <input type="text" id="person_1_name" name="person[1][name]" value="<%= @person.name %>" />

An index option may also be passed to form_for and fields_for. This automatically applies the index to all the nested fields.

There are also methods for helping to build form tags in classes/ActionView/Helpers/FormOptionsHelper.html, classes/ActionView/Helpers/DateHelper.html, and classes/ActionView/Helpers/ActiveRecordHelper.html

Methods

check_box fields_for file_field form_for hidden_field label password_field radio_button text_area text_field

Public Instance methods

check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")

Returns a checkbox tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). This object must be an instance object (@object) and not a local object. It‘s intended that method returns an integer and if that integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a hash with options. The checked_value defaults to 1 while the default unchecked_value is set to 0 which is convenient for boolean values.

Gotcha

The HTML specification says unchecked check boxes are not successful, and thus web browsers do not send them. Unfortunately this introduces a gotcha: if an Invoice model has a paid flag, and in the form that edits a paid invoice the user unchecks its check box, no paid parameter is sent. So, any mass-assignment idiom like

  @invoice.update_attributes(params[:invoice])

wouldn‘t update the flag.

To prevent this the helper generates a hidden field with the same name as the checkbox after the very check box. So, the client either sends only the hidden field (representing the check box is unchecked), or both fields. Since the HTML specification says key/value pairs have to be sent in the same order they appear in the form and Rails parameters extraction always gets the first occurrence of any given key, that works in ordinary forms.

Unfortunately that workaround does not work when the check box goes within an array-like parameter, as in

  <% fields_for "project[invoice_attributes][]", invoice, :index => nil do |form| %>
    <%= form.check_box :paid %>
    ...
  <% end %>

because parameter name repetition is precisely what Rails seeks to distinguish the elements of the array.

Examples

  # Let's say that @post.validated? is 1:
  check_box("post", "validated")
  # => <input type="checkbox" id="post_validated" name="post[validated]" value="1" />
  #    <input name="post[validated]" type="hidden" value="0" />

  # Let's say that @puppy.gooddog is "no":
  check_box("puppy", "gooddog", {}, "yes", "no")
  # => <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
  #    <input name="puppy[gooddog]" type="hidden" value="no" />

  check_box("eula", "accepted", { :class => 'eula_check' }, "yes", "no")
  # => <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
  #    <input name="eula[accepted]" type="hidden" value="no" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 672
672:       def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
673:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value)
674:       end
fields_for(record_or_name_or_array, *args) {|builder.new(object_name, object, self, options, block)| ...}

Creates a scope around a specific model object like form_for, but doesn‘t create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form.

Generic Examples

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    First name: <%= person_form.text_field :first_name %>
    Last name : <%= person_form.text_field :last_name %>

    <% fields_for @person.permission do |permission_fields| %>
      Admin?  : <%= permission_fields.check_box :admin %>
    <% end %>
  <% end %>

…or if you have an object that needs to be represented as a different parameter, like a Client that acts as a Person:

  <% fields_for :person, @client do |permission_fields| %>
    Admin?: <%= permission_fields.check_box :admin %>
  <% end %>

…or if you don‘t have an object, just a name of the parameter:

  <% fields_for :person do |permission_fields| %>
    Admin?: <%= permission_fields.check_box :admin %>
  <% end %>

Note: This also works for the methods in FormOptionHelper and DateHelper that are designed to work with an object as base, like FormOptionHelper#collection_select and DateHelper#datetime_select.

Nested Attributes Examples

When the object belonging to the current scope has a nested attribute writer for a certain attribute, fields_for will yield a new scope for that attribute. This allows you to create forms that set or change the attributes of a parent object and its associations in one go.

Nested attribute writers are normal setter methods named after an association. The most common way of defining these writers is either with accepts_nested_attributes_for in a model definition or by defining a method with the proper name. For example: the attribute writer for the association :address is called address_attributes=.

Whether a one-to-one or one-to-many style form builder will be yielded depends on whether the normal reader method returns a single object or an array of objects.

One-to-one

Consider a Person class which returns a single Address from the address reader method and responds to the address_attributes= writer method:

  class Person
    def address
      @address
    end

    def address_attributes=(attributes)
      # Process the attributes hash
    end
  end

This model can now be used with a nested fields_for, like so:

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    ...
    <% person_form.fields_for :address do |address_fields| %>
      Street  : <%= address_fields.text_field :street %>
      Zip code: <%= address_fields.text_field :zip_code %>
    <% end %>
  <% end %>

When address is already an association on a Person you can use accepts_nested_attributes_for to define the writer method for you:

  class Person < ActiveRecord::Base
    has_one :address
    accepts_nested_attributes_for :address
  end

If you want to destroy the associated model through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

  class Person < ActiveRecord::Base
    has_one :address
    accepts_nested_attributes_for :address, :allow_destroy => true
  end

Now, when you use a form element with the _delete parameter, with a value that evaluates to true, you will destroy the associated model (eg. 1, ‘1’, true, or ‘true’):

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    ...
    <% person_form.fields_for :address do |address_fields| %>
      ...
      Delete: <%= address_fields.check_box :_delete %>
    <% end %>
  <% end %>

One-to-many

Consider a Person class which returns an array of Project instances from the projects reader method and responds to the projects_attributes= writer method:

  class Person
    def projects
      [@project1, @project2]
    end

    def projects_attributes=(attributes)
      # Process the attributes hash
    end
  end

This model can now be used with a nested fields_for. The block given to the nested fields_for call will be repeated for each instance in the collection:

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    ...
    <% person_form.fields_for :projects do |project_fields| %>
      <% if project_fields.object.active? %>
        Name: <%= project_fields.text_field :name %>
      <% end %>
    <% end %>
  <% end %>

It‘s also possible to specify the instance to be used:

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    ...
    <% @person.projects.each do |project| %>
      <% if project.active? %>
        <% person_form.fields_for :projects, project do |project_fields| %>
          Name: <%= project_fields.text_field :name %>
        <% end %>
      <% end %>
    <% end %>
  <% end %>

When projects is already an association on Person you can use accepts_nested_attributes_for to define the writer method for you:

  class Person < ActiveRecord::Base
    has_many :projects
    accepts_nested_attributes_for :projects
  end

If you want to destroy any of the associated models through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

  class Person < ActiveRecord::Base
    has_many :projects
    accepts_nested_attributes_for :projects, :allow_destroy => true
  end

This will allow you to specify which models to destroy in the attributes hash by adding a form element for the _delete parameter with a value that evaluates to true (eg. 1, ‘1’, true, or ‘true’):

  <% form_for @person, :url => { :action => "update" } do |person_form| %>
    ...
    <% person_form.fields_for :projects do |project_fields| %>
      Delete: <%= project_fields.check_box :_delete %>
    <% end %>
  <% end %>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 476
476:       def fields_for(record_or_name_or_array, *args, &block)
477:         raise ArgumentError, "Missing block" unless block_given?
478:         options = args.extract_options!
479:
480:         case record_or_name_or_array
481:         when String, Symbol
482:           object_name = record_or_name_or_array
483:           object = args.first
484:         else
485:           object = record_or_name_or_array
486:           object_name = ActionController::RecordIdentifier.singular_class_name(object)
487:         end
488:
489:         builder = options[:builder] || ActionView::Base.default_form_builder
490:         yield builder.new(object_name, object, self, options, block)
491:       end
file_field(object_name, method, options = {})

Returns an file upload input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

Examples

  file_field(:user, :avatar)
  # => <input type="file" id="user_avatar" name="user[avatar]" />

  file_field(:post, :attached, :accept => 'text/html')
  # => <input type="file" id="post_attached" name="post[attached]" />

  file_field(:attachment, :file, :class => 'file_input')
  # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 589
589:       def file_field(object_name, method, options = {})
590:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options)
591:       end
form_for(record_or_name_or_array, *args, &proc)

Creates a form and a scope around a specific model object that is used as a base for questioning about values for the fields.

Rails provides succinct resource-oriented form generation with form_for like this:

  <% form_for @offer do |f| %>
    <%= f.label :version, 'Version' %>:
    <%= f.text_field :version %><br />
    <%= f.label :author, 'Author' %>:
    <%= f.text_field :author %><br />
  <% end %>

There, form_for is able to generate the rest of RESTful form parameters based on introspection on the record, but to understand what it does we need to dig first into the alternative generic usage it is based upon.

Generic form_for

The generic way to call form_for yields a form builder around a model:

  <% form_for :person, :url => { :action => "update" } do |f| %>
    <%= f.error_messages %>
    First name: <%= f.text_field :first_name %><br />
    Last name : <%= f.text_field :last_name %><br />
    Biography : <%= f.text_area :biography %><br />
    Admin?    : <%= f.check_box :admin %><br />
  <% end %>

There, the first argument is a symbol or string with the name of the object the form is about, and also the name of the instance variable the object is stored in.

The form builder acts as a regular form helper that somehow carries the model. Thus, the idea is that

  <%= f.text_field :first_name %>

gets expanded to

  <%= text_field :person, :first_name %>

If the instance variable is not @person you can pass the actual record as the second argument:

  <% form_for :person, person, :url => { :action => "update" } do |f| %>
    ...
  <% end %>

In that case you can think

  <%= f.text_field :first_name %>

gets expanded to

  <%= text_field :person, :first_name, :object => person %>

You can even display error messages of the wrapped model this way:

  <%= f.error_messages %>

In any of its variants, the rightmost argument to form_for is an optional hash of options:

  • :url - The URL the form is submitted to. It takes the same fields you pass to url_for or link_to. In particular you may pass here a named route directly as well. Defaults to the current action.
  • :html - Optional HTML attributes for the form tag.

Worth noting is that the form_for tag is called in a ERb evaluation block, not an ERb output block. So that‘s <% %>, not <%= %>.

Also note that form_for doesn‘t create an exclusive scope. It‘s still possible to use both the stand-alone FormHelper methods and methods from FormTagHelper. For example:

  <% form_for :person, @person, :url => { :action => "update" } do |f| %>
    First name: <%= f.text_field :first_name %>
    Last name : <%= f.text_field :last_name %>
    Biography : <%= text_area :person, :biography %>
    Admin?    : <%= check_box_tag "person[admin]", @person.company.admin? %>
  <% end %>

This also works for the methods in FormOptionHelper and DateHelper that are designed to work with an object as base, like FormOptionHelper#collection_select and DateHelper#datetime_select.

Resource-oriented style

As we said above, in addition to manually configuring the form_for call, you can rely on automated resource identification, which will use the conventions and named routes of that approach. This is the preferred way to use form_for nowadays.

For example, if @post is an existing record you want to edit

  <% form_for @post do |f| %>
    ...
  <% end %>

is equivalent to something like:

  <% form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
    ...
  <% end %>

And for new records

  <% form_for(Post.new) do |f| %>
    ...
  <% end %>

expands to

  <% form_for :post, Post.new, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>
    ...
  <% end %>

You can also overwrite the individual conventions, like this:

  <% form_for(@post, :url => super_post_path(@post)) do |f| %>
    ...
  <% end %>

And for namespaced routes, like admin_post_url:

  <% form_for([:admin, @post]) do |f| %>
   ...
  <% end %>

Customized form builders

You can also build forms using a customized FormBuilder class. Subclass FormBuilder and override or define some more helpers, then use your custom builder. For example, let‘s say you made a helper to automatically add labels to form inputs.

  <% form_for :person, @person, :url => { :action => "update" }, :builder => LabellingFormBuilder do |f| %>
    <%= f.text_field :first_name %>
    <%= f.text_field :last_name %>
    <%= text_area :person, :biography %>
    <%= check_box_tag "person[admin]", @person.company.admin? %>
  <% end %>

In this case, if you use this:

  <%= render :partial => f %>

The rendered template is people/_labelling_form and the local variable referencing the form builder is called labelling_form.

The custom FormBuilder class is automatically merged with the options of a nested fields_for call, unless it‘s explicitely set.

In many cases you will want to wrap the above in another helper, so you could do something like the following:

  def labelled_form_for(record_or_name_or_array, *args, &proc)
    options = args.extract_options!
    form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &proc)
  end

If you don‘t need to attach a form to a model instance, then check out FormTagHelper#form_tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 261
261:       def form_for(record_or_name_or_array, *args, &proc)
262:         raise ArgumentError, "Missing block" unless block_given?
263:
264:         options = args.extract_options!
265:
266:         case record_or_name_or_array
267:         when String, Symbol
268:           object_name = record_or_name_or_array
269:         when Array
270:           object = record_or_name_or_array.last
271:           object_name = ActionController::RecordIdentifier.singular_class_name(object)
272:           apply_form_for_options!(record_or_name_or_array, options)
273:           args.unshift object
274:         else
275:           object = record_or_name_or_array
276:           object_name = ActionController::RecordIdentifier.singular_class_name(object)
277:           apply_form_for_options!([object], options)
278:           args.unshift object
279:         end
280:
281:         concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
282:         fields_for(object_name, *(args << options), &proc)
283:         concat('</form>')
284:       end
hidden_field(object_name, method, options = {})

Returns a hidden input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

Examples

  hidden_field(:signup, :pass_confirm)
  # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />

  hidden_field(:post, :tag_list)
  # => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.tag_list}" />

  hidden_field(:user, :token)
  # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 570
570:       def hidden_field(object_name, method, options = {})
571:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("hidden", options)
572:       end
label(object_name, method, text = nil, options = {})

Returns a label tag tailored for labelling an input field for a specified attribute (identified by method) on an object assigned to the template (identified by object). The text of label will default to the attribute name unless you specify it explicitly. Additional options on the label tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

Examples

  label(:post, :title)
  # => <label for="post_title">Title</label>

  label(:post, :title, "A short title")
  # => <label for="post_title">A short title</label>

  label(:post, :title, "A short title", :class => "title_label")
  # => <label for="post_title" class="title_label">A short title</label>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 508
508:       def label(object_name, method, text = nil, options = {})
509:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options)
510:       end
password_field(object_name, method, options = {})

Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

Examples

  password_field(:login, :pass, :size => 20)
  # => <input type="text" id="login_pass" name="login[pass]" size="20" value="#{@login.pass}" />

  password_field(:account, :secret, :class => "form_input")
  # => <input type="text" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />

  password_field(:user, :password, :onchange => "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }")
  # => <input type="text" id="user_password" name="user[password]" value="#{@user.password}" onchange = "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }"/>

  password_field(:account, :pin, :size => 20, :class => 'form_input')
  # => <input type="text" id="account_pin" name="account[pin]" size="20" value="#{@account.pin}" class="form_input" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 552
552:       def password_field(object_name, method, options = {})
553:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", options)
554:       end
radio_button(object_name, method, tag_value, options = {})

Returns a radio button tag for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). If the current value of method is tag_value the radio button will be checked.

To force the radio button to be checked pass :checked => true in the options hash. You may pass HTML options there as well.

Examples

  # Let's say that @post.category returns "rails":
  radio_button("post", "category", "rails")
  radio_button("post", "category", "java")
  # => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
  #    <input type="radio" id="post_category_java" name="post[category]" value="java" />

  radio_button("user", "receive_newsletter", "yes")
  radio_button("user", "receive_newsletter", "no")
  # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
  #    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 694
694:       def radio_button(object_name, method, tag_value, options = {})
695:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
696:       end
text_area(object_name, method, options = {})

Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options.

Examples

  text_area(:post, :body, :cols => 20, :rows => 40)
  # => <textarea cols="20" rows="40" id="post_body" name="post[body]">
  #      #{@post.body}
  #    </textarea>

  text_area(:comment, :text, :size => "20x30")
  # => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
  #      #{@comment.text}
  #    </textarea>

  text_area(:application, :notes, :cols => 40, :rows => 15, :class => 'app_input')
  # => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
  #      #{@application.notes}
  #    </textarea>

  text_area(:entry, :body, :size => "20x20", :disabled => 'disabled')
  # => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
  #      #{@entry.body}
  #    </textarea>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 617
617:       def text_area(object_name, method, options = {})
618:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_text_area_tag(options)
619:       end
text_field(object_name, method, options = {})

Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

Examples

  text_field(:post, :title, :size => 20)
  # => <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" />

  text_field(:post, :title, :class => "create_input")
  # => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />

  text_field(:session, :user, :onchange => "if $('session[user]').value == 'admin' { alert('Your login can not be admin!'); }")
  # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange = "if $('session[user]').value == 'admin' { alert('Your login can not be admin!'); }"/>

  text_field(:snippet, :code, :size => 20, :class => 'code_input')
  # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb, line 530
530:       def text_field(object_name, method, options = {})
531:         InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("text", options)
532:       end


Module: ActionView::Helpers::FormOptionsHelper

Module | ActionView::Helpers::FormOptionsHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb

Provides a number of methods for turning different kinds of containers into a set of option tags.

Options

The collection_select, select and time_zone_select methods take an options parameter, a hash:

  • :include_blank - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.

For example,

  select("post", "category", Post::CATEGORIES, {:include_blank => true})

could become:

  <select name="post[category]">
    <option></option>
    <option>joke</option>
    <option>poem</option>
  </select>

Another common case is a select tag for an belongs_to-associated object.

Example with @post.person_id => 2:

  select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:include_blank => 'None'})

could become:

  <select name="post[person_id]">
    <option value="">None</option>
    <option value="1">David</option>
    <option value="2" selected="selected">Sam</option>
    <option value="3">Tobias</option>
  </select>
  • :prompt - set to true or a prompt string. When the select element doesn‘t have a value yet, this prepends an option with a generic prompt — "Please select" — or the given prompt string.

Example:

  select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:prompt => 'Select Person'})

could become:

  <select name="post[person_id]">
    <option value="">Select Person</option>
    <option value="1">David</option>
    <option value="2">Sam</option>
    <option value="3">Tobias</option>
  </select>

Like the other form helpers, select can accept an :index option to manually set the ID used in the resulting output. Unlike other helpers, select expects this option to be in the html_options parameter.

Example:

  select("album[]", "genre", %w[rap rock country], {}, { :index => nil })

becomes:

  <select name="album[][genre]" id="album__genre">
    <option value="rap">rap</option>
    <option value="rock">rock</option>
    <option value="country">country</option>
  </select>
  • :disabled - can be a single value or an array of values that will be disabled options in the final output.

Example:

  select("post", "category", Post::CATEGORIES, {:disabled => 'restricted'})

could become:

  <select name="post[category]">
    <option></option>
    <option>joke</option>
    <option>poem</option>
    <option disabled="disabled">restricted</option>
  </select>

When used with the collection_select helper, :disabled can also be a Proc that identifies those options that should be disabled.

Example:

  collection_select(:post, :category_id, Category.all, :id, :name, {:disabled => lambda{|category| category.archived? }})

If the categories "2008 stuff" and "Christmas" return true when the method archived? is called, this would return:

  <select name="post[category_id]">
    <option value="1" disabled="disabled">2008 stuff</option>
    <option value="2" disabled="disabled">Christmas</option>
    <option value="3">Jokes</option>
    <option value="4">Poems</option>
  </select>

Methods

collection_select grouped_options_for_select option_groups_from_collection_for_select options_for_select options_from_collection_for_select select time_zone_options_for_select time_zone_select

Included Modules

ERB::Util

Public Instance methods

collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

Returns <select> and <option> tags for the collection of existing return values of method for object‘s class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made without including :prompt or :include_blank in the options hash.

The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each <option> tag, respectively.

Example object structure for use with this method:

  class Post < ActiveRecord::Base
    belongs_to :author
  end
  class Author < ActiveRecord::Base
    has_many :posts
    def name_with_initial
      "#{first_name.first}. #{last_name}"
    end
  end

Sample usage (selecting the associated Author for an instance of Post, @post):

  collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true})

If @post.author_id is already 1, this would return:

  <select name="post[author_id]">
    <option value="">Please select</option>
    <option value="1" selected="selected">D. Heinemeier Hansson</option>
    <option value="2">D. Thomas</option>
    <option value="3">M. Clark</option>
  </select>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 161
161:       def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
162:         InstanceTag.new(object, method, self, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options)
163:       end
grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)

Returns a string of <option> tags, like options_for_select, but wraps them with <optgroup> tags.

Parameters:

  • grouped_options - Accepts a nested array or hash of strings. The first value serves as the <optgroup> label while the second value must be an array of options. The second value can be a nested array of text-value pairs. See options_for_select for more info.
     Ex. ["North America",[["United States","US"],["Canada","CA"]]]
  • selected_key - A value equal to the value attribute for one of the <option> tags, which will have the selected attribute set. Note: It is possible for this value to match multiple options as you might have the same option in multiple groups. Each will then get selected="selected".
  • prompt - set to true or a prompt string. When the select element doesn’t have a value yet, this prepends an option with a generic prompt — "Please select" — or the given prompt string.

Sample usage (Array):

  grouped_options = [
   ['North America',
     [['United States','US'],'Canada']],
   ['Europe',
     ['Denmark','Germany','France']]
  ]
  grouped_options_for_select(grouped_options)

Sample usage (Hash):

  grouped_options = {
   'North America' => [['United States','US], 'Canada'],
   'Europe' => ['Denmark','Germany','France']
  }
  grouped_options_for_select(grouped_options)

Possible output:

  <optgroup label="Europe">
    <option value="Denmark">Denmark</option>
    <option value="Germany">Germany</option>
    <option value="France">France</option>
  </optgroup>
  <optgroup label="North America">
    <option value="US">United States</option>
    <option value="Canada">Canada</option>
  </optgroup>

Note: Only the <optgroup> and <option> tags are returned, so you still have to wrap the output in an appropriate <select> tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 380
380:       def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)
381:         body = ''
382:         body << content_tag(:option, prompt, :value => "") if prompt
383:
384:         grouped_options = grouped_options.sort if grouped_options.is_a?(Hash)
385:
386:         grouped_options.each do |group|
387:           body << content_tag(:optgroup, options_for_select(group[1], selected_key), :label => group[0])
388:         end
389:
390:         body
391:       end
option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)

Returns a string of <option> tags, like options_from_collection_for_select, but groups them by <optgroup> tags based on the object relationships of the arguments.

Parameters:

  • collection - An array of objects representing the <optgroup> tags.
  • group_method - The name of a method which, when called on a member of collection, returns an array of child objects representing the <option> tags.
  • group_label_method+ - The name of a method which, when called on a member of collection, returns a string to be used as the label attribute for its <optgroup> tag.
  • option_key_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the value attribute for its <option> tag.
  • option_value_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the contents of its <option> tag.
  • selected_key - A value equal to the value attribute for one of the <option> tags, which will have the selected attribute set. Corresponds to the return value of one of the calls to option_key_method. If nil, no selection is made. Can also be a hash if disabled values are to be specified.

Example object structure for use with this method:

  class Continent < ActiveRecord::Base
    has_many :countries
    # attribs: id, name
  end
  class Country < ActiveRecord::Base
    belongs_to :continent
    # attribs: id, name, continent_id
  end

Sample usage:

  option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)

Possible output:

  <optgroup label="Africa">
    <option value="1">Egypt</option>
    <option value="4">Rwanda</option>
    ...
  </optgroup>
  <optgroup label="Asia">
    <option value="3" selected="selected">China</option>
    <option value="12">India</option>
    <option value="5">Japan</option>
    ...
  </optgroup>

Note: Only the <optgroup> and <option> tags are returned, so you still have to wrap the output in an appropriate <select> tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 328
328:       def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
329:         collection.inject("") do |options_for_select, group|
330:           group_label_string = eval("group.#{group_label_method}")
331:           options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
332:           options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
333:           options_for_select += '</optgroup>'
334:         end
335:       end
options_for_select(container, selected = nil)

Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values become lasts. If selected is specified, the matching "last" or element will get the selected option-tag. selected may also be an array of values to be selected when using a multiple select.

Examples (call, result):

  options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
    <option value="$">Dollar</option>\n<option value="DKK">Kroner</option>

  options_for_select([ "VISA", "MasterCard" ], "MasterCard")
    <option>VISA</option>\n<option selected="selected">MasterCard</option>

  options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
    <option value="$20">Basic</option>\n<option value="$40" selected="selected">Plus</option>

  options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
    <option selected="selected">VISA</option>\n<option>MasterCard</option>\n<option selected="selected">Discover</option>

If you wish to specify disabled option tags, set selected to be a hash, with :disabled being either a value or array of values to be disabled. In this case, you can use :selected to specify selected option tags.

Examples:

  options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => "Super Platinum")
    <option value="Free">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>

  options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => ["Advanced", "Super Platinum"])
    <option value="Free">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced" disabled="disabled">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>

  options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :selected => "Free", :disabled => "Super Platinum")
    <option value="Free" selected="selected">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 232
232:       def options_for_select(container, selected = nil)
233:         container = container.to_a if Hash === container
234:         selected, disabled = extract_selected_and_disabled(selected)
235:
236:         options_for_select = container.inject([]) do |options, element|
237:           text, value = option_text_and_value(element)
238:           selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
239:           disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled)
240:           options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}>#{html_escape(text.to_s)}</option>)
241:         end
242:
243:         options_for_select.join("\n")
244:       end
options_from_collection_for_select(collection, value_method, text_method, selected = nil)

Returns a string of option tags that have been compiled by iterating over the collection and assigning the the result of a call to the value_method as the option value and the text_method as the option text. Example:

  options_from_collection_for_select(@people, 'id', 'name')

This will output the same HTML as if you did this:

  <option value="#{person.id}">#{person.name}</option>

This is more often than not used inside a select_tag like this example:

  select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')

If selected is specified as a value or array of values, the element(s) returning a match on value_method will be selected option tag(s).

If selected is specified as a Proc, those members of the collection that return true for the anonymous function are the selected values.

selected can also be a hash, specifying both :selected and/or :disabled values as required.

Be sure to specify the same class as the value_method when specifying selected or disabled options. Failure to do this will produce undesired results. Example:

  options_from_collection_for_select(@people, 'id', 'name', '1')

Will not select a person with the id of 1 because 1 (an Integer) is not the same as ‘1’ (a string)

  options_from_collection_for_select(@people, 'id', 'name', 1)

should produce the desired results.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 270
270:       def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
271:         options = collection.map do |element|
272:           [element.send(text_method), element.send(value_method)]
273:         end
274:         selected, disabled = extract_selected_and_disabled(selected)
275:         select_deselect = {}
276:         select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected)
277:         select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled)
278:
279:         options_for_select(options, select_deselect)
280:       end
select(object, method, choices, options = {}, html_options = {})

Create a select tag and a series of contained option tags for the provided object and method. The option currently held by the object will be selected, provided that the object is available. See options_for_select for the required format of the choices parameter.

Example with @post.person_id => 1:

  select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true })

could become:

  <select name="post[person_id]">
    <option value=""></option>
    <option value="1" selected="selected">David</option>
    <option value="2">Sam</option>
    <option value="3">Tobias</option>
  </select>

This can be used to provide a default set of options in the standard way: before rendering the create form, a new model instance is assigned the default options and bound to @model_name. Usually this model is not saved to the database. Instead, a second model object is created when the create request is received. This allows the user to submit a form page more than once with the expected results of creating multiple records. In addition, this allows a single partial to be used to generate form inputs for both edit and create forms.

By default, post.person_id is the selected option. Specify :selected => value to use a different selection or :selected => nil to leave all options unselected. Similarly, you can specify values to be disabled in the option tags by specifying the :disabled option. This can either be a single value or an array of values to be disabled.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 127
127:       def select(object, method, choices, options = {}, html_options = {})
128:         InstanceTag.new(object, method, self, options.delete(:object)).to_select_tag(choices, options, html_options)
129:       end
time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)

Returns a string of option tags for pretty much any time zone in the world. Supply a TimeZone name as selected to have it marked as the selected option tag. You can also supply an array of TimeZone objects as priority_zones, so that they will be listed above the rest of the (long) list. (You can use TimeZone.us_zones as a convenience for obtaining a list of the US time zones, or a Regexp to select the zones of your choice)

The selected parameter must be either nil, or a string that names a TimeZone.

By default, model is the TimeZone constant (which can be obtained in Active Record as a value object). The only requirement is that the model parameter be an object that responds to all, and returns an array of objects that represent time zones.

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 411
411:       def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
412:         zone_options = ""
413:
414:         zones = model.all
415:         convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }
416:
417:         if priority_zones
418:                 if priority_zones.is_a?(Regexp)
419:             priority_zones = model.all.find_all {|z| z =~ priority_zones}
420:                 end
421:           zone_options += options_for_select(convert_zones[priority_zones], selected)
422:           zone_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
423:
424:           zones = zones.reject { |z| priority_zones.include?( z ) }
425:         end
426:
427:         zone_options += options_for_select(convert_zones[zones], selected)
428:         zone_options
429:       end
time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})

Return select and option tags for the given object and method, using time_zone_options_for_select to generate the list of option tags.

In addition to the :include_blank option documented above, this method also supports a :model option, which defaults to TimeZone. This may be used by users to specify a different time zone model object. (See time_zone_options_for_select for more information.)

You can also supply an array of TimeZone objects as priority_zones, so that they will be listed above the rest of the (long) list. (You can use TimeZone.us_zones as a convenience for obtaining a list of the US time zones, or a Regexp to select the zones of your choice)

Finally, this method supports a :default option, which selects a default TimeZone if the object‘s time zone is nil.

Examples:

  time_zone_select( "user", "time_zone", nil, :include_blank => true)

  time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )

  time_zone_select( "user", 'time_zone', TimeZone.us_zones, :default => "Pacific Time (US & Canada)")

  time_zone_select( "user", 'time_zone', [ TimeZone['Alaska'], TimeZone['Hawaii'] ])

  time_zone_select( "user", 'time_zone', /Australia/)

  time_zone_select( "user", "time_zone", TZInfo::Timezone.all.sort, :model => TZInfo::Timezone)

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb, line 195
195:       def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
196:         InstanceTag.new(object, method, self,  options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options)
197:       end


Module: ActionView::Helpers::FormTagHelper

Module | ActionView::Helpers::FormTagHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb

Provides a number of methods for creating form tags that doesn‘t rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually.

NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying :disabled => true will give disabled="disabled".

Methods

check_box_tag field_set_tag file_field_tag form_tag hidden_field_tag image_submit_tag label_tag password_field_tag radio_button_tag select_tag submit_tag text_area_tag text_field_tag

Public Instance methods

check_box_tag(name, value = "1", checked = false, options = {})

Creates a check box form input tag.

Options

  • :disabled - If set to true, the user will not be able to use this input.
  • Any other key creates standard HTML options for the tag.

Examples

  check_box_tag 'accept'
  # => <input id="accept" name="accept" type="checkbox" value="1" />

  check_box_tag 'rock', 'rock music'
  # => <input id="rock" name="rock" type="checkbox" value="rock music" />

  check_box_tag 'receive_email', 'yes', true
  # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />

  check_box_tag 'tos', 'yes', false, :class => 'accept_tos'
  # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />

  check_box_tag 'eula', 'accepted', false, :disabled => true
  # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 284
284:       def check_box_tag(name, value = "1", checked = false, options = {})
285:         html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
286:         html_options["checked"] = "checked" if checked
287:         tag :input, html_options
288:       end
field_set_tag(legend = nil, options = nil, &block)

Creates a field set for grouping HTML form elements.

legend will become the fieldset‘s title (optional as per W3C). options accept the same values as tag.

Examples

  <% field_set_tag do %>
    <p><%= text_field_tag 'name' %></p>
  <% end %>
  # => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>

  <% field_set_tag 'Your details' do %>
    <p><%= text_field_tag 'name' %></p>
  <% end %>
  # => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>

  <% field_set_tag nil, :class => 'format' do %>
    <p><%= text_field_tag 'name' %></p>
  <% end %>
  # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 424
424:       def field_set_tag(legend = nil, options = nil, &block)
425:         content = capture(&block)
426:         concat(tag(:fieldset, options, true))
427:         concat(content_tag(:legend, legend)) unless legend.blank?
428:         concat(content)
429:         concat("</fieldset>")
430:       end
file_field_tag(name, options = {})

Creates a file upload field. If you are using file uploads then you will also need to set the multipart option for the form tag:

  <% form_tag '/upload', :multipart => true do %>
    <label for="file">File to Upload</label> <%= file_field_tag "file" %>
    <%= submit_tag %>
  <% end %>

The specified URL will then be passed a File object containing the selected file, or if the field was left blank, a StringIO object.

Options

  • Creates standard HTML attributes for the tag.
  • :disabled - If set to true, the user will not be able to use this input.

Examples

  file_field_tag 'attachment'
  # => <input id="attachment" name="attachment" type="file" />

  file_field_tag 'avatar', :class => 'profile-input'
  # => <input class="profile-input" id="avatar" name="avatar" type="file" />

  file_field_tag 'picture', :disabled => true
  # => <input disabled="disabled" id="picture" name="picture" type="file" />

  file_field_tag 'resume', :value => '~/resume.doc'
  # => <input id="resume" name="resume" type="file" value="~/resume.doc" />

  file_field_tag 'user_pic', :accept => 'image/png,image/gif,image/jpeg'
  # => <input accept="image/png,image/gif,image/jpeg" id="user_pic" name="user_pic" type="file" />

  file_field_tag 'file', :accept => 'text/html', :class => 'upload', :value => 'index.html'
  # => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 189
189:       def file_field_tag(name, options = {})
190:         text_field_tag(name, nil, options.update("type" => "file"))
191:       end
form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)

Starts a form tag that points the action to an url configured with url_for_options just like ActionController::Base#url_for. The method for the form defaults to POST.

Options

  • :multipart - If set to true, the enctype is set to "multipart/form-data".
  • :method - The method to use when submitting the form, usually either "get" or "post". If "put", "delete", or another verb is used, a hidden input with name _method is added to simulate the verb over post.
  • A list of parameters to feed to the URL the form will be posted to.

Examples

  form_tag('/posts')
  # => <form action="/posts" method="post">

  form_tag('/posts/1', :method => :put)
  # => <form action="/posts/1" method="put">

  form_tag('/upload', :multipart => true)
  # => <form action="/upload" method="post" enctype="multipart/form-data">

  <% form_tag '/posts' do -%>
    <div><%= submit_tag 'Save' %></div>
  <% end -%>
  # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 36
36:       def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)
37:         html_options = html_options_for_form(url_for_options, options, *parameters_for_url)
38:         if block_given?
39:           form_tag_in_block(html_options, &block)
40:         else
41:           form_tag_html(html_options)
42:         end
43:       end
hidden_field_tag(name, value = nil, options = {})

Creates a hidden form input field used to transmit data that would be lost due to HTTP‘s statelessness or data that should be hidden from the user.

Options

  • Creates standard HTML attributes for the tag.

Examples

  hidden_field_tag 'tags_list'
  # => <input id="tags_list" name="tags_list" type="hidden" />

  hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
  # => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />

  hidden_field_tag 'collected_input', '', :onchange => "alert('Input collected!')"
  # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
  #    type="hidden" value="" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 152
152:       def hidden_field_tag(name, value = nil, options = {})
153:         text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
154:       end
image_submit_tag(source, options = {})

Displays an image which when clicked will submit the form.

source is passed to AssetTagHelper#image_path

Options

  • :confirm => ‘question?‘ - This will add a JavaScript confirm prompt with the question specified. If the user accepts, the form is processed normally, otherwise no action is taken.
  • :disabled - If set to true, the user will not be able to use this input.
  • Any other key creates standard HTML options for the tag.

Examples

  image_submit_tag("login.png")
  # => <input src="/images/login.png" type="image" />

  image_submit_tag("purchase.png", :disabled => true)
  # => <input disabled="disabled" src="/images/purchase.png" type="image" />

  image_submit_tag("search.png", :class => 'search-button')
  # => <input class="search-button" src="/images/search.png" type="image" />

  image_submit_tag("agree.png", :disabled => true, :class => "agree-disagree-button")
  # => <input class="agree-disagree-button" disabled="disabled" src="/images/agree.png" type="image" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 393
393:       def image_submit_tag(source, options = {})
394:         options.stringify_keys!
395:
396:         if confirm = options.delete("confirm")
397:           options["onclick"] ||= ''
398:           options["onclick"] += "return #{confirm_javascript_function(confirm)};"
399:         end
400:
401:         tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
402:       end
label_tag(name, text = nil, options = {})

Creates a label field

Options

  • Creates standard HTML attributes for the tag.

Examples

  label_tag 'name'
  # => <label for="name">Name</label>

  label_tag 'name', 'Your name'
  # => <label for="name">Your Name</label>

  label_tag 'name', nil, :class => 'small_label'
  # => <label for="name" class="small_label">Name</label>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 132
132:       def label_tag(name, text = nil, options = {})
133:         content_tag :label, text || name.to_s.humanize, { "for" => sanitize_to_id(name) }.update(options.stringify_keys)
134:       end
password_field_tag(name = "password", value = nil, options = {})

Creates a password field, a masked text field that will hide the users input behind a mask character.

Options

  • :disabled - If set to true, the user will not be able to use this input.
  • :size - The number of visible characters that will fit in the input.
  • :maxlength - The maximum number of characters that the browser will allow the user to enter.
  • Any other key creates standard HTML attributes for the tag.

Examples

  password_field_tag 'pass'
  # => <input id="pass" name="pass" type="password" />

  password_field_tag 'secret', 'Your secret here'
  # => <input id="secret" name="secret" type="password" value="Your secret here" />

  password_field_tag 'masked', nil, :class => 'masked_input_field'
  # => <input class="masked_input_field" id="masked" name="masked" type="password" />

  password_field_tag 'token', '', :size => 15
  # => <input id="token" name="token" size="15" type="password" value="" />

  password_field_tag 'key', nil, :maxlength => 16
  # => <input id="key" maxlength="16" name="key" type="password" />

  password_field_tag 'confirm_pass', nil, :disabled => true
  # => <input disabled="disabled" id="confirm_pass" name="confirm_pass" type="password" />

  password_field_tag 'pin', '1234', :maxlength => 4, :size => 6, :class => "pin-input"
  # => <input class="pin-input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 222
222:       def password_field_tag(name = "password", value = nil, options = {})
223:         text_field_tag(name, value, options.update("type" => "password"))
224:       end
radio_button_tag(name, value, checked = false, options = {})

Creates a radio button; use groups of radio buttons named the same to allow users to select from a group of options.

Options

  • :disabled - If set to true, the user will not be able to use this input.
  • Any other key creates standard HTML options for the tag.

Examples

  radio_button_tag 'gender', 'male'
  # => <input id="gender_male" name="gender" type="radio" value="male" />

  radio_button_tag 'receive_updates', 'no', true
  # => <input checked="checked" id="receive_updates_no" name="receive_updates" type="radio" value="no" />

  radio_button_tag 'time_slot', "3:00 p.m.", false, :disabled => true
  # => <input disabled="disabled" id="time_slot_300_pm" name="time_slot" type="radio" value="3:00 p.m." />

  radio_button_tag 'color', "green", true, :class => "color_input"
  # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 309
309:       def radio_button_tag(name, value, checked = false, options = {})
310:         pretty_tag_value = value.to_s.gsub(/\s/, "_").gsub(/(?!-)\W/, "").downcase
311:         pretty_name = name.to_s.gsub(/\[/, "_").gsub(/\]/, "")
312:         html_options = { "type" => "radio", "name" => name, "id" => "#{pretty_name}_#{pretty_tag_value}", "value" => value }.update(options.stringify_keys)
313:         html_options["checked"] = "checked" if checked
314:         tag :input, html_options
315:       end
select_tag(name, option_tags = nil, options = {})

Creates a dropdown selection box, or if the :multiple option is set to true, a multiple choice selection box.

Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or associated records. option_tags is a string containing the option tags for the select box.

Options

  • :multiple - If set to true the selection will allow multiple choices.
  • :disabled - If set to true, the user will not be able to use this input.
  • Any other key creates standard HTML attributes for the tag.

Examples

  select_tag "people", "<option>David</option>"
  # => <select id="people" name="people"><option>David</option></select>

  select_tag "count", "<option>1</option><option>2</option><option>3</option><option>4</option>"
  # => <select id="count" name="count"><option>1</option><option>2</option>
  #    <option>3</option><option>4</option></select>

  select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>", :multiple => true
  # => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
  #    <option>Green</option><option>Blue</option></select>

  select_tag "locations", "<option>Home</option><option selected="selected">Work</option><option>Out</option>"
  # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
  #    <option>Out</option></select>

  select_tag "access", "<option>Read</option><option>Write</option>", :multiple => true, :class => 'form_input'
  # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
  #    <option>Write</option></select>

  select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>", :disabled => true
  # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
  #    <option>Paris</option><option>Rome</option></select>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 79
79:       def select_tag(name, option_tags = nil, options = {})
80:         html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
81:         content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
82:       end
submit_tag(value = "Save changes", options = {})

Creates a submit button with the text value as the caption.

Options

  • :confirm => ‘question?‘ - This will add a JavaScript confirm prompt with the question specified. If the user accepts, the form is processed normally, otherwise no action is taken.
  • :disabled - If true, the user will not be able to use this input.
  • :disable_with - Value of this parameter will be used as the value for a disabled version of the submit button when the form is submitted.
  • Any other key creates standard HTML options for the tag.

Examples

  submit_tag
  # => <input name="commit" type="submit" value="Save changes" />

  submit_tag "Edit this article"
  # => <input name="commit" type="submit" value="Edit this article" />

  submit_tag "Save edits", :disabled => true
  # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />

  submit_tag "Complete sale", :disable_with => "Please wait..."
  # => <input name="commit" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();"
  #    type="submit" value="Complete sale" />

  submit_tag nil, :class => "form_submit"
  # => <input class="form_submit" name="commit" type="submit" />

  submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button"
  # => <input class="edit-button" onclick="this.disabled=true;this.value='Editing...';this.form.submit();"
  #    name="commit" type="submit" value="Edit" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 348
348:       def submit_tag(value = "Save changes", options = {})
349:         options.stringify_keys!
350:
351:         if disable_with = options.delete("disable_with")
352:           disable_with = "this.value='#{disable_with}'"
353:           disable_with << ";#{options.delete('onclick')}" if options['onclick']
354:
355:           options["onclick"]  = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
356:           options["onclick"] << "else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }"
357:           options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
358:           options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
359:           options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
360:         end
361:
362:         if confirm = options.delete("confirm")
363:           options["onclick"] ||= 'return true;'
364:           options["onclick"] = "if (!#{confirm_javascript_function(confirm)}) return false; #{options['onclick']}"
365:         end
366:
367:         tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
368:       end
text_area_tag(name, content = nil, options = {})

Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.

Options

  • :size - A string specifying the dimensions (columns by rows) of the textarea (e.g., "25x10").
  • :rows - Specify the number of rows in the textarea
  • :cols - Specify the number of columns in the textarea
  • :disabled - If set to true, the user will not be able to use this input.
  • Any other key creates standard HTML attributes for the tag.

Examples

  text_area_tag 'post'
  # => <textarea id="post" name="post"></textarea>

  text_area_tag 'bio', @user.bio
  # => <textarea id="bio" name="bio">This is my biography.</textarea>

  text_area_tag 'body', nil, :rows => 10, :cols => 25
  # => <textarea cols="25" id="body" name="body" rows="10"></textarea>

  text_area_tag 'body', nil, :size => "25x10"
  # => <textarea name="body" id="body" cols="25" rows="10"></textarea>

  text_area_tag 'description', "Description goes here.", :disabled => true
  # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>

  text_area_tag 'comment', nil, :class => 'comment_input'
  # => <textarea class="comment_input" id="comment" name="comment"></textarea>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 253
253:       def text_area_tag(name, content = nil, options = {})
254:         options.stringify_keys!
255:
256:         if size = options.delete("size")
257:           options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
258:         end
259:
260:         content_tag :textarea, content, { "name" => name, "id" => name }.update(options.stringify_keys)
261:       end
text_field_tag(name, value = nil, options = {})

Creates a standard text field; use these text fields to input smaller chunks of text like a username or a search query.

Options

  • :disabled - If set to true, the user will not be able to use this input.
  • :size - The number of visible characters that will fit in the input.
  • :maxlength - The maximum number of characters that the browser will allow the user to enter.
  • Any other key creates standard HTML attributes for the tag.

Examples

  text_field_tag 'name'
  # => <input id="name" name="name" type="text" />

  text_field_tag 'query', 'Enter your search query here'
  # => <input id="query" name="query" type="text" value="Enter your search query here" />

  text_field_tag 'request', nil, :class => 'special_input'
  # => <input class="special_input" id="request" name="request" type="text" />

  text_field_tag 'address', '', :size => 75
  # => <input id="address" name="address" size="75" type="text" value="" />

  text_field_tag 'zip', nil, :maxlength => 5
  # => <input id="zip" maxlength="5" name="zip" type="text" />

  text_field_tag 'payment_amount', '$0.00', :disabled => true
  # => <input disabled="disabled" id="payment_amount" name="payment_amount" type="text" value="$0.00" />

  text_field_tag 'ip', '0.0.0.0', :maxlength => 15, :size => 20, :class => "ip-input"
  # => <input class="ip-input" id="ip" maxlength="15" name="ip" size="20" type="text" value="0.0.0.0" />

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb, line 114
114:       def text_field_tag(name, value = nil, options = {})
115:         tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
116:       end


Module: ActionView::Helpers::JavaScriptHelper

Module | ActionView::Helpers::JavaScriptHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb

Provides functionality for working with JavaScript in your views.

Ajax, controls and visual effects

  • For information on using Ajax, see ActionView::Helpers::PrototypeHelper.
  • For information on using controls and visual effects, see ActionView::Helpers::ScriptaculousHelper.

Including the JavaScript libraries into your pages

Rails includes the Prototype JavaScript framework and the Scriptaculous JavaScript controls and visual effects library. If you wish to use these libraries and their helpers (ActionView::Helpers::PrototypeHelper and ActionView::Helpers::ScriptaculousHelper), you must do one of the following:

  • Use <%= javascript_include_tag :defaults %> in the HEAD section of your page (recommended): This function will return references to the JavaScript files created by the rails command in your public/javascripts directory. Using it is recommended as the browser can then cache the libraries instead of fetching all the functions anew on every request.
  • Use <%= javascript_include_tag ‘prototype’ %>: As above, but will only include the Prototype core library, which means you are able to use all basic AJAX functionality. For the Scriptaculous-based JavaScript helpers, like visual effects, autocompletion, drag and drop and so on, you should use the method described above.

For documentation on javascript_include_tag see ActionView::Helpers::AssetTagHelper.

Methods

array_or_string_for_javascript button_to_function escape_javascript javascript_tag link_to_function options_for_javascript

Included Modules

PrototypeHelper

Constants

JAVASCRIPT_PATH | = | File.join(File.dirname(__FILE__), 'javascripts')
JS_ESCAPE_MAP | = | { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }

Public Instance methods

button_to_function(name, *args, &block)

Returns a button with the given name text that‘ll trigger a JavaScript function using the onclick handler.

The first argument name is used as the button‘s value or display text.

The next arguments are optional and may include the javascript function definition and a hash of html_options.

The function argument can be omitted in favor of an update_page block, which evaluates to a string when the template is rendered (instead of making an Ajax request first).

The html_options will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"

Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the function parameter to nil

Examples:

  button_to_function "Greeting", "alert('Hello world!')"
  button_to_function "Delete", "if (confirm('Really?')) do_delete()"
  button_to_function "Details" do |page|
    page[:details].visual_effect :toggle_slide
  end
  button_to_function "Details", :class => "details_button" do |page|
    page[:details].visual_effect :toggle_slide
  end

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 122
122:       def button_to_function(name, *args, &block)
123:         html_options = args.extract_options!.symbolize_keys
124:
125:         function = block_given? ? update_page(&block) : args[0] || ''
126:         onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
127:
128:         tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
129:       end
escape_javascript(javascript)

Escape carrier returns and single and double quotes for JavaScript segments.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 141
141:       def escape_javascript(javascript)
142:         if javascript
143:           javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
144:         else
145:           ''
146:         end
147:       end
javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)

Returns a JavaScript tag with the content inside. Example:

  javascript_tag "alert('All is good')"

Returns:

  <script type="text/javascript">
  //<![CDATA[
  alert('All is good')
  //]]>
  </script>

html_options may be a hash of attributes for the <script> tag. Example:

  javascript_tag "alert('All is good')", :defer => 'defer'
  # => <script defer="defer" type="text/javascript">alert('All is good')</script>

Instead of passing the content as an argument, you can also use a block in which case, you pass your html_options as the first parameter.

  <% javascript_tag :defer => 'defer' do -%>
    alert('All is good')
  <% end -%>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 168
168:       def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
169:         content =
170:           if block_given?
171:             html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
172:             capture(&block)
173:           else
174:             content_or_options_with_block
175:           end
176:
177:         tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
178:
179:         if block_called_from_erb?(block)
180:           concat(tag)
181:         else
182:           tag
183:         end
184:       end
link_to_function(name, *args, &block)

Returns a link of the given name that will trigger a JavaScript function using the onclick handler and return false after the fact.

The first argument name is used as the link text.

The next arguments are optional and may include the javascript function definition and a hash of html_options.

The function argument can be omitted in favor of an update_page block, which evaluates to a string when the template is rendered (instead of making an Ajax request first).

The html_options will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"

Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the function parameter to nil

Examples:

  link_to_function "Greeting", "alert('Hello world!')"
    Produces:
      <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>

  link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
    Produces:
      <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
        <img src="/images/delete.png?" alt="Delete"/>
      </a>

  link_to_function("Show me more", nil, :id => "more_link") do |page|
    page[:details].visual_effect  :toggle_blind
    page[:more_link].replace_html "Show me less"
  end
    Produces:
      <a href="#" id="more_link" onclick="try {
        $(&quot;details&quot;).visualEffect(&quot;toggle_blind&quot;);
        $(&quot;more_link&quot;).update(&quot;Show me less&quot;);
      }
      catch (e) {
        alert('RJS error:\n\n' + e.toString());
        alert('$(\&quot;details\&quot;).visualEffect(\&quot;toggle_blind\&quot;);
        \n$(\&quot;more_link\&quot;).update(\&quot;Show me less\&quot;);');
        throw e
      };
      return false;">Show me more</a>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 88
88:       def link_to_function(name, *args, &block)
89:         html_options = args.extract_options!.symbolize_keys
90:
91:         function = block_given? ? update_page(&block) : args[0] || ''
92:         onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
93:         href = html_options[:href] || '#'
94:
95:         content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
96:       end

Protected Instance methods

array_or_string_for_javascript(option)

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 199
199:       def array_or_string_for_javascript(option)
200:         if option.kind_of?(Array)
201:           "['#{option.join('\',\'')}']"
202:         elsif !option.nil?
203:           "'#{option}'"
204:         end
205:       end
options_for_javascript(options)

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb, line 191
191:       def options_for_javascript(options)
192:         if options.empty?
193:           '{}'
194:         else
195:           "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
196:         end
197:       end


Module: ActionView::Helpers::NumberHelper

Module | ActionView::Helpers::NumberHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb

Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, and file size.

Methods

number_to_currency number_to_human_size number_to_percentage number_to_phone number_with_delimiter number_with_precision

Constants

STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze

Public Instance methods

number_to_currency(number, options = {})

Formats a number into a currency string (e.g., $13.65). You can customize the format in the options hash.

Options

  • :precision - Sets the level of precision (defaults to 2).
  • :unit - Sets the denomination of the currency (defaults to "$").
  • :separator - Sets the separator between the units (defaults to ".").
  • :delimiter - Sets the thousands delimiter (defaults to ",").
  • :format - Sets the format of the output string (defaults to "%u%n"). The field types are:
      %u  The currency unit
  %n  The number

Examples

 number_to_currency(1234567890.50)                    # => $1,234,567,890.50
 number_to_currency(1234567890.506)                   # => $1,234,567,890.51
 number_to_currency(1234567890.506, :precision => 3)  # => $1,234,567,890.506

 number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
 # => &pound;1234567890,50
 number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
 # => 1234567890,50 &pound;

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 73
73:       def number_to_currency(number, options = {})
74:         options.symbolize_keys!
75:
76:         defaults  = I18n.translate('number.format''number.format', :locale => options[:locale], :raise => true) rescue {}
77:         currency  = I18n.translate('number.currency.format''number.currency.format', :locale => options[:locale], :raise => true) rescue {}
78:         defaults  = defaults.merge(currency)
79:
80:         precision = options[:precision] || defaults[:precision]
81:         unit      = options[:unit]      || defaults[:unit]
82:         separator = options[:separator] || defaults[:separator]
83:         delimiter = options[:delimiter] || defaults[:delimiter]
84:         format    = options[:format]    || defaults[:format]
85:         separator = '' if precision == 0
86:
87:         begin
88:           format.gsub(/%n/, number_with_precision(number,
89:             :precision => precision,
90:             :delimiter => delimiter,
91:             :separator => separator)
92:           ).gsub(/%u/, unit)
93:         rescue
94:           number
95:         end
96:       end
number_to_human_size(number, *args)

Formats the bytes in size into a more understandable representation (e.g., giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to users. This method returns nil if size cannot be converted into a number. You can customize the format in the options hash.

Options

  • :precision - Sets the level of precision (defaults to 1).
  • :separator - Sets the separator between the units (defaults to ".").
  • :delimiter - Sets the thousands delimiter (defaults to "").

Examples

 number_to_human_size(123)                                          # => 123 Bytes
 number_to_human_size(1234)                                         # => 1.2 KB
 number_to_human_size(12345)                                        # => 12.1 KB
 number_to_human_size(1234567)                                      # => 1.2 MB
 number_to_human_size(1234567890)                                   # => 1.1 GB
 number_to_human_size(1234567890123)                                # => 1.1 TB
 number_to_human_size(1234567, :precision => 2)                     # => 1.18 MB
 number_to_human_size(483989, :precision => 0)                      # => 473 KB
 number_to_human_size(1234567, :precision => 2, :separator => ',')  # => 1,18 MB

You can still use number_to_human_size with the old API that accepts the precision as its optional second parameter:

 number_to_human_size(1234567, 2)    # => 1.18 MB
 number_to_human_size(483989, 0)     # => 473 KB

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 253
253:       def number_to_human_size(number, *args)
254:         return nil if number.nil?
255:
256:         options = args.extract_options!
257:         options.symbolize_keys!
258:
259:         defaults = I18n.translate('number.format''number.format', :locale => options[:locale], :raise => true) rescue {}
260:         human    = I18n.translate('number.human.format''number.human.format', :locale => options[:locale], :raise => true) rescue {}
261:         defaults = defaults.merge(human)
262:
263:         unless args.empty?
264:           ActiveSupport::Deprecation.warn('number_to_human_size takes an option hash ' +
265:             'instead of a separate precision argument.', caller)
266:           precision = args[0] || defaults[:precision]
267:         end
268:
269:         precision ||= (options[:precision] || defaults[:precision])
270:         separator ||= (options[:separator] || defaults[:separator])
271:         delimiter ||= (options[:delimiter] || defaults[:delimiter])
272:
273:         storage_units_format = I18n.translate('number.human.storage_units.format''number.human.storage_units.format', :locale => options[:locale], :raise => true)
274:
275:         if number.to_i < 1024
276:           unit = I18n.translate('number.human.storage_units.units.byte''number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
277:           storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit)
278:         else
279:           max_exp  = STORAGE_UNITS.size - 1
280:           number   = Float(number)
281:           exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
282:           exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
283:           number  /= 1024 ** exponent
284:
285:           unit_key = STORAGE_UNITS[exponent]
286:           unit = I18n.translate("number.human.storage_units.units.#{unit_key}""number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
287:
288:           begin
289:             escaped_separator = Regexp.escape(separator)
290:             formatted_number = number_with_precision(number,
291:               :precision => precision,
292:               :separator => separator,
293:               :delimiter => delimiter
294:             ).sub(/(\d)(#{escaped_separator}[1-9]*)?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
295:             storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
296:           rescue
297:             number
298:           end
299:         end
300:       end
number_to_percentage(number, options = {})

Formats a number as a percentage string (e.g., 65%). You can customize the format in the options hash.

Options

  • :precision - Sets the level of precision (defaults to 3).
  • :separator - Sets the separator between the units (defaults to ".").
  • :delimiter - Sets the thousands delimiter (defaults to "").

Examples

 number_to_percentage(100)                                        # => 100.000%
 number_to_percentage(100, :precision => 0)                       # => 100%
 number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
 number_to_percentage(302.24398923423, :precision => 5)           # => 302.24399%

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 111
111:       def number_to_percentage(number, options = {})
112:         options.symbolize_keys!
113:
114:         defaults   = I18n.translate('number.format''number.format', :locale => options[:locale], :raise => true) rescue {}
115:         percentage = I18n.translate('number.percentage.format''number.percentage.format', :locale => options[:locale], :raise => true) rescue {}
116:         defaults  = defaults.merge(percentage)
117:
118:         precision = options[:precision] || defaults[:precision]
119:         separator = options[:separator] || defaults[:separator]
120:         delimiter = options[:delimiter] || defaults[:delimiter]
121:
122:         begin
123:           number_with_precision(number,
124:             :precision => precision,
125:             :separator => separator,
126:             :delimiter => delimiter) + "%"
127:         rescue
128:           number
129:         end
130:       end
number_to_phone(number, options = {})

Formats a number into a US phone number (e.g., (555) 123-9876). You can customize the format in the options hash.

Options

  • :area_code - Adds parentheses around the area code.
  • :delimiter - Specifies the delimiter to use (defaults to "-").
  • :extension - Specifies an extension to add to the end of the generated number.
  • :country_code - Sets the country code for the phone number.

Examples

 number_to_phone(5551234)                                           # => 555-1234
 number_to_phone(1235551234)                                        # => 123-555-1234
 number_to_phone(1235551234, :area_code => true)                    # => (123) 555-1234
 number_to_phone(1235551234, :delimiter => " ")                     # => 123 555 1234
 number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
 number_to_phone(1235551234, :country_code => 1)                    # => +1-123-555-1234

 number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
 => +1.123.555.1234 x 1343

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 27
27:       def number_to_phone(number, options = {})
28:         number       = number.to_s.strip unless number.nil?
29:         options      = options.symbolize_keys
30:         area_code    = options[:area_code] || nil
31:         delimiter    = options[:delimiter] || "-"
32:         extension    = options[:extension].to_s.strip || nil
33:         country_code = options[:country_code] || nil
34:
35:         begin
36:           str = ""
37:           str << "+#{country_code}#{delimiter}" unless country_code.blank?
38:           str << if area_code
39:             number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3")
40:           else
41:             number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
42:             number.starts_with?('-') ? number.slice!(1..-1) : number
43:           end
44:           str << " x #{extension}" unless extension.blank?
45:           str
46:         rescue
47:           number
48:         end
49:       end
number_with_delimiter(number, *args)

Formats a number with grouped thousands using delimiter (e.g., 12,324). You can customize the format in the options hash.

Options

  • :delimiter - Sets the thousands delimiter (defaults to ",").
  • :separator - Sets the separator between the units (defaults to ".").

Examples

 number_with_delimiter(12345678)                        # => 12,345,678
 number_with_delimiter(12345678.05)                     # => 12,345,678.05
 number_with_delimiter(12345678, :delimiter => ".")     # => 12.345.678
 number_with_delimiter(12345678, :seperator => ",")     # => 12,345,678
 number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
 # => 98 765 432,98

You can still use number_with_delimiter with the old API that accepts the delimiter as its optional second and the separator as its optional third parameter:

 number_with_delimiter(12345678, " ")                     # => 12 345.678
 number_with_delimiter(12345678.05, ".", ",")             # => 12.345.678,05

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 152
152:       def number_with_delimiter(number, *args)
153:         options = args.extract_options!
154:         options.symbolize_keys!
155:
156:         defaults = I18n.translate('number.format''number.format', :locale => options[:locale], :raise => true) rescue {}
157:
158:         unless args.empty?
159:           ActiveSupport::Deprecation.warn('number_with_delimiter takes an option hash ' +
160:             'instead of separate delimiter and precision arguments.', caller)
161:           delimiter = args[0] || defaults[:delimiter]
162:           separator = args[1] || defaults[:separator]
163:         end
164:
165:         delimiter ||= (options[:delimiter] || defaults[:delimiter])
166:         separator ||= (options[:separator] || defaults[:separator])
167:
168:         begin
169:           parts = number.to_s.split('.')
170:           parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
171:           parts.join(separator)
172:         rescue
173:           number
174:         end
175:       end
number_with_precision(number, *args)

Formats a number with the specified level of :precision (e.g., 112.32 has a precision of 2). You can customize the format in the options hash.

Options

  • :precision - Sets the level of precision (defaults to 3).
  • :separator - Sets the separator between the units (defaults to ".").
  • :delimiter - Sets the thousands delimiter (defaults to "").

Examples

 number_with_precision(111.2345)                    # => 111.235
 number_with_precision(111.2345, :precision => 2)   # => 111.23
 number_with_precision(13, :precision => 5)         # => 13.00000
 number_with_precision(389.32314, :precision => 0)  # => 389
 number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
 # => 1.111,23

You can still use number_with_precision with the old API that accepts the precision as its optional second parameter:

  number_with_precision(number_with_precision(111.2345, 2)   # => 111.23

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb, line 196
196:       def number_with_precision(number, *args)
197:         options = args.extract_options!
198:         options.symbolize_keys!
199:
200:         defaults           = I18n.translate('number.format''number.format', :locale => options[:locale], :raise => true) rescue {}
201:         precision_defaults = I18n.translate('number.precision.format''number.precision.format', :locale => options[:locale],
202:                                                                         :raise => true) rescue {}
203:         defaults           = defaults.merge(precision_defaults)
204:
205:         unless args.empty?
206:           ActiveSupport::Deprecation.warn('number_with_precision takes an option hash ' +
207:             'instead of a separate precision argument.', caller)
208:           precision = args[0] || defaults[:precision]
209:         end
210:
211:         precision ||= (options[:precision] || defaults[:precision])
212:         separator ||= (options[:separator] || defaults[:separator])
213:         delimiter ||= (options[:delimiter] || defaults[:delimiter])
214:
215:         begin
216:           rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision
217:           number_with_delimiter("%01.#{precision}f" % rounded_number,
218:             :separator => separator,
219:             :delimiter => delimiter)
220:         rescue
221:           number
222:         end
223:       end


Module: ActionView::Helpers::PrototypeHelper

Module | ActionView::Helpers::PrototypeHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb

Prototype is a JavaScript library that provides DOM manipulation, Ajax functionality, and more traditional object-oriented facilities for JavaScript. This module provides a set of helpers to make it more convenient to call functions from Prototype using Rails, including functionality to call remote Rails methods (that is, making a background request to a Rails action) using Ajax. This means that you can call actions in your controllers without reloading the page, but still update certain parts of it using injections into the DOM. A common use case is having a form that adds a new element to a list without reloading the page or updating a shopping cart total when a new item is added.

Usage

To be able to use these helpers, you must first include the Prototype JavaScript framework in your pages.

 javascript_include_tag 'prototype'

(See the documentation for ActionView::Helpers::JavaScriptHelper for more information on including this and other JavaScript files in your Rails templates.)

Now you‘re ready to call a remote action either through a link…

 link_to_remote "Add to cart",
   :url => { :action => "add", :id => product.id },
   :update => { :success => "cart", :failure => "error" }

…through a form…

 <% form_remote_tag :url => '/shipping' do -%>
   <div><%= submit_tag 'Recalculate Shipping' %></div>
 <% end -%>

…periodically…

 periodically_call_remote(:url => 'update', :frequency => '5', :update => 'ticker')

…or through an observer (i.e., a form or field that is observed and calls a remote action when changed).

 <%= observe_field(:searchbox,
      :url => { :action => :live_search }),
      :frequency => 0.5,
      :update => :hits,
      :with => 'query'
      %>

As you can see, there are numerous ways to use Prototype‘s Ajax functions (and actually more than are listed here); check out the documentation for each method to find out more about its usage and options.

Common Options

See link_to_remote for documentation of options common to all Ajax helpers; any of the options specified by link_to_remote can be used by the other helpers.

Designing your Rails actions for Ajax

When building your action handlers (that is, the Rails actions that receive your background requests), it‘s important to remember a few things. First, whatever your action would normally return to the browser, it will return to the Ajax call. As such, you typically don‘t want to render with a layout. This call will cause the layout to be transmitted back to your page, and, if you have a full HTML/CSS, will likely mess a lot of things up. You can turn the layout off on particular actions by doing the following:

 class SiteController < ActionController::Base
   layout "standard", :except => [:ajax_method, :more_ajax, :another_ajax]
 end

Optionally, you could do this in the method you wish to lack a layout:

 render :layout => false

You can tell the type of request from within your action using the request.xhr? (XmlHttpRequest, the method that Ajax uses to make background requests) method.

 def name
   # Is this an XmlHttpRequest request?
   if (request.xhr?)
     render :text => @name.to_s
   else
     # No?  Then render an action.
     render :action => 'view_attribute', :attr => @name
   end
 end

The else clause can be left off and the current action will render with full layout and template. An extension to this solution was posted to Ryan Heneise‘s blog at ArtOfMission.

 layout proc{ |c| c.request.xhr? ? false : "application" }

Dropping this in your ApplicationController turns the layout off for every request that is an "xhr" request.

If you are just returning a little data or don‘t want to build a template for your output, you may opt to simply render text output, like this:

 render :text => 'Return this from my method!'

Since whatever the method returns is injected into the DOM, this will simply inject some text (or HTML, if you tell it to). This is usually how small updates, such updating a cart total or a file count, are handled.

Updating multiple elements

See JavaScriptGenerator for information on updating multiple elements on the page in an Ajax response.

Methods

build_callbacks build_observer button_to_remote evaluate_remote_response form_remote_for form_remote_tag link_to_remote method_option_to_s observe_field observe_form options_for_ajax periodically_call_remote remote_form_for remote_function submit_to_remote update_page update_page_tag

Constants

CALLBACKS | = | Set.new([ :create, :uninitialized, :loading, :loaded, :interactive, :complete, :failure, :success ] + (100..599).to_a)
AJAX_OPTIONS | = | Set.new([ :before, :after, :condition, :url, :asynchronous, :method, :insertion, :position, :form, :with, :update, :script, :type ]).merge(CALLBACKS)

Public Instance methods

button_to_remote(name, options = {}, html_options = {})

Creates a button with an onclick event which calls a remote action via XMLHttpRequest The options for specifying the target with :url and defining callbacks is the same as link_to_remote.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 263
263:       def button_to_remote(name, options = {}, html_options = {})
264:         button_to_function(name, remote_function(options), html_options)
265:       end
evaluate_remote_response()

Returns ‘eval(request.responseText)’ which is the JavaScript function that form_remote_tag can call in :complete to evaluate a multiple update return document using update_element_function calls.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 433
433:       def evaluate_remote_response
434:         "eval(request.responseText)"
435:       end
form_remote_for(record_or_name_or_array, *args, &proc)

Alias for remote_form_for

form_remote_tag(options = {}, &block)

Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement. Even though it‘s using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side (all elements available in params). The options for specifying the target with :url and defining callbacks is the same as link_to_remote.

A "fall-through" target for browsers that doesn‘t do JavaScript can be specified with the :action/:method options on :html.

Example:

  # Generates:
  #      <form action="/some/place" method="post" onsubmit="new Ajax.Request('',
  #      {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
  form_remote_tag :html => { :action =>
    url_for(:controller => "some", :action => "place") }

The Hash passed to the :html key is equivalent to the options (2nd) argument in the FormTagHelper.form_tag method.

By default the fall-through action is the same as the one specified in the :url (and the default method is :post).

form_remote_tag also takes a block, like form_tag:

  # Generates:
  #     <form action="/" method="post" onsubmit="new Ajax.Request('/',
  #     {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)});
  #     return false;"> <div><input name="commit" type="submit" value="Save" /></div>
  #     </form>
  <% form_remote_tag :url => '/posts' do -%>
    <div><%= submit_tag 'Save' %></div>
  <% end -%>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 331
331:       def form_remote_tag(options = {}, &block)
332:         options[:form] = true
333:
334:         options[:html] ||= {}
335:         options[:html][:onsubmit] =
336:           (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") +
337:           "#{remote_function(options)}; return false;"
338:
339:         form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], &block)
340:       end
link_to_remote(name, options = {}, html_options = nil)

Returns a link to a remote action defined by options[:url] (using the url_for format) that‘s called in the background using XMLHttpRequest. The result of that request can then be inserted into a DOM object whose id can be specified with options[:update]. Usually, the result would be a partial prepared by the controller with render :partial.

Examples:

  # Generates: <a href="#" onclick="new Ajax.Updater('posts', '/blog/destroy/3', {asynchronous:true, evalScripts:true});
  #            return false;">Delete this post</a>
  link_to_remote "Delete this post", :update => "posts",
    :url => { :action => "destroy", :id => post.id }

  # Generates: <a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true});
  #            return false;"><img alt="Refresh" src="/images/refresh.png?" /></a>
  link_to_remote(image_tag("refresh"), :update => "emails",
    :url => { :action => "list_emails" })

You can override the generated HTML options by specifying a hash in options[:html].

  link_to_remote "Delete this post", :update => "posts",
    :url  => post_url(@post), :method => :delete,
    :html => { :class  => "destructive" }

You can also specify a hash for options[:update] to allow for easy redirection of output to an other DOM element if a server-side error occurs:

Example:

  # Generates: <a href="#" onclick="new Ajax.Updater({success:'posts',failure:'error'}, '/blog/destroy/5',
  #            {asynchronous:true, evalScripts:true}); return false;">Delete this post</a>
  link_to_remote "Delete this post",
    :url => { :action => "destroy", :id => post.id },
    :update => { :success => "posts", :failure => "error" }

Optionally, you can use the options[:position] parameter to influence how the target DOM element is updated. It must be one of :before, :top, :bottom, or :after.

The method used is by default POST. You can also specify GET or you can simulate PUT or DELETE over POST. All specified with options[:method]

Example:

  # Generates: <a href="#" onclick="new Ajax.Request('/person/4', {asynchronous:true, evalScripts:true, method:'delete'});
  #            return false;">Destroy</a>
  link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete

By default, these remote requests are processed asynchronous during which various JavaScript callbacks can be triggered (for progress indicators and the likes). All callbacks get access to the request object, which holds the underlying XMLHttpRequest.

To access the server response, use request.responseText, to find out the HTTP status, use request.status.

Example:

  # Generates: <a href="#" onclick="new Ajax.Request('/words/undo?n=33', {asynchronous:true, evalScripts:true,
  #            onComplete:function(request){undoRequestCompleted(request)}}); return false;">hello</a>
  word = 'hello'
  link_to_remote word,
    :url => { :action => "undo", :n => word_counter },
    :complete => "undoRequestCompleted(request)"

The callbacks that may be specified are (in order):

:loading: | Called when the remote document is being loaded with data by the browser.
:loaded: | Called when the browser has finished loading the remote document.
:interactive: | Called when the user can interact with the remote document, even though it has not finished loading.
:success: | Called when the XMLHttpRequest is completed, and the HTTP status code is in the 2XX range.
:failure: | Called when the XMLHttpRequest is completed, and the HTTP status code is not in the 2XX range.
:complete: | Called when the XMLHttpRequest is complete (fires after success/failure if they are present).

You can further refine :success and :failure by adding additional callbacks for specific status codes.

Example:

  # Generates: <a href="#" onclick="new Ajax.Request('/testing/action', {asynchronous:true, evalScripts:true,
  #            on404:function(request){alert('Not found...? Wrong URL...?')},
  #            onFailure:function(request){alert('HTTP Error ' + request.status + '!')}}); return false;">hello</a>
  link_to_remote word,
    :url => { :action => "action" },
    404 => "alert('Not found...? Wrong URL...?')",
    :failure => "alert('HTTP Error ' + request.status + '!')"

A status code callback overrides the success/failure handlers if present.

If you for some reason or another need synchronous processing (that‘ll block the browser while the request is happening), you can specify options[:type] = :synchronous.

You can customize further browser side call logic by passing in JavaScript code snippets via some optional parameters. In their order of use these are:

:confirm: Adds confirmation dialog.
:condition: Perform remote request conditionally by this expression. Use this to describe browser-side conditions when request should not be initiated.
:before: Called before request is initiated.
:after: Called immediately after request was initiated and before :loading.
:submit: Specifies the DOM element ID that‘s used as the parent of the form elements. By default this is the current form, but it could just as well be the ID of a table row or any other DOM element.
:with: A JavaScript expression specifying the parameters for the XMLHttpRequest. Any expressions should return a valid URL query string.

Example:

  :with => "'name=' + $('name').value"

You can generate a link that uses AJAX in the general case, while degrading gracefully to plain link behavior in the absence of JavaScript by setting html_options[:href] to an alternate URL. Note the extra curly braces around the options hash separate it as the second parameter from html_options, the third.

Example:

  link_to_remote "Delete this post",
    { :update => "posts", :url => { :action => "destroy", :id => post.id } },
    :href => url_for(:action => "destroy", :id => post.id)

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 255
255:       def link_to_remote(name, options = {}, html_options = nil)
256:         link_to_function(name, remote_function(options), html_options || options.delete(:html))
257:       end
observe_field(field_id, options = {})

Observes the field with the DOM ID specified by field_id and calls a callback when its contents have changed. The default callback is an Ajax call. By default the value of the observed field is sent as a parameter with the Ajax call.

Example:

 # Generates: new Form.Element.Observer('suggest', 0.25, function(element, value) {new Ajax.Updater('suggest',
 #         '/testing/find_suggestion', {asynchronous:true, evalScripts:true, parameters:'q=' + value})})
 <%= observe_field :suggest, :url => { :action => :find_suggestion },
      :frequency => 0.25,
      :update => :suggest,
      :with => 'q'
      %>

Required options are either of:

:url: url_for-style options for the action to call when the field has changed.
:function: Instead of making a remote call to a URL, you can specify javascript code to be called instead. Note that the value of this option is used as the body of the javascript function, a function definition with parameters named element and value will be generated for you for example:
  observe_field("glass", :frequency => 1, :function => "alert('Element changed')")

will generate:

  new Form.Element.Observer('glass', 1, function(element, value) {alert('Element changed')})

The element parameter is the DOM element being observed, and the value is its value at the time the observer is triggered.

Additional options are:

:frequency: The frequency (in seconds) at which changes to this field will be detected. Not setting this option at all or to a value equal to or less than zero will use event based observation instead of time based observation.
:update: Specifies the DOM ID of the element whose innerHTML should be updated with the XMLHttpRequest response text.
:with: A JavaScript expression specifying the parameters for the XMLHttpRequest. The default is to send the key and value of the observed field. Any custom expressions should return a valid URL query string. The value of the field is stored in the JavaScript variable value.

Examples

  :with => "'my_custom_key=' + value"
  :with => "'person[name]=' + prompt('New name')"
  :with => "Form.Element.serialize('other-field')"

Finally

  :with => 'name'

is shorthand for

  :with => "'name=' + value"

This essentially just changes the key of the parameter.

Additionally, you may specify any of the options documented in the Common options section at the top of this document.

Example:

  # Sends params: {:title => 'Title of the book'} when the book_title input
  # field is changed.
  observe_field 'book_title',
    :url => 'http://example.com/books/edit/1',
    :with => 'title'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 547
547:       def observe_field(field_id, options = {})
548:         if options[:frequency] && options[:frequency] > 0
549:           build_observer('Form.Element.Observer', field_id, options)
550:         else
551:           build_observer('Form.Element.EventObserver', field_id, options)
552:         end
553:       end
observe_form(form_id, options = {})

Observes the form with the DOM ID specified by form_id and calls a callback when its contents have changed. The default callback is an Ajax call. By default all fields of the observed field are sent as parameters with the Ajax call.

The options for observe_form are the same as the options for observe_field. The JavaScript variable value available to the :with option is set to the serialized form by default.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 563
563:       def observe_form(form_id, options = {})
564:         if options[:frequency]
565:           build_observer('Form.Observer', form_id, options)
566:         else
567:           build_observer('Form.EventObserver', form_id, options)
568:         end
569:       end
periodically_call_remote(options = {})

Periodically calls the specified url (options[:url]) every options[:frequency] seconds (default is 10). Usually used to update a specified div (options[:update]) with the results of the remote call. The options for specifying the target with :url and defining callbacks is the same as link_to_remote. Examples:

 # Call get_averages and put its results in 'avg' every 10 seconds
 # Generates:
 #      new PeriodicalExecuter(function() {new Ajax.Updater('avg', '/grades/get_averages',
 #      {asynchronous:true, evalScripts:true})}, 10)
 periodically_call_remote(:url => { :action => 'get_averages' }, :update => 'avg')

 # Call invoice every 10 seconds with the id of the customer
 # If it succeeds, update the invoice DIV; if it fails, update the error DIV
 # Generates:
 #      new PeriodicalExecuter(function() {new Ajax.Updater({success:'invoice',failure:'error'},
 #      '/testing/invoice/16', {asynchronous:true, evalScripts:true})}, 10)
 periodically_call_remote(:url => { :action => 'invoice', :id => customer.id },
    :update => { :success => "invoice", :failure => "error" }

 # Call update every 20 seconds and update the new_block DIV
 # Generates:
 # new PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
 periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 292
292:       def periodically_call_remote(options = {})
293:          frequency = options[:frequency] || 10 # every ten seconds by default
294:          code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
295:          javascript_tag(code)
296:       end
remote_form_for(record_or_name_or_array, *args, &proc)

Creates a form that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement and a scope around a specific resource that is used as a base for questioning about values for the fields.

Resource

Example:

  <% remote_form_for(@post) do |f| %>
    ...
  <% end %>

This will expand to be the same as:

  <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
    ...
  <% end %>

Nested Resource

Example:

  <% remote_form_for([@post, @comment]) do |f| %>
    ...
  <% end %>

This will expand to be the same as:

  <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %>
    ...
  <% end %>

If you don‘t need to attach a form to a resource, then check out form_remote_tag.

See FormHelper#form_for for additional semantics.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 376
376:       def remote_form_for(record_or_name_or_array, *args, &proc)
377:         options = args.extract_options!
378:
379:         case record_or_name_or_array
380:         when String, Symbol
381:           object_name = record_or_name_or_array
382:         when Array
383:           object = record_or_name_or_array.last
384:           object_name = ActionController::RecordIdentifier.singular_class_name(object)
385:           apply_form_for_options!(record_or_name_or_array, options)
386:           args.unshift object
387:         else
388:           object      = record_or_name_or_array
389:           object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array)
390:           apply_form_for_options!(object, options)
391:           args.unshift object
392:         end
393:
394:         concat(form_remote_tag(options))
395:         fields_for(object_name, *(args << options), &proc)
396:         concat('</form>')
397:       end
remote_function(options)

Returns the JavaScript needed for a remote function. Takes the same arguments as link_to_remote.

Example:

  # Generates: <select id="options" onchange="new Ajax.Updater('options',
  # '/testing/update_options', {asynchronous:true, evalScripts:true})">
  <select id="options" onchange="<%= remote_function(:update => "options",
      :url => { :action => :update_options }) %>">
    <option value="0">Hello</option>
    <option value="1">World</option>
  </select>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 448
448:       def remote_function(options)
449:         javascript_options = options_for_ajax(options)
450:
451:         update = ''
452:         if options[:update] && options[:update].is_a?(Hash)
453:           update  = []
454:           update << "success:'#{options[:update][:success]}'" if options[:update][:success]
455:           update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure]
456:           update  = '{' + update.join(',') + '}'
457:         elsif options[:update]
458:           update << "'#{options[:update]}'"
459:         end
460:
461:         function = update.empty? ?
462:           "new Ajax.Request(" :
463:           "new Ajax.Updater(#{update}, "
464:
465:         url_options = options[:url]
466:         url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
467:         function << "'#{escape_javascript(url_for(url_options))}'"
468:         function << ", #{javascript_options})"
469:
470:         function = "#{options[:before]}; #{function}" if options[:before]
471:         function = "#{function}; #{options[:after]}"  if options[:after]
472:         function = "if (#{options[:condition]}) { #{function}; }" if options[:condition]
473:         function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm]
474:
475:         return function
476:       end
submit_to_remote(name, value, options = {})

Returns a button input tag with the element name of name and a value (i.e., display text) of value that will submit form using XMLHttpRequest in the background instead of a regular POST request that reloads the page.

 # Create a button that submits to the create action
 #
 # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
 #     {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
 #     return false;" type="button" value="Create" />
 <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>

 # Submit to the remote action update and update the DIV succeed or fail based
 # on the success or failure of the request
 #
 # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
 #      '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
 #      return false;" type="button" value="Update" />
 <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
    :update => { :success => "succeed", :failure => "fail" }

options argument is the same as in form_remote_tag.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 421
421:       def submit_to_remote(name, value, options = {})
422:         options[:with] ||= 'Form.serialize(this.form)'
423:
424:         html_options = options.delete(:html) || {}
425:         html_options[:name] = name
426:
427:         button_to_remote(value, options, html_options)
428:       end
update_page(&block)

Yields a JavaScriptGenerator and returns the generated JavaScript code. Use this to update multiple elements on a page in an Ajax response. See JavaScriptGenerator for more information.

Example:

  update_page do |page|
    page.hide 'spinner'
  end

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1028
1028:       def update_page(&block)
1029:         JavaScriptGenerator.new(@template, &block).to_s
1030:       end
update_page_tag(html_options = {}, &block)

Works like update_page but wraps the generated JavaScript in a <script> tag. Use this to include generated JavaScript in an ERb template. See JavaScriptGenerator for more information.

html_options may be a hash of <script> attributes to be passed to ActionView::Helpers::JavaScriptHelper#javascript_tag.

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1038
1038:       def update_page_tag(html_options = {}, &block)
1039:         javascript_tag update_page(&block), html_options
1040:       end

Protected Instance methods

build_callbacks(options)

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1091
1091:       def build_callbacks(options)
1092:         callbacks = {}
1093:         options.each do |callback, code|
1094:           if CALLBACKS.include?(callback)
1095:             name = 'on' + callback.to_s.capitalize
1096:             callbacks[name] = "function(request){#{code}}"
1097:           end
1098:         end
1099:         callbacks
1100:       end
build_observer(klass, name, options = {})

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1075
1075:       def build_observer(klass, name, options = {})
1076:         if options[:with] && (options[:with] !~ /[\{=(.]/)
1077:           options[:with] = "'#{options[:with]}=' + encodeURIComponent(value)"
1078:         else
1079:           options[:with] ||= 'value' unless options[:function]
1080:         end
1081:
1082:         callback = options[:function] || remote_function(options)
1083:         javascript  = "new #{klass}('#{name}', "
1084:         javascript << "#{options[:frequency]}, " if options[:frequency]
1085:         javascript << "function(element, value) {"
1086:         javascript << "#{callback}}"
1087:         javascript << ")"
1088:         javascript_tag(javascript)
1089:       end
method_option_to_s(method)

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1071
1071:       def method_option_to_s(method)
1072:         (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'"
1073:       end
options_for_ajax(options)

[Source]

      # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 1043
1043:       def options_for_ajax(options)
1044:         js_options = build_callbacks(options)
1045:
1046:         js_options['asynchronous'] = options[:type] != :synchronous
1047:         js_options['method']       = method_option_to_s(options[:method]) if options[:method]
1048:         js_options['insertion']    = "'#{options[:position].to_s.downcase}'" if options[:position]
1049:         js_options['evalScripts']  = options[:script].nil? || options[:script]
1050:
1051:         if options[:form]
1052:           js_options['parameters'] = 'Form.serialize(this)'
1053:         elsif options[:submit]
1054:           js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
1055:         elsif options[:with]
1056:           js_options['parameters'] = options[:with]
1057:         end
1058:
1059:         if protect_against_forgery? && !options[:form]
1060:           if js_options['parameters']
1061:             js_options['parameters'] << " + '&"
1062:           else
1063:             js_options['parameters'] = "'"
1064:           end
1065:           js_options['parameters'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
1066:         end
1067:
1068:         options_for_javascript(js_options)
1069:       end


Module: ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods

Module | ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods
In: | vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb

JavaScriptGenerator generates blocks of JavaScript code that allow you to change the content and presentation of multiple DOM elements. Use this in your Ajax response bodies, either in a <script> tag or as plain JavaScript sent with a Content-type of "text/javascript".

Create new instances with PrototypeHelper#update_page or with ActionController::Base#render, then call insert_html, replace_html, remove, show, hide, visual_effect, or any other of the built-in methods on the yielded generator in any order you like to modify the content and appearance of the current page.

Example:

  # Generates:
  #     new Element.insert("list", { bottom: "<li>Some item</li>" });
  #     new Effect.Highlight("list");
  #     ["status-indicator", "cancel-link"].each(Element.hide);
  update_page do |page|
    page.insert_html :bottom, 'list', "<li>#{@item.name}</li>"
    page.visual_effect :highlight, 'list'
    page.hide 'status-indicator', 'cancel-link'
  end

Helper methods can be used in conjunction with JavaScriptGenerator. When a helper method is called inside an update block on the page object, that method will also have access to a page object.

Example:

  module ApplicationHelper
    def update_time
      page.replace_html 'time', Time.now.to_s(:db)
      page.visual_effect :highlight, 'time'
    end
  end

  # Controller action
  def poll
    render(:update) { |page| page.update_time }
  end

Calls to JavaScriptGenerator not matching a helper method below generate a proxy to the JavaScript Class named by the method called.

Examples:

  # Generates:
  #     Foo.init();
  update_page do |page|
    page.foo.init
  end

  # Generates:
  #     Event.observe('one', 'click', function () {
  #       $('two').show();
  #     });
  update_page do |page|
    page.event.observe('one', 'click') do |p|
     p[:two].show
    end
  end

You can also use PrototypeHelper#update_page_tag instead of PrototypeHelper#update_page to wrap the generated JavaScript in a <script> tag.

Methods

<< [] alert assign call delay draggable drop_receiving hide insert_html literal redirect_to reload remove replace replace_html select show sortable toggle visual_effect

Public Instance methods

<<(javascript)

Writes raw JavaScript to the page.

Example:

 page << "alert('JavaScript with Prototype.');"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 926
926:           def <<(javascript)
927:             @lines << javascript
928:           end
[](id)

Returns a element reference by finding it through id in the DOM. This element can then be used for further method calls. Examples:

  page['blank_slate']                  # => $('blank_slate');
  page['blank_slate'].show             # => $('blank_slate').show();
  page['blank_slate'].show('first').up # => $('blank_slate').show('first').up();

You can also pass in a record, which will use ActionController::RecordIdentifier.dom_id to lookup the correct id:

  page[@post]     # => $('post_45')
  page[Post.new]  # => $('new_post')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 677
677:           def [](id)
678:             case id
679:               when String, Symbol, NilClass
680:                 JavaScriptElementProxy.new(self, id)
681:               else
682:                 JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
683:             end
684:           end
alert(message)

Displays an alert dialog with the given message.

Example:

  # Generates: alert('This message is from Rails!')
  page.alert('This message is from Rails!')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 849
849:           def alert(message)
850:             call 'alert', message
851:           end
assign(variable, value)

Assigns the JavaScript variable the given value.

Examples:

 # Generates: my_string = "This is mine!";
 page.assign 'my_string', 'This is mine!'

 # Generates: record_count = 33;
 page.assign 'record_count', 33

 # Generates: tabulated_total = 47
 page.assign 'tabulated_total', @total_from_cart

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 917
917:           def assign(variable, value)
918:             record "#{variable} = #{javascript_object_for(value)}"
919:           end
call(function, *arguments, &block)

Calls the JavaScript function, optionally with the given arguments.

If a block is given, the block will be passed to a new JavaScriptGenerator; the resulting JavaScript code will then be wrapped inside function() { … } and passed as the called function‘s final argument.

Examples:

  # Generates: Element.replace(my_element, "My content to replace with.")
  page.call 'Element.replace', 'my_element', "My content to replace with."

  # Generates: alert('My message!')
  page.call 'alert', 'My message!'

  # Generates:
  #     my_method(function() {
  #       $("one").show();
  #       $("two").hide();
  #    });
  page.call(:my_method) do |p|
     p[:one].show
     p[:two].hide
  end

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 900
900:           def call(function, *arguments, &block)
901:             record "#{function}(#{arguments_for_call(arguments, block)})"
902:           end
delay(seconds = 1) {|| ...}

Executes the content of the block after a delay of seconds. Example:

  # Generates:
  #     setTimeout(function() {
  #     ;
  #     new Effect.Fade("notice",{});
  #     }, 20000);
  page.delay(20) do
    page.visual_effect :fade, 'notice'
  end

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 940
940:           def delay(seconds = 1)
941:             record "setTimeout(function() {\n\n"
942:             yield
943:             record "}, #{(seconds * 1000).to_i})"
944:           end
draggable(id, options = {})

Creates a script.aculo.us draggable element. See ActionView::Helpers::ScriptaculousHelper for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 962
962:           def draggable(id, options = {})
963:             record @context.send(:draggable_element_js, id, options)
964:           end
drop_receiving(id, options = {})

Creates a script.aculo.us drop receiving element. See ActionView::Helpers::ScriptaculousHelper for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 968
968:           def drop_receiving(id, options = {})
969:             record @context.send(:drop_receiving_element_js, id, options)
970:           end
hide(*ids)

Hides the visible DOM elements with the given ids.

Example:

 # Hide a few people
 # Generates: ["person_29", "person_9", "person_0"].each(Element.hide);
 page.hide 'person_29', 'person_9', 'person_0'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 827
827:           def hide(*ids)
828:             loop_on_multiple_args 'Element.hide', ids
829:           end
insert_html(position, id, *options_for_render)

Inserts HTML at the specified position relative to the DOM element identified by the given id.

position may be one of:

:top: | HTML is inserted inside the element, before the element‘s existing content.
:bottom: | HTML is inserted inside the element, after the element‘s existing content.
:before: | HTML is inserted immediately preceding the element.
:after: | HTML is inserted immediately following the element.

options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

  # Insert the rendered 'navigation' partial just before the DOM
  # element with ID 'content'.
  # Generates: Element.insert("content", { before: "-- Contents of 'navigation' partial --" });
  page.insert_html :before, 'content', :partial => 'navigation'

  # Add a list item to the bottom of the <ul> with ID 'list'.
  # Generates: Element.insert("list", { bottom: "<li>Last item</li>" });
  page.insert_html :bottom, 'list', '<li>Last item</li>'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 742
742:           def insert_html(position, id, *options_for_render)
743:             content = javascript_object_for(render(*options_for_render))
744:             record "Element.insert(\"#{id}\", { #{position.to_s.downcase}: #{content} });"
745:           end
literal(code)

Returns an object whose to_json evaluates to code. Use this to pass a literal JavaScript expression as an argument to another JavaScriptGenerator method.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 688
688:           def literal(code)
689:             ActiveSupport::JSON::Variable.new(code.to_s)
690:           end
redirect_to(location)

Redirects the browser to the given location using JavaScript, in the same form as url_for.

Examples:

 # Generates: window.location.href = "/mycontroller";
 page.redirect_to(:action => 'index')

 # Generates: window.location.href = "/account/signup";
 page.redirect_to(:controller => 'account', :action => 'signup')

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 862
862:           def redirect_to(location)
863:             url = location.is_a?(String) ? location : @context.url_for(location)
864:             record "window.location.href = #{url.inspect}"
865:           end
reload()

Reloads the browser‘s current location using JavaScript

Examples:

 # Generates: window.location.reload();
 page.reload

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 873
873:           def reload
874:             record 'window.location.reload()'
875:           end
remove(*ids)

Removes the DOM elements with the given ids from the page.

Example:

 # Remove a few people
 # Generates: ["person_23", "person_9", "person_2"].each(Element.remove);
 page.remove 'person_23', 'person_9', 'person_2'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 803
803:           def remove(*ids)
804:             loop_on_multiple_args 'Element.remove', ids
805:           end
replace(id, *options_for_render)

Replaces the "outer HTML" (i.e., the entire element, not just its contents) of the DOM element with the given id.

options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

  # Replace the DOM element having ID 'person-45' with the
  # 'person' partial for the appropriate object.
  page.replace 'person-45', :partial => 'person', :object => @person

This allows the same partial that is used for the insert_html to be also used for the input to replace without resorting to the use of wrapper elements.

Examples:

  <div id="people">
    <%= render :partial => 'person', :collection => @people %>
  </div>

  # Insert a new person
  #
  # Generates: new Insertion.Bottom({object: "Matz", partial: "person"}, "");
  page.insert_html :bottom, :partial => 'person', :object => @person

  # Replace an existing person

  # Generates: Element.replace("person_45", "-- Contents of partial --");
  page.replace 'person_45', :partial => 'person', :object => @person

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 791
791:           def replace(id, *options_for_render)
792:             call 'Element.replace', id, render(*options_for_render)
793:           end
replace_html(id, *options_for_render)

Replaces the inner HTML of the DOM element with the given id.

options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

  # Replace the HTML of the DOM element having ID 'person-45' with the
  # 'person' partial for the appropriate object.
  # Generates:  Element.update("person-45", "-- Contents of 'person' partial --");
  page.replace_html 'person-45', :partial => 'person', :object => @person

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 757
757:           def replace_html(id, *options_for_render)
758:             call 'Element.update', id, render(*options_for_render)
759:           end
select(pattern)

Returns a collection reference by finding it through a CSS pattern in the DOM. This collection can then be used for further method calls. Examples:

  page.select('p')                      # => $$('p');
  page.select('p.welcome b').first      # => $$('p.welcome b').first();
  page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide();

You can also use prototype enumerations with the collection. Observe:

  # Generates: $$('#items li').each(function(value) { value.hide(); });
  page.select('#items li').each do |value|
    value.hide
  end

Though you can call the block param anything you want, they are always rendered in the javascript as ‘value, index.’ Other enumerations, like collect() return the last statement:

  # Generates: var hidden = $$('#items li').collect(function(value, index) { return value.hide(); });
  page.select('#items li').collect('hidden') do |item|
    item.hide
  end

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 714
714:           def select(pattern)
715:             JavaScriptElementCollectionProxy.new(self, pattern)
716:           end
show(*ids)

Shows hidden DOM elements with the given ids.

Example:

 # Show a few people
 # Generates: ["person_6", "person_13", "person_223"].each(Element.show);
 page.show 'person_6', 'person_13', 'person_223'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 815
815:           def show(*ids)
816:             loop_on_multiple_args 'Element.show', ids
817:           end
sortable(id, options = {})

Creates a script.aculo.us sortable element. Useful to recreate sortable elements after items get added or deleted. See ActionView::Helpers::ScriptaculousHelper for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 956
956:           def sortable(id, options = {})
957:             record @context.send(:sortable_element_js, id, options)
958:           end
toggle(*ids)

Toggles the visibility of the DOM elements with the given ids. Example:

 # Show a few people
 # Generates: ["person_14", "person_12", "person_23"].each(Element.toggle);
 page.toggle 'person_14', 'person_12', 'person_23'      # Hides the elements
 page.toggle 'person_14', 'person_12', 'person_23'      # Shows the previously hidden elements

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 839
839:           def toggle(*ids)
840:             loop_on_multiple_args 'Element.toggle', ids
841:           end
visual_effect(name, id = nil, options = {})

Starts a script.aculo.us visual effect. See ActionView::Helpers::ScriptaculousHelper for more information.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb, line 948
948:           def visual_effect(name, id = nil, options = {})
949:             record @context.send(:visual_effect, name, id, options)
950:           end


Module: ActionView::Helpers::RecordIdentificationHelper

Module | ActionView::Helpers::RecordIdentificationHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/record_identification_helper.rb

Methods

dom_class dom_id partial_path

Public Instance methods

dom_class(*args, &block)

See ActionController::RecordIdentifier.dom_class — this is just a delegate to that for convenient access in the view.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/record_identification_helper.rb, line 10
10:       def dom_class(*args, &block)
11:         ActionController::RecordIdentifier.dom_class(*args, &block)
12:       end
dom_id(*args, &block)

See ActionController::RecordIdentifier.dom_id — this is just a delegate to that for convenient access in the view.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/record_identification_helper.rb, line 15
15:       def dom_id(*args, &block)
16:         ActionController::RecordIdentifier.dom_id(*args, &block)
17:       end
partial_path(*args, &block)

See ActionController::RecordIdentifier.partial_path — this is just a delegate to that for convenient access in the view.

[Source]

   # File vendor/rails/actionpack/lib/action_view/helpers/record_identification_helper.rb, line 5
5:       def partial_path(*args, &block)
6:         ActionController::RecordIdentifier.partial_path(*args, &block)
7:       end


Module: ActionView::Helpers::RecordTagHelper

Module | ActionView::Helpers::RecordTagHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/record_tag_helper.rb

Methods

content_tag_for div_for

Public Instance methods

content_tag_for(tag_name, record, *args, &block)

content_tag_for creates an HTML element with id and class parameters that relate to the specified Active Record object. For example:

   <% content_tag_for(:tr, @person) do %>
     <td><%=h @person.first_name %></td>
     <td><%=h @person.last_name %></td>
   <% end %>

would produce the following HTML (assuming @person is an instance of a Person object, with an id value of 123):

   <tr id="person_123" class="person">....</tr>

If you require the HTML id attribute to have a prefix, you can specify it:

   <% content_tag_for(:tr, @person, :foo) do %> ...

produces:

   <tr id="foo_person_123" class="person">...

content_tag_for also accepts a hash of options, which will be converted to additional HTML attributes. If you specify a :class value, it will be combined with the default class name for your object. For example:

   <% content_tag_for(:li, @person, :class => "bar") %>...

produces:

   <li id="person_123" class="person bar">...

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/record_tag_helper.rb, line 50
50:       def content_tag_for(tag_name, record, *args, &block)
51:         prefix  = args.first.is_a?(Hash) ? nil : args.shift
52:         options = args.extract_options!
53:         options.merge!({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
54:         content_tag(tag_name, options, &block)
55:       end
div_for(record, *args, &block)

Produces a wrapper DIV element with id and class parameters that relate to the specified Active Record object. Usage example:

   <% div_for(@person, :class => "foo") do %>
      <%=h @person.name %>
   <% end %>

produces:

   <div id="person_123" class="person foo"> Joe Bloggs </div>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/record_tag_helper.rb, line 15
15:       def div_for(record, *args, &block)
16:         content_tag_for(:div, record, *args, &block)
17:       end


Module: ActionView::Helpers::SanitizeHelper

Module | ActionView::Helpers::SanitizeHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb

The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. These helper methods extend ActionView making them callable within your template files.

Methods

sanitize sanitize_css strip_links strip_tags

Public Instance methods

sanitize(html, options = {})

This sanitize helper will html encode all tags and strip all attributes that aren‘t specifically allowed. It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out the extensive test suite.

  <%= sanitize @article.body %>

You can add or remove tags/attributes if you want to customize it a bit. See ActionView::Base for full docs on the available options. You can add tags/attributes for single uses of sanitize by passing either the :attributes or :tags options:

Normal Use

  <%= sanitize @article.body %>

Custom Use (only the mentioned tags and attributes are allowed, nothing else)

  <%= sanitize @article.body, :tags => %w(table tr td), :attributes => %w(id class style)

Add table tags to the default allowed tags

  Rails::Initializer.run do |config|
    config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
  end

Remove tags to the default allowed tags

  Rails::Initializer.run do |config|
    config.after_initialize do
      ActionView::Base.sanitized_allowed_tags.delete 'div'
    end
  end

Change allowed default attributes

  Rails::Initializer.run do |config|
    config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
  end

Please note that sanitizing user-provided text does not guarantee that the resulting markup is valid (conforming to a document type) or even well-formed. The output may still contain e.g. unescaped ’<’, ’>’, ’&’ characters and confuse browsers.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb, line 51
51:       def sanitize(html, options = {})
52:         self.class.white_list_sanitizer.sanitize(html, options)
53:       end
sanitize_css(style)

Sanitizes a block of CSS code. Used by sanitize when it comes across a style attribute.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb, line 56
56:       def sanitize_css(style)
57:         self.class.white_list_sanitizer.sanitize_css(style)
58:       end
strip_links(html)

Strips all link tags from text leaving just the link text.

Examples

  strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
  # => Ruby on Rails

  strip_links('Please e-mail me at <a href="mailto:me@email.com">me@email.com</a>.')
  # => Please e-mail me at me@email.com.

  strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
  # => Blog: Visit

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb, line 89
89:       def strip_links(html)
90:         self.class.link_sanitizer.sanitize(html)
91:       end
strip_tags(html)

Strips all HTML tags from the html, including comments. This uses the html-scanner tokenizer and so its HTML parsing ability is limited by that of html-scanner.

Examples

  strip_tags("Strip <i>these</i> tags!")
  # => Strip these tags!

  strip_tags("<b>Bold</b> no more!  <a href='more.html'>See more here</a>...")
  # => Bold no more!  See more here...

  strip_tags("<div id='top-bar'>Welcome to my website!</div>")
  # => Welcome to my website!

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb, line 74
74:       def strip_tags(html)
75:         self.class.full_sanitizer.sanitize(html)
76:       end


Module: ActionView::Helpers::ScriptaculousHelper

Module | ActionView::Helpers::ScriptaculousHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb

Provides a set of helpers for calling Scriptaculous JavaScript functions, including those which create Ajax controls and visual effects.

To be able to use these helpers, you must include the Prototype JavaScript framework and the Scriptaculous JavaScript library in your pages. See the documentation for ActionView::Helpers::JavaScriptHelper for more information on including the necessary JavaScript.

The Scriptaculous helpers’ behavior can be tweaked with various options. See the documentation at script.aculo.us for more information on using these helpers in your application.

Methods

draggable_element drop_receiving_element sortable_element visual_effect

Constants

TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind]

Public Instance methods

draggable_element(element_id, options = {})

Makes the element with the DOM ID specified by element_id draggable.

Example:

  <%= draggable_element("my_image", :revert => true)

You can change the behaviour with various options, see script.aculo.us for more documentation.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb, line 162
162:       def draggable_element(element_id, options = {})
163:         javascript_tag(draggable_element_js(element_id, options).chop!)
164:       end
drop_receiving_element(element_id, options = {})

Makes the element with the DOM ID specified by element_id receive dropped draggable elements (created by draggable_element). and make an AJAX call. By default, the action called gets the DOM ID of the element as parameter.

Example:

  <%= drop_receiving_element("my_cart", :url =>
    { :controller => "cart", :action => "add" }) %>

You can change the behaviour with various options, see script.aculo.us for more documentation.

Some of these options include:

  • :accept - Set this to a string or an array of strings describing the allowable CSS classes that the draggable_element must have in order to be accepted by this drop_receiving_element.
  • :confirm - Adds a confirmation dialog. Example:
      :confirm => "Are you sure you want to do this?"
  • :hoverclass - If set, the drop_receiving_element will have this additional CSS class when an accepted draggable_element is hovered over it.
  • :onDrop - Called when a draggable_element is dropped onto this element. Override this callback with a JavaScript expression to change the default drop behaviour. Example:
      :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }"

    This callback gets three parameters: The Draggable element, the Droppable element and the Event object. You can extract additional information about the drop - like if the Ctrl or Shift keys were pressed - from the Event object.

  • :with - A JavaScript expression specifying the parameters for the XMLHttpRequest. Any expressions should return a valid URL query string.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb, line 207
207:       def drop_receiving_element(element_id, options = {})
208:         javascript_tag(drop_receiving_element_js(element_id, options).chop!)
209:       end
sortable_element(element_id, options = {})

Makes the element with the DOM ID specified by element_id sortable by drag-and-drop and make an Ajax call whenever the sort order has changed. By default, the action called gets the serialized sortable element as parameters.

Example:

  <%= sortable_element("my_list", :url => { :action => "order" }) %>

In the example, the action gets a "my_list" array parameter containing the values of the ids of elements the sortable consists of, in the current order.

Important: For this to work, the sortable elements must have id attributes in the form "string_identifier". For example, "item_1". Only the identifier part of the id attribute will be serialized.

Additional options are:

  • :format - A regular expression to determine what to send as the serialized id to the server (the default is /^[^_]*_(.*)$/).
  • :constraint - Whether to constrain the dragging to either :horizontal or :vertical (or false to make it unconstrained).
  • :overlap - Calculate the item overlap in the :horizontal or :vertical direction.
  • :tag - Which children of the container element to treat as sortable (default is li).
  • :containment - Takes an element or array of elements to treat as potential drop targets (defaults to the original target element).
  • :only - A CSS class name or array of class names used to filter out child elements as candidates.
  • :scroll - Determines whether to scroll the list during drag operations if the list runs past the visual border.
  • :tree - Determines whether to treat nested lists as part of the main sortable list. This means that you can create multi-layer lists, and not only sort items at the same level, but drag and sort items between levels.
  • :hoverclass - If set, the Droppable will have this additional CSS class when an accepted Draggable is hovered over it.
  • :handle - Sets whether the element should only be draggable by an embedded handle. The value may be a string referencing a CSS class value (as of script.aculo.us V1.5). The first child/grandchild/etc. element found within the element that has this CSS class value will be used as the handle.
  • :ghosting - Clones the element and drags the clone, leaving the original in place until the clone is dropped (default is false).
  • :dropOnEmpty - If true the Sortable container will be made into a Droppable, that can receive a Draggable (as according to the containment rules) as a child element when there are no more elements inside (default is false).
  • :onChange - Called whenever the sort order changes while dragging. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the affected element as its parameter.
  • :onUpdate - Called when the drag ends and the Sortable‘s order is changed in any way. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the container as its parameter.

See script.aculo.us for more documentation.

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb, line 136
136:       def sortable_element(element_id, options = {})
137:         javascript_tag(sortable_element_js(element_id, options).chop!)
138:       end
visual_effect(name, element_id = false, js_options = {})

Returns a JavaScript snippet to be used on the Ajax callbacks for starting visual effects.

Example:

  <%= link_to_remote "Reload", :update => "posts",
        :url => { :action => "reload" },
        :complete => visual_effect(:highlight, "posts", :duration => 0.5)

If no element_id is given, it assumes "element" which should be a local variable in the generated JavaScript execution context. This can be used for example with drop_receiving_element:

  <%= drop_receiving_element (...), :loading => visual_effect(:fade) %>

This would fade the element that was dropped on the drop receiving element.

For toggling visual effects, you can use :toggle_appear, :toggle_slide, and :toggle_blind which will alternate between appear/fade, slidedown/slideup, and blinddown/blindup respectively.

You can change the behaviour with various options, see script.aculo.us for more documentation.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb, line 45
45:       def visual_effect(name, element_id = false, js_options = {})
46:         element = element_id ? element_id.to_json : "element"
47:
48:         js_options[:queue] = if js_options[:queue].is_a?(Hash)
49:           '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}'
50:         elsif js_options[:queue]
51:           "'#{js_options[:queue]}'"
52:         end if js_options[:queue]
53:
54:         [:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option|
55:           js_options[option] = "'#{js_options[option]}'" if js_options[option]
56:         end
57:
58:         if TOGGLE_EFFECTS.include? name.to_sym
59:           "Effect.toggle(#{element},'#{name.to_s.gsub(/^toggle_/,'')}',#{options_for_javascript(js_options)});"
60:         else
61:           "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});"
62:         end
63:       end


Module: ActionView::Helpers::TagHelper

Module | ActionView::Helpers::TagHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb

Provides methods to generate HTML tags programmatically when you can‘t use a Builder. By default, they output XHTML compliant tags.

Methods

cdata_section content_tag escape_once tag

Included Modules

ERB::Util

Constants

BOOLEAN_ATTRIBUTES | = | %w(disabled readonly multiple checked).to_set
BLOCK_CALLED_FROM_ERB | = | 'defined? __in_erb_template'

Public Instance methods

cdata_section(content)

Returns a CDATA section with the given content. CDATA sections are used to escape blocks of text containing characters which would otherwise be recognized as markup. CDATA sections begin with the string <![CDATA[ and end with (and may not contain) the string ]]>.

Examples

  cdata_section("<hello world>")
  # => <![CDATA[<hello world>]]>

  cdata_section(File.read("hello_world.txt"))
  # => <![CDATA[<hello from a text file]]>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb, line 93
93:       def cdata_section(content)
94:         "<![CDATA[#{content}]]>"
95:       end
content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)

Returns an HTML block tag of type name surrounding the content. Add HTML attributes by passing an attributes hash to options. Instead of passing the content as an argument, you can also use a block in which case, you pass your options as the second parameter. Set escape to false to disable attribute value escaping.

Options

The options hash is used with attributes with no value like (disabled and readonly), which you can give a value of true in the options hash. You can use symbols or strings for the attribute names.

Examples

  content_tag(:p, "Hello world!")
   # => <p>Hello world!</p>
  content_tag(:div, content_tag(:p, "Hello world!"), :class => "strong")
   # => <div class="strong"><p>Hello world!</p></div>
  content_tag("select", options, :multiple => true)
   # => <select multiple="multiple">...options...</select>

  <% content_tag :div, :class => "strong" do -%>
    Hello world!
  <% end -%>
   # => <div class="strong">Hello world!</div>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb, line 67
67:       def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
68:         if block_given?
69:           options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
70:           content_tag = content_tag_string(name, capture(&block), options, escape)
71:
72:           if block_called_from_erb?(block)
73:             concat(content_tag)
74:           else
75:             content_tag
76:           end
77:         else
78:           content_tag_string(name, content_or_options_with_block, options, escape)
79:         end
80:       end
escape_once(html)

Returns an escaped version of html without affecting existing escaped entities.

Examples

  escape_once("1 < 2 &amp; 3")
  # => "1 &lt; 2 &amp; 3"

  escape_once("&lt;&lt; Accept & Checkout")
  # => "&lt;&lt; Accept &amp; Checkout"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb, line 105
105:       def escape_once(html)
106:         html.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
107:       end
tag(name, options = nil, open = false, escape = true)

Returns an empty HTML tag of type name which by default is XHTML compliant. Set open to true to create an open tag compatible with HTML 4.0 and below. Add HTML attributes by passing an attributes hash to options. Set escape to false to disable attribute value escaping.

Options

The options hash is used with attributes with no value like (disabled and readonly), which you can give a value of true in the options hash. You can use symbols or strings for the attribute names.

Examples

  tag("br")
  # => <br />

  tag("br", nil, true)
  # => <br>

  tag("input", { :type => 'text', :disabled => true })
  # => <input type="text" disabled="disabled" />

  tag("img", { :src => "open & shut.png" })
  # => <img src="open &amp; shut.png" />

  tag("img", { :src => "open &amp; shut.png" }, false, false)
  # => <img src="open &amp; shut.png" />

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb, line 40
40:       def tag(name, options = nil, open = false, escape = true)
41:         "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}"
42:       end


Module: ActionView::Helpers::TextHelper

Module | ActionView::Helpers::TextHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb

The TextHelper module provides a set of methods for filtering, formatting and transforming strings, which can reduce the amount of inline Ruby code in your views. These helper methods extend ActionView making them callable within your template files.

Methods

auto_link concat current_cycle cycle excerpt highlight markdown pluralize reset_cycle simple_format textilize textilize_without_paragraph truncate word_wrap

Constants

AUTO_LINK_RE | = | %r{ ( https?:// | www\. ) [^\s<]+ }x unless const_defined?(:AUTO_LINK_RE)
BRACKETS | = | { ']' => '[', ')' => '(', '}' => '{' }

Public Instance methods

auto_link(text, *args, &block)

Turns all URLs and e-mail addresses into clickable links. The :link option will limit what should be linked. You can add HTML attributes to the links using :href_options. Possible values for :link are :all (default), :email_addresses, and :urls. If a block is given, each URL and e-mail address is yielded and the result is used as the link text.

Examples

  auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
  # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
  #     say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"

  auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
  # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
  #     or e-mail david@loudthinking.com"

  auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
  # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"

  post_body = "Welcome to my new blog at http://www.myblog.com/.  Please e-mail me at me@email.com."
  auto_link(post_body, :href_options => { :target => '_blank' }) do |text|
    truncate(text, 15)
  end
  # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
        Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."

You can still use auto_link with the old API that accepts the link as its optional second parameter and the html_options hash as its optional third parameter:

  post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
  auto_link(post_body, :urls)     # => Once upon\na time
  # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>.
        Please e-mail me at me@email.com."

  auto_link(post_body, :all, :target => "_blank")     # => Once upon\na time
  # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>.
        Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 362
362:       def auto_link(text, *args, &block)#link = :all, href_options = {}, &block)
363:         return '' if text.blank?
364:
365:         options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter
366:         unless args.empty?
367:           options[:link] = args[0] || :all
368:           options[:html] = args[1] || {}
369:         end
370:         options.reverse_merge!(:link => :all, :html => {})
371:
372:         case options[:link].to_sym
373:           when :all                         then auto_link_email_addresses(auto_link_urls(text, options[:html], &block), options[:html], &block)
374:           when :email_addresses             then auto_link_email_addresses(text, options[:html], &block)
375:           when :urls                        then auto_link_urls(text, options[:html], &block)
376:         end
377:       end
concat(string, unused_binding = nil)

The preferred method of outputting text in your views is to use the <%= "text" %> eRuby syntax. The regular puts and print methods do not operate as expected in an eRuby code block. If you absolutely must output text within a non-output code block (i.e., <% %>), you can use the concat method.

Examples

  <%
      concat "hello"
      # is the equivalent of <%= "hello" %>

      if (logged_in == true):
        concat "Logged in!"
      else
        concat link_to('login', :action => login)
      end
      # will either display "Logged in!" or a login link
  %>

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 27
27:       def concat(string, unused_binding = nil)
28:         if unused_binding
29:           ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed.  Please remove it from your views and helpers.", caller)
30:         end
31:
32:         output_buffer << string
33:       end
current_cycle(name = "default")

Returns the current cycle string after a cycle has been started. Useful for complex table highlighing or any other design need which requires the current cycle string in more than one place.

Example

  # Alternate background colors
  @items = [1,2,3,4]
  <% @items.each do |item| %>
    <div style="background-color:<%= cycle("red","white","blue") %>">
      <span style="background-color:<%= current_cycle %>"><%= item %></span>
    </div>
  <% end %>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 445
445:       def current_cycle(name = "default")
446:         cycle = get_cycle(name)
447:         cycle.current_value unless cycle.nil?
448:       end
cycle(first_value, *values)

Creates a Cycle object whose to_s method cycles through elements of an array every time it is called. This can be used for example, to alternate classes for table rows. You can use named cycles to allow nesting in loops. Passing a Hash as the last parameter with a :name key will create a named cycle. The default name for a cycle without a +:name+ key is "default". You can manually reset a cycle by calling reset_cycle and passing the name of the cycle. The current cycle string can be obtained anytime using the current_cycle method.

Examples

  # Alternate CSS classes for even and odd numbers...
  @items = [1,2,3,4]
  <table>
  <% @items.each do |item| %>
    <tr class="<%= cycle("even", "odd") -%>">
      <td>item</td>
    </tr>
  <% end %>
  </table>

  # Cycle CSS classes for rows, and text colors for values within each row
  @items = x = [{:first => 'Robert', :middle => 'Daniel', :last => 'James'},
               {:first => 'Emily', :middle => 'Shannon', :maiden => 'Pike', :last => 'Hicks'},
              {:first => 'June', :middle => 'Dae', :last => 'Jones'}]
  <% @items.each do |item| %>
    <tr class="<%= cycle("even", "odd", :name => "row_class") -%>">
      <td>
        <% item.values.each do |value| %>
          <%# Create a named cycle "colors" %>
          <span style="color:<%= cycle("red", "green", "blue", :name => "colors") -%>">
            <%= value %>
          </span>
        <% end %>
        <% reset_cycle("colors") %>
      </td>
   </tr>
 <% end %>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 417
417:       def cycle(first_value, *values)
418:         if (values.last.instance_of? Hash)
419:           params = values.pop
420:           name = params[:name]
421:         else
422:           name = "default"
423:         end
424:         values.unshift(first_value)
425:
426:         cycle = get_cycle(name)
427:         if (cycle.nil? || cycle.values != values)
428:           cycle = set_cycle(name, Cycle.new(*values))
429:         end
430:         return cycle.to_s
431:       end
excerpt(text, phrase, *args)

Extracts an excerpt from text that matches the first instance of phrase. The :radius option expands the excerpt on each side of the first occurrence of phrase by the number of characters defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the text, then the :omission option (which defaults to "…") will be prepended/appended accordingly. The resulting string will be stripped in any case. If the phrase isn‘t found, nil is returned.

Examples

  excerpt('This is an example', 'an', :radius => 5)
  # => ...s is an exam...

  excerpt('This is an example', 'is', :radius => 5)
  # => This is a...

  excerpt('This is an example', 'is')
  # => This is an example

  excerpt('This next thing is an example', 'ex', :radius => 2)
  # => ...next...

  excerpt('This is also an example', 'an', :radius => 8, :omission => '<chop> ')
  # => <chop> is also an example

You can still use excerpt with the old API that accepts the radius as its optional third and the ellipsis as its optional forth parameter:

  excerpt('This is an example', 'an', 5)                   # => ...s is an exam...
  excerpt('This is also an example', 'an', 8, '<chop> ')   # => <chop> is also an example

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 141
141:       def excerpt(text, phrase, *args)
142:         options = args.extract_options!
143:         unless args.empty?
144:           options[:radius] = args[0] || 100
145:           options[:omission] = args[1] || "..."
146:         end
147:         options.reverse_merge!(:radius => 100, :omission => "...")
148:
149:         if text && phrase
150:           phrase = Regexp.escape(phrase)
151:
152:           if found_pos = text.mb_chars =~ /(#{phrase})/i
153:             start_pos = [ found_pos - options[:radius], 0 ].max
154:             end_pos   = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min
155:
156:             prefix  = start_pos > 0 ? options[:omission] : ""
157:             postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : ""
158:
159:             prefix + text.mb_chars[start_pos..end_pos].strip + postfix
160:           else
161:             nil
162:           end
163:         end
164:       end
highlight(text, phrases, *args)

Highlights one or more phrases everywhere in text by inserting it into a :highlighter string. The highlighter can be specialized by passing :highlighter as a single-quoted string with \1 where the phrase is to be inserted (defaults to ’<strong class="highlight">\1</strong>’)

Examples

  highlight('You searched for: rails', 'rails')
  # => You searched for: <strong class="highlight">rails</strong>

  highlight('You searched for: ruby, rails, dhh', 'actionpack')
  # => You searched for: ruby, rails, dhh

  highlight('You searched for: rails', ['for', 'rails'], :highlighter => '<em>\1</em>')
  # => You searched <em>for</em>: <em>rails</em>

  highlight('You searched for: rails', 'rails', :highlighter => '<a href="search?q=\1">\1</a>')
  # => You searched for: <a href="search?q=rails">rails</a>

You can still use highlight with the old API that accepts the highlighter as its optional third parameter:

  highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>')     # => You searched for: <a href="search?q=rails">rails</a>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 99
 99:       def highlight(text, phrases, *args)
100:         options = args.extract_options!
101:         unless args.empty?
102:           options[:highlighter] = args[0] || '<strong class="highlight">\1</strong>'
103:         end
104:         options.reverse_merge!(:highlighter => '<strong class="highlight">\1</strong>')
105:
106:         if text.blank? || phrases.blank?
107:           text
108:         else
109:           match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
110:           text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
111:         end
112:       end
markdown(text)

Returns the text with all the Markdown codes turned into HTML tags. This method requires BlueCloth to be available.

Examples

  markdown("We are using __Markdown__ now!")
  # => "<p>We are using <strong>Markdown</strong> now!</p>"

  markdown("We like to _write_ `code`, not just _read_ it!")
  # => "<p>We like to <em>write</em> <code>code</code>, not just <em>read</em> it!</p>"

  markdown("The [Markdown website](http://daringfireball.net/projects/markdown/) has more information.")
  # => "<p>The <a href="http://daringfireball.net/projects/markdown/">Markdown website</a>
  #     has more information.</p>"

  markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
  # => '<p><img src="http://rubyonrails.com/images/rails.png" alt="The ROR logo" title="Ruby on Rails" /></p>'

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 290
290:       def markdown(text)
291:         text.blank? ? "" : BlueCloth.new(text).to_html
292:       end
pluralize(count, singular, plural = nil)

Attempts to pluralize the singular word unless count is 1. If plural is supplied, it will use that when count is > 1, otherwise it will use the Inflector to determine the plural form

Examples

  pluralize(1, 'person')
  # => 1 person

  pluralize(2, 'person')
  # => 2 people

  pluralize(3, 'person', 'users')
  # => 3 users

  pluralize(0, 'person')
  # => 0 people

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 182
182:       def pluralize(count, singular, plural = nil)
183:         "#{count || 0} " + ((count == 1 || count == '1') ? singular : (plural || singular.pluralize))
184:       end
reset_cycle(name = "default")

Resets a cycle so that it starts from the first element the next time it is called. Pass in name to reset a named cycle.

Example

  # Alternate CSS classes for even and odd numbers...
  @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
  <table>
  <% @items.each do |item| %>
    <tr class="<%= cycle("even", "odd") -%>">
        <% item.each do |value| %>
          <span style="color:<%= cycle("#333", "#666", "#999", :name => "colors") -%>">
            <%= value %>
          </span>
        <% end %>

        <% reset_cycle("colors") %>
    </tr>
  <% end %>
  </table>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 469
469:       def reset_cycle(name = "default")
470:         cycle = get_cycle(name)
471:         cycle.reset unless cycle.nil?
472:       end
simple_format(text, html_options={})

Returns text transformed into HTML using simple formatting rules. Two or more consecutive newlines(\n\n) are considered as a paragraph and wrapped in <p> tags. One newline (\n) is considered as a linebreak and a <br /> tag is appended. This method does not remove the newlines from the text.

You can pass any HTML attributes into html_options. These will be added to all created paragraphs.

Examples

  my_text = "Here is some basic text...\n...with a line break."

  simple_format(my_text)
  # => "<p>Here is some basic text...\n<br />...with a line break.</p>"

  more_text = "We want to put a paragraph...\n\n...right there."

  simple_format(more_text)
  # => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"

  simple_format("Look ma! A class!", :class => 'description')
  # => "<p class='description'>Look ma! A class!</p>"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 315
315:       def simple_format(text, html_options={})
316:         start_tag = tag('p', html_options, true)
317:         text = text.to_s.dup
318:         text.gsub!(/\r\n?/, "\n")                    # \r\n and \r -> \n
319:         text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}")  # 2+ newline  -> paragraph
320:         text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline   -> br
321:         text.insert 0, start_tag
322:         text << "</p>"
323:       end
textilize(text)

Returns the text with all the Textile codes turned into HTML tags.

You can learn more about Textile‘s syntax at its website. This method is only available if RedCloth is available.

Examples

  textilize("*This is Textile!*  Rejoice!")
  # => "<p><strong>This is Textile!</strong>  Rejoice!</p>"

  textilize("I _love_ ROR(Ruby on Rails)!")
  # => "<p>I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!</p>"

  textilize("h2. Textile makes markup -easy- simple!")
  # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"

  textilize("Visit the Rails website "here":http://www.rubyonrails.org/.)
  # => "<p>Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>.</p>"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 237
237:       def textilize(text)
238:         if text.blank?
239:           ""
240:         else
241:           textilized = RedCloth.new(text, [ :hard_breaks ])
242:           textilized.hard_breaks = true if textilized.respond_to?(:hard_breaks=)
243:           textilized.to_html
244:         end
245:       end
textilize_without_paragraph(text)

Returns the text with all the Textile codes turned into HTML tags, but without the bounding <p> tag that RedCloth adds.

You can learn more about Textile‘s syntax at its website. This method is requires RedCloth to be available.

Examples

  textilize_without_paragraph("*This is Textile!*  Rejoice!")
  # => "<strong>This is Textile!</strong>  Rejoice!"

  textilize_without_paragraph("I _love_ ROR(Ruby on Rails)!")
  # => "I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!"

  textilize_without_paragraph("h2. Textile makes markup -easy- simple!")
  # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"

  textilize_without_paragraph("Visit the Rails website "here":http://www.rubyonrails.org/.)
  # => "Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>."

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 266
266:       def textilize_without_paragraph(text)
267:         textiled = textilize(text)
268:         if textiled[0..2] == "<p>" then textiled = textiled[3..-1] end
269:         if textiled[-4..-1] == "</p>" then textiled = textiled[0..-5] end
270:         return textiled
271:       end
truncate(text, *args)

Truncates a given text after a given :length if text is longer than :length (defaults to 30). The last characters will be replaced with the :omission (defaults to "…").

Examples

  truncate("Once upon a time in a world far far away")
  # => Once upon a time in a world f...

  truncate("Once upon a time in a world far far away", :length => 14)
  # => Once upon a...

  truncate("And they found that many people were sleeping better.", :length => 25, "(clipped)")
  # => And they found that many (clipped)

  truncate("And they found that many people were sleeping better.", :omission => "... (continued)", :length => 15)
  # => And they found... (continued)

You can still use truncate with the old API that accepts the length as its optional second and the ellipsis as its optional third parameter:

  truncate("Once upon a time in a world far far away", 14)
  # => Once upon a time in a world f...

  truncate("And they found that many people were sleeping better.", 15, "... (continued)")
  # => And they found... (continued)

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 60
60:       def truncate(text, *args)
61:         options = args.extract_options!
62:         unless args.empty?
63:           ActiveSupport::Deprecation.warn('truncate takes an option hash instead of separate ' +
64:             'length and omission arguments', caller)
65:
66:           options[:length] = args[0] || 30
67:           options[:omission] = args[1] || "..."
68:         end
69:         options.reverse_merge!(:length => 30, :omission => "...")
70:
71:         if text
72:           l = options[:length] - options[:omission].mb_chars.length
73:           chars = text.mb_chars
74:           (chars.length > options[:length] ? chars[0...l] + options[:omission] : text).to_s
75:         end
76:       end
word_wrap(text, *args)

Wraps the text into lines no longer than line_width width. This method breaks on the first whitespace character that does not exceed line_width (which is 80 by default).

Examples

  word_wrap('Once upon a time')
  # => Once upon a time

  word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
  # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\n a successor to the throne turned out to be more trouble than anyone could have\n imagined...

  word_wrap('Once upon a time', :line_width => 8)
  # => Once upon\na time

  word_wrap('Once upon a time', :line_width => 1)
  # => Once\nupon\na\ntime

You can still use word_wrap with the old API that accepts the line_width as its optional second parameter:

  word_wrap('Once upon a time', 8)     # => Once upon\na time

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb, line 207
207:       def word_wrap(text, *args)
208:         options = args.extract_options!
209:         unless args.blank?
210:           options[:line_width] = args[0] || 80
211:         end
212:         options.reverse_merge!(:line_width => 80)
213:
214:         text.split("\n").collect do |line|
215:           line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
216:         end * "\n"
217:       end


Module: ActionView::Helpers::TranslationHelper

Module | ActionView::Helpers::TranslationHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/translation_helper.rb

Methods

l localize t translate

Public Instance methods

l(*args)

Alias for localize

localize(*args)

Delegates to I18n.localize with no additional functionality.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/translation_helper.rb, line 23
23:       def localize(*args)
24:         I18n.localize *args
25:       end
t(key, options = {})

Alias for translate

translate(key, options = {})

Delegates to I18n#translate but also performs two additional functions. First, it‘ll catch MissingTranslationData exceptions and turn them into inline spans that contains the missing key, such that you can see in a view what is missing where.

Second, it‘ll scope the key by the current partial if the key starts with a period. So if you call translate(".foo") from the people/index.html.erb template, you‘ll actually be calling I18n.translate("people.index.foo"). This makes it less repetitive to translate many keys within the same partials and gives you a simple framework for scoping them consistently. If you don‘t prepend the key with a period, nothing is converted.

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/translation_helper.rb, line 13
13:       def translate(key, options = {})
14:         options[:raise] = true
15:         I18n.translate(scope_key_by_partial(key), options)
16:       rescue I18n::MissingTranslationData => e
17:         keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope])
18:         content_tag('span', keys.join(', '), :class => 'translation_missing')
19:       end


Module: ActionView::Helpers::UrlHelper

Module | ActionView::Helpers::UrlHelper
In: | vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb

Provides a set of methods for making links and getting URLs that depend on the routing subsystem (see ActionController::Routing). This allows you to use the same format for links in views and controllers.

Methods

button_to current_page? link_to link_to_if link_to_unless link_to_unless_current mail_to url_for

Included Modules

JavaScriptHelper

Public Instance methods

button_to(name, options = {}, html_options = {})

Generates a form containing a single button that submits to the URL created by the set of options. This is the safest method to ensure links that cause changes to your data are not triggered by search bots or accelerators. If the HTML button does not work with your layout, you can also consider using the link_to method with the :method modifier as described in the link_to documentation.

The generated FORM element has a class name of button-to to allow styling of the form itself and its children. You can control the form submission and input element behavior using html_options. This method accepts the :method and :confirm modifiers described in the link_to documentation. If no :method modifier is given, it will default to performing a POST operation. You can also disable the button by passing :disabled => true in html_options. If you are using RESTful routes, you can pass the :method to change the HTTP verb used to submit the form.

Options

The options hash accepts the same options at url_for.

There are a few special html_options:

  • :method - Specifies the anchor name to be appended to the path.
  • :disabled - Specifies the anchor name to be appended to the path.
  • :confirm - This will add a JavaScript confirm prompt with the question specified. If the user accepts, the link is processed normally, otherwise no action is taken.

Examples

  <%= button_to "New", :action => "new" %>
  # => "<form method="post" action="/controller/new" class="button-to">
  #      <div><input value="New" type="submit" /></div>
  #    </form>"

  button_to "Delete Image", { :action => "delete", :id => @image.id },
            :confirm => "Are you sure?", :method => :delete
  # => "<form method="post" action="/images/delete/1" class="button-to">
  #      <div>
  #        <input type="hidden" name="_method" value="delete" />
  #        <input onclick="return confirm('Are you sure?');"
  #              value="Delete" type="submit" />
  #      </div>
  #    </form>"

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 286
286:       def button_to(name, options = {}, html_options = {})
287:         html_options = html_options.stringify_keys
288:         convert_boolean_attributes!(html_options, %w( disabled ))
289:
290:         method_tag = ''
291:         if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
292:           method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
293:         end
294:
295:         form_method = method.to_s == 'get' ? 'get' : 'post'
296:
297:         request_token_tag = ''
298:         if form_method == 'post' && protect_against_forgery?
299:           request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
300:         end
301:
302:         if confirm = html_options.delete("confirm")
303:           html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
304:         end
305:
306:         url = options.is_a?(String) ? options : self.url_for(options)
307:         name ||= url
308:
309:         html_options.merge!("type" => "submit", "value" => name)
310:
311:         "<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
312:           method_tag + tag("input", html_options) + request_token_tag + "</div></form>"
313:       end
current_page?(options)

True if the current request URI was generated by the given options.

Examples

Let‘s say we‘re in the /shop/checkout?order=desc action.

  current_page?(:action => 'process')
  # => false

  current_page?(:controller => 'shop', :action => 'checkout')
  # => true

  current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc')
  # => false

  current_page?(:action => 'checkout')
  # => true

  current_page?(:controller => 'library', :action => 'checkout')
  # => false

Let‘s say we‘re in the /shop/checkout?order=desc&page=1 action.

  current_page?(:action => 'process')
  # => false

  current_page?(:controller => 'shop', :action => 'checkout')
  # => true

  current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'1')
  # => true

  current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'2')
  # => false

  current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc')
  # => false

  current_page?(:action => 'checkout')
  # => true

  current_page?(:controller => 'library', :action => 'checkout')
  # => false

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 541
541:       def current_page?(options)
542:         url_string = CGI.unescapeHTML(url_for(options))
543:         request = @controller.request
544:         # We ignore any extra parameters in the request_uri if the
545:         # submitted url doesn't have any either.  This lets the function
546:         # work with things like ?order=asc
547:         if url_string.index("?")
548:           request_uri = request.request_uri
549:         else
550:           request_uri = request.request_uri.split('?').first
551:         end
552:         if url_string =~ /^\w+:\/\//
553:           url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
554:         else
555:           url_string == request_uri
556:         end
557:       end
link_to(*args, &block)

Creates a link tag of the given name using a URL created by the set of options. See the valid options in the documentation for url_for. It‘s also possible to pass a string instead of an options hash to get a link tag that uses the value of the string as the href for the link, or use :back to link to the referrer - a JavaScript back link will be used in place of a referrer if none exists. If nil is passed as a name, the link itself will become the name.

Signatures

  link_to(name, options = {}, html_options = nil)
  link_to(options = {}, html_options = nil) do
    # name
  end

Options

  • :confirm => ‘question?‘ - This will add a JavaScript confirm prompt with the question specified. If the user accepts, the link is processed normally, otherwise no action is taken.
  • :popup => true || array of window options - This will force the link to open in a popup window. By passing true, a default browser window will be opened with the URL. You can also specify an array of options that are passed-thru to JavaScripts window.open method.
  • :method => symbol of HTTP verb - This modifier will dynamically create an HTML form and immediately submit the form for processing using the HTTP verb specified. Useful for having links perform a POST operation in dangerous actions like deleting a record (which search bots can follow while spidering your site). Supported verbs are :post, :delete and :put. Note that if the user has JavaScript disabled, the request will fall back to using GET. If you are relying on the POST behavior, you should check for it in your controller‘s action by using the request object‘s methods for post?, delete? or put?.
  • The html_options will accept a hash of html attributes for the link tag.

Note that if the user has JavaScript disabled, the request will fall back to using GET. If :href => ’#’ is used and the user has JavaScript disabled clicking the link will have no effect. If you are relying on the POST behavior, your should check for it in your controller‘s action by using the request object‘s methods for post?, delete? or put?.

You can mix and match the html_options with the exception of :popup and :method which will raise an ActionView::ActionViewError exception.

Examples

Because it relies on url_for, link_to supports both older-style controller/action/id arguments and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base your application on resources and use

  link_to "Profile", profile_path(@profile)
  # => <a href="/profiles/1">Profile</a>

or the even pithier

  link_to "Profile", @profile
  # => <a href="/profiles/1">Profile</a>

in place of the older more verbose, non-resource-oriented

  link_to "Profile", :controller => "profiles", :action => "show", :id => @profile
  # => <a href="/profiles/show/1">Profile</a>

Similarly,

  link_to "Profiles", profiles_path
  # => <a href="/profiles">Profiles</a>

is better than

  link_to "Profiles", :controller => "profiles"
  # => <a href="/profiles">Profiles</a>

You can use a block as well if your link target is hard to fit into the name parameter. ERb example:

  <% link_to(@profile) do %>
    <strong><%= @profile.name %></strong> -- <span>Check it out!!</span>
  <% end %>
  # => <a href="/profiles/1"><strong>David</strong> -- <span>Check it out!!</span></a>

Classes and ids for CSS are easy to produce:

  link_to "Articles", articles_path, :id => "news", :class => "article"
  # => <a href="/articles" class="article" id="news">Articles</a>

Be careful when using the older argument style, as an extra literal hash is needed:

  link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
  # => <a href="/articles" class="article" id="news">Articles</a>

Leaving the hash off gives the wrong link:

  link_to "WRONG!", :controller => "articles", :id => "news", :class => "article"
  # => <a href="/articles/index/news?class=article">WRONG!</a>

link_to can also produce links with anchors or query strings:

  link_to "Comment wall", profile_path(@profile, :anchor => "wall")
  # => <a href="/profiles/1#wall">Comment wall</a>

  link_to "Ruby on Rails search", :controller => "searches", :query => "ruby on rails"
  # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>

  link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
  # => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>

The three options specific to link_to (:confirm, :popup, and :method) are used as follows:

  link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
  # => <a href="http://www.rubyonrails.org/" onclick="return confirm('Are you sure?');">Visit Other Site</a>

  link_to "Help", { :action => "help" }, :popup => true
  # => <a href="/testing/help/" onclick="window.open(this.href);return false;">Help</a>

  link_to "View Image", @image, :popup => ['new_window_name', 'height=300,width=600']
  # => <a href="/images/9" onclick="window.open(this.href,'new_window_name','height=300,width=600');return false;">View Image</a>

  link_to "Delete Image", @image, :confirm => "Are you sure?", :method => :delete
  # => <a href="/images/9" onclick="if (confirm('Are you sure?')) { var f = document.createElement('form');
       f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
       var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
       m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 218
218:       def link_to(*args, &block)
219:         if block_given?
220:           options      = args.first || {}
221:           html_options = args.second
222:           concat(link_to(capture(&block), options, html_options))
223:         else
224:           name         = args.first
225:           options      = args.second || {}
226:           html_options = args.third
227:
228:           url = url_for(options)
229:
230:           if html_options
231:             html_options = html_options.stringify_keys
232:             href = html_options['href']
233:             convert_options_to_javascript!(html_options, url)
234:             tag_options = tag_options(html_options)
235:           else
236:             tag_options = nil
237:           end
238:
239:           href_attr = "href=\"#{url}\"" unless href
240:           "<a #{href_attr}#{tag_options}>#{name || url}</a>"
241:         end
242:       end
link_to_if(condition, name, options = {}, html_options = {}, &block)

Creates a link tag of the given name using a URL created by the set of options if condition is true, in which case only the name is returned. To specialize the default behavior, you can pass a block that accepts the name or the full argument list for link_to_unless (see the examples in link_to_unless).

Examples

  <%= link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) %>
  # If the user isn't logged in...
  # => <a href="/sessions/new/">Login</a>

  <%=
     link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) do
       link_to(@current_user.login, { :controller => "accounts", :action => "show", :id => @current_user })
     end
  %>
  # If the user isn't logged in...
  # => <a href="/sessions/new/">Login</a>
  # If they are logged in...
  # => <a href="/accounts/show/3">my_username</a>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 410
410:       def link_to_if(condition, name, options = {}, html_options = {}, &block)
411:         link_to_unless !condition, name, options, html_options, &block
412:       end
link_to_unless(condition, name, options = {}, html_options = {}) {|name| ...}

Creates a link tag of the given name using a URL created by the set of options unless condition is true, in which case only the name is returned. To specialize the default behavior (i.e., show a login link rather than just the plaintext link text), you can pass a block that accepts the name or the full argument list for link_to_unless.

Examples

  <%= link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) %>
  # If the user is logged in...
  # => <a href="/controller/reply/">Reply</a>

  <%=
     link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) do |name|
       link_to(name, { :controller => "accounts", :action => "signup" })
     end
  %>
  # If the user is logged in...
  # => <a href="/controller/reply/">Reply</a>
  # If not...
  # => <a href="/accounts/signup">Reply</a>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 378
378:       def link_to_unless(condition, name, options = {}, html_options = {}, &block)
379:         if condition
380:           if block_given?
381:             block.arity <= 1 ? yield(name) : yield(name, options, html_options)
382:           else
383:             name
384:           end
385:         else
386:           link_to(name, options, html_options)
387:         end
388:       end
link_to_unless_current(name, options = {}, html_options = {}, &block)

Creates a link tag of the given name using a URL created by the set of options unless the current request URI is the same as the links, in which case only the name is returned (or the given block is yielded, if one exists). You can give link_to_unless_current a block which will specialize the default behavior (e.g., show a "Start Here" link rather than the link‘s text).

Examples

Let‘s say you have a navigation menu…

  <ul id="navbar">
    <li><%= link_to_unless_current("Home", { :action => "index" }) %></li>
    <li><%= link_to_unless_current("About Us", { :action => "about" }) %></li>
  </ul>

If in the "about" action, it will render…

  <ul id="navbar">
    <li><a href="/controller/index">Home</a></li>
    <li>About Us</li>
  </ul>

…but if in the "index" action, it will render:

  <ul id="navbar">
    <li>Home</li>
    <li><a href="/controller/about">About Us</a></li>
  </ul>

The implicit block given to link_to_unless_current is evaluated if the current action is the action given. So, if we had a comments page and wanted to render a "Go Back" link instead of a link to the comments page, we could do something like this…

   <%=
       link_to_unless_current("Comment", { :controller => 'comments', :action => 'new}) do
          link_to("Go back", { :controller => 'posts', :action => 'index' })
       end
    %>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 354
354:       def link_to_unless_current(name, options = {}, html_options = {}, &block)
355:         link_to_unless current_page?(options), name, options, html_options, &block
356:       end
mail_to(email_address, name = nil, html_options = {})

Creates a mailto link tag to the specified email_address, which is also used as the name of the link unless name is specified. Additional HTML attributes for the link can be passed in html_options.

mail_to has several methods for hindering email harvesters and customizing the email itself by passing special keys to html_options.

Options

  • :encode - This key will accept the strings "javascript" or "hex". Passing "javascript" will dynamically create and encode the mailto: link then eval it into the DOM of the page. This method will not show the link on the page if the user has JavaScript disabled. Passing "hex" will hex encode the email_address before outputting the mailto: link.
  • :replace_at - When the link name isn‘t provided, the email_address is used for the link label. You can use this option to obfuscate the email_address by substituting the @ sign with the string given as the value.
  • :replace_dot - When the link name isn‘t provided, the email_address is used for the link label. You can use this option to obfuscate the email_address by substituting the . in the email with the string given as the value.
  • :subject - Preset the subject line of the email.
  • :body - Preset the body of the email.
  • :cc - Carbon Copy addition recipients on the email.
  • :bcc - Blind Carbon Copy additional recipients on the email.

Examples

  mail_to "me@domain.com"
  # => <a href="mailto:me@domain.com">me@domain.com</a>

  mail_to "me@domain.com", "My email", :encode => "javascript"
  # => <script type="text/javascript">eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script>

  mail_to "me@domain.com", "My email", :encode => "hex"
  # => <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>

  mail_to "me@domain.com", nil, :replace_at => "_at_", :replace_dot => "_dot_", :class => "email"
  # => <a href="mailto:me@domain.com" class="email">me_at_domain_dot_com</a>

  mail_to "me@domain.com", "My email", :cc => "ccaddress@domain.com",
           :subject => "This is an example email"
  # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>

[Source]

     # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 456
456:       def mail_to(email_address, name = nil, html_options = {})
457:         html_options = html_options.stringify_keys
458:         encode = html_options.delete("encode").to_s
459:         cc, bcc, subject, body = html_options.delete("cc"), html_options.delete("bcc"), html_options.delete("subject"), html_options.delete("body")
460:
461:         string = ''
462:         extras = ''
463:         extras << "cc=#{CGI.escape(cc).gsub("+", "%20")}&" unless cc.nil?
464:         extras << "bcc=#{CGI.escape(bcc).gsub("+", "%20")}&" unless bcc.nil?
465:         extras << "body=#{CGI.escape(body).gsub("+", "%20")}&" unless body.nil?
466:         extras << "subject=#{CGI.escape(subject).gsub("+", "%20")}&" unless subject.nil?
467:         extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty?
468:
469:         email_address = email_address.to_s
470:
471:         email_address_obfuscated = email_address.dup
472:         email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
473:         email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
474:
475:         if encode == "javascript"
476:           "document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
477:             string << sprintf("%%%x", c)
478:           end
479:           "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>"
480:         elsif encode == "hex"
481:           email_address_encoded = ''
482:           email_address_obfuscated.each_byte do |c|
483:             email_address_encoded << sprintf("&#%d;", c)
484:           end
485:
486:           protocol = 'mailto:'
487:           protocol.each_byte { |c| string << sprintf("&#%d;", c) }
488:
489:           email_address.each_byte do |c|
490:             char = c.chr
491:             string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
492:           end
493:           content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" })
494:         else
495:           content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
496:         end
497:       end
url_for(options = {})

Returns the URL for the set of options provided. This takes the same options as url_for in Action Controller (see the documentation for ActionController::Base#url_for). Note that by default :only_path is true so you‘ll get the relative /controller/action instead of the fully qualified URL like example.com/controller/action.

When called from a view, url_for returns an HTML escaped url. If you need an unescaped url, pass :escape => false in the options.

Options

  • :anchor - Specifies the anchor name to be appended to the path.
  • :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (true by default unless :host is specified).
  • :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this is currently not recommended since it breaks caching.
  • :host - Overrides the default (current) host if provided.
  • :protocol - Overrides the default (current) protocol if provided.
  • :user - Inline HTTP authentication (only plucked out if :password is also present).
  • :password - Inline HTTP authentication (only plucked out if :user is also present).
  • :escape - Determines whether the returned URL will be HTML escaped or not (true by default).

Relying on named routes

If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter, you‘ll trigger the named route for that record. The lookup will happen on the name of the class. So passing a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as admin_workshop_path you‘ll have to call that explicitly (it‘s impossible for url_for to guess that route).

Examples

  <%= url_for(:action => 'index') %>
  # => /blog/

  <%= url_for(:action => 'find', :controller => 'books') %>
  # => /books/find

  <%= url_for(:action => 'login', :controller => 'members', :only_path => false, :protocol => 'https') %>
  # => https://www.railsapplication.com/members/login/

  <%= url_for(:action => 'play', :anchor => 'player') %>
  # => /messages/play/#player

  <%= url_for(:action => 'checkout', :anchor => 'tax&ship') %>
  # => /testing/jump/#tax&amp;ship

  <%= url_for(:action => 'checkout', :anchor => 'tax&ship', :escape => false) %>
  # => /testing/jump/#tax&ship

  <%= url_for(Workshop.new) %>
  # relies on Workshop answering a new_record? call (and in this case returning true)
  # => /workshops

  <%= url_for(@workshop) %>
  # calls @workshop.to_s
  # => /workshops/5

  <%= url_for("http://www.example.com") %>
  # => http://www.example.com

  <%= url_for(:back) %>
  # if request.env["HTTP_REFERER"] is set to "http://www.example.com"
  # => http://www.example.com

  <%= url_for(:back) %>
  # if request.env["HTTP_REFERER"] is not set or is blank
  # => javascript:history.back()

[Source]

    # File vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb, line 76
76:       def url_for(options = {})
77:         options ||= {}
78:         url = case options
79:         when String
80:           escape = true
81:           options
82:         when Hash
83:           options = { :only_path => options[:host].nil? }.update(options.symbolize_keys)
84:           escape  = options.key?(:escape) ? options.delete(:escape) : true
85:           @controller.send(:url_for, options)
86:         when :back
87:           escape = false
88:           @controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
89:         else
90:           escape = false
91:           polymorphic_path(options)
92:         end
93:
94:         escape ? escape_once(url) : url
95:       end


Module: ActionView::Partials

Module | ActionView::Partials
In: | vendor/rails/actionpack/lib/action_view/partials.rb

There‘s also a convenience method for rendering sub templates within the current controller that depends on a single object (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being prefixed with an underscore — as to separate them from regular templates that could be rendered on their own.

In a template for Advertiser#account:

 <%= render :partial => "account" %>

This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable account to the template for display.

In another template for Advertiser#buy, we could have:

  <%= render :partial => "account", :locals => { :account => @buyer } %>

  <% for ad in @advertisements %>
    <%= render :partial => "ad", :locals => { :ad => ad } %>
  <% end %>

This would first render "advertiser/_account.erb" with @buyer passed in as the local variable account, then render "advertiser/_ad.erb" and pass the local variable ad to the template for display.

Rendering a collection of partials

The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within. So the three-lined example in "Using partials" can be rewritten with a single line:

  <%= render :partial => "ad", :collection => @advertisements %>

This will render "advertiser/_ad.erb" and pass the local variable ad to the template for display. An iteration counter will automatically be made available to the template with a name of the form partial_name_counter. In the case of the example above, the template would be fed ad_counter.

NOTE: Due to backwards compatibility concerns, the collection can‘t be one of hashes. Normally you‘d also just keep domain objects, like Active Records, in there.

Rendering shared partials

Two controllers can share a set of partials and render them like this:

  <%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>

This will render the partial "advertisement/_ad.erb" regardless of which controller this is being called from.

Rendering objects with the RecordIdentifier

Instead of explicitly naming the location of a partial, you can also let the RecordIdentifier do the work if you‘re following its conventions for RecordIdentifier#partial_path. Examples:

 # @account is an Account instance, so it uses the RecordIdentifier to replace
 # <%= render :partial => "accounts/account", :locals => { :account => @buyer } %>
 <%= render :partial => @account %>

 # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
 # <%= render :partial => "posts/post", :collection => @posts %>
 <%= render :partial => @posts %>

Rendering the default case

If you‘re not going to be using any of the options like collections or layouts, you can also use the short-hand defaults of render to render partials. Examples:

 # Instead of <%= render :partial => "account" %>
 <%= render "account" %>

 # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %>
 <%= render "account", :account => @buyer %>

 # @account is an Account instance, so it uses the RecordIdentifier to replace
 # <%= render :partial => "accounts/account", :locals => { :account => @account } %>
 <%= render(@account) %>

 # @posts is an array of Post instances, so it uses the RecordIdentifier to replace
 # <%= render :partial => "posts/post", :collection => @posts %>
 <%= render(@posts) %>

Rendering partials with layouts

Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types of users:

  <%# app/views/users/index.html.erb &>
  Here's the administrator:
  <%= render :partial => "user", :layout => "administrator", :locals => { :user => administrator } %>

  Here's the editor:
  <%= render :partial => "user", :layout => "editor", :locals => { :user => editor } %>

  <%# app/views/users/_user.html.erb &>
  Name: <%= user.name %>

  <%# app/views/users/_administrator.html.erb &>
  <div id="administrator">
    Budget: $<%= user.budget %>
    <%= yield %>
  </div>

  <%# app/views/users/_editor.html.erb &>
  <div id="editor">
    Deadline: <%= user.deadline %>
    <%= yield %>
  </div>

…this will return:

  Here's the administrator:
  <div id="administrator">
    Budget: $<%= user.budget %>
    Name: <%= user.name %>
  </div>

  Here's the editor:
  <div id="editor">
    Deadline: <%= user.deadline %>
    Name: <%= user.name %>
  </div>

You can also apply a layout to a block within any template:

  <%# app/views/users/_chief.html.erb &>
  <% render(:layout => "administrator", :locals => { :user => chief }) do %>
    Title: <%= chief.title %>
  <% end %>

…this will return:

  <div id="administrator">
    Budget: $<%= user.budget %>
    Title: <%= chief.name %>
  </div>

As you can see, the :locals hash is shared between both the partial and its layout.

If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass an array to layout and treat it as an enumerable.

  <%# app/views/users/_user.html.erb &>
  <div class="user">
    Budget: $<%= user.budget %>
    <%= yield user %>
  </div>

  <%# app/views/users/index.html.erb &>
  <% render :layout => @users do |user| %>
    Title: <%= user.title %>
  <% end %>

This will render the layout for each user and yield to the block, passing the user, each time.

You can also yield multiple times in one layout and use block arguments to differentiate the sections.

  <%# app/views/users/_user.html.erb &>
  <div class="user">
    <%= yield user, :header %>
    Budget: $<%= user.budget %>
    <%= yield user, :footer %>
  </div>

  <%# app/views/users/index.html.erb &>
  <% render :layout => @users do |user, section| %>
    <%- case section when :header -%>
      Title: <%= user.title %>
    <%- when :footer -%>
      Deadline: <%= user.deadline %>
    <%- end -%>
  <% end %>


Class: ActionView::ReloadableTemplate

Class | ActionView::ReloadableTemplate
In: | vendor/rails/actionpack/lib/action_view/reloadable_template.rb
Parent: | Template

Methods

mtime new reset_cache_if_stale! stale? undef_my_compiled_methods!

Classes and Modules

Module ActionView::ReloadableTemplate::Unfreezable
Class ActionView::ReloadableTemplate::ReloadablePath
Class ActionView::ReloadableTemplate::TemplateDeleted

Attributes

previously_last_modified [RW]

Public Class methods

new(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 80
80:     def initialize(*args)
81:       super
82:
83:       # we don't ever want to get frozen
84:       extend Unfreezable
85:     end

Public Instance methods

mtime()

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 87
87:     def mtime
88:       File.mtime(filename)
89:     end
reset_cache_if_stale!()

[Source]

     # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 100
100:     def reset_cache_if_stale!
101:       if stale?
102:         flush_cache 'source', 'compiled_source'
103:         undef_my_compiled_methods!
104:         @previously_last_modified = mtime
105:       end
106:       self
107:     end
stale?()

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 93
93:     def stale?
94:       previously_last_modified.nil? || previously_last_modified < mtime
95:     rescue Errno::ENOENT => e
96:       undef_my_compiled_methods!
97:       raise TemplateDeleted
98:     end
undef_my_compiled_methods!()

remove any compiled methods that look like they might belong to me

[Source]

     # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 110
110:     def undef_my_compiled_methods!
111:       ActionView::Base::CompiledTemplates.public_instance_methods.grep(/#{Regexp.escape(method_name_without_locals)}(?:_locals_)?/).each do |m|
112:         ActionView::Base::CompiledTemplates.send(:remove_method, m)
113:       end
114:     end


Class: ActionView::ReloadableTemplate::ReloadablePath

Class | ActionView::ReloadableTemplate::ReloadablePath
In: | vendor/rails/actionpack/lib/action_view/reloadable_template.rb
Parent: | Template::Path

Methods

[] load! new new_request!

Public Class methods

new(path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 9
 9:       def initialize(path)
10:         super
11:         @paths = {}
12:         new_request!
13:       end

Public Instance methods

[](path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 20
20:       def [](path)
21:         if found_template = @paths[path]
22:           begin
23:             found_template.reset_cache_if_stale!
24:           rescue TemplateDeleted
25:             unregister_template(found_template)
26:             self[path]
27:           end
28:         else
29:           load_all_templates_from_dir(templates_dir_from_path(path))
30:           # don't ever hand out a template without running a stale check
31:           (new_template = @paths[path]) && new_template.reset_cache_if_stale!
32:         end
33:       end
load!()

Alias for new_request!

new_request!()

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 15
15:       def new_request!
16:         @disk_cache = {}
17:       end


Class: ActionView::ReloadableTemplate::TemplateDeleted

Class | ActionView::ReloadableTemplate::TemplateDeleted
In: | vendor/rails/actionpack/lib/action_view/reloadable_template.rb
Parent: | ActionView::ActionViewError


Module: ActionView::ReloadableTemplate::Unfreezable

Module | ActionView::ReloadableTemplate::Unfreezable
In: | vendor/rails/actionpack/lib/action_view/reloadable_template.rb

Methods

freeze

Public Instance methods

freeze()

[Source]

    # File vendor/rails/actionpack/lib/action_view/reloadable_template.rb, line 77
77:       def freeze; self; end


Class: ActionView::Template

Class | ActionView::Template
In: | vendor/rails/actionpack/lib/action_view/template.rb
Parent: | Object

Methods

accessible_paths content_type exempt_from_layout exempt_from_layout? format_and_extension load! method_segment mime_type multipart? new path path_without_extension path_without_format_and_extension relative_path render_template source

Included Modules

Renderable

Classes and Modules

Class ActionView::Template::EagerPath
Class ActionView::Template::Path

Attributes

base_path | [RW]
extension | [RW]
filename | [RW]
format | [RW]
load_path | [RW]
locale | [RW]
name | [RW]
template_path | [RW]

Public Class methods

exempt_from_layout(*extensions)

Don‘t render layouts for templates with the given extensions.

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 99
 99:     def self.exempt_from_layout(*extensions)
100:       regexps = extensions.collect do |extension|
101:         extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
102:       end
103:       @@exempt_from_layout.merge(regexps)
104:     end
new(template_path, load_path)

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 110
110:     def initialize(template_path, load_path)
111:       @template_path = template_path.dup
112:       @load_path, @filename = load_path, File.join(load_path, template_path)
113:       @base_path, @name, @locale, @format, @extension = split(template_path)
114:       @base_path.to_s.gsub!(/\/$/, '') # Push to split method
115:
116:       # Extend with partial super powers
117:       extend RenderablePartial if @name =~ /^_/
118:     end

Public Instance methods

accessible_paths()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 120
120:     def accessible_paths
121:       paths = []
122:
123:       if valid_extension?(extension)
124:         paths << path
125:         paths << path_without_extension
126:         if multipart?
127:           formats = format.split(".")
128:           paths << "#{path_without_format_and_extension}.#{formats.first}"
129:           paths << "#{path_without_format_and_extension}.#{formats.second}"
130:         end
131:       else
132:         # template without explicit template handler should only be reachable through its exact path
133:         paths << template_path
134:       end
135:
136:       paths
137:     end
content_type()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 148
148:     def content_type
149:       format.gsub('.', '/')
150:     end
exempt_from_layout?()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 179
179:     def exempt_from_layout?
180:       @@exempt_from_layout.any? { |exempted| path =~ exempted }
181:     end
format_and_extension()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 139
139:     def format_and_extension
140:       (extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
141:     end
load!()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 205
205:     def load!
206:       freeze
207:     end
method_segment()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 188
188:     def method_segment
189:       relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
190:     end
mime_type()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 152
152:     def mime_type
153:       Mime::Type.lookup_by_extension(format) if format && defined?(::Mime)
154:     end
multipart?()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 144
144:     def multipart?
145:       format && format.include?('.')
146:     end
path()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 157
157:     def path
158:       [base_path, [name, locale, format, extension].compact.join('.')].compact.join('/')
159:     end
path_without_extension()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 162
162:     def path_without_extension
163:       [base_path, [name, locale, format].compact.join('.')].compact.join('/')
164:     end
path_without_format_and_extension()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 167
167:     def path_without_format_and_extension
168:       [base_path, [name, locale].compact.join('.')].compact.join('/')
169:     end
relative_path()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 172
172:     def relative_path
173:       path = File.expand_path(filename)
174:       path.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '') if defined?(RAILS_ROOT)
175:       path
176:     end
render_template(view, local_assigns = {})

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 193
193:     def render_template(view, local_assigns = {})
194:       render(view, local_assigns)
195:     rescue Exception => e
196:       raise e unless filename
197:       if TemplateError === e
198:         e.sub_template_of(self)
199:         raise e
200:       else
201:         raise TemplateError.new(self, view.assigns, e)
202:       end
203:     end
source()

[Source]

     # File vendor/rails/actionpack/lib/action_view/template.rb, line 183
183:     def source
184:       File.read(filename)
185:     end


Class: ActionView::Template::EagerPath

Class | ActionView::Template::EagerPath
In: | vendor/rails/actionpack/lib/action_view/template.rb
Parent: | Path

Methods

[] load!

Public Instance methods

[](path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 74
74:       def [](path)
75:         load! unless @loaded
76:         @paths[path]
77:       end
load!()

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 60
60:       def load!
61:         return if @loaded
62:
63:         @paths = {}
64:         templates_in_path do |template|
65:           template.load!
66:           template.accessible_paths.each do |path|
67:             @paths[path] = template
68:           end
69:         end
70:         @paths.freeze
71:         @loaded = true
72:       end


Class: ActionView::Template::Path

Class | ActionView::Template::Path
In: | vendor/rails/actionpack/lib/action_view/template.rb
Parent: | Object

Methods

== [] eql? load! new new_and_loaded to_s to_str

Attributes

path | [R]
paths | [R]

Public Class methods

new(path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 7
 7:       def initialize(path)
 8:         raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
 9:         @path = (path.ends_with?(File::SEPARATOR) ? path.to(-2) : path).freeze
10:       end
new_and_loaded(path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 47
47:       def self.new_and_loaded(path)
48:         returning new(path) do |path|
49:           path.load!
50:         end
51:       end

Public Instance methods

==(path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 24
24:       def ==(path)
25:         to_str == path.to_str
26:       end
[](path)

Returns a ActionView::Template object for the given path string. The input path should be relative to the view path directory, +hello/index.html.erb+. This method also has a special exception to match partial file names without a handler extension. So +hello/index.html+ will match the first template it finds with a known template extension, +hello/index.html.erb+. Template extensions should not be confused with format extensions html, js, xml, etc. A format must be supplied to match a formated file. +hello/index+ will never match +hello/index.html.erb+.

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 41
41:       def [](path)
42:       end
eql?(path)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 28
28:       def eql?(path)
29:         to_str == path.to_str
30:       end
load!()

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 44
44:       def load!
45:       end
to_s()

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 12
12:       def to_s
13:         if defined?(RAILS_ROOT)
14:           path.to_s.sub(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '')
15:         else
16:           path.to_s
17:         end
18:       end
to_str()

[Source]

    # File vendor/rails/actionpack/lib/action_view/template.rb, line 20
20:       def to_str
21:         path.to_str
22:       end


Class: ActionView::TemplateHandler

Class | ActionView::TemplateHandler
In: | vendor/rails/actionpack/lib/action_view/template_handler.rb
Parent: | Object

Methods

call new render

Public Class methods

call(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 22
22:     def self.call(template)
23:       "#{name}.new(self).render(template, local_assigns)"
24:     end
new(view = nil)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 26
26:     def initialize(view = nil)
27:       @view = view
28:     end

Public Instance methods

render(template, local_assigns)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 30
30:     def render(template, local_assigns)
31:       raise "Need to implement #{self.class.name}#render(template, local_assigns)"
32:     end


Class: ActionView::TemplateHandlers::Builder

Class | ActionView::TemplateHandlers::Builder
In: | vendor/rails/actionpack/lib/action_view/template_handlers/builder.rb
Parent: | TemplateHandler

Methods

compile

Included Modules

Compilable

Public Instance methods

compile(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handlers/builder.rb, line 8
 8:       def compile(template)
 9:         "_set_controller_content_type(Mime::XML);" +
10:           "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
11:           "self.output_buffer = xml.target!;" +
12:           template.source +
13:           ";xml.target!;"
14:       end


Module: ActionView::TemplateHandlers::Compilable

Module | ActionView::TemplateHandlers::Compilable
In: | vendor/rails/actionpack/lib/action_view/template_handler.rb

Methods

compile included

Classes and Modules

Module ActionView::TemplateHandlers::Compilable::ClassMethods

Public Class methods

included(base)

[Source]

   # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 5
5:       def self.included(base)
6:         base.extend(ClassMethods)
7:       end

Public Instance methods

compile(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 15
15:       def compile(template)
16:          raise "Need to implement #{self.class.name}#compile(template)"
17:        end


Module: ActionView::TemplateHandlers::Compilable::ClassMethods

Module | ActionView::TemplateHandlers::Compilable::ClassMethods
In: | vendor/rails/actionpack/lib/action_view/template_handler.rb

Methods

call

Public Instance methods

call(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handler.rb, line 10
10:         def call(template)
11:           new.compile(template)
12:         end


Class: ActionView::TemplateHandlers::ERB

Class | ActionView::TemplateHandlers::ERB
In: | vendor/rails/actionpack/lib/action_view/template_handlers/erb.rb
Parent: | TemplateHandler

Methods

compile

Included Modules

Compilable

Public Instance methods

compile(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handlers/erb.rb, line 13
13:       def compile(template)
14:         src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
15:
16:         # Ruby 1.9 prepends an encoding to the source. However this is
17:         # useless because you can only set an encoding on the first line
18:         RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
19:       end


Class: ActionView::TemplateHandlers::RJS

Class | ActionView::TemplateHandlers::RJS
In: | vendor/rails/actionpack/lib/action_view/template_handlers/rjs.rb
Parent: | TemplateHandler

Methods

compile

Included Modules

Compilable

Public Instance methods

compile(template)

[Source]

    # File vendor/rails/actionpack/lib/action_view/template_handlers/rjs.rb, line 6
 6:       def compile(template)
 7:         "@template_format = :html;" +
 8:         "controller.response.content_type ||= Mime::JS;" +
 9:           "update_page do |page|;#{template.source}\nend"
10:       end


Class: ActionView::TestCase

Class | ActionView::TestCase
In: | vendor/rails/actionpack/lib/action_view/test_case.rb
Parent: | ActiveSupport::TestCase

Methods

determine_default_helper_class helper_class setup_with_helper_class tests

Included Modules

ActionController::TestCase::Assertions
ActionController::TestProcess
ActionView::Helpers
ActionController::PolymorphicRoutes
ActionController::RecordIdentifier

Classes and Modules

Class ActionView::TestCase::TestController

Attributes

output_buffer [RW]

Public Class methods

determine_default_helper_class(name)

[Source]

    # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 44
44:       def determine_default_helper_class(name)
45:         name.sub(/Test$/, '').constantize
46:       rescue NameError
47:         nil
48:       end
helper_class()

[Source]

    # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 36
36:       def helper_class
37:         if current_helper_class = read_inheritable_attribute(:helper_class)
38:           current_helper_class
39:         else
40:           self.helper_class = determine_default_helper_class(name)
41:         end
42:       end
tests(helper_class)

[Source]

    # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 32
32:       def tests(helper_class)
33:         self.helper_class = helper_class
34:       end

Public Instance methods

setup_with_helper_class()

[Source]

    # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 57
57:     def setup_with_helper_class
58:       if helper_class && !self.class.ancestors.include?(helper_class)
59:         self.class.send(:include, helper_class)
60:       end
61:
62:       self.output_buffer = ''
63:     end


Class: ActionView::TestCase::TestController

Class | ActionView::TestCase::TestController
In: | vendor/rails/actionpack/lib/action_view/test_case.rb
Parent: | ActionController::Base

Methods

new

Attributes

params | [RW]
request | [RW]
response | [RW]

Public Class methods

new()

[Source]

    # File vendor/rails/actionpack/lib/action_view/test_case.rb, line 68
68:       def initialize
69:         @request = ActionController::TestRequest.new
70:         @response = ActionController::TestResponse.new
71:
72:         @params = {}
73:         send(:initialize_current_url)
74:       end


File: base.rb

base.rb

Path: | vendor/rails/actionpack/lib/action_view/base.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: util.rb

util.rb

Path: | vendor/rails/actionpack/lib/action_view/erb/util.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

erb


File: helpers.rb

helpers.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: active_record_helper.rb

active_record_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi action_view/helpers/form_helper


File: asset_tag_helper.rb

asset_tag_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi action_view/helpers/url_helper action_view/helpers/tag_helper


File: atom_feed_helper.rb

atom_feed_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/atom_feed_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

set


File: benchmark_helper.rb

benchmark_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

benchmark


File: cache_helper.rb

cache_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: capture_helper.rb

capture_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: date_helper.rb

date_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

date action_view/helpers/tag_helper


File: debug_helper.rb

debug_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009


File: form_helper.rb

form_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb
Last Update: | Sun Mar 15 23:31:32 -0500 2009

Required files

cgi action_view/helpers/date_helper action_view/helpers/tag_helper action_view/helpers/form_tag_helper


File: form_options_helper.rb

form_options_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

cgi erb action_view/helpers/form_helper


File: form_tag_helper.rb

form_tag_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

cgi action_view/helpers/tag_helper


File: javascript_helper.rb

javascript_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/tag_helper action_view/helpers/prototype_helper


File: number_helper.rb

number_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: prototype_helper.rb

prototype_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

set active_support/json


File: record_identification_helper.rb

record_identification_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/record_identification_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: record_tag_helper.rb

record_tag_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/record_tag_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: sanitize_helper.rb

sanitize_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/sanitize_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/tag_helper


File: scriptaculous_helper.rb

scriptaculous_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/javascript_helper active_support/json


File: tag_helper.rb

tag_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/erb/util set


File: text_helper.rb

text_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/tag_helper


File: translation_helper.rb

translation_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/translation_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/tag_helper


File: url_helper.rb

url_helper.rb

Path: | vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

action_view/helpers/javascript_helper


File: inline_template.rb

inline_template.rb

Path: | vendor/rails/actionpack/lib/action_view/inline_template.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: partials.rb

partials.rb

Path: | vendor/rails/actionpack/lib/action_view/partials.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: paths.rb

paths.rb

Path: | vendor/rails/actionpack/lib/action_view/paths.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: reloadable_template.rb

reloadable_template.rb

Path: | vendor/rails/actionpack/lib/action_view/reloadable_template.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: renderable.rb

renderable.rb

Path: | vendor/rails/actionpack/lib/action_view/renderable.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

encoding: utf-8


File: renderable_partial.rb

renderable_partial.rb

Path: | vendor/rails/actionpack/lib/action_view/renderable_partial.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: template.rb

template.rb

Path: | vendor/rails/actionpack/lib/action_view/template.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: template_error.rb

template_error.rb

Path: | vendor/rails/actionpack/lib/action_view/template_error.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: template_handler.rb

template_handler.rb

Path: | vendor/rails/actionpack/lib/action_view/template_handler.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Legacy TemplateHandler stub


File: template_handlers.rb

template_handlers.rb

Path: | vendor/rails/actionpack/lib/action_view/template_handlers.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: builder.rb

builder.rb

Path: | vendor/rails/actionpack/lib/action_view/template_handlers/builder.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

builder


File: erb.rb

erb.rb

Path: | vendor/rails/actionpack/lib/action_view/template_handlers/erb.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: rjs.rb

rjs.rb

Path: | vendor/rails/actionpack/lib/action_view/template_handlers/rjs.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009


File: test_case.rb

test_case.rb

Path: | vendor/rails/actionpack/lib/action_view/test_case.rb
Last Update: | Sun Mar 15 23:31:33 -0500 2009

Required files

active_support/test_case


File: README

README

Path: | vendor/rails/actionmailer/README
Last Update: | Sun Mar 15 23:31:35 -0500 2009

Action Mailer — Easy email delivery and testing

Action Mailer is a framework for designing email-service layers. These layers are used to consolidate code for sending out forgotten passwords, welcome wishes on signup, invoices for billing, and any other use case that requires a written notification to either a person or another system.

Additionally, an Action Mailer class can be used to process incoming email, such as allowing a weblog to accept new posts from an email (which could even have been sent from a phone).

Sending emails

The framework works by setting up all the email details, except the body, in methods on the service layer. Subject, recipients, sender, and timestamp are all set up this way. An example of such a method:

  def signed_up(recipient)
    recipients recipient
    subject    "[Signed up] Welcome #{recipient}"
    from       "system@loudthinking.com"
    body       :recipient => recipient
  end

The body of the email is created by using an Action View template (regular ERb) that has the content of the body hash parameter available as instance variables. So the corresponding body template for the method above could look like this:

  Hello there,

  Mr. <%= @recipient %>

And if the recipient was given as "david@loudthinking.com", the email generated would look like this:

  Date: Sun, 12 Dec 2004 00:00:00 +0100
  From: system@loudthinking.com
  To: david@loudthinking.com
  Subject: [Signed up] Welcome david@loudthinking.com

  Hello there,

  Mr. david@loudthinking.com

You never actually call the instance methods like signed_up directly. Instead, you call class methods like deliver_* and create_* that are automatically created for each instance method. So if the signed_up method sat on ApplicationMailer, it would look like this:

  ApplicationMailer.create_signed_up("david@loudthinking.com")  # => tmail object for testing
  ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email
  ApplicationMailer.new.signed_up("david@loudthinking.com")     # won't work!

Receiving emails

To receive emails, you need to implement a public instance method called receive that takes a tmail object as its single parameter. The Action Mailer framework has a corresponding class method, which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns into the tmail object and calls the receive instance method.

Example:

  class Mailman < ActionMailer::Base
    def receive(email)
      page = Page.find_by_address(email.to.first)
      page.emails.create(
        :subject => email.subject, :body => email.body
      )

      if email.has_attachments?
        for attachment in email.attachments
          page.attachments.create({
            :file => attachment, :description => email.subject
          })
        end
      end
    end
  end

This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the trivial case like this:

  ./script/runner 'Mailman.receive(STDIN.read)'

However, invoking Rails in the runner for each mail to be received is very resource intensive. A single instance of Rails should be run within a daemon if it is going to be utilized to process more than just a limited number of email.

Configuration

The Base class has the full list of configuration options. Here‘s an example:

  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.yourserver.com', # default: localhost
    :port           => '25',                  # default: 25
    :user_name      => 'user',
    :password       => 'pass',
    :authentication => :plain                 # :plain, :login or :cram_md5
  }

Dependencies

Action Mailer requires that the Action Pack is either available to be required immediately or is accessible as a GEM.

Bundled software

  • tmail 0.10.8 by Minero Aoki released under LGPL Read more on i.loveruby.net/en/prog/tmail.html
  • Text::Format 0.63 by Austin Ziegler released under OpenSource Read more on www.halostatue.ca/ruby/Text__Format.html

Download

The latest version of Action Mailer can be found at

  • rubyforge.org/project/showfiles.php?group_id=361

Documentation can be found at

  • actionmailer.rubyonrails.org

Installation

You can install Action Mailer with the following command.

  % [sudo] ruby install.rb

from its distribution directory.

License

Action Mailer is released under the MIT license.

Support

The Action Mailer homepage is www.rubyonrails.org. You can find the Action Mailer RubyForge page at rubyforge.org/projects/actionmailer. And as Jim from Rake says:

   Feel free to submit commits or feature requests.  If you send a patch,
   remember to update the corresponding unit tests.  If fact, I prefer
   new feature to be submitted in the form of new unit tests.


Class: ActionMailer::Base

Class | ActionMailer::Base
In: | vendor/rails/actionmailer/lib/action_mailer/base.rb
Parent: | Object

Action Mailer allows you to send email from your application using a mailer model and views.

Mailer Models

To use Action Mailer, you need to create a mailer model.

  $ script/generate mailer Notifier

The generated model inherits from ActionMailer::Base. Emails are defined by creating methods within the model which are then used to set variables to be used in the mail template, to change options on the mail, or to add attachments.

Examples:

 class Notifier < ActionMailer::Base
   def signup_notification(recipient)
     recipients recipient.email_address_with_name
     bcc        ["bcc@example.com", "Order Watcher <watcher@example.com>"]
     from       "system@example.com"
     subject    "New account information"
     body       :account => recipient
   end
 end

Mailer methods have the following configuration methods available.

  • recipients - Takes one or more email addresses. These addresses are where your email will be delivered to. Sets the To: header.
  • subject - The subject of your email. Sets the Subject: header.
  • from - Who the email you are sending is from. Sets the From: header.
  • cc - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the Cc: header.
  • bcc - Takes one or more email addresses. These addresses will receive a blind carbon copy of your email. Sets the Bcc: header.
  • reply_to - Takes one or more email addresses. These addresses will be listed as the default recipients when replying to your email. Sets the Reply-To: header.
  • sent_on - The date on which the message was sent. If not set, the header wil be set by the delivery agent.
  • content_type - Specify the content type of the message. Defaults to text/plain.
  • headers - Specify additional headers to be set for the message, e.g. headers ‘X-Mail-Count’ => 107370.

When a headers ‘return-path‘ is specified, that value will be used as the ‘envelope from’ address. Setting this is useful when you want delivery notifications sent to a different address than the one in from.

The body method has special behavior. It takes a hash which generates an instance variable named after each key in the hash containing the value that that key points to.

So, for example, body :account => recipient would result in an instance variable @account with the value of recipient being accessible in the view.

Mailer views

Like Action Controller, each mailer class has a corresponding view directory in which each method of the class looks for a template with its name. To define a template to be used with a mailing, create an .erb file with the same name as the method in your mailer model. For example, in the mailer defined above, the template at app/views/notifier/signup_notification.erb would be used to generate the email.

Variables defined in the model are accessible as instance variables in the view.

Emails by default are sent in plain text, so a sample view for our model example might look like this:

  Hi <%= @account.name %>,
  Thanks for joining our service! Please check back often.

You can even use Action Pack helpers in these views. For example:

  You got a new note!
  <%= truncate(note.body, 25) %>

Generating URLs

URLs can be generated in mailer views using url_for or named routes. Unlike controllers from Action Pack, the mailer instance doesn‘t have any context about the incoming request, so you‘ll need to provide all of the details needed to generate a URL.

When using url_for you‘ll need to provide the :host, :controller, and :action:

  <%= url_for(:host => "example.com", :controller => "welcome", :action => "greeting") %>

When using named routes you only need to supply the :host:

  <%= users_url(:host => "example.com") %>

You will want to avoid using the name_of_route_path form of named routes because it doesn‘t make sense to generate relative URLs in email messages.

It is also possible to set a default host that will be used in all mailers by setting the :host option in the ActionMailer::Base.default_url_options hash as follows:

  ActionMailer::Base.default_url_options[:host] = "example.com"

This can also be set as a configuration option in config/environment.rb:

  config.action_mailer.default_url_options = { :host => "example.com" }

If you do decide to set a default :host for your mailers you will want to use the :only_path => false option when using url_for. This will ensure that absolute URLs are generated because the url_for view helper will, by default, generate relative URLs when a :host option isn‘t explicitly provided.

Sending mail

Once a mailer action and template are defined, you can deliver your message or create it and save it for delivery later:

  Notifier.deliver_signup_notification(david) # sends the email
  mail = Notifier.create_signup_notification(david)  # => a tmail object
  Notifier.deliver(mail)

You never instantiate your mailer class. Rather, your delivery instance methods are automatically wrapped in class methods that start with the word deliver_ followed by the name of the mailer method that you would like to deliver. The signup_notification method defined above is delivered by invoking Notifier.deliver_signup_notification.

HTML email

To send mail as HTML, make sure your view (the .erb file) generates HTML and set the content type to html.

  class MyMailer < ActionMailer::Base
    def signup_notification(recipient)
      recipients   recipient.email_address_with_name
      subject      "New account information"
      from         "system@example.com"
      body         :account => recipient
      content_type "text/html"
    end
  end

Multipart email

You can explicitly specify multipart messages:

  class ApplicationMailer < ActionMailer::Base
    def signup_notification(recipient)
      recipients      recipient.email_address_with_name
      subject         "New account information"
      from            "system@example.com"
      content_type    "multipart/alternative"

      part :content_type => "text/html",
        :body => render_message("signup-as-html", :account => recipient)

      part "text/plain" do |p|
        p.body = render_message("signup-as-plain", :account => recipient)
        p.transfer_encoding = "base64"
      end
    end
  end

Multipart messages can also be used implicitly because Action Mailer will automatically detect and use multipart templates, where each template is named after the name of the action, followed by the content type. Each such detected template will be added as separate part to the message.

For example, if the following templates existed:

  • signup_notification.text.plain.erb
  • signup_notification.text.html.erb
  • signup_notification.text.xml.builder
  • signup_notification.text.x-yaml.erb

Each would be rendered and added as a separate part to the message, with the corresponding content type. The content type for the entire message is automatically set to multipart/alternative, which indicates that the email contains multiple different representations of the same email body. The same body hash is passed to each template.

Implicit template rendering is not performed if any attachments or parts have been added to the email. This means that you‘ll have to manually add each part to the email and set the content type of the email to multipart/alternative.

Attachments

Attachments can be added by using the attachment method.

Example:

  class ApplicationMailer < ActionMailer::Base
    # attachments
    def signup_notification(recipient)
      recipients      recipient.email_address_with_name
      subject         "New account information"
      from            "system@example.com"

      attachment :content_type => "image/jpeg",
        :body => File.read("an-image.jpg")

      attachment "application/pdf" do |a|
        a.body = generate_your_pdf_here()
      end
    end
  end

Configuration options

These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates"

  • template_root - Determines the base from which template references will be made.
  • logger - the logger is used for generating information on the mailing run if available. Can be set to nil for no logging. Compatible with both Ruby‘s own Logger and Log4r loggers.
  • smtp_settings - Allows detailed configuration for :smtp delivery method:
    • :address - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
    • :port - On the off chance that your mail server doesn‘t run on port 25, you can change it.
    • :domain - If you need to specify a HELO domain, you can do it here.
    • :user_name - If your mail server requires authentication, set the username in this setting.
    • :password - If your mail server requires authentication, set the password in this setting.
    • :authentication - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of :plain, :login, :cram_md5.
    • :enable_starttls_auto - When set to true, detects if STARTTLS is enabled in your SMTP server and starts to use it. It works only on Ruby >= 1.8.7 and Ruby >= 1.9. Default is true.
  • sendmail_settings - Allows you to override options for the :sendmail delivery method.
    • :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail.
    • :arguments - The command line arguments. Defaults to -i -t.
  • raise_delivery_errors - Whether or not errors should be raised if the email fails to be delivered.
  • delivery_method - Defines a delivery method. Possible values are :smtp (default), :sendmail, and :test.
  • perform_deliveries - Determines whether deliver_* methods are actually carried out. By default they are, but this can be turned off to help functional testing.
  • deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.
  • default_charset - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also pick a different charset from inside a method with charset.
  • default_content_type - The default content type used for the main part of the message. Defaults to "text/plain". You can also pick a different content type from inside a method with content_type.
  • default_mime_version - The default mime version used for the message. Defaults to 1.0. You can also pick a different value from inside a method with mime_version.
  • default_implicit_parts_order - When a message is built implicitly (i.e. multiple parts are assembled from templates which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to ["text/html", "text/enriched", "text/plain"]. Items that appear first in the array have higher priority in the mail client and appear last in the mime encoded message. You can also pick a different order from inside a method with implicit_parts_order.

Methods

controller_name controller_path deliver deliver! mailer_name mailer_name mailer_name= receive template_root template_root=

Included Modules

AdvAttrAccessor PartContainer Quoting Utils ActionController::UrlWriter ActionController::Layout

Attributes

action_name | [R] |
default_template_name | [R] |
mail | [R] | The mail object instance referenced by this mailer.
mailer_name | [W] |
template_name | [R] |

Public Class methods

deliver(mail)

Deliver the given mail object directly. This can be used to deliver a preconstructed mail object, like:

  email = MyMailer.create_some_mail(parameters)
  email.set_some_obscure_header "frobnicate"
  MyMailer.deliver(email)

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 428
428:       def deliver(mail)
429:         new.deliver!(mail)
430:       end
mailer_name()

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 379
379:       def mailer_name
380:         @mailer_name ||= name.underscore
381:       end
receive(raw_email)

Receives a raw email, parses it into an email object, decodes it, instantiates a new mailer, and passes the email object to the mailer object‘s receive method. If you want your mailer to be able to process incoming messages, you‘ll need to implement a receive method that accepts the email object as a parameter:

  class MyMailer < ActionMailer::Base
    def receive(mail)
      ...
    end
  end

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 415
415:       def receive(raw_email)
416:         logger.info "Received mail:\n #{raw_email}" unless logger.nil?
417:         mail = TMail::Mail.parse(raw_email)
418:         mail.base64_decode
419:         new.receive(mail)
420:       end
template_root()

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 432
432:       def template_root
433:         self.view_paths && self.view_paths.first
434:       end
template_root=(root)

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 436
436:       def template_root=(root)
437:         self.view_paths = ActionView::Base.process_view_paths(root)
438:       end

Public Instance methods

controller_name(value = nil)

Alias for mailer_name

controller_path(value = nil)

Alias for mailer_name

deliver!(mail = @mail)

Delivers a TMail::Mail object. By default, it delivers the cached mail object (from the create! method). If no cached mail object exists, and no alternate has been given as the parameter, this will fail.

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 515
515:     def deliver!(mail = @mail)
516:       raise "no mail object available for delivery!" unless mail
517:       unless logger.nil?
518:         logger.info  "Sent mail to #{Array(recipients).join(', ')}"
519:         logger.debug "\n#{mail.encoded}"
520:       end
521:
522:       begin
523:         __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
524:       rescue Exception => e  # Net::SMTP errors or sendmail pipe errors
525:         raise e if raise_delivery_errors
526:       end
527:
528:       return mail
529:     end
mailer_name(value = nil)

Override the mailer name, which defaults to an inflected version of the mailer‘s class name. If you want to use a template in a non-standard location, you can use this to specify that location.

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 360
360:     def mailer_name(value = nil)
361:       if value
362:         self.mailer_name = value
363:       else
364:         self.class.mailer_name
365:       end
366:     end
mailer_name=(value)

[Source]

     # File vendor/rails/actionmailer/lib/action_mailer/base.rb, line 368
368:     def mailer_name=(value)
369:       self.class.mailer_name = value
370:     end


File: base.rb

base.rb

Path: | vendor/rails/actionmailer/lib/action_mailer/base.rb
Last Update: | Sun Mar 15 23:31:35 -0500 2009


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/actionmailer/CHANGELOG
Last Update: | Sun Mar 15 23:31:35 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP 1842 [Matt Jones]
  • Fixed RFC-2045 quoted-printable bug 1421 [squadette]
  • Fixed that no body charset would be set when there are attachments present 740 [Paweł Kondzior]

*2.2.1 [RC2] (November 14th, 2008)*

  • Turn on STARTTLS if it is available in Net::SMTP (added in Ruby 1.8.7) and the SMTP server supports it (This is required for Gmail‘s SMTP server) 1336 [Grant Hollingworth]

*2.2.0 [RC1] (October 24th, 2008)*

  • Add layout functionality to mailers [Pratik Naik]

    Mailer layouts behaves just like controller layouts, except layout names need to have ‘_mailer’ postfix for them to be automatically picked up.

*2.1.0 (May 31st, 2008)*

  • Fixed that a return-path header would be ignored 7572 [joost]
  • Less verbose mail logging: just recipients for :info log level; the whole email for :debug only. 8000 [iaddict, Tarmo Tänav]
  • Updated TMail to version 1.2.1 [Mikel Lindsaar]
  • Fixed that you don‘t have to call super in ActionMailer::TestCase#setup 10406 [jamesgolick]

*2.0.2* (December 16th, 2007)

  • Included in Rails 2.0.2

*2.0.1* (December 7th, 2007)

  • Update ActionMailer so it treats ActionView the same way that ActionController does. Closes 10244 [Rick Olson]
    • Pass the template_root as an array as ActionView‘s view_path
    • Request templates with the "#{mailer_name}/#{action}" as opposed to just "#{action}"
  • Fixed that partials would be broken when using text.plain.erb as the extension 10130 [java]
  • Update README to use new smtp settings configuration API. Closes 10060 [psq]
  • Allow ActionMailer subclasses to individually set their delivery method (so two subclasses can have different delivery methods) 10033 [Zach Dennis]
  • Update TMail to v1.1.0. Use an updated version of TMail if available. [Mikel Lindsaar]
  • Introduce a new base test class for testing Mailers. ActionMailer::TestCase [Michael Koziarski]
  • Fix silent failure of rxml templates. 9879 [jstewart]
  • Fix attachment decoding when using the TMail C extension. 7861 [orangechicken]
  • Increase mail delivery test coverage. 8692 [Kamal Fariz Mahyuddin]
  • Register alternative template engines using ActionMailer::Base.register_template_extension(‘haml’). 7534 [cwd, Josh Peek]
  • Only load ActionController::UrlWriter if ActionController is present [Rick Olson]
  • Make sure parsed emails recognized attachments nested inside multipart parts. 6714 [Jamis Buck]
  • Allow mailer actions named send by using send internally. 6467 [iGEL]
  • Add assert_emails and assert_no_emails to test the number of emails delivered. 6479 [Jonathan Viney]
      # Assert total number of emails delivered:
  assert_emails 0
  ContactMailer.deliver_contact
  assert_emails 1

  # Assert number of emails delivered within a block:
  assert_emails 1 do
    post :signup, :name => 'Jonathan'
  end

*1.3.3* (March 12th, 2007)

  • Depend on Action Pack 1.13.3

*1.3.2* (February 5th, 2007)

  • Deprecate server_settings renaming it to smtp_settings, add sendmail_settings to allow you to override the arguments to and location of the sendmail executable. [Michael Koziarski]

*1.3.1* (January 16th, 2007)

  • Depend on Action Pack 1.13.1

*1.3.0* (January 16th, 2007)

  • Make mime version default to 1.0. closes 2323 [ror@andreas-s.net]
  • Make sure quoted-printable text is decoded correctly when only portions of the text are encoded. closes 3154. [jon@siliconcircus.com]
  • Make sure DOS newlines in quoted-printable text are normalized to unix newlines before unquoting. closes 4166 and 4452. [Jamis Buck]
  • Fixed that iconv decoding should catch InvalidEncoding 3153 [jon@siliconcircus.com]
  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Automatically included ActionController::UrlWriter, such that URL generation can happen within ActionMailer controllers. [David Heinemeier Hansson]
  • Replace Reloadable with Reloadable::Deprecated. [Nicholas Seckar]
  • Mailer template root applies to a class and its subclasses rather than acting globally. 5555 [somekool@gmail.com]
  • Resolve action naming collision. 5520 [ssinghi@kreeti.com]
  • ActionMailer::Base documentation rewrite. Closes 4991 [Kevin Clark, Marcel Molina Jr.]
  • Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Correct spurious documentation example code which results in a SyntaxError. [Marcel Molina Jr.]

*1.2.1* (April 6th, 2006)

  • Be part of Rails 1.1.1

*1.2.0* (March 27th, 2006)

  • Nil charset caused subject line to be improperly quoted in implicitly multipart messages 2662 [ehalvorsen+rails@runbox.com]
  • Parse content-type apart before using it so that sub-parts of the header can be set correctly 2918 [Jamis Buck]
  • Make custom headers work in subparts 4034 [elan@bluemandrill.com]
  • Template paths with dot chars in them no longer mess up implicit template selection for multipart messages 3332 [Chad Fowler]
  • Make sure anything with content-disposition of "attachment" is passed to the attachment presenter when parsing an email body [Jamis Buck]
  • Make sure TMail#attachments includes anything with content-disposition of "attachment", regardless of content-type [Jamis Buck]

*1.1.5* (December 13th, 2005)

  • Become part of Rails 1.0

*1.1.4* (December 7th, 2005)

  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]
  • Stricter matching for implicitly multipart filenames excludes files ending in unsupported extensions (such as foo.rhtml.bak) and without a two-part content type (such as foo.text.rhtml or foo.text.really.plain.rhtml). 2398 [Dave Burt <dave@burt.id.au>, Jeremy Kemper]

*1.1.3* (November 7th, 2005)

  • Allow Mailers to have custom initialize methods that set default instance variables for all mail actions 2563 [mrj@bigpond.net.au]

*1.1.2* (October 26th, 2005)

  • Upgraded to Action Pack 1.10.2

*1.1.1* (October 19th, 2005)

  • Upgraded to Action Pack 1.10.1

*1.1.0* (October 16th, 2005)

  • Update and extend documentation (rdoc)
  • Minero Aoki made TMail available to Rails/ActionMailer under the MIT license (instead of LGPL) [RubyConf ‘05]
  • Austin Ziegler made Text::Simple available to Rails/ActionMailer under a MIT-like licens [See rails ML, subject "Text::Format Licence Exception" on Oct 15, 2005]
  • Fix vendor require paths to prevent files being required twice
  • Don‘t add charset to content-type header for a part that contains subparts (for AOL compatibility) 2013 [John Long]
  • Preserve underscores when unquoting message bodies 1930
  • Encode multibyte characters correctly 1894
  • Multipart messages specify a MIME-Version header automatically 2003 [John Long]
  • Add a unified render method to ActionMailer (delegates to ActionView::Base#render)
  • Move mailer initialization to a separate (overridable) method, so that subclasses may alter the various defaults 1727
  • Look at content-location header (if available) to determine filename of attachments 1670
  • ActionMailer::Base.deliver(email) had been accidentally removed, but was documented in the Rails book 1849
  • Fix problem with sendmail delivery where headers should be delimited by \n characters instead of \r\n, which confuses some mail readers 1742 [Kent Sibilev]

*1.0.1* (11 July, 2005)

  • Bind to Action Pack 1.9.1

*1.0.0* (6 July, 2005)

  • Avoid adding nil header values 1392
  • Better multipart support with implicit multipart/alternative and sorting of subparts [John Long]
  • Allow for nested parts in multipart mails 1570 [Flurin Egger]
  • Normalize line endings in outgoing mail bodies to "\n" 1536 [John Long]
  • Allow template to be explicitly specified 1448 [tuxie@dekadance.se]
  • Allow specific "multipart/xxx" content-type to be set on multipart messages 1412 [Flurin Egger]
  • Unquoted @ characters in headers are now accepted in spite of RFC 822 1206
  • Helper support (borrowed from ActionPack)
  • Silently ignore Errno::EINVAL errors when converting text.
  • Don‘t cause an error when parsing an encoded attachment name 1340 [lon@speedymac.com]
  • Nested multipart message parts are correctly processed in TMail::Mail#body
  • BCC headers are removed when sending via SMTP 1402
  • Added ‘content_type’ accessor, to allow content type to be set on a per-message basis. content_type defaults to "text/plain".
  • Silently ignore Iconv::IllegalSequence errors when converting text 1341 [lon@speedymac.com]
  • Support attachments and multipart messages.
  • Added new accessors for the various mail properties.
  • Fix to only perform the charset conversion if a ‘from’ and a ‘to’ charset are given (make no assumptions about what the charset was) 1276 [Jamis Buck]
  • Fix attachments and content-type problems 1276 [Jamis Buck]
  • Fixed the TMail#body method to look at the content-transfer-encoding header and unquote the body according to the rules it specifies 1265 [Jamis Buck]
  • Added unquoting even if the iconv lib can‘t be loaded—in that case, only the charset conversion is skipped 1265 [Jamis Buck]
  • Added automatic decoding of base64 bodies 1214 [Jamis Buck]
  • Added that delivery errors are caught in a way so the mail is still returned whether the delivery was successful or not
  • Fixed that email address like "Jamis Buck, M.D." <wild.medicine@example.net> would cause the quoter to generate emails resulting in "bad address" errors from the mail server 1220 [Jamis Buck]

*0.9.1* (20th April, 2005)

  • Depend on Action Pack 1.8.1

*0.9.0* (19th April, 2005)

  • Added that deliver_* will now return the email that was sent
  • Added that quoting to UTF-8 only happens if the characters used are in that range 955 [Jamis Buck]
  • Fixed quoting for all address headers, not just to 955 [Jamis Buck]
  • Fixed unquoting of emails that doesn‘t have an explicit charset 1036 [wolfgang@stufenlos.net]

*0.8.1* (27th March, 2005)

  • Fixed that if charset was found that the end of a mime part declaration TMail would throw an error 919 [lon@speedymac.com]
  • Fixed that TMail::Unquoter would fail to recognize quoting method if it was in lowercase 919 [lon@speedymac.com]
  • Fixed that TMail::Encoder would fail when it attempts to parse e-mail addresses which are encoded using something other than the messages encoding method 919 [lon@speedymac.com]
  • Added rescue for missing iconv library and throws warnings if subject/body is called on a TMail object without it instead

*0.8.0* (22th March, 2005)

  • Added framework support for processing incoming emails with an Action Mailer class. See example in README.

*0.7.1* (7th March, 2005)

  • Bind to newest Action Pack (1.5.1)

*0.7.0* (24th February, 2005)

  • Added support for charsets for both subject and body. The default charset is now UTF-8 673 [Jamis Buck]. Examples:
      def iso_charset(recipient)
    @recipients = recipient
    @subject    = "testing iso charsets"
    @from       = "system@loudthinking.com"
    @body       = "Nothing to see here."
    @charset    = "iso-8859-1"
  end

  def unencoded_subject(recipient)
    @recipients = recipient
    @subject    = "testing unencoded subject"
    @from       = "system@loudthinking.com"
    @body       = "Nothing to see here."
    @encode_subject = false
    @charset    = "iso-8859-1"
  end

*0.6.1* (January 18th, 2005)

  • Fixed sending of emails to use Tmail#from not the deprecated Tmail#from_address

*0.6* (January 17th, 2005)

  • Fixed that bcc and cc should be settable through @bcc and @cc — not just @headers["Bcc"] and @headers["Cc"] 453 [Eric Hodel]
  • Fixed Action Mailer to be "warnings safe" so you can run with ruby -w and not get framework warnings 453 [Eric Hodel]

*0.5*

  • Added access to custom headers, like cc, bcc, and reply-to 268 [Andreas Schwarz]. Example:
      def post_notification(recipients, post)
    @recipients          = recipients
    @from                = post.author.email_address_with_name
    @headers["bcc"]      = SYSTEM_ADMINISTRATOR_EMAIL
    @headers["reply-to"] = "notifications@example.com"
    @subject             = "[#{post.account.name} #{post.title}]"
    @body["post"]        = post
  end

*0.4* (5)

  • Consolidated the server configuration options into Base#server_settings= and expanded that with controls for authentication and more [Marten] NOTE: This is an API change that could potentially break your application if you used the old application form. Please do change!
  • Added Base#deliveries as an accessor for an array of emails sent out through that ActionMailer class when using the :test delivery option. [Jeremy Kemper]
  • Added Base#perform_deliveries= which can be set to false to turn off the actual delivery of the email through smtp or sendmail. This is especially useful for functional testing that shouldn‘t send off real emails, but still trigger delivery_* methods.
  • Added option to specify delivery method with Base#delivery_method=. Default is :smtp and :sendmail is currently the only other option. Sendmail is assumed to be present at "/usr/sbin/sendmail" if that option is used. [Kent Sibilev]
  • Dropped "include TMail" as it added to much baggage into the default namespace (like Version) [Chad Fowler]

*0.3*

  • First release


File: README

README

Path: | vendor/rails/activeresource/README
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Active Resource

Active Resource (ARes) connects business objects and Representational State Transfer (REST) web services. It implements object-relational mapping for REST webservices to provide transparent proxying capabilities between a client (ActiveResource) and a RESTful service (which is provided by Simply RESTful routing in ActionController::Resources).

Philosophy

Active Resource attempts to provide a coherent wrapper object-relational mapping for REST web services. It follows the same philosophy as Active Record, in that one of its prime aims is to reduce the amount of code needed to map to these resources. This is made possible by relying on a number of code- and protocol-based conventions that make it easy for Active Resource to infer complex relations and structures. These conventions are outlined in detail in the documentation for ActiveResource::Base.

Overview

Model classes are mapped to remote REST resources by Active Resource much the same way Active Record maps model classes to database tables. When a request is made to a remote resource, a REST XML request is generated, transmitted, and the result received and serialized into a usable Ruby object.

Configuration and Usage

Putting ActiveResource to use is very similar to ActiveRecord. It‘s as simple as creating a model class that inherits from ActiveResource::Base and providing a site class variable to it:

   class Person < ActiveResource::Base
     self.site = "http://api.people.com:3000/"
   end

Now the Person class is REST enabled and can invoke REST services very similarly to how ActiveRecord invokes lifecycle methods that operate against a persistent store.

   # Find a person with id = 1
   ryan = Person.find(1)
   Person.exists?(1)  #=> true

As you can see, the methods are quite similar to Active Record‘s methods for dealing with database records. But rather than dealing directly with a database record, you‘re dealing with HTTP resources (which may or may not be database records).

Protocol

Active Resource is built on a standard XML format for requesting and submitting resources over HTTP. It mirrors the RESTful routing built into ActionController but will also work with any other REST service that properly implements the protocol. REST uses HTTP, but unlike "typical" web applications, it makes use of all the verbs available in the HTTP specification:

  • GET requests are used for finding and retrieving resources.
  • POST requests are used to create new resources.
  • PUT requests are used to update existing resources.
  • DELETE requests are used to delete resources.

For more information on how this protocol works with Active Resource, see the ActiveResource::Base documentation; for more general information on REST web services, see the article here.

Find

GET Http requests expect the XML form of whatever resource/resources is/are being requested. So, for a request for a single element - the XML of that item is expected in response:

   # Expects a response of
   #
   # <person><id type="integer">1</id><attribute1>value1</attribute1><attribute2>..</attribute2></person>
   #
   # for GET http://api.people.com:3000/people/1.xml
   #
   ryan = Person.find(1)

The XML document that is received is used to build a new object of type Person, with each XML element becoming an attribute on the object.

   ryan.is_a? Person  #=> true
   ryan.attribute1  #=> 'value1'

Any complex element (one that contains other elements) becomes its own object:

   # With this response:
   #
   # <person><id>1</id><attribute1>value1</attribute1><complex><attribute2>value2</attribute2></complex></person>
   #
   # for GET http://api.people.com:3000/people/1.xml
   #
   ryan = Person.find(1)
   ryan.complex  #=> <Person::Complex::xxxxx>
   ryan.complex.attribute2  #=> 'value2'

Collections can also be requested in a similar fashion

   # Expects a response of
   #
   # <people type="array">
   #  <person><id type="integer">1</id><first>Ryan</first></person>
   #  <person><id type="integer">2</id><first>Jim</first></person>
   # </people>
   #
   # for GET http://api.people.com:3000/people.xml
   #
   people = Person.find(:all)
   people.first  #=> <Person::xxx 'first' => 'Ryan' ...>
   people.last  #=> <Person::xxx 'first' => 'Jim' ...>

Create

Creating a new resource submits the xml form of the resource as the body of the request and expects a ‘Location’ header in the response with the RESTful URL location of the newly created resource. The id of the newly created resource is parsed out of the Location response header and automatically set as the id of the ARes object.

  # <person><first>Ryan</first></person>
  #
  # is submitted as the body on
  #
  # POST http://api.people.com:3000/people.xml
  #
  # when save is called on a new Person object.  An empty response is
  # is expected with a 'Location' header value:
  #
  # Response (201): Location: http://api.people.com:3000/people/2
  #
  ryan = Person.new(:first => 'Ryan')
  ryan.new?  #=> true
  ryan.save  #=> true
  ryan.new?  #=> false
  ryan.id    #=> 2

Update

‘save’ is also used to update an existing resource - and follows the same protocol as creating a resource with the exception that no response headers are needed - just an empty response when the update on the server side was successful.

  # <person><first>Ryan</first></person>
  #
  # is submitted as the body on
  #
  # PUT http://api.people.com:3000/people/1.xml
  #
  # when save is called on an existing Person object.  An empty response is
  # is expected with code (204)
  #
  ryan = Person.find(1)
  ryan.first #=> 'Ryan'
  ryan.first = 'Rizzle'
  ryan.save  #=> true

Delete

Destruction of a resource can be invoked as a class and instance method of the resource.

  # A request is made to
  #
  # DELETE http://api.people.com:3000/people/1.xml
  #
  # for both of these forms.  An empty response with
  # is expected with response code (200)
  #
  ryan = Person.find(1)
  ryan.destroy  #=> true
  ryan.exists?  #=> false
  Person.delete(2)  #=> true
  Person.exists?(2) #=> false

You can find more usage information in the ActiveResource::Base documentation.


Class: ActiveResource::BadRequest

Class | ActiveResource::BadRequest
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ClientError

400 Bad Request


Class: ActiveResource::Base

Class | ActiveResource::Base
In: | vendor/rails/activeresource/lib/active_resource/base.rb
Parent: | Object

ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.

For an outline of what Active Resource is capable of, see files/vendor/rails/activeresource/README.html.

Automated mapping

Active Resource objects represent your RESTful resources as manipulatable Ruby objects. To map resources to Ruby objects, Active Resource only needs a class name that corresponds to the resource name (e.g., the class Person maps to the resources people, very similarly to Active Record) and a site value, which holds the URI of the resources.

  class Person < ActiveResource::Base
    self.site = "http://api.people.com:3000/"
  end

Now the Person class is mapped to RESTful resources located at api.people.com:3000/people/, and you can now use Active Resource‘s lifecycles methods to manipulate resources. In the case where you already have an existing model with the same name as the desired RESTful resource you can set the element_name value.

  class PersonResource < ActiveResource::Base
    self.site = "http://api.people.com:3000/"
    self.element_name = "person"
  end

Lifecycle methods

Active Resource exposes methods for creating, finding, updating, and deleting resources from REST web services.

  ryan = Person.new(:first => 'Ryan', :last => 'Daigle')
  ryan.save                # => true
  ryan.id                  # => 2
  Person.exists?(ryan.id)  # => true
  ryan.exists?             # => true

  ryan = Person.find(1)
  # Resource holding our newly created Person object

  ryan.first = 'Rizzle'
  ryan.save                # => true

  ryan.destroy             # => true

As you can see, these are very similar to Active Record‘s lifecycle methods for database records. You can read more about each of these methods in their respective documentation.

Custom REST methods

Since simple CRUD/lifecycle methods can‘t accomplish every task, Active Resource also supports defining your own custom REST methods. To invoke them, Active Resource provides the get, post, put and \delete methods where you can specify a custom REST method name to invoke.

  # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
  Person.new(:name => 'Ryan').post(:register)
  # => { :id => 1, :name => 'Ryan', :position => 'Clerk' }

  # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.xml?position=Manager.
  Person.find(1).put(:promote, :position => 'Manager')
  # => { :id => 1, :name => 'Ryan', :position => 'Manager' }

  # GET all the positions available, i.e. GET /people/positions.xml.
  Person.get(:positions)
  # => [{:name => 'Manager'}, {:name => 'Clerk'}]

  # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
  Person.find(1).delete(:fire)

For more information on using custom REST methods, see the ActiveResource::CustomMethods documentation.

Validations

You can validate resources client side by overriding validation methods in the base class.

  class Person < ActiveResource::Base
     self.site = "http://api.people.com:3000/"
     protected
       def validate
         errors.add("last", "has invalid characters") unless last =~ /[a-zA-Z]*/
       end
  end

See the ActiveResource::Validations documentation for more information.

Authentication

Many REST APIs will require authentication, usually in the form of basic HTTP authentication. Authentication can be specified by:

  • putting the credentials in the URL for the site variable.
     class Person < ActiveResource::Base
   self.site = "http://ryan:password@api.people.com:3000/"
 end
  • defining user and/or password variables
     class Person < ActiveResource::Base
   self.site = "http://api.people.com:3000/"
   self.user = "ryan"
   self.password = "password"
 end

For obvious security reasons, it is probably best if such services are available over HTTPS.

Note: Some values cannot be provided in the URL passed to site. e.g. email addresses as usernames. In those situations you should use the separate user and password option.

Errors & Validation

Error handling and validation is handled in much the same manner as you‘re used to seeing in Active Record. Both the response code in the HTTP response and the body of the response are used to indicate that an error occurred.

Resource errors

When a GET is requested for a resource that does not exist, the HTTP 404 (Resource Not Found) response code will be returned from the server which will raise an ActiveResource::ResourceNotFound exception.

  # GET http://api.people.com:3000/people/999.xml
  ryan = Person.find(999) # 404, raises ActiveResource::ResourceNotFound

404 is just one of the HTTP error response codes that Active Resource will handle with its own exception. The following HTTP response codes will also result in these exceptions:

  • 200..399 - Valid response, no exception (other than 301, 302)
  • 301, 302 - ActiveResource::Redirection
  • 400 - ActiveResource::BadRequest
  • 401 - ActiveResource::UnauthorizedAccess
  • 403 - ActiveResource::ForbiddenAccess
  • 404 - ActiveResource::ResourceNotFound
  • 405 - ActiveResource::MethodNotAllowed
  • 409 - ActiveResource::ResourceConflict
  • 422 - ActiveResource::ResourceInvalid (rescued by save as validation errors)
  • 401..499 - ActiveResource::ClientError
  • 500..599 - ActiveResource::ServerError
  • Other - ActiveResource::ConnectionError

These custom exceptions allow you to deal with resource errors more naturally and with more precision rather than returning a general HTTP error. For example:

  begin
    ryan = Person.find(my_id)
  rescue ActiveResource::ResourceNotFound
    redirect_to :action => 'not_found'
  rescue ActiveResource::ResourceConflict, ActiveResource::ResourceInvalid
    redirect_to :action => 'new'
  end

Validation errors

Active Resource supports validations on resources and will return errors if any these validations fail (e.g., "First name can not be blank" and so on). These types of errors are denoted in the response by a response code of 422 and an XML representation of the validation errors. The save operation will then fail (with a false return value) and the validation errors can be accessed on the resource in question.

  ryan = Person.find(1)
  ryan.first # => ''
  ryan.save  # => false

  # When
  # PUT http://api.people.com:3000/people/1.xml
  # is requested with invalid values, the response is:
  #
  # Response (422):
  # <errors type="array"><error>First cannot be empty</error></errors>
  #

  ryan.errors.invalid?(:first)  # => true
  ryan.errors.full_messages     # => ['First cannot be empty']

Learn more about Active Resource‘s validation features in the ActiveResource::Validations documentation.

Timeouts

Active Resource relies on HTTP to access RESTful APIs and as such is inherently susceptible to slow or unresponsive servers. In such cases, your Active Resource method calls could \timeout. You can control the amount of time before Active Resource times out with the timeout variable.

  class Person < ActiveResource::Base
    self.site = "http://api.people.com:3000/"
    self.timeout = 5
  end

This sets the timeout to 5 seconds. You can adjust the timeout to a value suitable for the RESTful API you are accessing. It is recommended to set this to a reasonably low value to allow your Active Resource clients (especially if you are using Active Resource in a Rails application) to fail-fast (see en.wikipedia.org/wiki/Fail-fast) rather than cause cascading failures that could incapacitate your server.

When a \timeout occurs, an ActiveResource::TimeoutError is raised. You should rescue from ActiveResource::TimeoutError in your Active Resource method calls.

Internally, Active Resource relies on Ruby‘s Net::HTTP library to make HTTP requests. Setting timeout sets the read_timeout of the internal Net::HTTP instance to the same value. The default read_timeout is 60 seconds on most Ruby implementations.

Methods

== clone collection_path collection_path connection connection create create delete destroy dup element_path element_path encode eql? exists? exists? find format format= hash headers id id= id_from_response load load_attributes_from_response new new? new_record? password password= prefix prefix= prefix_source reload respond_to? save site site= timeout timeout= to_json to_param to_xml update user user=

External Aliases

prefix= | -> | set_prefix
element_name= | -> | set_element_name
collection_name= | -> | set_collection_name
primary_key= | -> | set_primary_key
respond_to? | -> | respond_to_without_attributes?
 | For checking respond_to? without searching the attributes (which is faster).

Public Class methods

collection_path(prefix_options = {}, query_options = nil)

Gets the collection path for the REST resources. If the query_options parameter is omitted, Rails will split from the prefix_options.

Options

  • prefix_options - A hash to add a prefix to the request for nested URL‘s (e.g., :account_id => 19 would yield a URL like /accounts/19/purchases.xml).
  • query_options - A hash to add items to the query string for the request.

Examples

  Post.collection_path
  # => /posts.xml

  Comment.collection_path(:post_id => 5)
  # => /posts/5/comments.xml

  Comment.collection_path(:post_id => 5, :active => 1)
  # => /posts/5/comments.xml?active=1

  Comment.collection_path({:post_id => 5}, {:active => 1})
  # => /posts/5/comments.xml?active=1

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 434
434:       def collection_path(prefix_options = {}, query_options = nil)
435:         prefix_options, query_options = split_options(prefix_options) if query_options.nil?
436:         "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
437:       end
connection(refresh = false)

An instance of ActiveResource::Connection that is the base \connection to the remote service. The refresh parameter toggles whether or not the \connection is refreshed at every request or not (defaults to false).

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 321
321:       def connection(refresh = false)
322:         if defined?(@connection) || superclass == Object
323:           @connection = Connection.new(site, format) if refresh || @connection.nil?
324:           @connection.user = user if user
325:           @connection.password = password if password
326:           @connection.timeout = timeout if timeout
327:           @connection
328:         else
329:           superclass.connection
330:         end
331:       end
create(attributes = {})

Creates a new resource instance and makes a request to the remote service that it be saved, making it equivalent to the following simultaneous calls:

  ryan = Person.new(:first => 'ryan')
  ryan.save

Returns the newly created resource. If a failure has occurred an exception will be raised (see save). If the resource is invalid and has not been saved then valid? will return false, while new? will still return true.

Examples

  Person.create(:name => 'Jeremy', :email => 'myname@nospam.com', :enabled => true)
  my_person = Person.find(:first)
  my_person.email # => myname@nospam.com

  dhh = Person.create(:name => 'David', :email => 'dhh@nospam.com', :enabled => true)
  dhh.valid? # => true
  dhh.new?   # => false

  # We'll assume that there's a validation that requires the name attribute
  that_guy = Person.create(:name => '', :email => 'thatguy@nospam.com', :enabled => true)
  that_guy.valid? # => false
  that_guy.new?   # => true

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 465
465:       def create(attributes = {})
466:         self.new(attributes).tap { |resource| resource.save }
467:       end
delete(id, options = {})

Deletes the resources with the ID in the id parameter.

Options

All options specify \prefix and query parameters.

Examples

  Event.delete(2) # sends DELETE /events/2

  Event.create(:name => 'Free Concert', :location => 'Community Center')
  my_event = Event.find(:first) # let's assume this is event with ID 7
  Event.delete(my_event.id) # sends DELETE /events/7

  # Let's assume a request to events/5/cancel.xml
  Event.delete(params[:id]) # sends DELETE /events/5

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 542
542:       def delete(id, options = {})
543:         connection.delete(element_path(id, options))
544:       end
element_path(id, prefix_options = {}, query_options = nil)

Gets the element path for the given ID in id. If the query_options parameter is omitted, Rails will split from the \prefix options.

Options

prefix_options - A \hash to add a \prefix to the request for nested URLs (e.g., :account_id => 19

                   would yield a URL like <tt>/accounts/19/purchases.xml</tt>).

query_options - A \hash to add items to the query string for the request.

Examples

  Post.element_path(1)
  # => /posts/1.xml

  Comment.element_path(1, :post_id => 5)
  # => /posts/5/comments/1.xml

  Comment.element_path(1, :post_id => 5, :active => 1)
  # => /posts/5/comments/1.xml?active=1

  Comment.element_path(1, {:post_id => 5}, {:active => 1})
  # => /posts/5/comments/1.xml?active=1

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 408
408:       def element_path(id, prefix_options = {}, query_options = nil)
409:         prefix_options, query_options = split_options(prefix_options) if query_options.nil?
410:         "#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}"
411:       end
exists?(id, options = {})

Asserts the existence of a resource, returning true if the resource is found.

Examples

  Note.create(:title => 'Hello, world.', :body => 'Nothing more for now...')
  Note.exists?(1) # => true

  Note.exists(1349) # => false

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 553
553:       def exists?(id, options = {})
554:         if id
555:           prefix_options, query_options = split_options(options[:params])
556:           path = element_path(id, prefix_options, query_options)
557:           response = connection.head(path, headers)
558:           response.code.to_i == 200
559:         end
560:         # id && !find_single(id, options).nil?
561:       rescue ActiveResource::ResourceNotFound
562:         false
563:       end
find(*arguments)

Core method for finding resources. Used similarly to Active Record‘s find method.

Arguments

The first argument is considered to be the scope of the query. That is, how many resources are returned from the request. It can be one of the following.

  • :one - Returns a single resource.
  • :first - Returns the first resource found.
  • :last - Returns the last resource found.
  • :all - Returns every resource that matches the request.

Options

  • :from - Sets the path or custom method that resources will be fetched from.
  • :params - Sets query and \prefix (nested URL) parameters.

Examples

  Person.find(1)
  # => GET /people/1.xml

  Person.find(:all)
  # => GET /people.xml

  Person.find(:all, :params => { :title => "CEO" })
  # => GET /people.xml?title=CEO

  Person.find(:first, :from => :managers)
  # => GET /people/managers.xml

  Person.find(:last, :from => :managers)
  # => GET /people/managers.xml

  Person.find(:all, :from => "/companies/1/people.xml")
  # => GET /companies/1/people.xml

  Person.find(:one, :from => :leader)
  # => GET /people/leader.xml

  Person.find(:all, :from => :developers, :params => { :language => 'ruby' })
  # => GET /people/developers.xml?language=ruby

  Person.find(:one, :from => "/companies/1/manager.xml")
  # => GET /companies/1/manager.xml

  StreetAddress.find(1, :params => { :person_id => 1 })
  # => GET /people/1/street_addresses/1.xml

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 515
515:       def find(*arguments)
516:         scope   = arguments.slice!(0)
517:         options = arguments.slice!(0) || {}
518:
519:         case scope
520:           when :all   then find_every(options)
521:           when :first then find_every(options).first
522:           when :last  then find_every(options).last
523:           when :one   then find_one(options)
524:           else             find_single(scope, options)
525:         end
526:       end
format()

Returns the current format, default is ActiveResource::Formats::XmlFormat.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 299
299:       def format
300:         read_inheritable_attribute(:format) || ActiveResource::Formats[:xml]
301:       end
format=(mime_type_reference_or_format)

Sets the format that attributes are sent and received in from a mime type reference:

  Person.format = :json
  Person.find(1) # => GET /people/1.json

  Person.format = ActiveResource::Formats::XmlFormat
  Person.find(1) # => GET /people/1.xml

Default format is :xml.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 290
290:       def format=(mime_type_reference_or_format)
291:         format = mime_type_reference_or_format.is_a?(Symbol) ?
292:           ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
293:
294:         write_inheritable_attribute(:format, format)
295:         connection.format = format if site
296:       end
headers()

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 333
333:       def headers
334:         @headers ||= {}
335:       end
new(attributes = {})

Constructor method for \new resources; the optional attributes parameter takes a \hash of attributes for the \new resource.

Examples

  my_course = Course.new
  my_course.name = "Western Civilization"
  my_course.lecturer = "Don Trotter"
  my_course.save

  my_other_course = Course.new(:name => "Philosophy: Reason and Being", :lecturer => "Ralph Cling")
  my_other_course.save

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 653
653:     def initialize(attributes = {})
654:       @attributes     = {}
655:       @prefix_options = {}
656:       load(attributes)
657:     end
password()

Gets the \password for REST HTTP authentication.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 266
266:       def password
267:         # Not using superclass_delegating_reader. See +site+ for explanation
268:         if defined?(@password)
269:           @password
270:         elsif superclass != Object && superclass.password
271:           superclass.password.dup.freeze
272:         end
273:       end
password=(password)

Sets the \password for REST HTTP authentication.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 276
276:       def password=(password)
277:         @connection = nil
278:         @password = password
279:       end
prefix(options={})

Gets the \prefix for a resource‘s nested URL (e.g., prefix/collectionname/1.xml) This method is regenerated at runtime based on what the \prefix is set to.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 346
346:       def prefix(options={})
347:         default = site.path
348:         default << '/' unless default[-1..-1] == '/'
349:         # generate the actual method based on the current site path
350:         self.prefix = default
351:         prefix(options)
352:       end
prefix=(value = '/')

Sets the \prefix for a resource‘s nested URL (e.g., prefix/collectionname/1.xml). Default value is site.path.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 363
363:       def prefix=(value = '/')
364:         # Replace :placeholders with '#{embedded options[:lookups]}'
365:         prefix_call = value.gsub(/:\w+/) { |key| "\#{options[#{key}]}" }
366:
367:         # Clear prefix parameters in case they have been cached
368:         @prefix_parameters = nil
369:
370:         # Redefine the new methods.
371:         code = "def prefix_source() \"\#{value}\" end\ndef prefix(options={}) \"\#{prefix_call}\" end\n"
372:         silence_warnings { instance_eval code, __FILE__, __LINE__ }
373:       rescue
374:         logger.error "Couldn't set prefix: #{$!}\n  #{code}"
375:         raise
376:       end
prefix_source()

An attribute reader for the source string for the resource path \prefix. This method is regenerated at runtime based on what the \prefix is set to.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 356
356:       def prefix_source
357:         prefix # generate #prefix and #prefix_source methods first
358:         prefix_source
359:       end
site()

Gets the URI of the REST resources to map for this class. The site variable is required for Active Resource‘s mapping to work.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 213
213:       def site
214:         # Not using superclass_delegating_reader because don't want subclasses to modify superclass instance
215:         #
216:         # With superclass_delegating_reader
217:         #
218:         #   Parent.site = 'http://anonymous@test.com'
219:         #   Subclass.site # => 'http://anonymous@test.com'
220:         #   Subclass.site.user = 'david'
221:         #   Parent.site # => 'http://david@test.com'
222:         #
223:         # Without superclass_delegating_reader (expected behaviour)
224:         #
225:         #   Parent.site = 'http://anonymous@test.com'
226:         #   Subclass.site # => 'http://anonymous@test.com'
227:         #   Subclass.site.user = 'david' # => TypeError: can't modify frozen object
228:         #
229:         if defined?(@site)
230:           @site
231:         elsif superclass != Object && superclass.site
232:           superclass.site.dup.freeze
233:         end
234:       end
site=(site)

Sets the URI of the REST resources to map for this class to the value in the site argument. The site variable is required for Active Resource‘s mapping to work.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 238
238:       def site=(site)
239:         @connection = nil
240:         if site.nil?
241:           @site = nil
242:         else
243:           @site = create_site_uri_from(site)
244:           @user = URI.decode(@site.user) if @site.user
245:           @password = URI.decode(@site.password) if @site.password
246:         end
247:       end
timeout()

Gets the number of seconds after which requests to the REST API should time out.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 310
310:       def timeout
311:         if defined?(@timeout)
312:           @timeout
313:         elsif superclass != Object && superclass.timeout
314:           superclass.timeout
315:         end
316:       end
timeout=(timeout)

Sets the number of seconds after which requests to the REST API should time out.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 304
304:       def timeout=(timeout)
305:         @connection = nil
306:         @timeout = timeout
307:       end
user()

Gets the \user for REST HTTP authentication.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 250
250:       def user
251:         # Not using superclass_delegating_reader. See +site+ for explanation
252:         if defined?(@user)
253:           @user
254:         elsif superclass != Object && superclass.user
255:           superclass.user.dup.freeze
256:         end
257:       end
user=(user)

Sets the \user for REST HTTP authentication.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 260
260:       def user=(user)
261:         @connection = nil
262:         @user = user
263:       end

Public Instance methods

==(other)

Test for equality. Resource are equal if and only if other is the same object or is an instance of the same class, is not new?, and has the same id.

Examples

  ryan = Person.create(:name => 'Ryan')
  jamie = Person.create(:name => 'Jamie')

  ryan == jamie
  # => false (Different name attribute and id)

  ryan_again = Person.new(:name => 'Ryan')
  ryan == ryan_again
  # => false (ryan_again is new?)

  ryans_clone = Person.create(:name => 'Ryan')
  ryan == ryans_clone
  # => false (Different id attributes)

  ryans_twin = Person.find(ryan.id)
  ryan == ryans_twin
  # => true

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 749
749:     def ==(other)
750:       other.equal?(self) || (other.instance_of?(self.class) && other.id == id && other.prefix_options == prefix_options)
751:     end
clone()

Returns a \clone of the resource that hasn‘t been assigned an id yet and is treated as a \new resource.

  ryan = Person.find(1)
  not_ryan = ryan.clone
  not_ryan.new?  # => true

Any active resource member attributes will NOT be cloned, though all other attributes are. This is to prevent the conflict between any prefix_options that refer to the original parent resource and the newly cloned parent resource that does not exist.

  ryan = Person.find(1)
  ryan.address = StreetAddress.find(1, :person_id => ryan.id)
  ryan.hash = {:not => "an ARes instance"}

  not_ryan = ryan.clone
  not_ryan.new?            # => true
  not_ryan.address         # => NoMethodError
  not_ryan.hash            # => {:not => "an ARes instance"}

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 679
679:     def clone
680:       # Clone all attributes except the pk and any nested ARes
681:       cloned = attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.inject({}) do |attrs, (k, v)|
682:         attrs[k] = v.clone
683:         attrs
684:       end
685:       # Form the new resource - bypass initialize of resource with 'new' as that will call 'load' which
686:       # attempts to convert hashes into member objects and arrays into collections of objects.  We want
687:       # the raw objects to be cloned so we bypass load by directly setting the attributes hash.
688:       resource = self.class.new({})
689:       resource.prefix_options = self.prefix_options
690:       resource.send :instance_variable_set, '@attributes', cloned
691:       resource
692:     end
destroy()

Deletes the resource from the remote service.

Examples

  my_id = 3
  my_person = Person.find(my_id)
  my_person.destroy
  Person.find(my_id) # 404 (Resource Not Found)

  new_person = Person.create(:name => 'James')
  new_id = new_person.id # => 7
  new_person.destroy
  Person.find(new_id) # 404 (Resource Not Found)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 812
812:     def destroy
813:       connection.delete(element_path, self.class.headers)
814:     end
dup()

Duplicate the current resource without saving it.

Examples

  my_invoice = Invoice.create(:customer => 'That Company')
  next_invoice = my_invoice.dup
  next_invoice.new? # => true

  next_invoice.save
  next_invoice == my_invoice # => false (different id attributes)

  my_invoice.customer   # => That Company
  next_invoice.customer # => That Company

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 776
776:     def dup
777:       self.class.new.tap do |resource|
778:         resource.attributes     = @attributes
779:         resource.prefix_options = @prefix_options
780:       end
781:     end
encode(options={})

Returns the serialized string representation of the resource in the configured serialization format specified in ActiveResource::Base.format. The options applicable depend on the configured encoding format.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 897
897:     def encode(options={})
898:       case self.class.format
899:         when ActiveResource::Formats[:xml]
900:           self.class.format.encode(attributes, {:root => self.class.element_name}.merge(options))
901:         else
902:           self.class.format.encode(attributes, options)
903:       end
904:     end
eql?(other)

Tests for equality (delegates to ==).

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 754
754:     def eql?(other)
755:       self == other
756:     end
exists?()

Evaluates to true if this resource is not new? and is found on the remote service. Using this method, you can check for resources that may have been deleted between the object‘s instantiation and actions on it.

Examples

  Person.create(:name => 'Theodore Roosevelt')
  that_guy = Person.find(:first)
  that_guy.exists? # => true

  that_lady = Person.new(:name => 'Paul Bean')
  that_lady.exists? # => false

  guys_id = that_guy.id
  Person.delete(guys_id)
  that_guy.exists? # => false

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 832
832:     def exists?
833:       !new? && self.class.exists?(to_param, :params => prefix_options)
834:     end
hash()

Delegates to id in order to allow two resources of the same type and \id to work with something like:

  [Person.find(1), Person.find(2)] & [Person.find(1), Person.find(4)] # => [Person.find(1)]

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 760
760:     def hash
761:       id.hash
762:     end
id()

Gets the \id attribute of the resource.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 713
713:     def id
714:       attributes[self.class.primary_key]
715:     end
id=(id)

Sets the \id attribute of the resource.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 718
718:     def id=(id)
719:       attributes[self.class.primary_key] = id
720:     end
load(attributes)

A method to manually load attributes from a \hash. Recursively loads collections of resources. This method is called in initialize and create when a \hash of attributes is provided.

Examples

  my_attrs = {:name => 'J&J Textiles', :industry => 'Cloth and textiles'}
  my_attrs = {:name => 'Marty', :colors => ["red", "green", "blue"]}

  the_supplier = Supplier.find(:first)
  the_supplier.name # => 'J&M Textiles'
  the_supplier.load(my_attrs)
  the_supplier.name('J&J Textiles')

  # These two calls are the same as Supplier.new(my_attrs)
  my_supplier = Supplier.new
  my_supplier.load(my_attrs)

  # These three calls are the same as Supplier.create(my_attrs)
  your_supplier = Supplier.new
  your_supplier.load(my_attrs)
  your_supplier.save

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 942
942:     def load(attributes)
943:       raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
944:       @prefix_options, attributes = split_options(attributes)
945:       attributes.each do |key, value|
946:         @attributes[key.to_s] =
947:           case value
948:             when Array
949:               resource = find_or_create_resource_for_collection(key)
950:               value.map { |attrs| attrs.is_a?(String) ? attrs.dup : resource.new(attrs) }
951:             when Hash
952:               resource = find_or_create_resource_for(key)
953:               resource.new(value)
954:             else
955:               value.dup rescue value
956:           end
957:       end
958:       self
959:     end
new?()

A method to determine if the resource a \new object (i.e., it has not been POSTed to the remote service yet).

Examples

  not_new = Computer.create(:brand => 'Apple', :make => 'MacBook', :vendor => 'MacMall')
  not_new.new? # => false

  is_new = Computer.new(:brand => 'IBM', :make => 'Thinkpad', :vendor => 'IBM')
  is_new.new? # => true

  is_new.save
  is_new.new? # => false

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 707
707:     def new?
708:       id.nil?
709:     end
new_record?()

Alias for new?

reload()

A method to \reload the attributes of this object from the remote web service.

Examples

  my_branch = Branch.find(:first)
  my_branch.name # => "Wislon Raod"

  # Another client fixes the typo...

  my_branch.name # => "Wislon Raod"
  my_branch.reload
  my_branch.name # => "Wilson Road"

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 917
917:     def reload
918:       self.load(self.class.find(to_param, :params => @prefix_options).attributes)
919:     end
respond_to?(method, include_priv = false)

A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a Person object with a name attribute can answer true to my_person.respond_to?(:name), my_person.respond_to?(:name=), and my_person.respond_to?(:name?).

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 967
967:     def respond_to?(method, include_priv = false)
968:       method_name = method.to_s
969:       if attributes.nil?
970:         return super
971:       elsif attributes.has_key?(method_name)
972:         return true
973:       elsif ['?','='].include?(method_name.last) && attributes.has_key?(method_name.first(-1))
974:         return true
975:       end
976:       # super must be called at the end of the method, because the inherited respond_to?
977:       # would return true for generated readers, even if the attribute wasn't present
978:       super
979:     end
save()

A method to \save (POST) or \update (PUT) a resource. It delegates to create if a \new object, update if it is existing. If the response to the \save includes a body, it will be assumed that this body is XML for the final object as it looked after the \save (which would include attributes like created_at that weren‘t part of the original submit).

Examples

  my_company = Company.new(:name => 'RoleModel Software', :owner => 'Ken Auer', :size => 2)
  my_company.new? # => true
  my_company.save # sends POST /companies/ (create)

  my_company.new? # => false
  my_company.size = 10
  my_company.save # sends PUT /companies/1 (update)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 796
796:     def save
797:       new? ? create : update
798:     end
to_json(options={})

Returns a JSON string representing the model. Some configuration is available through options.

Options

The options are passed to the to_json method on each attribute, so the same options as the to_json methods in Active Support.

  • :only - Only include the specified attribute or list of attributes in the serialized output. Attribute names must be specified as strings.
  • :except - Do not include the specified attribute or list of attributes in the serialized output. Attribute names must be specified as strings.

Examples

  person = Person.new(:first_name => "Jim", :last_name => "Smith")
  person.to_json
  # => {"first_name": "Jim", "last_name": "Smith"}

  person.to_json(:only => ["first_name"])
  # => {"first_name": "Jim"}

  person.to_json(:except => ["first_name"])
  # => {"last_name": "Smith"}

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 890
890:     def to_json(options={})
891:       attributes.to_json(options)
892:     end
to_param()

Allows Active Resource objects to be used as parameters in Action Pack URL generation.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 723
723:     def to_param
724:       id && id.to_s
725:     end
to_xml(options={})

A method to convert the the resource to an XML string.

Options

The options parameter is handed off to the to_xml method on each attribute, so it has the same options as the to_xml methods in Active Support.

  • :indent - Set the indent level for the XML output (default is +2+).
  • :dasherize - Boolean option to determine whether or not element names should replace underscores with dashes (default is false).
  • :skip_instruct - Toggle skipping the +instruct!+ call on the XML builder that generates the XML declaration (default is false).

Examples

  my_group = SubsidiaryGroup.find(:first)
  my_group.to_xml
  # => <?xml version="1.0" encoding="UTF-8"?>
  #    <subsidiary_group> [...] </subsidiary_group>

  my_group.to_xml(:dasherize => true)
  # => <?xml version="1.0" encoding="UTF-8"?>
  #    <subsidiary-group> [...] </subsidiary-group>

  my_group.to_xml(:skip_instruct => true)
  # => <subsidiary_group> [...] </subsidiary_group>

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 861
861:     def to_xml(options={})
862:       attributes.to_xml({:root => self.class.element_name}.merge(options))
863:     end

Protected Instance methods

collection_path(options = nil)

[Source]

      # File vendor/rails/activeresource/lib/active_resource/base.rb, line 1017
1017:       def collection_path(options = nil)
1018:         self.class.collection_path(options || prefix_options)
1019:       end
connection(refresh = false)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 983
983:       def connection(refresh = false)
984:         self.class.connection(refresh)
985:       end
create()

Create (i.e., \save to the remote service) the \new resource.

[Source]

      # File vendor/rails/activeresource/lib/active_resource/base.rb, line 995
 995:       def create
 996:         connection.post(collection_path, encode, self.class.headers).tap do |response|
 997:           self.id = id_from_response(response)
 998:           load_attributes_from_response(response)
 999:         end
1000:       end
element_path(options = nil)

[Source]

      # File vendor/rails/activeresource/lib/active_resource/base.rb, line 1013
1013:       def element_path(options = nil)
1014:         self.class.element_path(to_param, options || prefix_options)
1015:       end
id_from_response(response)

Takes a response from a typical create post and pulls the ID out

[Source]

      # File vendor/rails/activeresource/lib/active_resource/base.rb, line 1009
1009:       def id_from_response(response)
1010:         response['Location'][/\/([^\/]*?)(\.\w+)?$/, 1] if response['Location']
1011:       end
load_attributes_from_response(response)

[Source]

      # File vendor/rails/activeresource/lib/active_resource/base.rb, line 1002
1002:       def load_attributes_from_response(response)
1003:         if response['Content-Length'] != "0" && response.body.strip.size > 0
1004:           load(self.class.format.decode(response.body))
1005:         end
1006:       end
update()

Update the resource on the remote service.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/base.rb, line 988
988:       def update
989:         connection.put(element_path(prefix_options), encode, self.class.headers).tap do |response|
990:           load_attributes_from_response(response)
991:         end
992:       end


Class: ActiveResource::ClientError

Class | ActiveResource::ClientError
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ConnectionError

4xx Client Error


Class: ActiveResource::Connection

Class | ActiveResource::Connection
In: | vendor/rails/activeresource/lib/active_resource/connection.rb vendor/rails/activeresource/lib/active_resource/http_mock.rb
Parent: | Object

Class to handle connections to remote web services. This class is used by ActiveResource::Base to interface with REST services.

Methods

delete get head new password= post put requests site= timeout= user=

Constants

HTTP_FORMAT_HEADER_NAMES = { :get => 'Accept', :put => 'Content-Type', :post => 'Content-Type', :delete => 'Accept'

Attributes

format | [RW]
password | [R]
site | [R]
timeout | [R]
user | [R]

Public Class methods

new(site, format = ActiveResource::Formats[:xml])

The site parameter is required and will set the site attribute to the URI for the remote resource service.

[Source]

    # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 84
84:     def initialize(site, format = ActiveResource::Formats[:xml])
85:       raise ArgumentError, 'Missing site URI' unless site
86:       @user = @password = nil
87:       self.site = site
88:       self.format = format
89:     end
requests()

[Source]

    # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 77
77:       def requests
78:         @@requests ||= []
79:       end

Public Instance methods

delete(path, headers = {})

Execute a DELETE request (see HTTP protocol documentation if unfamiliar). Used to delete resources.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 121
121:     def delete(path, headers = {})
122:       request(:delete, path, build_request_headers(headers, :delete))
123:     end
get(path, headers = {})

Execute a GET request. Used to get (find) resources.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 115
115:     def get(path, headers = {})
116:       format.decode(request(:get, path, build_request_headers(headers, :get)).body)
117:     end
head(path, headers = {})

Execute a HEAD request. Used to obtain meta-information about resources, such as whether they exist and their size (via response headers).

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 139
139:     def head(path, headers = {})
140:       request(:head, path, build_request_headers(headers))
141:     end
password=(password)

Set password for remote service.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 104
104:     def password=(password)
105:       @password = password
106:     end
post(path, body = '', headers = {})

Execute a POST request. Used to create new resources.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 133
133:     def post(path, body = '', headers = {})
134:       request(:post, path, body.to_s, build_request_headers(headers, :post))
135:     end
put(path, body = '', headers = {})

Execute a PUT request (see HTTP protocol documentation if unfamiliar). Used to update resources.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 127
127:     def put(path, body = '', headers = {})
128:       request(:put, path, body.to_s, build_request_headers(headers, :put))
129:     end
site=(site)

Set URI for remote service.

[Source]

    # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 92
92:     def site=(site)
93:       @site = site.is_a?(URI) ? site : URI.parse(site)
94:       @user = URI.decode(@site.user) if @site.user
95:       @password = URI.decode(@site.password) if @site.password
96:     end
timeout=(timeout)

Set the number of seconds after which HTTP requests to the remote service should time out.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 109
109:     def timeout=(timeout)
110:       @timeout = timeout
111:     end
user=(user)

Set user for remote service.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 99
 99:     def user=(user)
100:       @user = user
101:     end


Module: ActiveResource::CustomMethods

Module | ActiveResource::CustomMethods
In: | vendor/rails/activeresource/lib/active_resource/custom_methods.rb

A module to support custom REST methods and sub-resources, allowing you to break out of the "default" REST methods with your own custom resource requests. For example, say you use Rails to expose a REST service and configure your routes with:

   map.resources :people, :new => { :register => :post },
                          :member => { :promote => :put, :deactivate => :delete }
                          :collection => { :active => :get }

 This route set creates routes for the following HTTP requests:

   POST    /people/new/register.xml # PeopleController.register
   PUT     /people/1/promote.xml    # PeopleController.promote with :id => 1
   DELETE  /people/1/deactivate.xml # PeopleController.deactivate with :id => 1
   GET     /people/active.xml       # PeopleController.active

Using this module, Active Resource can use these custom REST methods just like the standard methods.

  class Person < ActiveResource::Base
    self.site = "http://37s.sunrise.i:3000"
  end

  Person.new(:name => 'Ryan).post(:register)  # POST /people/new/register.xml
  # => { :id => 1, :name => 'Ryan' }

  Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
  Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml

  Person.get(:active)  # GET /people/active.xml
  # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]

Methods

delete get included post put

Included Modules

ActiveResource::CustomMethods::InstanceMethods

Classes and Modules

Module ActiveResource::CustomMethods::ClassMethods
Module ActiveResource::CustomMethods::InstanceMethods

External Aliases

delete -> orig_delete

Public Class methods

delete(custom_method_name, options = {})

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 68
68:           def delete(custom_method_name, options = {})
69:             # Need to jump through some hoops to retain the original class 'delete' method
70:             if custom_method_name.is_a?(Symbol)
71:               connection.delete(custom_method_collection_url(custom_method_name, options), headers)
72:             else
73:               orig_delete(custom_method_name, options)
74:             end
75:           end
get(custom_method_name, options = {})

Invokes a GET to a given custom REST method. For example:

  Person.get(:active)  # GET /people/active.xml
  # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]

  Person.get(:active, :awesome => true)  # GET /people/active.xml?awesome=true
  # => [{:id => 1, :name => 'Ryan'}]

Note: the objects returned from this method are not automatically converted into ActiveResource::Base instances - they are ordinary Hashes. If you are expecting ActiveResource::Base instances, use the find class method with the :from option. For example:

  Person.find(:all, :from => :active)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 56
56:           def get(custom_method_name, options = {})
57:             connection.get(custom_method_collection_url(custom_method_name, options), headers)
58:           end
included(base)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 34
34:     def self.included(base)
35:       base.class_eval do
36:         extend ActiveResource::CustomMethods::ClassMethods
37:         include ActiveResource::CustomMethods::InstanceMethods
38:
39:         class << self
40:           alias :orig_delete :delete
41:
42:           # Invokes a GET to a given custom REST method. For example:
43:           #
44:           #   Person.get(:active)  # GET /people/active.xml
45:           #   # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
46:           #
47:           #   Person.get(:active, :awesome => true)  # GET /people/active.xml?awesome=true
48:           #   # => [{:id => 1, :name => 'Ryan'}]
49:           #
50:           # Note: the objects returned from this method are not automatically converted
51:           # into ActiveResource::Base instances - they are ordinary Hashes. If you are expecting
52:           # ActiveResource::Base instances, use the <tt>find</tt> class method with the
53:           # <tt>:from</tt> option. For example:
54:           #
55:           #   Person.find(:all, :from => :active)
56:           def get(custom_method_name, options = {})
57:             connection.get(custom_method_collection_url(custom_method_name, options), headers)
58:           end
59:
60:           def post(custom_method_name, options = {}, body = '')
61:             connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
62:           end
63:
64:           def put(custom_method_name, options = {}, body = '')
65:             connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
66:           end
67:
68:           def delete(custom_method_name, options = {})
69:             # Need to jump through some hoops to retain the original class 'delete' method
70:             if custom_method_name.is_a?(Symbol)
71:               connection.delete(custom_method_collection_url(custom_method_name, options), headers)
72:             else
73:               orig_delete(custom_method_name, options)
74:             end
75:           end
76:         end
77:       end
78:     end
post(custom_method_name, options = {}, body = '')

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 60
60:           def post(custom_method_name, options = {}, body = '')
61:             connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
62:           end
put(custom_method_name, options = {}, body = '')

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 64
64:           def put(custom_method_name, options = {}, body = '')
65:             connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
66:           end


Module: ActiveResource::CustomMethods::ClassMethods

Module | ActiveResource::CustomMethods::ClassMethods
In: | vendor/rails/activeresource/lib/active_resource/custom_methods.rb

Methods

custom_method_collection_url

Public Instance methods

custom_method_collection_url(method_name, options = {})

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 81
81:       def custom_method_collection_url(method_name, options = {})
82:         prefix_options, query_options = split_options(options)
83:         "#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}"
84:       end


Module: ActiveResource::CustomMethods::InstanceMethods

Module | ActiveResource::CustomMethods::InstanceMethods
In: | vendor/rails/activeresource/lib/active_resource/custom_methods.rb

Methods

delete get post put

Public Instance methods

delete(method_name, options = {})

[Source]

     # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 105
105:       def delete(method_name, options = {})
106:         connection.delete(custom_method_element_url(method_name, options), self.class.headers)
107:       end
get(method_name, options = {})

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 88
88:       def get(method_name, options = {})
89:         connection.get(custom_method_element_url(method_name, options), self.class.headers)
90:       end
post(method_name, options = {}, body = nil)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 92
92:       def post(method_name, options = {}, body = nil)
93:         request_body = body.blank? ? encode : body
94:         if new?
95:           connection.post(custom_method_new_element_url(method_name, options), request_body, self.class.headers)
96:         else
97:           connection.post(custom_method_element_url(method_name, options), request_body, self.class.headers)
98:         end
99:       end
put(method_name, options = {}, body = '')

[Source]

     # File vendor/rails/activeresource/lib/active_resource/custom_methods.rb, line 101
101:       def put(method_name, options = {}, body = '')
102:         connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
103:       end


Class: ActiveResource::Errors

Class | ActiveResource::Errors
In: | vendor/rails/activeresource/lib/active_resource/validations.rb
Parent: | Object

Active Resource validation is reported to and from this object, which is used by Base#save to determine whether the object in a valid state to be saved. See usage example in Validations.

Methods

[] add add_to_base clear count each each_full from_xml full_messages invalid? length on on_base size

Included Modules

Enumerable

Attributes

errors [R]

Public Instance methods

[](attribute)

Alias for on

add(attribute, msg)

Adds an error to an Active Resource object‘s attribute (named for the attribute parameter) with the error message in msg.

Examples

  my_resource = Node.find(1)
  my_resource.errors.add('name', 'can not be "base"') if my_resource.name == 'base'
  my_resource.errors.on('name')
  # => 'can not be "base"!'

  my_resource.errors.add('desc', 'can not be blank') if my_resource.desc == ''
  my_resource.valid?
  # => false
  my_resource.errors.on('desc')
  # => 'can not be blank!'

[Source]

    # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 50
50:     def add(attribute, msg)
51:       @errors[attribute.to_s] = [] if @errors[attribute.to_s].nil?
52:       @errors[attribute.to_s] << msg
53:     end
add_to_base(msg)

Add an error to the base Active Resource object rather than an attribute.

Examples

  my_folder = Folder.find(1)
  my_folder.errors.add_to_base("You can't edit an existing folder")
  my_folder.errors.on_base
  # => "You can't edit an existing folder"

  my_folder.errors.add_to_base("This folder has been tagged as frozen")
  my_folder.valid?
  # => false
  my_folder.errors.on_base
  # => ["You can't edit an existing folder", "This folder has been tagged as frozen"]

[Source]

    # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 31
31:     def add_to_base(msg)
32:       add(:base, msg)
33:     end
clear()

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 178
178:     def clear
179:       @errors = {}
180:     end
count()

Alias for size

each() {|attr, msg| ...}

Yields each attribute and associated message per error added.

Examples

  my_person = Person.new(params[:person])

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.errors.add('password', 'can not be empty') if my_person.password == ''
  messages = ''
  my_person.errors.each {|attr, msg| messages += attr.humanize + " " + msg + "<br />"}
  messages
  # => "Login can not be empty<br />Password can not be empty<br />"

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 128
128:     def each
129:       @errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } }
130:     end
each_full() {|msg| ...}

Yields each full error message added. So Person.errors.add("first_name", "can‘t be empty") will be returned through iteration as "First name can‘t be empty".

Examples

  my_person = Person.new(params[:person])

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.errors.add('password', 'can not be empty') if my_person.password == ''
  messages = ''
  my_person.errors.each_full {|msg| messages += msg + "<br/>"}
  messages
  # => "Login can not be empty<br />Password can not be empty<br />"

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 145
145:     def each_full
146:       full_messages.each { |msg| yield msg }
147:     end
from_xml(xml)

Grabs errors from the XML response.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 203
203:     def from_xml(xml)
204:       clear
205:       humanized_attributes = @base.attributes.keys.inject({}) { |h, attr_name| h.update(attr_name.humanize => attr_name) }
206:       messages = Array.wrap(Hash.from_xml(xml)['errors']['error']) rescue []
207:       messages.each do |message|
208:         attr_message = humanized_attributes.keys.detect do |attr_name|
209:           if message[0, attr_name.size + 1] == "#{attr_name} "
210:             add humanized_attributes[attr_name], message[(attr_name.size + 1)..-1]
211:           end
212:         end
213:
214:         add_to_base message if attr_message.nil?
215:       end
216:     end
full_messages()

Returns all the full error messages in an array.

Examples

  my_person = Person.new(params[:person])

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.errors.add('password', 'can not be empty') if my_person.password == ''
  messages = ''
  my_person.errors.full_messages.each {|msg| messages += msg + "<br/>"}
  messages
  # => "Login can not be empty<br />Password can not be empty<br />"

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 161
161:     def full_messages
162:       full_messages = []
163:
164:       @errors.each_key do |attr|
165:         @errors[attr].each do |msg|
166:           next if msg.nil?
167:
168:           if attr == "base"
169:             full_messages << msg
170:           else
171:             full_messages << [attr.humanize, msg].join(' ')
172:           end
173:         end
174:       end
175:       full_messages
176:     end
invalid?(attribute)

Returns true if the specified attribute has errors associated with it.

Examples

  my_resource = Disk.find(1)
  my_resource.errors.add('location', 'must be Main') unless my_resource.location == 'Main'
  my_resource.errors.on('location')
  # => 'must be Main!'

  my_resource.errors.invalid?('location')
  # => true
  my_resource.errors.invalid?('name')
  # => false

[Source]

    # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 67
67:     def invalid?(attribute)
68:       !@errors[attribute.to_s].nil?
69:     end
length()

Alias for size

on(attribute)

A method to return the errors associated with attribute, which returns nil, if no errors are associated with the specified attribute, the error message if one error is associated with the specified attribute, or an array of error messages if more than one error is associated with the specified attribute.

Examples

  my_person = Person.new(params[:person])
  my_person.errors.on('login')
  # => nil

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.errors.on('login')
  # => 'can not be empty'

  my_person.errors.add('login', 'can not be longer than 10 characters') if my_person.login.length > 10
  my_person.errors.on('login')
  # => ['can not be empty', 'can not be longer than 10 characters']

[Source]

    # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 87
87:     def on(attribute)
88:       errors = @errors[attribute.to_s]
89:       return nil if errors.nil?
90:       errors.size == 1 ? errors.first : errors
91:     end
on_base()

A method to return errors assigned to base object through add_to_base, which returns nil, if no errors are associated with the specified attribute, the error message if one error is associated with the specified attribute, or an array of error messages if more than one error is associated with the specified attribute.

Examples

  my_account = Account.find(1)
  my_account.errors.on_base
  # => nil

  my_account.errors.add_to_base("This account is frozen")
  my_account.errors.on_base
  # => "This account is frozen"

  my_account.errors.add_to_base("This account has been closed")
  my_account.errors.on_base
  # => ["This account is frozen", "This account has been closed"]

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 112
112:     def on_base
113:       on(:base)
114:     end
size()

Returns the total number of errors added. Two errors added to the same attribute will be counted as such with this as well.

Examples

  my_person = Person.new(params[:person])
  my_person.errors.size
  # => 0

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.errors.add('password', 'can not be empty') if my_person.password == ''
  my_person.error.size
  # => 2

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 195
195:     def size
196:       @errors.values.inject(0) { |error_count, attribute| error_count + attribute.size }
197:     end


Class: ActiveResource::ForbiddenAccess

Class | ActiveResource::ForbiddenAccess
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ClientError

403 Forbidden


Module: ActiveResource::Formats

Module | ActiveResource::Formats
In: | vendor/rails/activeresource/lib/active_resource/formats/json_format.rb vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb vendor/rails/activeresource/lib/active_resource/formats.rb

Methods

[]

Classes and Modules

Module ActiveResource::Formats::JsonFormat
Module ActiveResource::Formats::XmlFormat

Public Class methods

[](mime_type_reference)

Lookup the format class from a mime type reference symbol. Example:

  ActiveResource::Formats[:xml]  # => ActiveResource::Formats::XmlFormat
  ActiveResource::Formats[:json] # => ActiveResource::Formats::JsonFormat

[Source]

   # File vendor/rails/activeresource/lib/active_resource/formats.rb, line 7
7:     def self.[](mime_type_reference)
8:       ActiveResource::Formats.const_get(mime_type_reference.to_s.camelize + "Format")
9:     end


Module: ActiveResource::Formats::JsonFormat

Module | ActiveResource::Formats::JsonFormat
In: | vendor/rails/activeresource/lib/active_resource/formats/json_format.rb

Methods

decode encode extension mime_type

Public Instance methods

decode(json)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/json_format.rb, line 18
18:       def decode(json)
19:         ActiveSupport::JSON.decode(json)
20:       end
encode(hash, options={})

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/json_format.rb, line 14
14:       def encode(hash, options={})
15:         hash.to_json(options)
16:       end
extension()

[Source]

   # File vendor/rails/activeresource/lib/active_resource/formats/json_format.rb, line 6
6:       def extension
7:         "json"
8:       end
mime_type()

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/json_format.rb, line 10
10:       def mime_type
11:         "application/json"
12:       end


Module: ActiveResource::Formats::XmlFormat

Module | ActiveResource::Formats::XmlFormat
In: | vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb

Methods

decode encode extension mime_type

Public Instance methods

decode(xml)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb, line 18
18:       def decode(xml)
19:         from_xml_data(Hash.from_xml(xml))
20:       end
encode(hash, options={})

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb, line 14
14:       def encode(hash, options={})
15:         hash.to_xml(options)
16:       end
extension()

[Source]

   # File vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb, line 6
6:       def extension
7:         "xml"
8:       end
mime_type()

[Source]

    # File vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb, line 10
10:       def mime_type
11:         "application/xml"
12:       end


Class: ActiveResource::HttpMock

Class | ActiveResource::HttpMock
In: | vendor/rails/activeresource/lib/active_resource/http_mock.rb
Parent: | Object

One thing that has always been a pain with remote web services is testing. The HttpMock class makes it easy to test your Active Resource models by creating a set of mock responses to specific requests.

To test your Active Resource model, you simply call the ActiveResource::HttpMock.respond_to method with an attached block. The block declares a set of URIs with expected input, and the output each request should return. The passed in block has any number of entries in the following generalized format:

  mock.http_method(path, request_headers = {}, body = nil, status = 200, response_headers = {})
  • http_method - The HTTP method to listen for. This can be get, post, put, delete or head.
  • path - A string, starting with a "/", defining the URI that is expected to be called.
  • request_headers - Headers that are expected along with the request. This argument uses a hash format, such as { "Content-Type" => "application/xml" }. This mock will only trigger if your tests sends a request with identical headers.
  • body - The data to be returned. This should be a string of Active Resource parseable content, such as XML.
  • status - The HTTP response code, as an integer, to return with the response.
  • response_headers - Headers to be returned with the response. Uses the same hash format as request_headers listed above.

In order for a mock to deliver its content, the incoming request must match by the http_method, path and request_headers. If no match is found an InvalidRequestError exception will be raised letting you know you need to create a new mock for that request.

Example

  def setup
    @matz  = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
    ActiveResource::HttpMock.respond_to do |mock|
      mock.post   "/people.xml",   {}, @matz, 201, "Location" => "/people/1.xml"
      mock.get    "/people/1.xml", {}, @matz
      mock.put    "/people/1.xml", {}, nil, 204
      mock.delete "/people/1.xml", {}, nil, 200
    end
  end

  def test_get_matz
    person = Person.find(1)
    assert_equal "Matz", person.name
  end

Methods

requests reset! respond_to responses

Public Class methods

requests()

Returns an array of all request objects that have been sent to the mock. You can use this to check if your model actually sent an HTTP request.

Example

  def setup
    @matz  = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
    ActiveResource::HttpMock.respond_to do |mock|
      mock.get "/people/1.xml", {}, @matz
    end
  end

  def test_should_request_remote_service
    person = Person.find(1)  # Call the remote service

    # This request object has the same HTTP method and path as declared by the mock
    expected_request = ActiveResource::Request.new(:get, "/people/1.xml")

    # Assert that the mock received, and responded to, the expected request from the model
    assert ActiveResource::HttpMock.requests.include?(expected_request)
  end

[Source]

    # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 91
91:       def requests
92:         @@requests ||= []
93:       end
reset!()

Deletes all logged requests and responses.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 114
114:       def reset!
115:         requests.clear
116:         responses.clear
117:       end
respond_to(pairs = {}) {|mock| ...}

Accepts a block which declares a set of requests and responses for the HttpMock to respond to. See the main ActiveResource::HttpMock description for a more detailed explanation.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 103
103:       def respond_to(pairs = {}) #:yields: mock
104:         reset!
105:         responses.concat pairs.to_a
106:         if block_given?
107:           yield Responder.new(responses)
108:         else
109:           Responder.new(responses)
110:         end
111:       end
responses()

Returns the list of requests and their mocked responses. Look up a response for a request using responses.assoc(request).

[Source]

    # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 97
97:       def responses
98:         @@responses ||= []
99:       end


Class: ActiveResource::InvalidRequestError

Class | ActiveResource::InvalidRequestError
In: | vendor/rails/activeresource/lib/active_resource/http_mock.rb
Parent: | StandardError


Class: ActiveResource::Request

Class | ActiveResource::Request
In: | vendor/rails/activeresource/lib/active_resource/http_mock.rb
Parent: | Object

Methods

== new to_s

Attributes

body | [RW]
headers | [RW]
method | [RW]
path | [RW]

Public Class methods

new(method, path, body = nil, headers = {})

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 148
148:     def initialize(method, path, body = nil, headers = {})
149:       @method, @path, @body, @headers = method, path, body, headers.merge(ActiveResource::Connection::HTTP_FORMAT_HEADER_NAMES[method] => 'application/xml')
150:     end

Public Instance methods

==(req)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 152
152:     def ==(req)
153:       path == req.path && method == req.method && headers == req.headers
154:     end
to_s()

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 156
156:     def to_s
157:       "<#{method.to_s.upcase}: #{path} [#{headers}] (#{body})>"
158:     end


Class: ActiveResource::ResourceConflict

Class | ActiveResource::ResourceConflict
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ClientError

409 Conflict


Class: ActiveResource::ResourceNotFound

Class | ActiveResource::ResourceNotFound
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ClientError

404 Not Found


Class: ActiveResource::Response

Class | ActiveResource::Response
In: | vendor/rails/activeresource/lib/active_resource/http_mock.rb
Parent: | Object

Methods

== [] []= new success?

Attributes

body | [RW]
code | [RW]
headers | [RW]
message | [RW]

Public Class methods

new(body, message = 200, headers = {})

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 164
164:     def initialize(body, message = 200, headers = {})
165:       @body, @message, @headers = body, message.to_s, headers
166:       @code = @message[0,3].to_i
167:
168:       resp_cls = Net::HTTPResponse::CODE_TO_OBJ[@code.to_s]
169:       if resp_cls && !resp_cls.body_permitted?
170:         @body = nil
171:       end
172:
173:       if @body.nil?
174:         self['Content-Length'] = "0"
175:       else
176:         self['Content-Length'] = body.size.to_s
177:       end
178:     end

Public Instance methods

==(other)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 192
192:     def ==(other)
193:       if (other.is_a?(Response))
194:         other.body == body && other.message == message && other.headers == headers
195:       else
196:         false
197:       end
198:     end
[](key)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 184
184:     def [](key)
185:       headers[key]
186:     end
[]=(key, value)

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 188
188:     def []=(key, value)
189:       headers[key] = value
190:     end
success?()

[Source]

     # File vendor/rails/activeresource/lib/active_resource/http_mock.rb, line 180
180:     def success?
181:       (200..299).include?(code)
182:     end


Class: ActiveResource::ServerError

Class | ActiveResource::ServerError
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ConnectionError

5xx Server Error


Class: ActiveResource::TimeoutError

Class | ActiveResource::TimeoutError
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ConnectionError

Raised when a Timeout::Error occurs.

Methods

new to_s

Public Class methods

new(message)

[Source]

    # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 23
23:     def initialize(message)
24:       @message = message
25:     end

Public Instance methods

to_s()

[Source]

    # File vendor/rails/activeresource/lib/active_resource/connection.rb, line 26
26:     def to_s; @message ;end


Class: ActiveResource::UnauthorizedAccess

Class | ActiveResource::UnauthorizedAccess
In: | vendor/rails/activeresource/lib/active_resource/connection.rb
Parent: | ClientError

401 Unauthorized


Module: ActiveResource::Validations

Module | ActiveResource::Validations
In: | vendor/rails/activeresource/lib/active_resource/validations.rb

Module to support validation and errors with Active Resource objects. The module overrides Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned in the web service response. The module also adds an errors collection that mimics the interface of the errors provided by ActiveRecord::Errors.

Example

Consider a Person resource on the server requiring both a first_name and a last_name with a validates_presence_of :first_name, :last_name declaration in the model:

  person = Person.new(:first_name => "Jim", :last_name => "")
  person.save                   # => false (server returns an HTTP 422 status code and errors)
  person.valid?                 # => false
  person.errors.empty?          # => false
  person.errors.count           # => 1
  person.errors.full_messages   # => ["Last name can't be empty"]
  person.errors.on(:last_name)  # => "can't be empty"
  person.last_name = "Halpert"
  person.save                   # => true (and person is now saved to the remote service)

Methods

errors save_with_validation valid?

Public Instance methods

errors()

Returns the Errors object that holds all information about attribute error messages.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 270
270:     def errors
271:       @errors ||= Errors.new(self)
272:     end
save_with_validation()

Validate a resource and save (POST) it to the remote web service.

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 247
247:     def save_with_validation
248:       save_without_validation
249:       true
250:     rescue ResourceInvalid => error
251:       errors.from_xml(error.response.body)
252:       false
253:     end
valid?()

Checks for errors on an object (i.e., is resource.errors empty?).

Examples

  my_person = Person.create(params[:person])
  my_person.valid?
  # => true

  my_person.errors.add('login', 'can not be empty') if my_person.login == ''
  my_person.valid?
  # => false

[Source]

     # File vendor/rails/activeresource/lib/active_resource/validations.rb, line 265
265:     def valid?
266:       errors.empty?
267:     end


File: active_resource.rb

active_resource.rb

Path: | vendor/rails/activeresource/lib/active_resource.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_support active_support active_resource/formats active_resource/base active_resource/validations active_resource/custom_methods


File: base.rb

base.rb

Path: | vendor/rails/activeresource/lib/active_resource/base.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_resource/connection cgi set


File: connection.rb

connection.rb

Path: | vendor/rails/activeresource/lib/active_resource/connection.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

net/https date time uri benchmark


File: custom_methods.rb

custom_methods.rb

Path: | vendor/rails/activeresource/lib/active_resource/custom_methods.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: formats.rb

formats.rb

Path: | vendor/rails/activeresource/lib/active_resource/formats.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_resource/formats/xml_format active_resource/formats/json_format


File: json_format.rb

json_format.rb

Path: | vendor/rails/activeresource/lib/active_resource/formats/json_format.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: xml_format.rb

xml_format.rb

Path: | vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: http_mock.rb

http_mock.rb

Path: | vendor/rails/activeresource/lib/active_resource/http_mock.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_resource/connection


File: validations.rb

validations.rb

Path: | vendor/rails/activeresource/lib/active_resource/validations.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: version.rb

version.rb

Path: | vendor/rails/activeresource/lib/active_resource/version.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/activeresource/CHANGELOG
Last Update: | Sun Mar 15 23:31:37 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • Nothing new, just included in 2.3.2

*2.2.1 [RC2] (November 14th, 2008)*

  • Fixed that ActiveResource#post would post an empty string when it shouldn‘t be posting anything 525 [Paolo Angelini]

*2.2.0 [RC1] (October 24th, 2008)*

  • Add ActiveResource::Base#to_xml and ActiveResource::Base#to_json. 1011 [Rasik Pandey, Cody Fauser]
  • Add ActiveResource::Base.find(:last). [754 state:resolved] (Adrian Mugnolo)
  • Fixed problems with the logger used if the logging string included %’s [840 state:resolved] (Jamis Buck)
  • Fixed Base#exists? to check status code as integer [299 state:resolved] (Wes Oldenbeuving)

*2.1.0 (May 31st, 2008)*

  • Fixed response logging to use length instead of the entire thing (seangeo) [27]
  • Fixed that to_param should be used and honored instead of hardcoding the id 11406 [gspiers]
  • Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert]
  • Use HEAD instead of GET in exists? [bscofield]
  • Fix small documentation typo. Closes 10670 [Luca Guidi]
  • find_or_create_resource_for handles module nesting. 10646 [xavier]
  • Allow setting ActiveResource::Base#format before site. [Rick Olson]
  • Support agnostic formats when calling custom methods. Closes 10635 [joerichsen]
  • Document custom methods. 10589 [Cheah Chu Yeow]
  • Ruby 1.9 compatibility. [Jeremy Kemper]

*2.0.2* (December 16th, 2007)

  • Added more specific exceptions for 400, 401, and 403 (all descending from ClientError so existing rescues will work) 10326 [trek]
  • Correct empty response handling. 10445 [seangeo]

*2.0.1* (December 7th, 2007)

  • Don‘t cache net/http object so that ActiveResource is more thread-safe. Closes 10142 [kou]
  • Update XML documentation examples to include explicit type attributes. Closes 9754 [Josh Susser]
  • Added one-off declarations of mock behavior [David Heinemeier Hansson]. Example:
      Before:
    ActiveResource::HttpMock.respond_to do |mock|
      mock.get "/people/1.xml", {}, "<person><name>David</name></person>"
    end

  Now:
    ActiveResource::HttpMock.respond_to.get "/people/1.xml", {}, "<person><name>David</name></person>"
  • Added ActiveResource.format= which defaults to :xml but can also be set to :json [David Heinemeier Hansson]. Example:
      class Person < ActiveResource::Base
    self.site   = "http://app/"
    self.format = :json
  end

  person = Person.find(1) # => GET http://app/people/1.json
  person.name = "David"
  person.save             # => PUT http://app/people/1.json {name: "David"}

  Person.format = :xml
  person.name = "Mary"
  person.save             # => PUT http://app/people/1.json <person><name>Mary</name></person>
  • Fix reload error when path prefix is used. 8727 [Ian Warshak]
  • Remove ActiveResource::Struct because it hasn‘t proven very useful. Creating a new ActiveResource::Base subclass is often less code and always clearer. 8612 [Josh Peek]
  • Fix query methods on resources. [Cody Fauser]
  • pass the prefix_options to the instantiated record when using find without a specific id. Closes 8544 [Eloy Duran]
  • Recognize and raise an exception on 405 Method Not Allowed responses. 7692 [Josh Peek]
  • Handle string and symbol param keys when splitting params into prefix params and query params.
      Comment.find(:all, :params => { :article_id => 5, :page => 2 }) or Comment.find(:all, :params => { 'article_id' => 5, :page => 2 })
  • Added find-one with symbol [David Heinemeier Hansson]. Example: Person.find(:one, :from => :leader) # => GET /people/leader.xml
  • BACKWARDS INCOMPATIBLE: Changed the finder API to be more extensible with :params and more strict usage of scopes [David Heinemeier Hansson]. Changes:
      Person.find(:all, :title => "CEO")      ...becomes: Person.find(:all, :params => { :title => "CEO" })
  Person.find(:managers)                  ...becomes: Person.find(:all, :from => :managers)
  Person.find("/companies/1/manager.xml") ...becomes: Person.find(:one, :from => "/companies/1/manager.xml")
  • Add support for setting custom headers per Active Resource model [Rick Olson]

    class Project

      headers['X-Token'] = 'foo'

    end

    # makes the GET request with the custom X-Token header Project.find(:all)

  • Added find-by-path options to ActiveResource::Base.find [David Heinemeier Hansson]. Examples:
      employees = Person.find(:all, :from => "/companies/1/people.xml") # => GET /companies/1/people.xml
  manager   = Person.find("/companies/1/manager.xml")               # => GET /companies/1/manager.xml
  • Added support for using classes from within a single nested module [David Heinemeier Hansson]. Example:
      module Highrise
    class Note < ActiveResource::Base
      self.site = "http://37s.sunrise.i:3000"
    end

    class Comment < ActiveResource::Base
      self.site = "http://37s.sunrise.i:3000"
    end
  end

    assert_kind_of Highrise::Comment, Note.find(1).comments.first

  • Added load_attributes_from_response as a way of loading attributes from other responses than just create [David Heinemeier Hansson]
      class Highrise::Task < ActiveResource::Base
    def complete
      load_attributes_from_response(post(:complete))
    end
  end

    …will set "done_at" when complete is called.

  • Added support for calling custom methods 6979 [rwdaigle]
      Person.find(:managers)    # => GET /people/managers.xml
  Kase.find(1).post(:close) # => POST /kases/1/close.xml
  • Remove explicit prefix_options parameter for ActiveResource::Base#initialize. [Rick Olson] ActiveResource splits the prefix_options from it automatically.
  • Allow ActiveResource::Base.delete with custom prefix. [Rick Olson]
  • Add ActiveResource::Base#dup [Rick Olson]
  • Fixed constant warning when fetching the same object multiple times [David Heinemeier Hansson]
  • Added that saves which get a body response (and not just a 201) will use that response to update themselves [David Heinemeier Hansson]
  • Disregard namespaces from the default element name, so Highrise::Person will just try to fetch from "/people", not "/highrise/people" [David Heinemeier Hansson]
  • Allow array and hash query parameters. 7756 [Greg Spurrier]
  • Loading a resource preserves its prefix_options. 7353 [Ryan Daigle]
  • Carry over the convenience of create from ActiveRecord. Closes 7340. [Ryan Daigle]
  • Increase ActiveResource::Base test coverage. Closes 7173, 7174 [Rich Collins]
  • Interpret 422 Unprocessable Entity as ResourceInvalid. 7097 [dkubb]
  • Mega documentation patches. 7025, 7069 [rwdaigle]
  • Base.exists?(id, options) and Base#exists? check whether the resource is found. 6970 [rwdaigle]
  • Query string support. [untext, Jeremy Kemper]
      # GET /forums/1/topics.xml?sort=created_at
  Topic.find(:all, :forum_id => 1, :sort => 'created_at')
  • Base#==, eql?, and hash methods. == returns true if its argument is identical to self or if it‘s an instance of the same class, is not new?, and has the same id. eql? is an alias for ==. hash delegates to id. [Jeremy Kemper]
  • Allow subclassed resources to share the site info [Rick Olson, Jeremy Kemper]

d

    class BeastResource < ActiveResource::Base
      self.site = 'http://beast.caboo.se'
    end

    class Forum < BeastResource
      # taken from BeastResource
      # self.site = 'http://beast.caboo.se'
    end

    class Topic < BeastResource
      self.site += '/forums/:forum_id'
    end
  • Fix issues with ActiveResource collection handling. Closes 6291. [bmilekic]
  • Use attr_accessor_with_default to dry up attribute initialization. References 6538. [Stuart Halloway]
  • Add basic logging support for logging outgoing requests. [Jamis Buck]
  • Add Base.delete for deleting resources without having to instantiate them first. [Jamis Buck]
  • Make save behavior mimic AR::Base#save (true on success, false on failure). [Jamis Buck]
  • Add Basic HTTP Authentication to ActiveResource (closes 6305). [jonathan]
  • Extracted id_from_response as an entry point for customizing how a created resource gets its own ID. By default, it extracts from the Location response header.
  • Optimistic locking: raise ActiveResource::ResourceConflict on 409 Conflict response. [Jeremy Kemper]
      # Example controller action
  def update
    @person.save!
  rescue ActiveRecord::StaleObjectError
    render :xml => @person.reload.to_xml, :status => '409 Conflict'
  end
  • Basic validation support [Rick Olson]

    Parses the xml response of ActiveRecord::Errors#to_xml with a similar interface to ActiveRecord::Errors.

      render :xml => @person.errors.to_xml, :status => '400 Validation Error'
  • Deep hashes are converted into collections of resources. [Jeremy Kemper]
      Person.new :name => 'Bob',
             :address => { :id => 1, :city => 'Portland' },
             :contacts => [{ :id => 1 }, { :id => 2 }]

    Looks for Address and Contact resources and creates them if unavailable. So clients can fetch a complex resource in a single request if you e.g.

      render :xml => @person.to_xml(:include => [:address, :contacts])

    in your controller action.

  • Major updates [Rick Olson]
    • Add full support for find/create/update/destroy
    • Add support for specifying prefixes.
    • Allow overriding of element_name, collection_name, and primary key
    • Provide simpler HTTP mock interface for testing

      # rails routing code map.resources :posts do |post|

        post.resources :comments

      end

      # ActiveResources class Post < ActiveResource::Base

        self.site = "http://37s.sunrise.i:3000/"

      end

      class Comment < ActiveResource::Base

        self.site = "http://37s.sunrise.i:3000/posts/:post_id/"

      end

      @post = Post.find 5 @comments = Comment.find :all, :post_id => @post.id

      @comment = Comment.new({:body => ‘hello world’}, {:post_id => @post.id}) @comment.save

  • Base.site= accepts URIs. 200...400 are valid response codes. PUT and POST request bodies default to ’’. [Jeremy Kemper]
  • Initial checkin: object-oriented client for restful HTTP resources which follow the Rails convention. [David Heinemeier Hansson]


File: README

README

Path: | vendor/rails/activesupport/README
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Active Support — Utility classes and standard library extensions from Rails

Active Support is a collection of various utility classes and standard library extensions that were found useful for Rails. All these additions have hence been collected in this bundle as way to gather all that sugar that makes Ruby sweeter.

Download

The latest version of Active Support can be found at

  • rubyforge.org/project/showfiles.php?group_id=182

Documentation can be found at

  • as.rubyonrails.com

Installation

The preferred method of installing Active Support is through its GEM file. You‘ll need to have RubyGems installed for that, though. If you have it, then use:

  % [sudo] gem install activesupport-1.0.0.gem

License

Active Support is released under the MIT license.

Support

The Active Support homepage is www.rubyonrails.com. You can find the Active Support RubyForge page at rubyforge.org/projects/activesupport. And as Jim from Rake says:

   Feel free to submit commits or feature requests.  If you send a patch,
   remember to update the corresponding unit tests.  If fact, I prefer
   new feature to be submitted in the form of new unit tests.

For other information, feel free to ask on the ruby-talk mailing list (which is mirrored to comp.lang.ruby) or contact david@loudthinking.com.


Class: ActiveSupport::BacktraceCleaner

Class | ActiveSupport::BacktraceCleaner
In: | vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb
Parent: | Object

Many backtraces include too much information that‘s not relevant for the context. This makes it hard to find the signal in the backtrace and adds debugging time. With a BacktraceCleaner, you can setup filters and silencers for your particular context, so only the relevant lines are included.

If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always call BacktraceCleaner#remove_silencers!

Example:

  bc = BacktraceCleaner.new
  bc.add_filter   { |line| line.gsub(Rails.root, '') }
  bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
  bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems

Inspired by the Quiet Backtrace gem by Thoughtbot.

Methods

add_filter add_silencer clean new remove_silencers!

Public Class methods

new()

[Source]

    # File vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb, line 18
18:     def initialize
19:       @filters, @silencers = [], []
20:     end

Public Instance methods

add_filter(&block)

Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.

Example:

  # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
  backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }

[Source]

    # File vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb, line 33
33:     def add_filter(&block)
34:       @filters << block
35:     end
add_silencer(&block)

Adds a silencer from the block provided. If the silencer returns true for a given line, it‘ll be excluded from the clean backtrace.

Example:

  # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
  backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }

[Source]

    # File vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb, line 44
44:     def add_silencer(&block)
45:       @silencers << block
46:     end
clean(backtrace)

Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.

[Source]

    # File vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb, line 23
23:     def clean(backtrace)
24:       silence(filter(backtrace))
25:     end
remove_silencers!()

Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as you suspect a bug in the libraries you use.

[Source]

    # File vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb, line 50
50:     def remove_silencers!
51:       @silencers = []
52:     end


Module: ActiveSupport::Base64

Module | ActiveSupport::Base64
In: | vendor/rails/activesupport/lib/active_support/base64.rb

Base64 provides utility methods for encoding and de-coding binary data using a base 64 representation. A base 64 representation of binary data consists entirely of printable US-ASCII characters. The Base64 module is included in Ruby 1.8, but has been removed in Ruby 1.9.

Methods

decode64 encode64

Public Class methods

decode64(data)

Decodes a base 64 encoded string to its original representation.

 ActiveSupport::Base64.decode64("T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==")
 # => "Original unencoded string"

[Source]

    # File vendor/rails/activesupport/lib/active_support/base64.rb, line 28
28:       def self.decode64(data)
29:         data.unpack("m").first
30:       end
encode64(data)

Encodes a string to its base 64 representation. Each 60 characters of output is separated by a newline character.

 ActiveSupport::Base64.encode64("Original unencoded string")
 # => "T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw==\n"

[Source]

    # File vendor/rails/activesupport/lib/active_support/base64.rb, line 20
20:       def self.encode64(data)
21:         [data].pack("m")
22:       end


Class: ActiveSupport::BasicObject

Class | ActiveSupport::BasicObject
In: | vendor/rails/activesupport/lib/active_support/basic_object.rb
Parent: | ::BasicObject

Methods

raise

Public Instance methods

raise(*args)

Let ActiveSupport::BasicObject at least raise exceptions.

[Source]

    # File vendor/rails/activesupport/lib/active_support/basic_object.rb, line 16
16:       def raise(*args)
17:         ::Object.send(:raise, *args)
18:       end


Class: ActiveSupport::BufferedLogger

Class | ActiveSupport::BufferedLogger
In: | vendor/rails/activesupport/lib/active_support/buffered_logger.rb
Parent: | Object

Inspired by the buffered logger idea by Ezra

Methods

add auto_flush auto_flushing= buffer clear_buffer close flush new silence

Included Modules

Severity

Classes and Modules

Module ActiveSupport::BufferedLogger::Severity

Constants

MAX_BUFFER_SIZE = 1000

Attributes

auto_flushing | [R]
level | [RW]

Public Class methods

new(log, level = DEBUG)

[Source]

    # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 39
39:     def initialize(log, level = DEBUG)
40:       @level         = level
41:       @buffer        = {}
42:       @auto_flushing = 1
43:       @guard = Mutex.new
44:
45:       if log.respond_to?(:write)
46:         @log = log
47:       elsif File.exist?(log)
48:         @log = open(log, (File::WRONLY | File::APPEND))
49:         @log.sync = true
50:       else
51:         FileUtils.mkdir_p(File.dirname(log))
52:         @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
53:         @log.sync = true
54:         @log.write("# Logfile created on %s" % [Time.now.to_s])
55:       end
56:     end

Public Instance methods

add(severity, message = nil, progname = nil, &block)

[Source]

    # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 58
58:     def add(severity, message = nil, progname = nil, &block)
59:       return if @level > severity
60:       message = (message || (block && block.call) || progname).to_s
61:       # If a newline is necessary then create a new message ending with a newline.
62:       # Ensures that the original message is not mutated.
63:       message = "#{message}\n" unless message[-1] == ?\n
64:       buffer << message
65:       auto_flush
66:       message
67:     end
auto_flushing=(period)

Set the auto-flush period. Set to true to flush after every log message, to an integer to flush every N messages, or to false, nil, or zero to never auto-flush. If you turn auto-flushing off, be sure to regularly flush the log yourself — it will eat up memory until you do.

[Source]

    # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 86
86:     def auto_flushing=(period)
87:       @auto_flushing =
88:         case period
89:         when true;                1
90:         when false, nil, 0;       MAX_BUFFER_SIZE
91:         when Integer;             period
92:         else raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
93:         end
94:     end
close()

[Source]

     # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 109
109:     def close
110:       flush
111:       @log.close if @log.respond_to?(:close)
112:       @log = nil
113:     end
flush()

[Source]

     # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 96
 96:     def flush
 97:       @guard.synchronize do
 98:         unless buffer.empty?
 99:           old_buffer = buffer
100:           @log.write(old_buffer.join)
101:         end
102:
103:         # Important to do this even if buffer was empty or else @buffer will
104:         # accumulate empty arrays for each request where nothing was logged.
105:         clear_buffer
106:       end
107:     end
silence(temporary_level = ERROR) {|self| ...}

Silences the logger for the duration of the block.

[Source]

    # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 23
23:     def silence(temporary_level = ERROR)
24:       if silencer
25:         begin
26:           old_logger_level, self.level = level, temporary_level
27:           yield self
28:         ensure
29:           self.level = old_logger_level
30:         end
31:       else
32:         yield self
33:       end
34:     end

Protected Instance methods

auto_flush()

[Source]

     # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 116
116:       def auto_flush
117:         flush if buffer.size >= @auto_flushing
118:       end
buffer()

[Source]

     # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 120
120:       def buffer
121:         @buffer[Thread.current] ||= []
122:       end
clear_buffer()

[Source]

     # File vendor/rails/activesupport/lib/active_support/buffered_logger.rb, line 124
124:       def clear_buffer
125:         @buffer.delete(Thread.current)
126:       end


Module: ActiveSupport::BufferedLogger::Severity

Module | ActiveSupport::BufferedLogger::Severity
In: | vendor/rails/activesupport/lib/active_support/buffered_logger.rb

Constants

DEBUG | = | 0
INFO | = | 1
WARN | = | 2
ERROR | = | 3
FATAL | = | 4
UNKNOWN | = | 5


Module: ActiveSupport::Cache

Module | ActiveSupport::Cache
In: | vendor/rails/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb vendor/rails/activesupport/lib/active_support/cache/drb_store.rb vendor/rails/activesupport/lib/active_support/cache/file_store.rb vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb vendor/rails/activesupport/lib/active_support/cache/memory_store.rb vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb vendor/rails/activesupport/lib/active_support/cache.rb

See ActiveSupport::Cache::Store for documentation.

Methods

expand_cache_key lookup_store

Classes and Modules

Module ActiveSupport::Cache::Strategy
Class ActiveSupport::Cache::CompressedMemCacheStore
Class ActiveSupport::Cache::FileStore
Class ActiveSupport::Cache::MemCacheStore
Class ActiveSupport::Cache::MemoryStore
Class ActiveSupport::Cache::Store
Class ActiveSupport::Cache::SynchronizedMemoryStore

Public Class methods

expand_cache_key(key, namespace = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache.rb, line 57
57:     def self.expand_cache_key(key, namespace = nil)
58:       expanded_cache_key = namespace ? "#{namespace}/" : ""
59:
60:       if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
61:         expanded_cache_key << "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/"
62:       end
63:
64:       expanded_cache_key << case
65:         when key.respond_to?(:cache_key)
66:           key.cache_key
67:         when key.is_a?(Array)
68:           key.collect { |element| expand_cache_key(element) }.to_param
69:         when key
70:           key.to_param
71:         end.to_s
72:
73:       expanded_cache_key
74:     end
lookup_store(*store_option)

Creates a new CacheStore object according to the given options.

If no arguments are passed to this method, then a new ActiveSupport::Cache::MemoryStore object will be returned.

If you pass a Symbol as the first argument, then a corresponding cache store class under the ActiveSupport::Cache namespace will be created. For example:

  ActiveSupport::Cache.lookup_store(:memory_store)
  # => returns a new ActiveSupport::Cache::MemoryStore object

  ActiveSupport::Cache.lookup_store(:drb_store)
  # => returns a new ActiveSupport::Cache::DRbStore object

Any additional arguments will be passed to the corresponding cache store class‘s constructor:

  ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache")
  # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache")

If the first argument is not a Symbol, then it will simply be returned:

  ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
  # => returns MyOwnCacheStore.new

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache.rb, line 42
42:     def self.lookup_store(*store_option)
43:       store, *parameters = *([ store_option ].flatten)
44:
45:       case store
46:       when Symbol
47:         store_class_name = (store == :drb_store ? "DRbStore" : store.to_s.camelize)
48:         store_class = ActiveSupport::Cache.const_get(store_class_name)
49:         store_class.new(*parameters)
50:       when nil
51:         ActiveSupport::Cache::MemoryStore.new
52:       else
53:         store
54:       end
55:     end


Class: ActiveSupport::Cache::CompressedMemCacheStore

Class | ActiveSupport::Cache::CompressedMemCacheStore
In: | vendor/rails/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb
Parent: | MemCacheStore

Methods

read write

Public Instance methods

read(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb, line 4
 4:       def read(name, options = nil)
 5:         if value = super(name, (options || {}).merge(:raw => true))
 6:           if raw?(options)
 7:             value
 8:           else
 9:             Marshal.load(ActiveSupport::Gzip.decompress(value))
10:           end
11:         end
12:       end
write(name, value, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb, line 14
14:       def write(name, value, options = nil)
15:         value = ActiveSupport::Gzip.compress(Marshal.dump(value)) unless raw?(options)
16:         super(name, value, (options || {}).merge(:raw => true))
17:       end


Class: ActiveSupport::Cache::FileStore

Class | ActiveSupport::Cache::FileStore
In: | vendor/rails/activesupport/lib/active_support/cache/file_store.rb
Parent: | Store

A cache store implementation which stores everything on the filesystem.

Methods

delete delete_matched exist? new read write

Attributes

cache_path [R]

Public Class methods

new(cache_path)

[Source]

   # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 7
7:       def initialize(cache_path)
8:         @cache_path = cache_path
9:       end

Public Instance methods

delete(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 25
25:       def delete(name, options = nil)
26:         super
27:         File.delete(real_file_path(name))
28:       rescue SystemCallError => e
29:         # If there's no cache, then there's nothing to complain about
30:       end
delete_matched(matcher, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 32
32:       def delete_matched(matcher, options = nil)
33:         super
34:         search_dir(@cache_path) do |f|
35:           if f =~ matcher
36:             begin
37:               File.delete(f)
38:             rescue SystemCallError => e
39:               # If there's no cache, then there's nothing to complain about
40:             end
41:           end
42:         end
43:       end
exist?(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 45
45:       def exist?(name, options = nil)
46:         super
47:         File.exist?(real_file_path(name))
48:       end
read(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 11
11:       def read(name, options = nil)
12:         super
13:         File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil
14:       end
write(name, value, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/file_store.rb, line 16
16:       def write(name, value, options = nil)
17:         super
18:         ensure_cache_path(File.dirname(real_file_path(name)))
19:         File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) }
20:         value
21:       rescue => e
22:         logger.error "Couldn't create cache directory: #{name} (#{e.message})" if logger
23:       end


Class: ActiveSupport::Cache::MemCacheStore

Class | ActiveSupport::Cache::MemCacheStore
In: | vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb
Parent: | Store

A cache store implementation which stores data in Memcached: www.danga.com/memcached/

This is currently the most popular cache store for production websites.

Special features:

  • Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online.
  • Time-based expiry support. See write and the +:expires_in+ option.
  • Per-request in memory cache for all communication with the MemCache server(s).

Methods

clear new stats write

Attributes

addresses [R]

Public Class methods

new(*addresses)

Creates a new MemCacheStore object, with the given memcached server addresses. Each address is either a host name, or a host-with-port string in the form of "host_name:port". For example:

  ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")

If no addresses are specified, then MemCacheStore will connect to localhost port 11211 (the default memcached port).

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb, line 36
36:       def initialize(*addresses)
37:         addresses = addresses.flatten
38:         options = addresses.extract_options!
39:         addresses = ["localhost"] if addresses.empty?
40:         @addresses = addresses
41:         @data = MemCache.new(addresses, options)
42:
43:         extend Strategy::LocalCache
44:       end

Public Instance methods

clear()

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb, line 114
114:       def clear
115:         @data.flush_all
116:       end
stats()

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb, line 118
118:       def stats
119:         @data.stats
120:       end
write(key, value, options = nil)

Writes a value to the cache.

Possible options:

  • +:unless_exist+ - set to true if you don‘t want to update the cache if the key is already set.
  • +:expires_in+ - the number of seconds that this value may stay in the cache. See ActiveSupport::Cache::Store#write for an example.

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb, line 61
61:       def write(key, value, options = nil)
62:         super
63:         method = options && options[:unless_exist] ? :add : :set
64:         # memcache-client will break the connection if you send it an integer
65:         # in raw mode, so we convert it to a string to be sure it continues working.
66:         value = value.to_s if raw?(options)
67:         response = @data.send(method, key, value, expires_in(options), raw?(options))
68:         response == Response::STORED
69:       rescue MemCache::MemCacheError => e
70:         logger.error("MemCacheError (#{e}): #{e.message}")
71:         false
72:       end


Class: ActiveSupport::Cache::MemoryStore

Class | ActiveSupport::Cache::MemoryStore
In: | vendor/rails/activesupport/lib/active_support/cache/memory_store.rb
Parent: | Store

A cache store implementation which stores everything into memory in the same process. If you‘re running multiple Ruby on Rails server processes (which is the case if you‘re using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won‘t be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using MemoryStore is ok. Otherwise, consider carefully whether you should be using this cache store.

MemoryStore is not only able to store strings, but also arbitrary Ruby objects.

MemoryStore is not thread-safe. Use SynchronizedMemoryStore instead if you need thread-safety.

Methods

clear delete delete_matched exist? new read write

Public Class methods

new()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 18
18:       def initialize
19:         @data = {}
20:       end

Public Instance methods

clear()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 47
47:       def clear
48:         @data.clear
49:       end
delete(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 32
32:       def delete(name, options = nil)
33:         super
34:         @data.delete(name)
35:       end
delete_matched(matcher, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 37
37:       def delete_matched(matcher, options = nil)
38:         super
39:         @data.delete_if { |k,v| k =~ matcher }
40:       end
exist?(name,options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 42
42:       def exist?(name,options = nil)
43:         super
44:         @data.has_key?(name)
45:       end
read(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 22
22:       def read(name, options = nil)
23:         super
24:         @data[name]
25:       end
write(name, value, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/memory_store.rb, line 27
27:       def write(name, value, options = nil)
28:         super
29:         @data[name] = value.freeze
30:       end


Class: ActiveSupport::Cache::Store

Class | ActiveSupport::Cache::Store
In: | vendor/rails/activesupport/lib/active_support/cache.rb
Parent: | Object

An abstract cache store class. There are multiple cache store implementations, each having its own additional features. See the classes under the ActiveSupport::Cache module, e.g. ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most popular cache store for large production websites.

ActiveSupport::Cache::Store is meant for caching strings. Some cache store implementations, like MemoryStore, are able to cache arbitrary Ruby objects, but don‘t count on every cache store to be able to do that.

  cache = ActiveSupport::Cache::MemoryStore.new

  cache.read("city")   # => nil
  cache.write("city", "Duckburgh")
  cache.read("city")   # => "Duckburgh"

Methods

decrement delete delete_matched exist? fetch increment read silence! write

Public Instance methods

decrement(key, amount = 1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 213
213:       def decrement(key, amount = 1)
214:         log("decrementing", key, amount)
215:         if num = read(key)
216:           write(key, num - amount)
217:         else
218:           nil
219:         end
220:       end
delete(key, options = nil)

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 192
192:       def delete(key, options = nil)
193:         log("delete", key, options)
194:       end
delete_matched(matcher, options = nil)

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 196
196:       def delete_matched(matcher, options = nil)
197:         log("delete matched", matcher.inspect, options)
198:       end
exist?(key, options = nil)

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 200
200:       def exist?(key, options = nil)
201:         log("exist?", key, options)
202:       end
fetch(key, options = {}) {|| ...}

Fetches data from the cache, using the given key. If there is data in the cache with the given key, then that data is returned.

If there is no such data in the cache (a cache miss occurred), then then nil will be returned. However, if a block has been passed, then that block will be run in the event of a cache miss. The return value of the block will be written to the cache under the given cache key, and that return value will be returned.

  cache.write("today", "Monday")
  cache.fetch("today")  # => "Monday"

  cache.fetch("city")   # => nil
  cache.fetch("city") do
    "Duckburgh"
  end
  cache.fetch("city")   # => "Duckburgh"

You may also specify additional options via the options argument. Setting :force => true will force a cache miss:

  cache.write("today", "Monday")
  cache.fetch("today", :force => true)  # => nil

Other options will be handled by the specific cache store implementation. Internally, fetch calls read, and calls write on a cache miss. options will be passed to the read and write calls.

For example, MemCacheStore‘s write method supports the +:expires_in+ option, which tells the memcached server to automatically expire the cache item after a certain period. We can use this option with fetch too:

  cache = ActiveSupport::Cache::MemCacheStore.new
  cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
    "bar"
  end
  cache.fetch("foo")  # => "bar"
  sleep(6)
  cache.fetch("foo")  # => nil

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 139
139:       def fetch(key, options = {})
140:         @logger_off = true
141:         if !options[:force] && value = read(key, options)
142:           @logger_off = false
143:           log("hit", key, options)
144:           value
145:         elsif block_given?
146:           @logger_off = false
147:           log("miss", key, options)
148:
149:           value = nil
150:           ms = Benchmark.ms { value = yield }
151:
152:           @logger_off = true
153:           write(key, value, options)
154:           @logger_off = false
155:
156:           log('write (will save %.2fms)' % ms, key, nil)
157:
158:           value
159:         end
160:       end
increment(key, amount = 1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 204
204:       def increment(key, amount = 1)
205:         log("incrementing", key, amount)
206:         if num = read(key)
207:           write(key, num + amount)
208:         else
209:           nil
210:         end
211:       end
read(key, options = nil)

Fetches data from the cache, using the given key. If there is data in the cache with the given key, then that data is returned. Otherwise, nil is returned.

You may also specify additional options via the options argument. The specific cache store implementation will decide what to do with options.

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 169
169:       def read(key, options = nil)
170:         log("read", key, options)
171:       end
silence!()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache.rb, line 94
94:       def silence!
95:         @silence = true
96:         self
97:       end
write(key, value, options = nil)

Writes the given value to the cache, with the given key.

You may also specify additional options via the options argument. The specific cache store implementation will decide what to do with options.

For example, MemCacheStore supports the +:expires_in+ option, which tells the memcached server to automatically expire the cache item after a certain period:

  cache = ActiveSupport::Cache::MemCacheStore.new
  cache.write("foo", "bar", :expires_in => 5.seconds)
  cache.read("foo")  # => "bar"
  sleep(6)
  cache.read("foo")  # => nil

[Source]

     # File vendor/rails/activesupport/lib/active_support/cache.rb, line 188
188:       def write(key, value, options = nil)
189:         log("write", key, options)
190:       end


Module: ActiveSupport::Cache::Strategy

Module | ActiveSupport::Cache::Strategy
In: | vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb vendor/rails/activesupport/lib/active_support/cache.rb

Classes and Modules

Module ActiveSupport::Cache::Strategy::LocalCache


Module: ActiveSupport::Cache::Strategy::LocalCache

Module | ActiveSupport::Cache::Strategy::LocalCache
In: | vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb

Methods

clear decrement delete exist increment middleware read with_local_cache write

Constants

NULL = 'remote_cache_store:null' this allows caching of the fact that there is nothing in the remote cache

Public Instance methods

clear()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 89
89:         def clear
90:           local_cache.clear if local_cache
91:           super
92:         end
decrement(key, amount = 1)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 80
80:         def decrement(key, amount = 1)
81:           if value = super
82:             local_cache.write(key, value.to_s) if local_cache
83:             value
84:           else
85:             nil
86:           end
87:         end
delete(key, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 55
55:         def delete(key, options = nil)
56:           local_cache.write(key, NULL) if local_cache
57:           super
58:         end
exist(key, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 60
60:         def exist(key, options = nil)
61:           value = local_cache.read(key) if local_cache
62:           if value == NULL
63:             false
64:           elsif value
65:             true
66:           else
67:             super
68:           end
69:         end
increment(key, amount = 1)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 71
71:         def increment(key, amount = 1)
72:           if value = super
73:             local_cache.write(key, value.to_s) if local_cache
74:             value
75:           else
76:             nil
77:           end
78:         end
middleware()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 15
15:         def middleware
16:           @middleware ||= begin
17:             klass = Class.new
18:             klass.class_eval("def initialize(app)\n@app = app\nend\n\ndef call(env)\nThread.current[:\#{thread_local_key}] = MemoryStore.new\n@app.call(env)\nensure\nThread.current[:\#{thread_local_key}] = nil\nend\n", __FILE__, __LINE__)
19:             klass
20:           end
21:         end
read(key, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 35
35:         def read(key, options = nil)
36:           value = local_cache && local_cache.read(key)
37:           if value == NULL
38:             nil
39:           elsif value.nil?
40:             value = super
41:             local_cache.write(key, value || NULL) if local_cache
42:             value
43:           else
44:             # forcing the value to be immutable
45:             value.duplicable? ? value.dup : value
46:           end
47:         end
with_local_cache() {|| ...}

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 8
 8:         def with_local_cache
 9:           Thread.current[thread_local_key] = MemoryStore.new
10:           yield
11:         ensure
12:           Thread.current[thread_local_key] = nil
13:         end
write(key, value, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb, line 49
49:         def write(key, value, options = nil)
50:           value = value.to_s if respond_to?(:raw?) && raw?(options)
51:           local_cache.write(key, value || NULL) if local_cache
52:           super
53:         end


Class: ActiveSupport::Cache::SynchronizedMemoryStore

Class | ActiveSupport::Cache::SynchronizedMemoryStore
In: | vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb
Parent: | MemoryStore

Like MemoryStore, but thread-safe.

Methods

clear decrement delete delete_matched exist? fetch increment new read write

Public Class methods

new()

[Source]

   # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 5
5:       def initialize
6:         super
7:         @guard = Monitor.new
8:       end

Public Instance methods

clear()

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 42
42:       def clear
43:         @guard.synchronize { super }
44:       end
decrement(key, amount = 1)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 38
38:       def decrement(key, amount = 1)
39:         @guard.synchronize { super }
40:       end
delete(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 22
22:       def delete(name, options = nil)
23:         @guard.synchronize { super }
24:       end
delete_matched(matcher, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 26
26:       def delete_matched(matcher, options = nil)
27:         @guard.synchronize { super }
28:       end
exist?(name,options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 30
30:       def exist?(name,options = nil)
31:         @guard.synchronize { super }
32:       end
fetch(key, options = {})

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 10
10:       def fetch(key, options = {})
11:         @guard.synchronize { super }
12:       end
increment(key, amount = 1)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 34
34:       def increment(key, amount = 1)
35:         @guard.synchronize { super }
36:       end
read(name, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 14
14:       def read(name, options = nil)
15:         @guard.synchronize { super }
16:       end
write(name, value, options = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb, line 18
18:       def write(name, value, options = nil)
19:         @guard.synchronize { super }
20:       end


Module: ActiveSupport::Callbacks

Module | ActiveSupport::Callbacks
In: | vendor/rails/activesupport/lib/active_support/callbacks.rb

Callbacks are hooks into the lifecycle of an object that allow you to trigger logic before or after an alteration of the object state.

Mixing in this module allows you to define callbacks in your class.

Example:

  class Storage
    include ActiveSupport::Callbacks

    define_callbacks :before_save, :after_save
  end

  class ConfigStorage < Storage
    before_save :saving_message
    def saving_message
      puts "saving..."
    end

    after_save do |object|
      puts "saved"
    end

    def save
      run_callbacks(:before_save)
      puts "- save"
      run_callbacks(:after_save)
    end
  end

  config = ConfigStorage.new
  config.save

Output:

  saving...
  - save
  saved

Callbacks from parent classes are inherited.

Example:

  class Storage
    include ActiveSupport::Callbacks

    define_callbacks :before_save, :after_save

    before_save :prepare
    def prepare
      puts "preparing save"
    end
  end

  class ConfigStorage < Storage
    before_save :saving_message
    def saving_message
      puts "saving..."
    end

    after_save do |object|
      puts "saved"
    end

    def save
      run_callbacks(:before_save)
      puts "- save"
      run_callbacks(:after_save)
    end
  end

  config = ConfigStorage.new
  config.save

Output:

  preparing save
  saving...
  - save
  saved

Methods

included run_callbacks

Classes and Modules

Module ActiveSupport::Callbacks::ClassMethods
Class ActiveSupport::Callbacks::Callback
Class ActiveSupport::Callbacks::CallbackChain

Public Class methods

included(base)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 200
200:     def self.included(base)
201:       base.extend ClassMethods
202:     end

Public Instance methods

run_callbacks(kind, options = {}, &block)

Runs all the callbacks defined for the given options.

If a block is given it will be called after each callback receiving as arguments:

 * the result from the callback
 * the object which has the callback

If the result from the block evaluates to false, the callback chain is stopped.

Example:

  class Storage
    include ActiveSupport::Callbacks

    define_callbacks :before_save, :after_save
  end

  class ConfigStorage < Storage
    before_save :pass
    before_save :pass
    before_save :stop
    before_save :pass

    def pass
      puts "pass"
    end

    def stop
      puts "stop"
      return false
    end

    def save
      result = run_callbacks(:before_save) { |result, object| result == false }
      puts "- save" if result
    end
  end

  config = ConfigStorage.new
  config.save

Output:

  pass
  pass
  stop

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 276
276:     def run_callbacks(kind, options = {}, &block)
277:       self.class.send("#{kind}_callback_chain").run(self, options, &block)
278:     end


Class: ActiveSupport::Callbacks::Callback

Class | ActiveSupport::Callbacks::Callback
In: | vendor/rails/activesupport/lib/active_support/callbacks.rb
Parent: | Object

Methods

== call dup eql? hash new

Attributes

identifier | [R]
kind | [R]
method | [R]
options | [R]

Public Class methods

new(kind, method, options = {})

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 133
133:       def initialize(kind, method, options = {})
134:         @kind       = kind
135:         @method     = method
136:         @identifier = options[:identifier]
137:         @options    = options
138:       end

Public Instance methods

==(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 140
140:       def ==(other)
141:         case other
142:         when Callback
143:           (self.identifier && self.identifier == other.identifier) || self.method == other.method
144:         else
145:           (self.identifier && self.identifier == other) || self.method == other
146:         end
147:       end
call(*args, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 165
165:       def call(*args, &block)
166:         evaluate_method(method, *args, &block) if should_run_callback?(*args)
167:       rescue LocalJumpError
168:         raise ArgumentError,
169:           "Cannot yield from a Proc type filter. The Proc must take two " +
170:           "arguments and execute #call on the second argument."
171:       end
dup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 153
153:       def dup
154:         self.class.new(@kind, @method, @options.dup)
155:       end
eql?(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 149
149:       def eql?(other)
150:         self == other
151:       end
hash()

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 157
157:       def hash
158:         if @identifier
159:           @identifier.hash
160:         else
161:           @method.hash
162:         end
163:       end


Class: ActiveSupport::Callbacks::CallbackChain

Class | ActiveSupport::Callbacks::CallbackChain
In: | vendor/rails/activesupport/lib/active_support/callbacks.rb
Parent: | Array

Methods

build delete find replace_or_append! run

Public Class methods

build(kind, *methods, &block)

[Source]

    # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 80
80:       def self.build(kind, *methods, &block)
81:         methods, options = extract_options(*methods, &block)
82:         methods.map! { |method| Callback.new(kind, method, options) }
83:         new(methods)
84:       end

Public Instance methods

delete(callback)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 113
113:       def delete(callback)
114:         super(callback.is_a?(Callback) ? callback : find(callback))
115:       end
find(callback) {|c| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 109
109:       def find(callback, &block)
110:         select { |c| c == callback && (!block_given? || yield(c)) }.first
111:       end
replace_or_append!(chain)

TODO: Decompose into more Array like behavior

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 100
100:       def replace_or_append!(chain)
101:         if index = index(chain)
102:           self[index] = chain
103:         else
104:           self << chain
105:         end
106:         self
107:       end
run(object, options = {}, &terminator)

[Source]

    # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 86
86:       def run(object, options = {}, &terminator)
87:         enumerator = options[:enumerator] || :each
88:
89:         unless block_given?
90:           send(enumerator) { |callback| callback.call(object) }
91:         else
92:           send(enumerator) do |callback|
93:             result = callback.call(object)
94:             break result if terminator.call(result, object)
95:           end
96:         end
97:       end


Module: ActiveSupport::Callbacks::ClassMethods

Module | ActiveSupport::Callbacks::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/callbacks.rb

Methods

define_callbacks

Public Instance methods

define_callbacks(*callbacks)

[Source]

     # File vendor/rails/activesupport/lib/active_support/callbacks.rb, line 205
205:       def define_callbacks(*callbacks)
206:         callbacks.each do |callback|
207:           class_eval "def self.\#{callback}(*methods, &block)                             # def self.before_save(*methods, &block)\ncallbacks = CallbackChain.build(:\#{callback}, *methods, &block)  #   callbacks = CallbackChain.build(:before_save, *methods, &block)\n@\#{callback}_callbacks ||= CallbackChain.new                     #   @before_save_callbacks ||= CallbackChain.new\n@\#{callback}_callbacks.concat callbacks                          #   @before_save_callbacks.concat callbacks\nend                                                                # end\n#\ndef self.\#{callback}_callback_chain                                # def self.before_save_callback_chain\n@\#{callback}_callbacks ||= CallbackChain.new                     #   @before_save_callbacks ||= CallbackChain.new\n#\nif superclass.respond_to?(:\#{callback}_callback_chain)           #   if superclass.respond_to?(:before_save_callback_chain)\nCallbackChain.new(                                             #     CallbackChain.new(\nsuperclass.\#{callback}_callback_chain +                      #       superclass.before_save_callback_chain +\n@\#{callback}_callbacks                                       #       @before_save_callbacks\n)                                                              #     )\nelse                                                             #   else\n@\#{callback}_callbacks                                         #     @before_save_callbacks\nend                                                              #   end\nend                                                                # end\n"
208:         end
209:       end


Module: ActiveSupport::CoreExtensions::Array::Access

Module | ActiveSupport::CoreExtensions::Array::Access
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb

Makes it easier to access parts of an array.

Methods

fifth forty_two fourth from second third to

Public Instance methods

fifth()

Equal to self[4].

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 42
42:         def fifth
43:           self[4]
44:         end
forty_two()

Equal to self[41]. Also known as accessing "the reddit".

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 47
47:         def forty_two
48:           self[41]
49:         end
fourth()

Equal to self[3].

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 37
37:         def fourth
38:           self[3]
39:         end
from(position)

Returns the tail of the array from position.

  %w( a b c d ).from(0)  # => %w( a b c d )
  %w( a b c d ).from(2)  # => %w( c d )
  %w( a b c d ).from(10) # => nil
  %w().from(0)           # => nil

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 12
12:         def from(position)
13:           self[position..-1]
14:         end
second()

Equal to self[1].

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 27
27:         def second
28:           self[1]
29:         end
third()

Equal to self[2].

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 32
32:         def third
33:           self[2]
34:         end
to(position)

Returns the beginning of the array up to position.

  %w( a b c d ).to(0)  # => %w( a )
  %w( a b c d ).to(2)  # => %w( a b c )
  %w( a b c d ).to(10) # => %w( a b c d )
  %w().to(0)           # => %w()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb, line 22
22:         def to(position)
23:           self[0..position]
24:         end


Module: ActiveSupport::CoreExtensions::Array::Conversions

Module | ActiveSupport::CoreExtensions::Array::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb

Methods

to_formatted_s to_param to_query to_sentence to_xml

Public Instance methods

to_formatted_s(format = :default)

Converts a collection of elements into a formatted string by calling to_s on all elements and joining them:

  Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"

Adding in the :db argument as the format yields a prettier output:

  Blog.find(:all).to_formatted_s(:db) # => "First Post,Second Post,Third Post"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb, line 74
74:         def to_formatted_s(format = :default)
75:           case format
76:             when :db
77:               if respond_to?(:empty?) && self.empty?
78:                 "null"
79:               else
80:                 collect { |element| element.id }.join(",")
81:               end
82:             else
83:               to_default_s
84:           end
85:         end
to_param()

Calls to_param on all its elements and joins the result with slashes. This is used by url_for in Action Pack.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb, line 45
45:         def to_param
46:           collect { |e| e.to_param }.join '/'
47:         end
to_query(key)

Converts an array into a string suitable for use as a URL query string, using the given key as the param name.

  ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb, line 53
53:         def to_query(key)
54:           prefix = "#{key}[]"
55:           collect { |value| value.to_query(prefix) }.join '&'
56:         end
to_sentence(options = {})

Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:

  • :words_connector - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
  • :two_words_connector - The sign or word used to join the elements in arrays with two elements (default: " and ")
  • :last_word_connector - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb, line 9
 9:         def to_sentence(options = {})
10:           default_words_connector     = I18n.translate('support.array.words_connector''support.array.words_connector',     :locale => options[:locale])
11:           default_two_words_connector = I18n.translate('support.array.two_words_connector''support.array.two_words_connector', :locale => options[:locale])
12:           default_last_word_connector = I18n.translate('support.array.last_word_connector''support.array.last_word_connector', :locale => options[:locale])
13:
14:           # Try to emulate to_senteces previous to 2.3
15:           if options.has_key?(:connector) || options.has_key?(:skip_last_comma)
16:             ::ActiveSupport::Deprecation.warn(":connector has been deprecated. Use :words_connector instead", caller) if options.has_key? :connector
17:             ::ActiveSupport::Deprecation.warn(":skip_last_comma has been deprecated. Use :last_word_connector instead", caller) if options.has_key? :skip_last_comma
18:
19:             skip_last_comma = options.delete :skip_last_comma
20:             if connector = options.delete(:connector)
21:               options[:last_word_connector] ||= skip_last_comma ? connector : ", #{connector}"
22:             else
23:               options[:last_word_connector] ||= skip_last_comma ? default_two_words_connector : default_last_word_connector
24:             end
25:           end
26:
27:           options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
28:           options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
29:
30:           case length
31:             when 0
32:               ""
33:             when 1
34:               self[0].to_s
35:             when 2
36:               "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
37:             else
38:               "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
39:           end
40:         end
to_xml(options = {}) {|xml if block_given?| ...}

Returns a string that represents this array in XML by sending to_xml to each element. Active Record collections delegate their representation in XML to this method.

All elements are expected to respond to to_xml, if any of them does not an exception is raised.

The root node reflects the class name of the first element in plural if all elements belong to the same type and that‘s not Hash:

  customer.projects.to_xml

  <?xml version="1.0" encoding="UTF-8"?>
  <projects type="array">
    <project>
      <amount type="decimal">20000.0</amount>
      <customer-id type="integer">1567</customer-id>
      <deal-date type="date">2008-04-09</deal-date>
      ...
    </project>
    <project>
      <amount type="decimal">57230.0</amount>
      <customer-id type="integer">1567</customer-id>
      <deal-date type="date">2008-04-15</deal-date>
      ...
    </project>
  </projects>

Otherwise the root element is "records":

  [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml

  <?xml version="1.0" encoding="UTF-8"?>
  <records type="array">
    <record>
      <bar type="integer">2</bar>
      <foo type="integer">1</foo>
    </record>
    <record>
      <baz type="integer">3</baz>
    </record>
  </records>

If the collection is empty the root element is "nil-classes" by default:

  [].to_xml

  <?xml version="1.0" encoding="UTF-8"?>
  <nil-classes type="array"/>

To ensure a meaningful root element use the :root option:

  customer_with_no_projects.projects.to_xml(:root => "projects")

  <?xml version="1.0" encoding="UTF-8"?>
  <projects type="array"/>

By default root children have as node name the one of the root singularized. You can change it with the :children option.

The options hash is passed downwards:

  Message.all.to_xml(:skip_types => true)

  <?xml version="1.0" encoding="UTF-8"?>
  <messages>
    <message>
      <created-at>2008-03-07T09:58:18+01:00</created-at>
      <id>1</id>
      <name>1</name>
      <updated-at>2008-03-07T09:58:18+01:00</updated-at>
      <user-id>1</user-id>
    </message>
  </messages>

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb, line 162
162:         def to_xml(options = {})
163:           raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
164:           require 'builder' unless defined?(Builder)
165:
166:           options[:root]     ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
167:           options[:children] ||= options[:root].singularize
168:           options[:indent]   ||= 2
169:           options[:builder]  ||= Builder::XmlMarkup.new(:indent => options[:indent])
170:
171:           root     = options.delete(:root).to_s
172:           children = options.delete(:children)
173:
174:           if !options.has_key?(:dasherize) || options[:dasherize]
175:             root = root.dasherize
176:           end
177:
178:           options[:builder].instruct! unless options.delete(:skip_instruct)
179:
180:           opts = options.merge({ :root => children })
181:
182:           xml = options[:builder]
183:           if empty?
184:             xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
185:           else
186:             xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) {
187:               yield xml if block_given?
188:               each { |e| e.to_xml(opts.merge({ :skip_instruct => true })) }
189:             }
190:           end
191:         end


Module: ActiveSupport::CoreExtensions::Array::ExtractOptions

Module | ActiveSupport::CoreExtensions::Array::ExtractOptions
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/extract_options.rb

Methods

extract_options!

Public Instance methods

extract_options!()

Extracts options from a set of arguments. Removes and returns the last element in the array if it‘s a hash, otherwise returns a blank hash.

  def options(*args)
    args.extract_options!
  end

  options(1, 2)           # => {}
  options(1, 2, :a => :b) # => {:a=>:b}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/extract_options.rb, line 14
14:         def extract_options!
15:           last.is_a?(::Hash) ? pop : {}
16:         end


Module: ActiveSupport::CoreExtensions::Array::Grouping

Module | ActiveSupport::CoreExtensions::Array::Grouping
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/grouping.rb

Methods

in_groups in_groups_of split

Public Instance methods

in_groups(number, fill_with = nil) {|g| ...}

Splits or iterates over the array in number of groups, padding any remaining slots with fill_with unless it is false.

  %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
  ["1", "2", "3", "4"]
  ["5", "6", "7", nil]
  ["8", "9", "10", nil]

  %w(1 2 3 4 5 6 7).in_groups(3, '&nbsp;') {|group| p group}
  ["1", "2", "3"]
  ["4", "5", "&nbsp;"]
  ["6", "7", "&nbsp;"]

  %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
  ["1", "2", "3"]
  ["4", "5"]
  ["6", "7"]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/grouping.rb, line 59
59:         def in_groups(number, fill_with = nil)
60:           # size / number gives minor group size;
61:           # size % number gives how many objects need extra accomodation;
62:           # each group hold either division or division + 1 items.
63:           division = size / number
64:           modulo = size % number
65:
66:           # create a new array avoiding dup
67:           groups = []
68:           start = 0
69:
70:           number.times do |index|
71:             length = division + (modulo > 0 && modulo > index ? 1 : 0)
72:             padding = fill_with != false &&
73:               modulo > 0 && length == division ? 1 : 0
74:             groups << slice(start, length).concat([fill_with] * padding)
75:             start += length
76:           end
77:
78:           if block_given?
79:             groups.each{|g| yield(g) }
80:           else
81:             groups
82:           end
83:         end
in_groups_of(number, fill_with = nil) {|slice| ...}

Splits or iterates over the array in groups of size number, padding any remaining slots with fill_with unless it is false.

  %w(1 2 3 4 5 6 7).in_groups_of(3) {|group| p group}
  ["1", "2", "3"]
  ["4", "5", "6"]
  ["7", nil, nil]

  %w(1 2 3).in_groups_of(2, '&nbsp;') {|group| p group}
  ["1", "2"]
  ["3", "&nbsp;"]

  %w(1 2 3).in_groups_of(2, false) {|group| p group}
  ["1", "2"]
  ["3"]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/grouping.rb, line 22
22:         def in_groups_of(number, fill_with = nil)
23:           if fill_with == false
24:             collection = self
25:           else
26:             # size % number gives how many extra we have;
27:             # subtracting from number gives how many to add;
28:             # modulo number ensures we don't add group of just fill.
29:             padding = (number - size % number) % number
30:             collection = dup.concat([fill_with] * padding)
31:           end
32:
33:           if block_given?
34:             collection.each_slice(number) { |slice| yield(slice) }
35:           else
36:             returning [] do |groups|
37:               collection.each_slice(number) { |group| groups << group }
38:             end
39:           end
40:         end
split(value = nil) {|element| ...}

Divides the array into one or more subarrays based on a delimiting value or the result of an optional block.

  [1, 2, 3, 4, 5].split(3)                # => [[1, 2], [4, 5]]
  (1..10).to_a.split { |i| i % 3 == 0 }   # => [[1, 2], [4, 5], [7, 8], [10]]

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/array/grouping.rb, line 90
 90:         def split(value = nil)
 91:           using_block = block_given?
 92:
 93:           inject([[]]) do |results, element|
 94:             if (using_block && yield(element)) || (value == element)
 95:               results << []
 96:             else
 97:               results.last << element
 98:             end
 99:
100:             results
101:           end
102:         end


Module: ActiveSupport::CoreExtensions::Array::RandomAccess

Module | ActiveSupport::CoreExtensions::Array::RandomAccess
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/random_access.rb

Methods

rand

Public Instance methods

rand()

Returns a random element from the array.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/array/random_access.rb, line 6
6:         def rand
7:           self[Kernel.rand(length)]
8:         end


Module: ActiveSupport::CoreExtensions::Array::Wrapper

Module | ActiveSupport::CoreExtensions::Array::Wrapper
In: | vendor/rails/activesupport/lib/active_support/core_ext/array/wrapper.rb

Methods

wrap

Public Instance methods

wrap(object)

Wraps the object in an Array unless it‘s an Array. Converts the object to an Array using to_ary if it implements that.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/array/wrapper.rb, line 7
 7:         def wrap(object)
 8:           case object
 9:           when nil
10:             []
11:           when self
12:             object
13:           else
14:             if object.respond_to?(:to_ary)
15:               object.to_ary
16:             else
17:               [object]
18:             end
19:           end
20:         end


Module: ActiveSupport::CoreExtensions::Base64::Encoding

Module | ActiveSupport::CoreExtensions::Base64::Encoding
In: | vendor/rails/activesupport/lib/active_support/core_ext/base64/encoding.rb

Methods

encode64s

Public Instance methods

encode64s(value)

Encodes the value as base64 without the newline breaks. This makes the base64 encoding readily usable as URL parameters or memcache keys without further processing.

 ActiveSupport::Base64.encode64s("Original unencoded string")
 # => "T3JpZ2luYWwgdW5lbmNvZGVkIHN0cmluZw=="

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/base64/encoding.rb, line 10
10:         def encode64s(value)
11:           encode64(value).gsub(/\n/, '')
12:         end


Module: ActiveSupport::CoreExtensions::BigDecimal::Conversions

Module | ActiveSupport::CoreExtensions::BigDecimal::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb

Methods

to_formatted_s to_yaml

Constants

DEFAULT_STRING_FORMAT | = | 'F'.freeze
YAML_TAG | = | 'tag:yaml.org,2002:float'.freeze
YAML_MAPPING | = | { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }

Public Instance methods

to_formatted_s(format = DEFAULT_STRING_FORMAT)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb, line 20
20:         def to_formatted_s(format = DEFAULT_STRING_FORMAT)
21:           _original_to_s(format)
22:         end
to_yaml(opts = {})

This emits the number without any scientific notation. This is better than self.to_f.to_s since it doesn‘t lose precision.

Note that reconstituting YAML floats to native floats may lose precision.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb, line 28
28:         def to_yaml(opts = {})
29:           YAML.quick_emit(nil, opts) do |out|
30:             string = to_s
31:             out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
32:           end
33:         end


Module: ActiveSupport::CoreExtensions::Date::Behavior

Module | ActiveSupport::CoreExtensions::Date::Behavior
In: | vendor/rails/activesupport/lib/active_support/core_ext/date/behavior.rb

Methods

acts_like_date?

Public Instance methods

acts_like_date?()

Enable more predictable duck-typing on Date-like classes. See Object#acts_like?.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/behavior.rb, line 9
 9:         def acts_like_date?
10:           true
11:         end


Module: ActiveSupport::CoreExtensions::Date::Calculations

Module | ActiveSupport::CoreExtensions::Date::Calculations
In: | vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb

Enables the use of time calculations within Time itself

Methods

advance ago at_beginning_of_day at_beginning_of_month at_beginning_of_quarter at_beginning_of_week at_beginning_of_year at_end_of_month at_end_of_quarter at_end_of_week at_end_of_year at_midnight beginning_of_day beginning_of_month beginning_of_quarter beginning_of_week beginning_of_year change end_of_day end_of_month end_of_quarter end_of_week end_of_year future? in last_month last_year midnight monday months_ago months_since next_month next_week next_year past? since today? tomorrow years_ago years_since yesterday

Classes and Modules

Module ActiveSupport::CoreExtensions::Date::Calculations::ClassMethods

Public Instance methods

advance(options)

Provides precise Date calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 94
 94:         def advance(options)
 95:           d = self
 96:           d = d >> options.delete(:years) * 12 if options[:years]
 97:           d = d >> options.delete(:months)     if options[:months]
 98:           d = d +  options.delete(:weeks) * 7  if options[:weeks]
 99:           d = d +  options.delete(:days)       if options[:days]
100:           d
101:         end
ago(seconds)

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) and then subtracts the specified number of seconds

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 52
52:         def ago(seconds)
53:           to_time.since(-seconds)
54:         end
at_beginning_of_day()

Alias for beginning_of_day

at_beginning_of_month()

Alias for beginning_of_month

at_beginning_of_quarter()

Alias for beginning_of_quarter

at_beginning_of_week()

Alias for beginning_of_week

at_beginning_of_year()

Alias for beginning_of_year

at_end_of_month()

Alias for end_of_month

at_end_of_quarter()

Alias for end_of_quarter

at_end_of_week()

Alias for end_of_week

at_end_of_year()

Alias for end_of_year

at_midnight()

Alias for beginning_of_day

beginning_of_day()

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 64
64:         def beginning_of_day
65:           to_time
66:         end
beginning_of_month()

Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 182
182:         def beginning_of_month
183:           self.acts_like?(:time) ? change(:day => 1,:hour => 0, :min => 0, :sec => 0) : change(:day => 1)
184:         end
beginning_of_quarter()

Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 195
195:         def beginning_of_quarter
196:           beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
197:         end
beginning_of_week()

Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 158
158:         def beginning_of_week
159:           days_to_monday = self.wday!=0 ? self.wday-1 : 6
160:           result = self - days_to_monday
161:           self.acts_like?(:time) ? result.midnight : result
162:         end
beginning_of_year()

Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 207
207:         def beginning_of_year
208:           self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0) : change(:month => 1, :day => 1)
209:         end
change(options)

Returns a new Date where one or more of the elements have been changed according to the options parameter.

Examples:

  Date.new(2007, 5, 12).change(:day => 1)                  # => Date.new(2007, 5, 1)
  Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 109
109:         def change(options)
110:           ::Date.new(
111:             options[:year]  || self.year,
112:             options[:month] || self.month,
113:             options[:day]   || self.day
114:           )
115:         end
end_of_day()

Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 72
72:         def end_of_day
73:           to_time.end_of_day
74:         end
end_of_month()

Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 188
188:         def end_of_month
189:           last_day = ::Time.days_in_month( self.month, self.year )
190:           self.acts_like?(:time) ? change(:day => last_day, :hour => 23, :min => 59, :sec => 59) : change(:day => last_day)
191:         end
end_of_quarter()

Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 201
201:         def end_of_quarter
202:           beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
203:         end
end_of_week()

Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 167
167:         def end_of_week
168:           days_to_sunday = self.wday!=0 ? 7-self.wday : 0
169:           result = self + days_to_sunday.days
170:           self.acts_like?(:time) ? result.end_of_day : result
171:         end
end_of_year()

Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 213
213:         def end_of_year
214:           self.acts_like?(:time) ? change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
215:         end
future?()

Tells whether the Date object‘s date lies in the future

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 46
46:         def future?
47:           self > ::Date.current
48:         end
in(seconds)

Alias for since

last_month()

Short-hand for months_ago(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 148
148:         def last_month
149:           months_ago(1)
150:         end
last_year()

Short-hand for years_ago(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 138
138:         def last_year
139:           years_ago(1)
140:         end
midnight()

Alias for beginning_of_day

monday()

Alias for beginning_of_week

months_ago(months)

Returns a new Date/DateTime representing the time a number of specified months ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 118
118:         def months_ago(months)
119:           advance(:months => -months)
120:         end
months_since(months)

Returns a new Date/DateTime representing the time a number of specified months in the future

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 123
123:         def months_since(months)
124:           advance(:months => months)
125:         end
next_month()

Short-hand for months_since(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 153
153:         def next_month
154:           months_since(1)
155:         end
next_week(day = :monday)

Returns a new Date/DateTime representing the start of the given day in next week (default is Monday).

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 175
175:         def next_week(day = :monday)
176:           days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
177:           result = (self + 7).beginning_of_week + days_into_week[day]
178:           self.acts_like?(:time) ? result.change(:hour => 0) : result
179:         end
next_year()

Short-hand for years_since(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 143
143:         def next_year
144:           years_since(1)
145:         end
past?()

Tells whether the Date object‘s date lies in the past

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 36
36:         def past?
37:           self < ::Date.current
38:         end
since(seconds)

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) and then adds the specified number of seconds

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 58
58:         def since(seconds)
59:           to_time.since(seconds)
60:         end
today?()

Tells whether the Date object‘s date is today

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 41
41:         def today?
42:           self.to_date == ::Date.current # we need the to_date because of DateTime
43:         end
tomorrow()

Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 224
224:         def tomorrow
225:           self + 1
226:         end
years_ago(years)

Returns a new Date/DateTime representing the time a number of specified years ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 128
128:         def years_ago(years)
129:           advance(:years => -years)
130:         end
years_since(years)

Returns a new Date/DateTime representing the time a number of specified years in the future

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 133
133:         def years_since(years)
134:           advance(:years => years)
135:         end
yesterday()

Convenience method which returns a new Date/DateTime representing the time 1 day ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 219
219:         def yesterday
220:           self - 1
221:         end


Module: ActiveSupport::CoreExtensions::Date::Calculations::ClassMethods

Module | ActiveSupport::CoreExtensions::Date::Calculations::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb

Methods

current tomorrow yesterday

Public Instance methods

current()

Returns Time.zone.today when config.time_zone is set, otherwise just returns Date.today.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 30
30:           def current
31:             ::Time.zone_default ? ::Time.zone.today : ::Date.today
32:           end
tomorrow()

Returns a new Date representing the date 1 day after today (i.e. tomorrow‘s date).

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 25
25:           def tomorrow
26:             ::Date.today.tomorrow
27:           end
yesterday()

Returns a new Date representing the date 1 day ago (i.e. yesterday‘s date).

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb, line 20
20:           def yesterday
21:             ::Date.today.yesterday
22:           end


Module: ActiveSupport::CoreExtensions::Date::Conversions

Module | ActiveSupport::CoreExtensions::Date::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb

Converting dates to formatted strings, times, and datetimes.

Methods

readable_inspect to_date to_datetime to_formatted_s to_time xmlschema

Constants

DATE_FORMATS = { :short => "%e %b", :long => "%B %e, %Y", :db => "%Y-%m-%d", :number => "%Y%m%d", :long_ordinal => lambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") }, # => "April 25th, 2007" :rfc822 => "%e %b %Y"

Public Instance methods

readable_inspect()

Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 66
66:         def readable_inspect
67:           strftime("%a, %d %b %Y")
68:         end
to_date()

A method to keep Time, Date and DateTime instances interchangeable on conversions. In this case, it simply returns self.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 72
72:         def to_date
73:           self
74:         end
to_datetime()

Converts a Date instance to a DateTime, where the time is set to the beginning of the day and UTC offset is set to 0.

Examples

  date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007

  date.to_datetime               # => Sat, 10 Nov 2007 00:00:00 0000

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 97
97:         def to_datetime
98:           ::DateTime.civil(year, month, day, 0, 0, 0, 0)
99:         end
to_formatted_s(format = :default)

Convert to a formatted string. See DATE_FORMATS for predefined formats.

This method is aliased to to_s.

Examples

  date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007

  date.to_formatted_s(:db)            # => "2007-11-10"
  date.to_s(:db)                      # => "2007-11-10"

  date.to_formatted_s(:short)         # => "10 Nov"
  date.to_formatted_s(:long)          # => "November 10, 2007"
  date.to_formatted_s(:long_ordinal)  # => "November 10th, 2007"
  date.to_formatted_s(:rfc822)        # => "10 Nov 2007"

Adding your own time formats to to_formatted_s

You can add your own formats to the Date::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a date argument as the value.

  # config/initializers/time_formats.rb
  Date::DATE_FORMATS[:month_and_year] = "%B %Y"
  Date::DATE_FORMATS[:short_ordinal] = lambda { |date| date.strftime("%B #{date.day.ordinalize}") }

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 53
53:         def to_formatted_s(format = :default)
54:           if formatter = DATE_FORMATS[format]
55:             if formatter.respond_to?(:call)
56:               formatter.call(self).to_s
57:             else
58:               strftime(formatter)
59:             end
60:           else
61:             to_default_s
62:           end
63:         end
to_time(form = :local)

Converts a Date instance to a Time, where the time is set to the beginning of the day. The timezone can be either :local or :utc (default :local).

Examples

  date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007

  date.to_time                   # => Sat Nov 10 00:00:00 0800 2007
  date.to_time(:local)           # => Sat Nov 10 00:00:00 0800 2007

  date.to_time(:utc)             # => Sat Nov 10 00:00:00 UTC 2007

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 86
86:         def to_time(form = :local)
87:           ::Time.send("#{form}_time", year, month, day)
88:         end
xmlschema()

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb, line 101
101:         def xmlschema
102:           to_time.xmlschema
103:         end


Module: ActiveSupport::CoreExtensions::DateTime::Calculations

Module | ActiveSupport::CoreExtensions::DateTime::Calculations
In: | vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb

Enables the use of time calculations within DateTime itself

Methods

advance ago at_beginning_of_day at_midnight beginning_of_day change compare_with_coercion end_of_day future? getutc in midnight past? seconds_since_midnight since utc utc? utc_offset

Classes and Modules

Module ActiveSupport::CoreExtensions::DateTime::Calculations::ClassMethods

Public Instance methods

advance(options)

Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 63
63:         def advance(options)
64:           d = to_date.advance(options)
65:           datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
66:           seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
67:           seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date.since(seconds_to_advance)
68:         end
ago(seconds)

Returns a new DateTime representing the time a number of seconds ago Do not use this method in combination with x.months, use months_ago instead!

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 72
72:         def ago(seconds)
73:           self.since(-seconds)
74:         end
at_beginning_of_day()

Alias for beginning_of_day

at_midnight()

Alias for beginning_of_day

beginning_of_day()

Returns a new DateTime representing the start of the day (0:00)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 84
84:         def beginning_of_day
85:           change(:hour => 0)
86:         end
change(options)

Returns a new DateTime where one or more of the elements have been changed according to the options parameter. The time options (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and minute is passed, then sec is set to 0.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 46
46:         def change(options)
47:           ::DateTime.civil(
48:             options[:year]  || self.year,
49:             options[:month] || self.month,
50:             options[:day]   || self.day,
51:             options[:hour]  || self.hour,
52:             options[:min]   || (options[:hour] ? 0 : self.min),
53:             options[:sec]   || ((options[:hour] || options[:min]) ? 0 : self.sec),
54:             options[:offset]  || self.offset,
55:             options[:start]  || self.start
56:           )
57:         end
compare_with_coercion(other)

Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 118
118:         def compare_with_coercion(other)
119:           other = other.comparable_time if other.respond_to?(:comparable_time)
120:           other = other.to_datetime unless other.acts_like?(:date)
121:           compare_without_coercion(other)
122:         end
end_of_day()

Returns a new DateTime representing the end of the day (23:59:59)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 92
92:         def end_of_day
93:           change(:hour => 23, :min => 59, :sec => 59)
94:         end
future?()

Tells whether the DateTime object‘s datetime lies in the future

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 34
34:         def future?
35:           self > ::DateTime.current
36:         end
getutc()

Alias for utc

in(seconds)

Alias for since

midnight()

Alias for beginning_of_day

past?()

Tells whether the DateTime object‘s datetime lies in the past

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 29
29:         def past?
30:           self < ::DateTime.current
31:         end
seconds_since_midnight()

Seconds since midnight: DateTime.now.seconds_since_midnight

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 39
39:         def seconds_since_midnight
40:           self.sec + (self.min * 60) + (self.hour * 3600)
41:         end
since(seconds)

Returns a new DateTime representing the time a number of seconds since the instance time Do not use this method in combination with x.months, use months_since instead!

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 78
78:         def since(seconds)
79:           self + Rational(seconds.round, 86400)
80:         end
utc()

Adjusts DateTime to UTC by adding its offset value; offset is set to 0

Example:

  DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))       # => Mon, 21 Feb 2005 10:11:12 -0600
  DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc   # => Mon, 21 Feb 2005 16:11:12 +0000

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 102
102:         def utc
103:           new_offset(0)
104:         end
utc?()

Returns true if offset == 0

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 108
108:         def utc?
109:           offset == 0
110:         end
utc_offset()

Returns the offset value in seconds

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 113
113:         def utc_offset
114:           (offset * 86400).to_i
115:         end


Module: ActiveSupport::CoreExtensions::DateTime::Calculations::ClassMethods

Module | ActiveSupport::CoreExtensions::DateTime::Calculations::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb

Methods

current local_offset

Public Instance methods

current()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 23
23:           def current
24:             ::Time.zone_default ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
25:           end
local_offset()

DateTimes aren‘t aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 19
19:           def local_offset
20:             ::Time.local(2007).utc_offset.to_r / 86400
21:           end


Module: ActiveSupport::CoreExtensions::DateTime::Conversions

Module | ActiveSupport::CoreExtensions::DateTime::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb

Converting datetimes to formatted strings, dates, and times.

Methods

formatted_offset readable_inspect to_date to_datetime to_f to_formatted_s to_time xmlschema

Public Instance methods

formatted_offset(colon = true, alternate_utc_string = nil)

Returns the utc_offset as an +HH:MM formatted string. Examples:

  datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
  datetime.formatted_offset         # => "-06:00"
  datetime.formatted_offset(false)  # => "-0600"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 58
58:         def formatted_offset(colon = true, alternate_utc_string = nil)
59:           utc? && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
60:         end
readable_inspect()

Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 63
63:         def readable_inspect
64:           to_s(:rfc822)
65:         end
to_date()

Converts self to a Ruby Date object; time portion is discarded

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 68
68:         def to_date
69:           ::Date.new(year, month, day)
70:         end
to_datetime()

To be able to keep Times, Dates and DateTimes interchangeable on conversions

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 79
79:         def to_datetime
80:           self
81:         end
to_f()

Converts self to a floating-point number of seconds since the Unix epoch

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 89
89:         def to_f
90:           days_since_unix_epoch = self - ::DateTime.civil(1970)
91:           (days_since_unix_epoch * 86_400).to_f
92:         end
to_formatted_s(format = :default)

Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.

This method is aliased to to_s.

Examples

  datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0)   # => Tue, 04 Dec 2007 00:00:00 +0000

  datetime.to_formatted_s(:db)            # => "2007-12-04 00:00:00"
  datetime.to_s(:db)                      # => "2007-12-04 00:00:00"
  datetime.to_s(:number)                  # => "20071204000000"
  datetime.to_formatted_s(:short)         # => "04 Dec 00:00"
  datetime.to_formatted_s(:long)          # => "December 04, 2007 00:00"
  datetime.to_formatted_s(:long_ordinal)  # => "December 4th, 2007 00:00"
  datetime.to_formatted_s(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"

Adding your own datetime formats to to_formatted_s

DateTime formats are shared with Time. You can add your own to the Time::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a time or datetime argument as the value.

  # config/initializers/time_formats.rb
  Time::DATE_FORMATS[:month_and_year] = "%B %Y"
  Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 48
48:         def to_formatted_s(format = :default)
49:           return to_default_s unless formatter = ::Time::DATE_FORMATS[format]
50:           formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
51:         end
to_time()

Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class If self has an offset other than 0, self will just be returned unaltered, since there‘s no clean way to map it to a Time

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 74
74:         def to_time
75:           self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec) : self
76:         end
xmlschema()

Converts datetime to an appropriate format for use in XML

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 84
84:         def xmlschema
85:           strftime("%Y-%m-%dT%H:%M:%S%Z")
86:         end


Module: ActiveSupport::CoreExtensions::File::Atomic

Module | ActiveSupport::CoreExtensions::File::Atomic
In: | vendor/rails/activesupport/lib/active_support/core_ext/file/atomic.rb

Methods

atomic_write

Public Instance methods

atomic_write(file_name, temp_dir = Dir.tmpdir) {|temp_file| ...}

Write to a file atomically. Useful for situations where you don‘t want other processes or threads to see half-written files.

  File.atomic_write("important.file") do |file|
    file.write("hello")
  end

If your temp directory is not on the same filesystem as the file you‘re trying to write, you can provide a different temporary directory.

  File.atomic_write("/data/something.important", "/data/tmp") do |f|
    file.write("hello")
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/file/atomic.rb, line 18
18:         def atomic_write(file_name, temp_dir = Dir.tmpdir)
19:           require 'tempfile' unless defined?(Tempfile)
20:
21:           temp_file = Tempfile.new(basename(file_name), temp_dir)
22:           yield temp_file
23:           temp_file.close
24:
25:           begin
26:             # Get original file permissions
27:             old_stat = stat(file_name)
28:           rescue Errno::ENOENT
29:             # No old permissions, write a temp file to determine the defaults
30:             check_name = join(dirname(file_name), ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}")
31:             open(check_name, "w") { }
32:             old_stat = stat(check_name)
33:             unlink(check_name)
34:           end
35:
36:           # Overwrite original file with temp file
37:           rename(temp_file.path, file_name)
38:
39:           # Set correct permissions on new file
40:           chown(old_stat.uid, old_stat.gid, file_name)
41:           chmod(old_stat.mode, file_name)
42:         end


Module: ActiveSupport::CoreExtensions::Float::Rounding

Module | ActiveSupport::CoreExtensions::Float::Rounding
In: | vendor/rails/activesupport/lib/active_support/core_ext/float/rounding.rb

Methods

round_with_precision

Public Instance methods

round_with_precision(precision = nil)

Rounds the float with the specified precision.

  x = 1.337
  x.round    # => 1
  x.round(1) # => 1.3
  x.round(2) # => 1.34

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/float/rounding.rb, line 18
18:         def round_with_precision(precision = nil)
19:           precision.nil? ? round_without_precision : (self * (10 ** precision)).round / (10 ** precision).to_f
20:         end


Module: ActiveSupport::CoreExtensions::Float::Time

Module | ActiveSupport::CoreExtensions::Float::Time
In: | vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb

Methods

month months months_without_deprecation year years years_without_deprecation

Public Instance methods

month()

Alias for months

months()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb, line 10
10:         def months
11:           ::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(:months, "Fractional months are not respected. Convert value to integer before calling #months."), caller)
12:           months_without_deprecation
13:         end
months_without_deprecation()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb, line 15
15:         def months_without_deprecation
16:           ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
17:         end
year()

Alias for years

years()

Deprication helper methods not available as core_ext is loaded first.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb, line 6
6:         def years
7:           ::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(:years, "Fractional years are not respected. Convert value to integer before calling #years."), caller)
8:           years_without_deprecation
9:         end
years_without_deprecation()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb, line 20
20:         def years_without_deprecation
21:           ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
22:         end


Module: ActiveSupport::CoreExtensions::Hash::ClassMethods

Module | ActiveSupport::CoreExtensions::Hash::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb

Methods

from_xml

Public Instance methods

from_xml(xml)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb, line 153
153:           def from_xml(xml)
154:             typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
155:           end


Module: ActiveSupport::CoreExtensions::Hash::Conversions

Module | ActiveSupport::CoreExtensions::Hash::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb

Constants

XML_TYPE_NAMES | = | { "Symbol" => "symbol", "Fixnum" => "integer", "Bignum" => "integer", "BigDecimal" => "decimal", "Float" => "float", "TrueClass" => "boolean", "FalseClass" => "boolean", "Date" => "date", "DateTime" => "datetime", "Time" => "datetime", "ActiveSupport::TimeWithZone" => "datetime"
XML_FORMATTING | = | { "symbol" => Proc.new { |symbol| symbol.to_s }, "date" => Proc.new { |date| date.to_s(:db) }, "datetime" => Proc.new { |time| time.xmlschema }, "binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) }, "yaml" => Proc.new { |yaml| yaml.to_yaml }
XML_PARSING | = | { "symbol" => Proc.new { |symbol| symbol.to_sym }, "date" => Proc.new { |date| ::Date.parse(date) }, "datetime" => Proc.new { |time| ::Time.parse(time).utc rescue ::DateTime.parse(time).utc }, "integer" => Proc.new { |integer| integer.to_i }, "float" => Proc.new { |float| float.to_f }, "decimal" => Proc.new { |number| BigDecimal(number) }, "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) }, "string" => Proc.new { |string| string.to_s }, "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml }, "base64Binary" => Proc.new { |bin| ActiveSupport::Base64.decode64(bin) }, "file" => Proc.new do |file, entity| f = StringIO.new(ActiveSupport::Base64.decode64(file))


Module: ActiveSupport::CoreExtensions::Hash::DeepMerge

Module | ActiveSupport::CoreExtensions::Hash::DeepMerge
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/deep_merge.rb

Allows for deep merging

Methods

deep_merge deep_merge!

Public Instance methods

deep_merge(other_hash)

Returns a new hash with self and other_hash merged recursively.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 7
 7:         def deep_merge(other_hash)
 8:           self.merge(other_hash) do |key, oldval, newval|
 9:             oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
10:             newval = newval.to_hash if newval.respond_to?(:to_hash)
11:             oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? oldval.deep_merge(newval) : newval
12:           end
13:         end
deep_merge!(other_hash)

Returns a new hash with self and other_hash merged recursively. Modifies the receiver in place.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 17
17:         def deep_merge!(other_hash)
18:           replace(deep_merge(other_hash))
19:         end


Module: ActiveSupport::CoreExtensions::Hash::Diff

Module | ActiveSupport::CoreExtensions::Hash::Diff
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/diff.rb

Methods

diff

Public Instance methods

diff(h2)

Returns a hash that represents the difference between two hashes.

Examples:

  {1 => 2}.diff(1 => 2)         # => {}
  {1 => 2}.diff(1 => 3)         # => {1 => 2}
  {}.diff(1 => 2)               # => {1 => 2}
  {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/diff.rb, line 13
13:         def diff(h2)
14:           self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
15:         end


Module: ActiveSupport::CoreExtensions::Hash::Except

Module | ActiveSupport::CoreExtensions::Hash::Except
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/except.rb

Return a hash that includes everything but the given keys. This is useful for limiting a set of parameters to everything but a few known toggles:

  @person.update_attributes(params[:person].except(:admin))

Methods

except except!

Public Instance methods

except(*keys)

Returns a new hash without the given keys.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/except.rb, line 12
12:         def except(*keys)
13:           dup.except!(*keys)
14:         end
except!(*keys)

Replaces the hash without the given keys.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/except.rb, line 17
17:         def except!(*keys)
18:           keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
19:           keys.each { |key| delete(key) }
20:           self
21:         end


Module: ActiveSupport::CoreExtensions::Hash::Keys

Module | ActiveSupport::CoreExtensions::Hash::Keys
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb

Methods

assert_valid_keys stringify_keys stringify_keys! symbolize_keys symbolize_keys! to_options to_options!

Public Instance methods

assert_valid_keys(*valid_keys)

Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols as keys, this will fail.

Examples

  { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
  { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
  { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb, line 45
45:         def assert_valid_keys(*valid_keys)
46:           unknown_keys = keys - [valid_keys].flatten
47:           raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
48:         end
stringify_keys()

Return a new hash with all keys converted to strings.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb, line 6
 6:         def stringify_keys
 7:           inject({}) do |options, (key, value)|
 8:             options[key.to_s] = value
 9:             options
10:           end
11:         end
stringify_keys!()

Destructively convert all keys to strings.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb, line 14
14:         def stringify_keys!
15:           keys.each do |key|
16:             self[key.to_s] = delete(key)
17:           end
18:           self
19:         end
symbolize_keys()

Return a new hash with all keys converted to symbols.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb, line 22
22:         def symbolize_keys
23:           inject({}) do |options, (key, value)|
24:             options[(key.to_sym rescue key) || key] = value
25:             options
26:           end
27:         end
symbolize_keys!()

Destructively convert all keys to symbols.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb, line 30
30:         def symbolize_keys!
31:           self.replace(self.symbolize_keys)
32:         end
to_options()

Alias for symbolize_keys

to_options!()

Alias for symbolize_keys!


Module: ActiveSupport::CoreExtensions::Hash::ReverseMerge

Module | ActiveSupport::CoreExtensions::Hash::ReverseMerge
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb

Allows for reverse merging two hashes where the keys in the calling hash take precedence over those in the other_hash. This is particularly useful for initializing an option hash with default values:

  def setup(options = {})
    options.reverse_merge! :size => 25, :velocity => 10
  end

Using merge, the above example would look as follows:

  def setup(options = {})
    { :size => 25, :velocity => 10 }.merge(options)
  end

The default :size and :velocity are only set if the options hash passed in doesn‘t already have the respective key.

Methods

reverse_merge reverse_merge! reverse_update

Public Instance methods

reverse_merge(other_hash)

Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 21
21:         def reverse_merge(other_hash)
22:           other_hash.merge(self)
23:         end
reverse_merge!(other_hash)

Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second. Modifies the receiver in place.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 27
27:         def reverse_merge!(other_hash)
28:           replace(reverse_merge(other_hash))
29:         end
reverse_update(other_hash)

Alias for reverse_merge!


Module: ActiveSupport::CoreExtensions::Hash::Slice

Module | ActiveSupport::CoreExtensions::Hash::Slice
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/slice.rb

Slice a hash to include only the given keys. This is useful for limiting an options hash to valid keys before passing to a method:

  def search(criteria = {})
    assert_valid_keys(:mass, :velocity, :time)
  end

  search(options.slice(:mass, :velocity, :time))

If you have an array of keys you want to limit to, you should splat them:

  valid_keys = [:mass, :velocity, :time]
  search(options.slice(*valid_keys))

Methods

slice slice!

Public Instance methods

slice(*keys)

Returns a new hash with only the given keys.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/slice.rb, line 19
19:         def slice(*keys)
20:           keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
21:           hash = self.class.new
22:           keys.each { |k| hash[k] = self[k] if has_key?(k) }
23:           hash
24:         end
slice!(*keys)

Replaces the hash with only the given keys. Returns a hash contained the removed key/value pairs

  {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/slice.rb, line 29
29:         def slice!(*keys)
30:           keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
31:           omit = slice(*self.keys - keys)
32:           hash = slice(*keys)
33:           replace(hash)
34:           omit
35:         end


Module: ActiveSupport::CoreExtensions::Integer::EvenOdd

Module | ActiveSupport::CoreExtensions::Integer::EvenOdd
In: | vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb

For checking if a fixnum is even or odd.

  2.even?  # => true
  2.odd?   # => false
  1.even?  # => false
  1.odd?   # => true
  0.even?  # => true
  0.odd?   # => false
  -1.even? # => false
  -1.odd?  # => true

Methods

even? multiple_of? odd?

Public Instance methods

even?()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb, line 19
19:         def even?
20:           multiple_of? 2
21:         end
multiple_of?(number)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb, line 15
15:         def multiple_of?(number)
16:           self % number == 0
17:         end
odd?()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb, line 23
23:         def odd?
24:           !even?
25:         end


Module: ActiveSupport::CoreExtensions::Integer::Inflections

Module | ActiveSupport::CoreExtensions::Integer::Inflections
In: | vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb

Methods

ordinalize

Public Instance methods

ordinalize()

Ordinalize turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

  1.ordinalize    # => "1st"
  2.ordinalize    # => "2nd"
  1002.ordinalize # => "1002nd"
  1003.ordinalize # => "1003rd"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb, line 14
14:         def ordinalize
15:           Inflector.ordinalize(self)
16:         end


Module: ActiveSupport::CoreExtensions::Integer::Time

Module | ActiveSupport::CoreExtensions::Integer::Time
In: | vendor/rails/activesupport/lib/active_support/core_ext/integer/time.rb

Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.

These methods use Time#advance for precise date calculations when using from_now, ago, etc. as well as adding or subtracting their results from a Time object. For example:

  # equivalent to Time.now.advance(:months => 1)
  1.month.from_now

  # equivalent to Time.now.advance(:years => 2)
  2.years.from_now

  # equivalent to Time.now.advance(:months => 4, :years => 5)
  (4.months + 5.years).from_now

While these methods provide precise calculation when used as in the examples above, care should be taken to note that this is not true if the result of `months’, `years’, etc is converted before use:

  # equivalent to 30.days.to_i.from_now
  1.month.to_i.from_now

  # equivalent to 365.25.days.to_f.from_now
  1.year.to_f.from_now

In such cases, Ruby‘s core Date and Time should be used for precision date and time arithmetic

Methods

month months year years

Public Instance methods

month()

Alias for months

months()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/time.rb, line 33
33:         def months
34:           ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
35:         end
year()

Alias for years

years()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/integer/time.rb, line 38
38:         def years
39:           ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
40:         end


Module: ActiveSupport::CoreExtensions::Module

Module | ActiveSupport::CoreExtensions::Module
In: | vendor/rails/activesupport/lib/active_support/core_ext/module/aliasing.rb vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb vendor/rails/activesupport/lib/active_support/core_ext/module.rb

Various extensions for the Ruby core Module class.

Methods

alias_attribute alias_method_chain local_constant_names local_constants model_name parent parent_name parents

Public Instance methods

alias_attribute(new_name, old_name)

Allows you to make aliases for attributes, which includes getter, setter, and query methods.

Example:

  class Content < ActiveRecord::Base
    # has a title attribute
  end

  class Email < Content
    alias_attribute :subject, :title
  end

  e = Email.find(1)
  e.title    # => "Superstars"
  e.subject  # => "Superstars"
  e.subject? # => true
  e.subject = "Megastars"
  e.title    # => "Megastars"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/aliasing.rb, line 65
65:       def alias_attribute(new_name, old_name)
66:         module_eval "def \#{new_name}; self.\#{old_name}; end          # def subject; self.title; end\ndef \#{new_name}?; self.\#{old_name}?; end        # def subject?; self.title?; end\ndef \#{new_name}=(v); self.\#{old_name} = v; end  # def subject=(v); self.title = v; end\n", __FILE__, __LINE__+1
67:       end
alias_method_chain(target, feature) {|aliased_target, punctuation| ...}

Encapsulates the common pattern of:

  alias_method :foo_without_feature, :foo
  alias_method :foo, :foo_with_feature

With this, you simply do:

  alias_method_chain :foo, :feature

And both aliases are set up for you.

Query and bang methods (foo?, foo!) keep the same punctuation:

  alias_method_chain :foo?, :feature

is equivalent to

  alias_method :foo_without_feature?, :foo?
  alias_method :foo?, :foo_with_feature?

so you can safely chain foo, foo?, and foo! with the same feature.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/aliasing.rb, line 25
25:       def alias_method_chain(target, feature)
26:         # Strip out punctuation on predicates or bang methods since
27:         # e.g. target?_without_feature is not a valid method name.
28:         aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
29:         yield(aliased_target, punctuation) if block_given?
30:
31:         with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
32:
33:         alias_method without_method, target
34:         alias_method target, with_method
35:
36:         case
37:           when public_method_defined?(without_method)
38:             public target
39:           when protected_method_defined?(without_method)
40:             protected target
41:           when private_method_defined?(without_method)
42:             private target
43:         end
44:       end
local_constant_names()

Returns the names of the constants defined locally rather than the constants themselves. See local_constants.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb, line 85
85:       def local_constant_names
86:         local_constants.map { |c| c.to_s }
87:       end
local_constants()

Returns the constants that have been defined locally by this object and not in an ancestor. This method is exact if running under Ruby 1.9. In previous versions it may miss some constants if their definition in some ancestor is identical to their definition in the receiver.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb, line 65
65:         def local_constants
66:           inherited = {}
67:
68:           ancestors.each do |anc|
69:             next if anc == self
70:             anc.constants.each { |const| inherited[const] = anc.const_get(const) }
71:           end
72:
73:           constants.select do |const|
74:             !inherited.key?(const) || inherited[const].object_id != const_get(const).object_id
75:           end
76:         end
model_name()

Returns an ActiveSupport::ModelName object for module. It can be used to retrieve all kinds of naming-related information.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb, line 18
18:       def model_name
19:         @model_name ||= ModelName.new(name)
20:       end
parent()

Returns the module which contains this one according to its name.

  module M
    module N
    end
  end
  X = M::N

  p M::N.parent # => M
  p X.parent    # => M

The parent of top-level and anonymous modules is Object.

  p M.parent          # => Object
  p Module.new.parent # => Object

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb, line 30
30:       def parent
31:         parent_name ? parent_name.constantize : Object
32:       end
parent_name()

Returns the name of the module containing this one.

  p M::N.parent_name # => "M"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb, line 7
 7:       def parent_name
 8:         unless defined? @parent_name
 9:           @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
10:         end
11:         @parent_name
12:       end
parents()

Returns all the parents of this module according to its name, ordered from nested outwards. The receiver is not contained within the result.

  module M
    module N
    end
  end
  X = M::N

  p M.parents    # => [Object]
  p M::N.parents # => [M, Object]
  p X.parents    # => [M, Object]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb, line 47
47:       def parents
48:         parents = []
49:         if parent_name
50:           parts = parent_name.split('::')
51:           until parts.empty?
52:             parents << (parts * '::').constantize
53:             parts.pop
54:           end
55:         end
56:         parents << Object unless parents.include? Object
57:         parents
58:       end


Module: ActiveSupport::CoreExtensions::Numeric::Bytes

Module | ActiveSupport::CoreExtensions::Numeric::Bytes
In: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb

Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes

Methods

byte bytes exabyte exabytes gigabyte gigabytes kilobyte kilobytes megabyte megabytes petabyte petabytes terabyte terabytes

Public Instance methods

byte()

Alias for bytes

bytes()

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 6
6:         def bytes
7:           self
8:         end
exabyte()

Alias for exabytes

exabytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 36
36:         def exabytes
37:           self * 1024.petabytes
38:         end
gigabyte()

Alias for gigabytes

gigabytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 21
21:         def gigabytes
22:           self * 1024.megabytes
23:         end
kilobyte()

Alias for kilobytes

kilobytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 11
11:         def kilobytes
12:           self * 1024
13:         end
megabyte()

Alias for megabytes

megabytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 16
16:         def megabytes
17:           self * 1024.kilobytes
18:         end
petabyte()

Alias for petabytes

petabytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 31
31:         def petabytes
32:           self * 1024.terabytes
33:         end
terabyte()

Alias for terabytes

terabytes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 26
26:         def terabytes
27:           self * 1024.gigabytes
28:         end


Module: ActiveSupport::CoreExtensions::Numeric::Conversions

Module | ActiveSupport::CoreExtensions::Numeric::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/conversions.rb

Methods

to_utc_offset_s

Public Instance methods

to_utc_offset_s(colon=true)

Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset) and turns this into an +HH:MM formatted string. Example:

  -21_600.to_utc_offset_s   # => "-06:00"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/conversions.rb, line 9
 9:         def to_utc_offset_s(colon=true)
10:           seconds = self
11:           sign = (seconds < 0 ? -1 : 1)
12:           hours = seconds.abs / 3600
13:           minutes = (seconds.abs % 3600) / 60
14:           "%+03d%s%02d" % [ hours * sign, colon ? ":" : "", minutes ]
15:         end


Module: ActiveSupport::CoreExtensions::Numeric::Time

Module | ActiveSupport::CoreExtensions::Numeric::Time
In: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb

Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.

These methods use Time#advance for precise date calculations when using from_now, ago, etc. as well as adding or subtracting their results from a Time object. For example:

  # equivalent to Time.now.advance(:months => 1)
  1.month.from_now

  # equivalent to Time.now.advance(:years => 2)
  2.years.from_now

  # equivalent to Time.now.advance(:months => 4, :years => 5)
  (4.months + 5.years).from_now

While these methods provide precise calculation when used as in the examples above, care should be taken to note that this is not true if the result of `months’, `years’, etc is converted before use:

  # equivalent to 30.days.to_i.from_now
  1.month.to_i.from_now

  # equivalent to 365.25.days.to_f.from_now
  1.year.to_f.from_now

In such cases, Ruby‘s core Date and Time should be used for precision date and time arithmetic

Methods

ago day days fortnight fortnights from_now hour hours minute minutes second seconds since until week weeks

Public Instance methods

ago(time = ::Time.now)

Reads best without arguments: 10.minutes.ago

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 64
64:         def ago(time = ::Time.now)
65:           time - self
66:         end
day()

Alias for days

days()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 48
48:         def days
49:           ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
50:         end
fortnight()

Alias for fortnights

fortnights()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 58
58:         def fortnights
59:           ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
60:         end
from_now(time = ::Time.now)

Alias for since

hour()

Alias for hours

hours()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 43
43:         def hours
44:           ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
45:         end
minute()

Alias for minutes

minutes()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 38
38:         def minutes
39:           ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
40:         end
second()

Alias for seconds

seconds()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 33
33:         def seconds
34:           ActiveSupport::Duration.new(self, [[:seconds, self]])
35:         end
since(time = ::Time.now)

Reads best with argument: 10.minutes.since(time)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 72
72:         def since(time = ::Time.now)
73:           time + self
74:         end
until(time = ::Time.now)

Alias for ago

week()

Alias for weeks

weeks()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb, line 53
53:         def weeks
54:           ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
55:         end


Module: ActiveSupport::CoreExtensions::Pathname::CleanWithin

Module | ActiveSupport::CoreExtensions::Pathname::CleanWithin
In: | vendor/rails/activesupport/lib/active_support/core_ext/pathname/clean_within.rb

Methods

clean_within

Public Instance methods

clean_within(string)

Clean the paths contained in the provided string.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/pathname/clean_within.rb, line 6
 6:         def clean_within(string)
 7:           string.gsub(%r{[\w. ]+(/[\w. ]+)+(\.rb)?(\b|$)}) do |path|
 8:             new(path).cleanpath
 9:           end
10:         end


Module: ActiveSupport::CoreExtensions::Range::BlocklessStep

Module | ActiveSupport::CoreExtensions::Range::BlocklessStep
In: | vendor/rails/activesupport/lib/active_support/core_ext/range/blockless_step.rb

Return an array when step is called without a block.

Methods

step_with_blockless step_with_blockless

Public Instance methods

step_with_blockless(value = 1, &block)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/range/blockless_step.rb, line 11
11:           def step_with_blockless(value = 1, &block)
12:             if block_given?
13:               step_without_blockless(value, &block)
14:             else
15:               returning [] do |array|
16:                 step_without_blockless(value) { |step| array << step }
17:               end
18:             end
19:           end
step_with_blockless(value = 1, &block)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/range/blockless_step.rb, line 21
21:           def step_with_blockless(value = 1, &block)
22:             if block_given?
23:               step_without_blockless(value, &block)
24:             else
25:               step_without_blockless(value).to_a
26:             end
27:           end


Module: ActiveSupport::CoreExtensions::Range::Conversions

Module | ActiveSupport::CoreExtensions::Range::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb

Getting ranges in different convenient string representations and other objects

Methods

to_formatted_s

Constants

RANGE_FORMATS = { :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }

Public Instance methods

to_formatted_s(format = :default)

Gives a human readable format of the range.

Example

  [1..100].to_formatted_s # => "1..100"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb, line 21
21:         def to_formatted_s(format = :default)
22:           RANGE_FORMATS[format] ? RANGE_FORMATS[format].call(first, last) : to_default_s
23:         end


Module: ActiveSupport::CoreExtensions::Range::IncludeRange

Module | ActiveSupport::CoreExtensions::Range::IncludeRange
In: | vendor/rails/activesupport/lib/active_support/core_ext/range/include_range.rb

Check if a Range includes another Range.

Methods

include_with_range?

Public Instance methods

include_with_range?(value)

Extends the default Range#include? to support range comparisons.

 (1..5).include?(1..5) # => true
 (1..5).include?(2..3) # => true
 (1..5).include?(2..6) # => false

The native Range#include? behavior is untouched.

 ("a".."f").include?("c") # => true
 (5..9).include?(11) # => false

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/range/include_range.rb, line 18
18:         def include_with_range?(value)
19:           if value.is_a?(::Range)
20:             operator = exclude_end? ? :< : :<=
21:             end_value = value.exclude_end? ? last.succ : last
22:             include?(value.first) && (value.last <=> end_value).send(operator, 0)
23:           else
24:             include_without_range?(value)
25:           end
26:         end


Module: ActiveSupport::CoreExtensions::Range::Overlaps

Module | ActiveSupport::CoreExtensions::Range::Overlaps
In: | vendor/rails/activesupport/lib/active_support/core_ext/range/overlaps.rb

Check if Ranges overlap.

Methods

overlaps?

Public Instance methods

overlaps?(other)

Compare two ranges and see if they overlap eachother

 (1..5).overlaps?(4..6) # => true
 (1..5).overlaps?(7..9) # => false

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/range/overlaps.rb, line 9
 9:         def overlaps?(other)
10:           include?(other.first) || other.include?(first)
11:         end


Module: ActiveSupport::CoreExtensions::String::Behavior

Module | ActiveSupport::CoreExtensions::String::Behavior
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/behavior.rb

Methods

acts_like_string?

Public Instance methods

acts_like_string?()

Enable more predictable duck-typing on String-like classes. See Object#acts_like?.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/string/behavior.rb, line 7
7:         def acts_like_string?
8:           true
9:         end


Module: ActiveSupport::CoreExtensions::String::Conversions

Module | ActiveSupport::CoreExtensions::String::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb

Converting strings to other objects

Methods

ord to_date to_datetime to_time

Public Instance methods

ord()

‘a’.ord == ‘a’[0] for Ruby 1.9 forward compatibility.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb, line 9
 9:         def ord
10:           self[0]
11:         end
to_date()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb, line 18
18:         def to_date
19:           ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
20:         end
to_datetime()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb, line 22
22:         def to_datetime
23:           ::DateTime.civil(*::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 })
24:         end
to_time(form = :utc)

Form can be either :utc (default) or :local.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb, line 14
14:         def to_time(form = :utc)
15:           ::Time.send("#{form}_time", *::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec).map { |arg| arg || 0 })
16:         end


Module: ActiveSupport::CoreExtensions::String::Filters

Module | ActiveSupport::CoreExtensions::String::Filters
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/filters.rb

Methods

squish squish!

Public Instance methods

squish()

Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.

Examples:

  %{ Multi-line
     string }.squish                   # => "Multi-line string"
  " foo   bar    \n   \t   boo".squish # => "foo bar boo"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/filters.rb, line 13
13:         def squish
14:           dup.squish!
15:         end
squish!()

Performs a destructive squish. See String#squish.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/filters.rb, line 18
18:         def squish!
19:           strip!
20:           gsub!(/\s+/, ' ')
21:           self
22:         end


Module: ActiveSupport::CoreExtensions::String::Inflections

Module | ActiveSupport::CoreExtensions::String::Inflections
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb

String inflections define new methods on the String class to transform names for different purposes. For instance, you can figure out the name of a database from the name of a class.

  "ScaleScore".tableize # => "scale_scores"

Methods

camelcase camelize classify constantize dasherize demodulize foreign_key humanize parameterize pluralize singularize tableize titlecase titleize underscore

Public Instance methods

camelcase(first_letter = :upper)

Alias for camelize

camelize(first_letter = :upper)

By default, camelize converts strings to UpperCamelCase. If the argument to camelize is set to :lower then camelize produces lowerCamelCase.

camelize will also convert ’/’ to ’::’ which is useful for converting paths to namespaces.

  "active_record".camelize                # => "ActiveRecord"
  "active_record".camelize(:lower)        # => "activeRecord"
  "active_record/errors".camelize         # => "ActiveRecord::Errors"
  "active_record/errors".camelize(:lower) # => "activeRecord::Errors"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 44
44:         def camelize(first_letter = :upper)
45:           case first_letter
46:             when :upper then Inflector.camelize(self, true)
47:             when :lower then Inflector.camelize(self, false)
48:           end
49:         end
classify()

Create a class name from a plural table name like Rails does for table names to models. Note that this returns a string and not a class. (To convert to an actual class follow classify with constantize.)

  "egg_and_hams".classify # => "EggAndHam"
  "posts".classify        # => "Post"

Singular names are not handled correctly.

  "business".classify # => "Busines"

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 129
129:         def classify
130:           Inflector.classify(self)
131:         end
constantize()

constantize tries to find a declared constant with the name specified in the string. It raises a NameError when the name is not in CamelCase or is not initialized.

Examples

  "Module".constantize # => Module
  "Class".constantize  # => Class

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 161
161:         def constantize
162:           Inflector.constantize(self)
163:         end
dasherize()

Replaces underscores with dashes in the string.

  "puni_puni" # => "puni-puni"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 78
78:         def dasherize
79:           Inflector.dasherize(self)
80:         end
demodulize()

Removes the module part from the constant expression in the string.

  "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
  "Inflections".demodulize                                       # => "Inflections"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 86
86:         def demodulize
87:           Inflector.demodulize(self)
88:         end
foreign_key(separate_class_name_and_id_with_underscore = true)

Creates a foreign key name from a class name. separate_class_name_and_id_with_underscore sets whether the method should put ‘_’ between the name and ‘id’.

Examples

  "Message".foreign_key        # => "message_id"
  "Message".foreign_key(false) # => "messageid"
  "Admin::Post".foreign_key    # => "post_id"

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 150
150:         def foreign_key(separate_class_name_and_id_with_underscore = true)
151:           Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
152:         end
humanize()

Capitalizes the first word, turns underscores into spaces, and strips ‘_id’. Like titleize, this is meant for creating pretty output.

  "employee_salary" # => "Employee salary"
  "author_id"       # => "Author"

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 138
138:         def humanize
139:           Inflector.humanize(self)
140:         end
parameterize(sep = '-')

Replaces special characters in a string so that it may be used as part of a ‘pretty’ URL.

Examples

  class Person
    def to_param
      "#{id}-#{name.parameterize}"
    end
  end

  @person = Person.find(1)
  # => #<Person id: 1, name: "Donald E. Knuth">

  <%= link_to(@person.name, person_path %>
  # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 105
105:         def parameterize(sep = '-')
106:           Inflector.parameterize(self, sep)
107:         end
pluralize()

Returns the plural form of the word in the string.

  "post".pluralize             # => "posts"
  "octopus".pluralize          # => "octopi"
  "sheep".pluralize            # => "sheep"
  "words".pluralize            # => "words"
  "the blue mailman".pluralize # => "the blue mailmen"
  "CamelOctopus".pluralize     # => "CamelOctopi"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 19
19:         def pluralize
20:           Inflector.pluralize(self)
21:         end
singularize()

The reverse of pluralize, returns the singular form of a word in a string.

  "posts".singularize            # => "post"
  "octopi".singularize           # => "octopus"
  "sheep".singularize            # => "sheep"
  "word".singularize             # => "word"
  "the blue mailmen".singularize # => "the blue mailman"
  "CamelOctopi".singularize      # => "CamelOctopus"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 31
31:         def singularize
32:           Inflector.singularize(self)
33:         end
tableize()

Creates the name of a table like Rails does for models to table names. This method uses the pluralize method on the last word in the string.

  "RawScaledScorer".tableize # => "raw_scaled_scorers"
  "egg_and_ham".tableize     # => "egg_and_hams"
  "fancyCategory".tableize   # => "fancy_categories"

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 115
115:         def tableize
116:           Inflector.tableize(self)
117:         end
titlecase()

Alias for titleize

titleize()

Capitalizes all the words and replaces some characters in the string to create a nicer looking title. titleize is meant for creating pretty output. It is not used in the Rails internals.

titleize is also aliased as titlecase.

  "man from the boondocks".titleize # => "Man From The Boondocks"
  "x-men: the last stand".titleize  # => "X Men: The Last Stand"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 60
60:         def titleize
61:           Inflector.titleize(self)
62:         end
underscore()

The reverse of camelize. Makes an underscored, lowercase form from the expression in the string.

underscore will also change ’::’ to ’/’ to convert namespaces to paths.

  "ActiveRecord".underscore         # => "active_record"
  "ActiveRecord::Errors".underscore # => active_record/errors

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb, line 71
71:         def underscore
72:           Inflector.underscore(self)
73:         end


Module: ActiveSupport::CoreExtensions::String::Iterators

Module | ActiveSupport::CoreExtensions::String::Iterators
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/iterators.rb

Custom string iterators

Methods

append_features each_char

Public Class methods

append_features(base)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/iterators.rb, line 8
 8:         def self.append_features(base)
 9:           super unless '1.9'.respond_to?(:each_char)
10:         end

Public Instance methods

each_char() {|c| ...}

Yields a single-character string for each character in the string. When $KCODE = ‘UTF8’, multi-byte characters are yielded appropriately.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/iterators.rb, line 14
14:         def each_char
15:           scanner, char = StringScanner.new(self), /./mu
16:           while c = scanner.scan(char)
17:             yield c
18:           end
19:         end


Module: ActiveSupport::CoreExtensions::String::Multibyte

Module | ActiveSupport::CoreExtensions::String::Multibyte
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb

Implements multibyte methods for easier access to multibyte characters in a String instance.

Methods

chars is_utf8? is_utf8? mb_chars mb_chars

Public Instance methods

chars()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb, line 57
57:             def chars
58:               ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller)
59:               mb_chars
60:             end
is_utf8?()

Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have them), returns false otherwise.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb, line 52
52:           def is_utf8?
53:             ActiveSupport::Multibyte::Chars.consumes?(self)
54:           end
is_utf8?(

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb, line 67
67:           def is_utf8? #:nodoc
68:             case encoding
69:             when Encoding::UTF_8
70:               valid_encoding?
71:             when Encoding::ASCII_8BIT, Encoding::US_ASCII
72:               dup.force_encoding(Encoding::UTF_8).valid_encoding?
73:             else
74:               false
75:             end
76:           end
mb_chars(

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb, line 63
63:           def mb_chars #:nodoc
64:             self
65:           end
mb_chars()

Multibyte proxy

mb_chars is a multibyte safe proxy for string methods.

In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy class. If the proxy class doesn‘t respond to a certain method, it‘s forwarded to the encapsuled string.

  name = 'Claus Müller'
  name.reverse  #=> "rell??M sualC"
  name.length   #=> 13

  name.mb_chars.reverse.to_s   #=> "rellüM sualC"
  name.mb_chars.length         #=> 12

In Ruby 1.9 and newer mb_chars returns self because String is (mostly) encoding aware. This means that it becomes easy to run one version of your code on multiple Ruby versions.

Method chaining

All the methods on the Chars proxy which normally return a string will return a Chars object. This allows method chaining on the result of any of these methods.

  name.mb_chars.reverse.length #=> 12

Interoperability and configuration

The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between String and Char work like expected. The bang! methods change the internal string representation in the Chars object. Interoperability problems can be resolved easily with a to_s call.

For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For information about how to change the default Multibyte behaviour see ActiveSupport::Multibyte.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb, line 42
42:           def mb_chars
43:             if ActiveSupport::Multibyte.proxy_class.wants?(self)
44:               ActiveSupport::Multibyte.proxy_class.new(self)
45:             else
46:               self
47:             end
48:           end


Module: ActiveSupport::CoreExtensions::String::StartsEndsWith

Module | ActiveSupport::CoreExtensions::String::StartsEndsWith
In: | vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb

Additional string tests.

Methods

append_features ends_with? starts_with?

Public Class methods

append_features(base)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb, line 6
 6:         def self.append_features(base)
 7:           if '1.8.7 and up'.respond_to?(:start_with?)
 8:             base.class_eval do
 9:               alias_method :starts_with?, :start_with?
10:               alias_method :ends_with?, :end_with?
11:             end
12:           else
13:             super
14:             base.class_eval do
15:               alias_method :start_with?, :starts_with?
16:               alias_method :end_with?, :ends_with?
17:             end
18:           end
19:         end

Public Instance methods

ends_with?(suffix)

Does the string end with the specified suffix?

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb, line 28
28:         def ends_with?(suffix)
29:           suffix = suffix.to_s
30:           self[-suffix.length, suffix.length] == suffix
31:         end
starts_with?(prefix)

Does the string start with the specified prefix?

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb, line 22
22:         def starts_with?(prefix)
23:           prefix = prefix.to_s
24:           self[0, prefix.length] == prefix
25:         end


Module: ActiveSupport::CoreExtensions::Time::Behavior

Module | ActiveSupport::CoreExtensions::Time::Behavior
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/behavior.rb

Methods

acts_like_time?

Public Instance methods

acts_like_time?()

Enable more predictable duck-typing on Time-like classes. See Object#acts_like?.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/time/behavior.rb, line 7
7:         def acts_like_time?
8:           true
9:         end


Module: ActiveSupport::CoreExtensions::Time::Calculations

Module | ActiveSupport::CoreExtensions::Time::Calculations
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb

Enables the use of time calculations within Time itself

Methods

advance ago at_beginning_of_day at_beginning_of_month at_beginning_of_quarter at_beginning_of_week at_beginning_of_year at_end_of_month at_end_of_quarter at_end_of_week at_end_of_year at_midnight beginning_of_day beginning_of_month beginning_of_quarter beginning_of_week beginning_of_year change compare_with_coercion end_of_day end_of_month end_of_quarter end_of_week end_of_year future? in last_month last_year midnight minus_with_coercion monday months_ago months_since next_month next_week next_year past? seconds_since_midnight since today? tomorrow years_ago years_since yesterday

Classes and Modules

Module ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods

Constants

COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

Public Instance methods

advance(options)

Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 102
102:         def advance(options)
103:           unless options[:weeks].nil?
104:             options[:weeks], partial_weeks = options[:weeks].divmod(1)
105:             options[:days] = (options[:days] || 0) + 7 * partial_weeks
106:           end
107:
108:           unless options[:days].nil?
109:             options[:days], partial_days = options[:days].divmod(1)
110:             options[:hours] = (options[:hours] || 0) + 24 * partial_days
111:           end
112:
113:           d = to_date.advance(options)
114:           time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
115:           seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
116:           seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
117:         end
ago(seconds)

Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 120
120:         def ago(seconds)
121:           self.since(-seconds)
122:         end
at_beginning_of_day()

Alias for beginning_of_day

at_beginning_of_month()

Alias for beginning_of_month

at_beginning_of_quarter()

Alias for beginning_of_quarter

at_beginning_of_week()

Alias for beginning_of_week

at_beginning_of_year()

Alias for beginning_of_year

at_end_of_month()

Alias for end_of_month

at_end_of_quarter()

Alias for end_of_quarter

at_end_of_week()

Alias for end_of_week

at_end_of_year()

Alias for end_of_year

at_midnight()

Alias for beginning_of_day

beginning_of_day()

Returns a new Time representing the start of the day (0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 203
203:         def beginning_of_day
204:           (self - self.seconds_since_midnight).change(:usec => 0)
205:         end
beginning_of_month()

Returns a new Time representing the start of the month (1st of the month, 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 216
216:         def beginning_of_month
217:           #self - ((self.mday-1).days + self.seconds_since_midnight)
218:           change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
219:         end
beginning_of_quarter()

Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 231
231:         def beginning_of_quarter
232:           beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
233:         end
beginning_of_week()

Returns a new Time representing the "start" of this week (Monday, 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 182
182:         def beginning_of_week
183:           days_to_monday = self.wday!=0 ? self.wday-1 : 6
184:           (self - days_to_monday.days).midnight
185:         end
beginning_of_year()

Returns a new Time representing the start of the year (1st of january, 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 243
243:         def beginning_of_year
244:           change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
245:         end
change(options)

Returns a new Time where one or more of the elements have been changed according to the options parameter. The time options (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and minute is passed, then sec and usec is set to 0.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 85
85:         def change(options)
86:           ::Time.send(
87:             self.utc? ? :utc_time : :local_time,
88:             options[:year]  || self.year,
89:             options[:month] || self.month,
90:             options[:day]   || self.day,
91:             options[:hour]  || self.hour,
92:             options[:min]   || (options[:hour] ? 0 : self.min),
93:             options[:sec]   || ((options[:hour] || options[:min]) ? 0 : self.sec),
94:             options[:usec]  || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
95:           )
96:         end
compare_with_coercion(other)

Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared with a Time

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 290
290:         def compare_with_coercion(other)
291:           # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
292:           other = other.comparable_time if other.respond_to?(:comparable_time)
293:           if other.acts_like?(:date)
294:             # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
295:             to_datetime.compare_without_coercion(other)
296:           else
297:             compare_without_coercion(other)
298:           end
299:         end
end_of_day()

Returns a new Time representing the end of the day (23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 211
211:         def end_of_day
212:           change(:hour => 23, :min => 59, :sec => 59)
213:         end
end_of_month()

Returns a new Time representing the end of the month (last day of the month, 0:00)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 223
223:         def end_of_month
224:           #self - ((self.mday-1).days + self.seconds_since_midnight)
225:           last_day = ::Time.days_in_month( self.month, self.year )
226:           change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 0)
227:         end
end_of_quarter()

Returns a new Time representing the end of the quarter (last day of march, june, september, december, 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 237
237:         def end_of_quarter
238:           beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
239:         end
end_of_week()

Returns a new Time representing the end of this week (Sunday, 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 190
190:         def end_of_week
191:           days_to_sunday = self.wday!=0 ? 7-self.wday : 0
192:           (self + days_to_sunday.days).end_of_day
193:         end
end_of_year()

Returns a new Time representing the end of the year (31st of december, 23:59:59)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 249
249:         def end_of_year
250:           change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59)
251:         end
future?()

Tells whether the Time object‘s time lies in the future

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 73
73:         def future?
74:           self > ::Time.current
75:         end
in(seconds)

Alias for since

last_month()

Short-hand for months_ago(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 172
172:         def last_month
173:           months_ago(1)
174:         end
last_year()

Short-hand for years_ago(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 161
161:         def last_year
162:           years_ago(1)
163:         end
midnight()

Alias for beginning_of_day

minus_with_coercion(other)

Time#- can also be used to determine the number of seconds between two Time instances. We‘re layering on additional behavior so that ActiveSupport::TimeWithZone instances are coerced into values that Time#- will recognize

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 283
283:         def minus_with_coercion(other)
284:           other = other.comparable_time if other.respond_to?(:comparable_time)
285:           minus_without_coercion(other)
286:         end
monday()

Alias for beginning_of_week

months_ago(months)

Returns a new Time representing the time a number of specified months ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 141
141:         def months_ago(months)
142:           advance(:months => -months)
143:         end
months_since(months)

Returns a new Time representing the time a number of specified months in the future

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 146
146:         def months_since(months)
147:           advance(:months => months)
148:         end
next_month()

Short-hand for months_since(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 177
177:         def next_month
178:           months_since(1)
179:         end
next_week(day = :monday)

Returns a new Time representing the start of the given day in next week (default is Monday).

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 197
197:         def next_week(day = :monday)
198:           days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
199:           since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
200:         end
next_year()

Short-hand for years_since(1)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 166
166:         def next_year
167:           years_since(1)
168:         end
past?()

Tells whether the Time object‘s time lies in the past

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 63
63:         def past?
64:           self < ::Time.current
65:         end
seconds_since_midnight()

Seconds since midnight: Time.now.seconds_since_midnight

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 78
78:         def seconds_since_midnight
79:           self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
80:         end
since(seconds)

Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around the Numeric extension.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 126
126:         def since(seconds)
127:           f = seconds.since(self)
128:           if ActiveSupport::Duration === seconds
129:             f
130:           else
131:             initial_dst = self.dst? ? 1 : 0
132:             final_dst   = f.dst? ? 1 : 0
133:             (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
134:           end
135:         rescue
136:           self.to_datetime.since(seconds)
137:         end
today?()

Tells whether the Time object‘s time is today

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 68
68:         def today?
69:           self.to_date == ::Date.current
70:         end
tomorrow()

Convenience method which returns a new Time representing the time 1 day since the instance time

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 260
260:         def tomorrow
261:           advance(:days => 1)
262:         end
years_ago(years)

Returns a new Time representing the time a number of specified years ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 151
151:         def years_ago(years)
152:           advance(:years => -years)
153:         end
years_since(years)

Returns a new Time representing the time a number of specified years in the future

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 156
156:         def years_since(years)
157:           advance(:years => years)
158:         end
yesterday()

Convenience method which returns a new Time representing the time 1 day ago

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 255
255:         def yesterday
256:           advance(:days => -1)
257:         end


Module: ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods

Module | ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb

Methods

=== days_in_month local_time time_with_datetime_fallback utc_time

Public Instance methods

===(other)

Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 30
30:           def ===(other)
31:             other.is_a?(::Time)
32:           end
days_in_month(month, year = now.year)

Return the number of days in the given month. If no year is specified, it will use the current year.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 36
36:           def days_in_month(month, year = now.year)
37:             return 29 if month == 2 && ::Date.gregorian_leap?(year)
38:             COMMON_YEAR_DAYS_IN_MONTH[month]
39:           end
local_time(*args)

Wraps class method time_with_datetime_fallback with utc_or_local set to :local.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 57
57:           def local_time(*args)
58:             time_with_datetime_fallback(:local, *args)
59:           end
time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)

Returns a new Time if requested year can be accommodated by Ruby‘s Time class (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture); otherwise returns a DateTime

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 44
44:           def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
45:             ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
46:           rescue
47:             offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0
48:             ::DateTime.civil(year, month, day, hour, min, sec, offset)
49:           end
utc_time(*args)

Wraps class method time_with_datetime_fallback with utc_or_local set to :utc.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 52
52:           def utc_time(*args)
53:             time_with_datetime_fallback(:utc, *args)
54:           end


Module: ActiveSupport::CoreExtensions::Time::Conversions

Module | ActiveSupport::CoreExtensions::Time::Conversions
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb

Converting times to formatted strings, dates, and datetimes.

Methods

formatted_offset to_date to_datetime to_formatted_s to_time

Constants

DATE_FORMATS = { :db => "%Y-%m-%d %H:%M:%S", :number => "%Y%m%d%H%M%S", :time => "%H:%M", :short => "%d %b %H:%M", :long => "%B %d, %Y %H:%M", :long_ordinal => lambda { |time| time.strftime("%B #{time.day.ordinalize}, %Y %H:%M") }, :rfc822 => lambda { |time| time.strftime("%a, %d %b %Y %H:%M:%S #{time.formatted_offset(false)}") }

Public Instance methods

formatted_offset(colon = true, alternate_utc_string = nil)

Returns the UTC offset as an +HH:MM formatted string.

  Time.local(2000).formatted_offset         # => "-06:00"
  Time.local(2000).formatted_offset(false)  # => "-0600"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb, line 56
56:         def formatted_offset(colon = true, alternate_utc_string = nil)
57:           utc? && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
58:         end
to_date()

Converts a Time object to a Date, dropping hour, minute, and second precision.

  my_time = Time.now  # => Mon Nov 12 22:59:51 -0500 2007
  my_time.to_date     # => Mon, 12 Nov 2007

  your_time = Time.parse("1/13/2009 1:13:03 P.M.")  # => Tue Jan 13 13:13:03 -0500 2009
  your_time.to_date                                 # => Tue, 13 Jan 2009

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb, line 67
67:         def to_date
68:           ::Date.new(year, month, day)
69:         end
to_datetime()

Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.

  my_time = Time.now    # => Mon Nov 12 23:04:21 -0500 2007
  my_time.to_datetime   # => Mon, 12 Nov 2007 23:04:21 -0500

  your_time = Time.parse("1/13/2009 1:13:03 P.M.")  # => Tue Jan 13 13:13:03 -0500 2009
  your_time.to_datetime                             # => Tue, 13 Jan 2009 13:13:03 -0500

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb, line 84
84:         def to_datetime
85:           ::DateTime.civil(year, month, day, hour, min, sec, Rational(utc_offset, 86400))
86:         end
to_formatted_s(format = :default)

Converts to a formatted string. See DATE_FORMATS for builtin formats.

This method is aliased to to_s.

  time = Time.now                     # => Thu Jan 18 06:10:17 CST 2007

  time.to_formatted_s(:time)          # => "06:10:17"
  time.to_s(:time)                    # => "06:10:17"

  time.to_formatted_s(:db)            # => "2007-01-18 06:10:17"
  time.to_formatted_s(:number)        # => "20070118061017"
  time.to_formatted_s(:short)         # => "18 Jan 06:10"
  time.to_formatted_s(:long)          # => "January 18, 2007 06:10"
  time.to_formatted_s(:long_ordinal)  # => "January 18th, 2007 06:10"
  time.to_formatted_s(:rfc822)        # => "Thu, 18 Jan 2007 06:10:17 -0600"

Adding your own time formats to to_formatted_s

You can add your own formats to the Time::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a time argument as the value.

  # config/initializers/time_formats.rb
  Time::DATE_FORMATS[:month_and_year] = "%B %Y"
  Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb, line 47
47:         def to_formatted_s(format = :default)
48:           return to_default_s unless formatter = DATE_FORMATS[format]
49:           formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
50:         end
to_time()

A method to keep Time, Date and DateTime instances interchangeable on conversions. In this case, it simply returns self.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb, line 73
73:         def to_time
74:           self
75:         end


Module: ActiveSupport::CoreExtensions::Time::Zones

Module | ActiveSupport::CoreExtensions::Time::Zones
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb

Methods

in_time_zone

Classes and Modules

Module ActiveSupport::CoreExtensions::Time::Zones::ClassMethods

Public Instance methods

in_time_zone(zone = ::Time.zone)

Returns the simultaneous time in Time.zone.

  Time.zone = 'Hawaii'         # => 'Hawaii'
  Time.utc(2000).in_time_zone  # => Fri, 31 Dec 1999 14:00:00 HST -10:00

This method is similar to Time#localtime, except that it uses Time.zone as the local zone instead of the operating system‘s time zone.

You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, and the conversion will be based on that zone instead of Time.zone.

  Time.utc(2000).in_time_zone('Alaska')  # => Fri, 31 Dec 1999 15:00:00 AKST -09:00

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb, line 80
80:         def in_time_zone(zone = ::Time.zone)
81:           ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
82:         end


Module: ActiveSupport::CoreExtensions::Time::Zones::ClassMethods

Module | ActiveSupport::CoreExtensions::Time::Zones::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb

Methods

current use_zone zone zone=

Attributes

zone_default [RW]

Public Instance methods

current()

Returns Time.zone.now when config.time_zone is set, otherwise just returns Time.now.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb, line 50
50:           def current
51:             ::Time.zone_default ? ::Time.zone.now : ::Time.now
52:           end
use_zone(time_zone) {|| ...}

Allows override of Time.zone locally inside supplied block; resets Time.zone to existing value when done.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb, line 42
42:           def use_zone(time_zone)
43:             old_zone, ::Time.zone = ::Time.zone, get_zone(time_zone)
44:             yield
45:           ensure
46:             ::Time.zone = old_zone
47:           end
zone()

Returns the TimeZone for the current request, if this has been set (via Time.zone=). If Time.zone has not been set for the current request, returns the TimeZone specified in config.time_zone.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb, line 14
14:           def zone
15:             Thread.current[:time_zone] || zone_default
16:           end
zone=(time_zone)

Sets Time.zone to a TimeZone object for the current request/thread.

This method accepts any of the following:

  • A Rails TimeZone object.
  • An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", -5.hours).
  • A TZInfo::Timezone object.
  • An identifier for a TZInfo::Timezone object (e.g., "America/New_York").

Here‘s an example of how you might set Time.zone on a per request basis — current_user.time_zone just needs to return a string identifying the user‘s preferred TimeZone:

  class ApplicationController < ActionController::Base
    before_filter :set_time_zone

    def set_time_zone
      Time.zone = current_user.time_zone
    end
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb, line 37
37:           def zone=(time_zone)
38:             Thread.current[:time_zone] = get_zone(time_zone)
39:           end


Class: ActiveSupport::Deprecation::DeprecatedObjectProxy

Class | ActiveSupport::Deprecation::DeprecatedObjectProxy
In: | vendor/rails/activesupport/lib/active_support/deprecation.rb
Parent: | DeprecationProxy

Methods

new

Public Class methods

new(object, message)

[Source]

     # File vendor/rails/activesupport/lib/active_support/deprecation.rb, line 141
141:       def initialize(object, message)
142:         @object = object
143:         @message = message
144:       end


Class: ActiveSupport::Duration

Class | ActiveSupport::Duration
In: | vendor/rails/activesupport/lib/active_support/duration.rb
Parent: | BasicObject

Provides accurate date and time measurements using Date#advance and Time#advance, respectively. It mainly supports the methods on Numeric, such as in this example:

  1.month.ago       # equivalent to Time.now.advance(:months => -1)

Methods

+ - == ago from_now since until

Attributes

parts | [RW]
value | [RW]

Public Instance methods

+(other)

Adds another Duration or a Numeric to this Duration. Numeric values are treated as seconds.

[Source]

    # File vendor/rails/activesupport/lib/active_support/duration.rb, line 18
18:     def +(other)
19:       if Duration === other
20:         Duration.new(value + other.value, @parts + other.parts)
21:       else
22:         Duration.new(value + other, @parts + [[:seconds, other]])
23:       end
24:     end
-(other)

Subtracts another Duration or a Numeric from this Duration. Numeric values are treated as seconds.

[Source]

    # File vendor/rails/activesupport/lib/active_support/duration.rb, line 28
28:     def -(other)
29:       self + (-other)
30:     end
==(other)

Returns true if other is also a Duration instance with the same value, or if other == value.

[Source]

    # File vendor/rails/activesupport/lib/active_support/duration.rb, line 42
42:     def ==(other)
43:       if Duration === other
44:         other.value == value
45:       else
46:         other == value
47:       end
48:     end
ago(time = ::Time.current)

Calculates a new Time or Date that is as far in the past as this Duration represents.

[Source]

    # File vendor/rails/activesupport/lib/active_support/duration.rb, line 63
63:     def ago(time = ::Time.current)
64:       sum(-1, time)
65:     end
from_now(time = ::Time.current)

Alias for since

since(time = ::Time.current)

Calculates a new Time or Date that is as far in the future as this Duration represents.

[Source]

    # File vendor/rails/activesupport/lib/active_support/duration.rb, line 56
56:     def since(time = ::Time.current)
57:       sum(1, time)
58:     end
until(time = ::Time.current)

Alias for ago


Module: ActiveSupport::Gzip

Module | ActiveSupport::Gzip
In: | vendor/rails/activesupport/lib/active_support/gzip.rb

A convenient wrapper for the zlib standard library that allows compression/decompression of strings with gzip.

Methods

compress decompress

Classes and Modules

Class ActiveSupport::Gzip::Stream

Public Class methods

compress(source)

Compresses a string using gzip.

[Source]

    # File vendor/rails/activesupport/lib/active_support/gzip.rb, line 17
17:     def self.compress(source)
18:       output = Stream.new
19:       gz = Zlib::GzipWriter.new(output)
20:       gz.write(source)
21:       gz.close
22:       output.string
23:     end
decompress(source)

Decompresses a gzipped string.

[Source]

    # File vendor/rails/activesupport/lib/active_support/gzip.rb, line 12
12:     def self.decompress(source)
13:       Zlib::GzipReader.new(StringIO.new(source)).read
14:     end


Class: ActiveSupport::Gzip::Stream

Class | ActiveSupport::Gzip::Stream
In: | vendor/rails/activesupport/lib/active_support/gzip.rb
Parent: | StringIO

Methods

close

Public Instance methods

close()

[Source]

   # File vendor/rails/activesupport/lib/active_support/gzip.rb, line 8
8:       def close; rewind; end


Module: ActiveSupport::Inflector

Module | ActiveSupport::Inflector
In: | vendor/rails/activesupport/lib/active_support/inflector.rb

The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without, and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept in inflections.rb.

The Rails core team has stated patches for the inflections library will not be accepted in order to avoid breaking legacy applications which may be relying on errant inflections. If you discover an incorrect inflection and require it for your application, you‘ll need to correct it yourself (explained below).

Methods

camelize classify constantize dasherize demodulize foreign_key humanize inflections ordinalize parameterize pluralize singularize tableize titleize transliterate transliterate transliterate underscore

Classes and Modules

Class ActiveSupport::Inflector::Inflections

Public Instance methods

camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)

By default, camelize converts strings to UpperCamelCase. If the argument to camelize is set to :lower then camelize produces lowerCamelCase.

camelize will also convert ’/’ to ’::’ which is useful for converting paths to namespaces.

Examples:

  "active_record".camelize                # => "ActiveRecord"
  "active_record".camelize(:lower)        # => "activeRecord"
  "active_record/errors".camelize         # => "ActiveRecord::Errors"
  "active_record/errors".camelize(:lower) # => "activeRecord::Errors"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 178
178:     def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
179:       if first_letter_in_uppercase
180:         lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
181:       else
182:         lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
183:       end
184:     end
classify(table_name)

Create a class name from a plural table name like Rails does for table names to models. Note that this returns a string and not a Class. (To convert to an actual class follow classify with constantize.)

Examples:

  "egg_and_hams".classify # => "EggAndHam"
  "posts".classify        # => "Post"

Singular names are not handled correctly:

  "business".classify     # => "Busines"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 318
318:     def classify(table_name)
319:       # strip out any leading schema name
320:       camelize(singularize(table_name.to_s.sub(/.*\./, '')))
321:     end
constantize(camel_cased_word)

Tries to find a constant with the name specified in the argument string:

  "Module".constantize     # => Module
  "Test::Unit".constantize # => Test::Unit

The name is assumed to be the one of a top-level constant, no matter whether it starts with "::" or not. No lexical context is taken into account:

  C = 'outside'
  module M
    C = 'inside'
    C               # => 'inside'
    "C".constantize # => 'outside', same as ::C
  end

NameError is raised when the name is not in CamelCase or the constant is unknown.

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 355
355:       def constantize(camel_cased_word)
356:         names = camel_cased_word.split('::')
357:         names.shift if names.empty? || names.first.empty?
358:
359:         constant = Object
360:         names.each do |name|
361:           constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
362:         end
363:         constant
364:       end
dasherize(underscored_word)

Replaces underscores with dashes in the string.

Example:

  "puni_puni" # => "puni-puni"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 218
218:     def dasherize(underscored_word)
219:       underscored_word.gsub(/_/, '-')
220:     end
demodulize(class_name_in_module)

Removes the module part from the expression in the string.

Examples:

  "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
  "Inflections".demodulize                                       # => "Inflections"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 240
240:     def demodulize(class_name_in_module)
241:       class_name_in_module.to_s.gsub(/^.*::/, '')
242:     end
foreign_key(class_name, separate_class_name_and_id_with_underscore = true)

Creates a foreign key name from a class name. separate_class_name_and_id_with_underscore sets whether the method should put ‘_’ between the name and ‘id’.

Examples:

  "Message".foreign_key        # => "message_id"
  "Message".foreign_key(false) # => "messageid"
  "Admin::Post".foreign_key    # => "post_id"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 331
331:     def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
332:       underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
333:     end
humanize(lower_case_and_underscored_word)

Capitalizes the first word and turns underscores into spaces and strips a trailing "_id", if any. Like titleize, this is meant for creating pretty output.

Examples:

  "employee_salary" # => "Employee salary"
  "author_id"       # => "Author"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 228
228:     def humanize(lower_case_and_underscored_word)
229:       result = lower_case_and_underscored_word.to_s.dup
230:
231:       inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
232:       result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
233:     end
inflections() {|Inflections.instance| ...}

Yields a singleton instance of Inflector::Inflections so you can specify additional inflector rules.

Example:

  ActiveSupport::Inflector.inflections do |inflect|
    inflect.uncountable "rails"
  end

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 122
122:     def inflections
123:       if block_given?
124:         yield Inflections.instance
125:       else
126:         Inflections.instance
127:       end
128:     end
ordinalize(number)

Turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

Examples:

  ordinalize(1)     # => "1st"
  ordinalize(2)     # => "2nd"
  ordinalize(1002)  # => "1002nd"
  ordinalize(1003)  # => "1003rd"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 386
386:     def ordinalize(number)
387:       if (11..13).include?(number.to_i % 100)
388:         "#{number}th"
389:       else
390:         case number.to_i % 10
391:           when 1; "#{number}st"
392:           when 2; "#{number}nd"
393:           when 3; "#{number}rd"
394:           else    "#{number}th"
395:         end
396:       end
397:     end
parameterize(string, sep = '-')

Replaces special characters in a string so that it may be used as part of a ‘pretty’ URL.

Examples

  class Person
    def to_param
      "#{id}-#{name.parameterize}"
    end
  end

  @person = Person.find(1)
  # => #<Person id: 1, name: "Donald E. Knuth">

  <%= link_to(@person.name, person_path(@person)) %>
  # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 259
259:     def parameterize(string, sep = '-')
260:       # replace accented chars with ther ascii equivalents
261:       parameterized_string = transliterate(string)
262:       # Turn unwanted chars into the seperator
263:       parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
264:       unless sep.blank?
265:         re_sep = Regexp.escape(sep)
266:         # No more than one of the separator in a row.
267:         parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
268:         # Remove leading/trailing separator.
269:         parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
270:       end
271:       parameterized_string.downcase
272:     end
pluralize(word)

Returns the plural form of the word in the string.

Examples:

  "post".pluralize             # => "posts"
  "octopus".pluralize          # => "octopi"
  "sheep".pluralize            # => "sheep"
  "words".pluralize            # => "words"
  "CamelOctopus".pluralize     # => "CamelOctopi"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 138
138:     def pluralize(word)
139:       result = word.to_s.dup
140:
141:       if word.empty? || inflections.uncountables.include?(result.downcase)
142:         result
143:       else
144:         inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
145:         result
146:       end
147:     end
singularize(word)

The reverse of pluralize, returns the singular form of a word in a string.

Examples:

  "posts".singularize            # => "post"
  "octopi".singularize           # => "octopus"
  "sheep".singluarize            # => "sheep"
  "word".singularize             # => "word"
  "CamelOctopi".singularize      # => "CamelOctopus"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 157
157:     def singularize(word)
158:       result = word.to_s.dup
159:
160:       if inflections.uncountables.include?(result.downcase)
161:         result
162:       else
163:         inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
164:         result
165:       end
166:     end
tableize(class_name)

Create the name of a table like Rails does for models to table names. This method uses the pluralize method on the last word in the string.

Examples

  "RawScaledScorer".tableize # => "raw_scaled_scorers"
  "egg_and_ham".tableize     # => "egg_and_hams"
  "fancyCategory".tableize   # => "fancy_categories"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 304
304:     def tableize(class_name)
305:       pluralize(underscore(class_name))
306:     end
titleize(word)

Capitalizes all the words and replaces some characters in the string to create a nicer looking title. titleize is meant for creating pretty output. It is not used in the Rails internals.

titleize is also aliased as as titlecase.

Examples:

  "man from the boondocks".titleize # => "Man From The Boondocks"
  "x-men: the last stand".titleize  # => "X Men: The Last Stand"

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 195
195:     def titleize(word)
196:       humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
197:     end
transliterate(string)

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 291
291:       def transliterate(string)
292:         string.mb_chars.normalize(:kd). # Decompose accented characters
293:           gsub(/[^\x00-\x7F]+/, '')     # Remove anything non-ASCII entirely (e.g. diacritics).
294:       end
transliterate(string)

Replaces accented characters with their ascii equivalents.

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 276
276:     def transliterate(string)
277:       Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
278:     end
transliterate(string)

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 282
282:       def transliterate(string)
283:         warn "Ruby 1.9 doesn't support Unicode normalization yet"
284:         string.dup
285:       end
underscore(camel_cased_word)

The reverse of camelize. Makes an underscored, lowercase form from the expression in the string.

Changes ’::’ to ’/’ to convert namespaces to paths.

Examples:

  "ActiveRecord".underscore         # => "active_record"
  "ActiveRecord::Errors".underscore # => active_record/errors

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 206
206:     def underscore(camel_cased_word)
207:       camel_cased_word.to_s.gsub(/::/, '/').
208:         gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
209:         gsub(/([a-z\d])([A-Z])/,'\1_\2').
210:         tr("-", "_").
211:         downcase
212:     end


Class: ActiveSupport::Inflector::Inflections

Class | ActiveSupport::Inflector::Inflections
In: | vendor/rails/activesupport/lib/active_support/inflector.rb
Parent: | Object

A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional inflection rules. Examples:

  ActiveSupport::Inflector.inflections do |inflect|
    inflect.plural /^(ox)$/i, '\1\2en'
    inflect.singular /^(ox)en/i, '\1'

    inflect.irregular 'octopus', 'octopi'

    inflect.uncountable "equipment"
  end

New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may already have been loaded.

Methods

clear human irregular new plural singular uncountable

Included Modules

Singleton

Attributes

humans | [R]
plurals | [R]
singulars | [R]
uncountables | [R]

Public Class methods

new()

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 37
37:       def initialize
38:         @plurals, @singulars, @uncountables, @humans = [], [], [], []
39:       end

Public Instance methods

clear(scope = :all)

Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type, the options are: :plurals, :singulars, :uncountables, :humans.

Examples:

  clear :all
  clear :plurals

[Source]

     # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 105
105:       def clear(scope = :all)
106:         case scope
107:           when :all
108:             @plurals, @singulars, @uncountables = [], [], []
109:           else
110:             instance_variable_set "@#{scope}", []
111:         end
112:       end
human(rule, replacement)

Specifies a humanized form of a string by a regular expression rule or by a string mapping. When using a regular expression based replacement, the normal humanize formatting is called after the replacement. When a string is used, the human form should be specified as desired (example: ‘The name’, not ‘the_name’)

Examples:

  human /_cnt$/i, '\1_count'
  human "legacy_col_person_name", "Name"

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 94
94:       def human(rule, replacement)
95:         @humans.insert(0, [rule, replacement])
96:       end
irregular(singular, plural)

Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used for strings, not regular expressions. You simply pass the irregular in singular and plural form.

Examples:

  irregular 'octopus', 'octopi'
  irregular 'person', 'people'

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 63
63:       def irregular(singular, plural)
64:         @uncountables.delete(singular)
65:         @uncountables.delete(plural)
66:         if singular[0,1].upcase == plural[0,1].upcase
67:           plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
68:           singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
69:         else
70:           plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
71:           plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
72:           singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
73:           singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
74:         end
75:       end
plural(rule, replacement)

Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression. The replacement should always be a string that may include references to the matched data from the rule.

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 43
43:       def plural(rule, replacement)
44:         @uncountables.delete(rule) if rule.is_a?(String)
45:         @uncountables.delete(replacement)
46:         @plurals.insert(0, [rule, replacement])
47:       end
singular(rule, replacement)

Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression. The replacement should always be a string that may include references to the matched data from the rule.

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 51
51:       def singular(rule, replacement)
52:         @uncountables.delete(rule) if rule.is_a?(String)
53:         @uncountables.delete(replacement)
54:         @singulars.insert(0, [rule, replacement])
55:       end
uncountable(*words)

Add uncountable words that shouldn‘t be attempted inflected.

Examples:

  uncountable "money"
  uncountable "money", "information"
  uncountable %w( money information rice )

[Source]

    # File vendor/rails/activesupport/lib/active_support/inflector.rb, line 83
83:       def uncountable(*words)
84:         (@uncountables << words).flatten!
85:       end


Module: ActiveSupport::JSON

Module | ActiveSupport::JSON
In: | vendor/rails/activesupport/lib/active_support/json/decoding.rb vendor/rails/activesupport/lib/active_support/json/encoders/string.rb vendor/rails/activesupport/lib/active_support/json/encoding.rb vendor/rails/activesupport/lib/active_support/json/variable.rb

Methods

decode encode

Classes and Modules

Module ActiveSupport::JSON::Encoding
Class ActiveSupport::JSON::CircularReferenceError
Class ActiveSupport::JSON::ParseError
Class ActiveSupport::JSON::Variable

Constants

DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/ matches YAML-formatted dates

Public Class methods

decode(json)

Converts a JSON string into a Ruby object.

[Source]

    # File vendor/rails/activesupport/lib/active_support/json/decoding.rb, line 11
11:       def decode(json)
12:         YAML.load(convert_json_to_yaml(json))
13:       rescue ArgumentError => e
14:         raise ParseError, "Invalid JSON string"
15:       end
encode(value, options = {})

Converts a Ruby object into a JSON string.

[Source]

    # File vendor/rails/activesupport/lib/active_support/json/encoding.rb, line 7
 7:     def self.encode(value, options = {})
 8:       seen = (options[:seen] ||= [])
 9:       raise CircularReferenceError, 'object references itself' if seen.include?(value)
10:       seen << value
11:       value.send(:to_json, options)
12:     ensure
13:       seen.pop
14:     end


Class: ActiveSupport::JSON::CircularReferenceError

Class | ActiveSupport::JSON::CircularReferenceError
In: | vendor/rails/activesupport/lib/active_support/json/encoding.rb
Parent: | StandardError


Module: ActiveSupport::JSON::Encoding

Module | ActiveSupport::JSON::Encoding
In: | vendor/rails/activesupport/lib/active_support/json/encoders/string.rb

Constants

ESCAPED_CHARS = { "\010" => '\b', "\f" => '\f', "\n" => '\n', "\r" => '\r', "\t" => '\t', '"' => '\"', '\\' => '\\\\', '>' => '\u003E', '<' => '\u003C', '&' => '\u0026'


Class: ActiveSupport::JSON::ParseError

Class | ActiveSupport::JSON::ParseError
In: | vendor/rails/activesupport/lib/active_support/json/decoding.rb
Parent: | StandardError


Class: ActiveSupport::JSON::Variable

Class | ActiveSupport::JSON::Variable
In: | vendor/rails/activesupport/lib/active_support/json/variable.rb
Parent: | String

A string that returns itself as its JSON-encoded form.

Methods

to_json

Public Instance methods

to_json(options=nil)

[Source]

   # File vendor/rails/activesupport/lib/active_support/json/variable.rb, line 5
5:       def to_json(options=nil)
6:         self
7:       end


Module: ActiveSupport::Memoizable

Module | ActiveSupport::Memoizable
In: | vendor/rails/activesupport/lib/active_support/memoizable.rb

Methods

memoize memoized_ivar_for

Classes and Modules

Module ActiveSupport::Memoizable::InstanceMethods

Public Class methods

memoized_ivar_for(symbol)

[Source]

   # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 3
3:     def self.memoized_ivar_for(symbol)
4:       "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym
5:     end

Public Instance methods

memoize(*symbols)

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 56
56:     def memoize(*symbols)
57:       symbols.each do |symbol|
58:         original_method = "_unmemoized_#{symbol}""_unmemoized_#{symbol}"
59:         memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol)
60:
61:         class_eval "include InstanceMethods                                                  # include InstanceMethods\n#\nif method_defined?(:\#{original_method})                                  # if method_defined?(:_unmemoized_mime_type)\nraise \"Already memoized \#{symbol}\"                                     #   raise \"Already memoized mime_type\"\nend                                                                      # end\nalias \#{original_method} \#{symbol}                                       # alias _unmemoized_mime_type mime_type\n#\nif instance_method(:\#{symbol}).arity == 0                                # if instance_method(:mime_type).arity == 0\ndef \#{symbol}(reload = false)                                          #   def mime_type(reload = false)\nif reload || !defined?(\#{memoized_ivar}) || \#{memoized_ivar}.empty?  #     if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty?\n\#{memoized_ivar} = [\#{original_method}.freeze]                     #       @_memoized_mime_type = [_unmemoized_mime_type.freeze]\nend                                                                  #     end\n\#{memoized_ivar}[0]                                                  #     @_memoized_mime_type[0]\nend                                                                    #   end\nelse                                                                     # else\ndef \#{symbol}(*args)                                                   #   def mime_type(*args)\n\#{memoized_ivar} ||= {} unless frozen?                               #     @_memoized_mime_type ||= {} unless frozen?\nreload = args.pop if args.last == true || args.last == :reload       #     reload = args.pop if args.last == true || args.last == :reload\n#\nif defined?(\#{memoized_ivar}) && \#{memoized_ivar}                    #     if defined?(@_memoized_mime_type) && @_memoized_mime_type\nif !reload && \#{memoized_ivar}.has_key?(args)                      #       if !reload && @_memoized_mime_type.has_key?(args)\n\#{memoized_ivar}[args]                                           #         @_memoized_mime_type[args]\nelsif \#{memoized_ivar}                                             #       elsif @_memoized_mime_type\n\#{memoized_ivar}[args] = \#{original_method}(*args).freeze        #         @_memoized_mime_type[args] = _unmemoized_mime_type(*args).freeze\nend                                                                #       end\nelse                                                                 #     else\n\#{original_method}(*args)                                          #       _unmemoized_mime_type(*args)\nend                                                                  #     end\nend                                                                    #   end\nend                                                                      # end\n#\nif private_method_defined?(\#{original_method.inspect})                   # if private_method_defined?(:_unmemoized_mime_type)\nprivate \#{symbol.inspect}                                              #   private :mime_type\nend                                                                      # end\n", __FILE__, __LINE__
62:       end
63:     end


Module: ActiveSupport::Memoizable::InstanceMethods

Module | ActiveSupport::Memoizable::InstanceMethods
In: | vendor/rails/activesupport/lib/active_support/memoizable.rb

Methods

flush_cache freeze_with_memoizable included memoize_all prime_cache unmemoize_all

Public Class methods

included(base)

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 8
 8:       def self.included(base)
 9:         base.class_eval do
10:           unless base.method_defined?(:freeze_without_memoizable)
11:             alias_method_chain :freeze, :memoizable
12:           end
13:         end
14:       end

Public Instance methods

flush_cache(*syms, &block)

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 44
44:       def flush_cache(*syms, &block)
45:         syms.each do |sym|
46:           methods.each do |m|
47:             if m.to_s =~ /^_unmemoized_(#{sym})/
48:               ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
49:               instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
50:             end
51:           end
52:         end
53:       end
freeze_with_memoizable()

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 16
16:       def freeze_with_memoizable
17:         memoize_all unless frozen?
18:         freeze_without_memoizable
19:       end
memoize_all()

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 21
21:       def memoize_all
22:         prime_cache ".*"
23:       end
prime_cache(*syms)

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 29
29:       def prime_cache(*syms)
30:         syms.each do |sym|
31:           methods.each do |m|
32:             if m.to_s =~ /^_unmemoized_(#{sym})/
33:               if method(m).arity == 0
34:                 __send__($1)
35:               else
36:                 ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
37:                 instance_variable_set(ivar, {})
38:               end
39:             end
40:           end
41:         end
42:       end
unmemoize_all()

[Source]

    # File vendor/rails/activesupport/lib/active_support/memoizable.rb, line 25
25:       def unmemoize_all
26:         flush_cache ".*"
27:       end


Class: ActiveSupport::MessageEncryptor

Class | ActiveSupport::MessageEncryptor
In: | vendor/rails/activesupport/lib/active_support/message_encryptor.rb
Parent: | Object

MessageEncryptor is a simple way to encrypt values which get stored somewhere you don‘t trust.

The cipher text and initialization vector are base64 encoded and returned to you.

This can be used in situations similar to the MessageVerifier, but where you don‘t want users to be able to determine the value of the payload.

Methods

decrypt decrypt_and_verify encrypt encrypt_and_sign new

Classes and Modules

Class ActiveSupport::MessageEncryptor::InvalidMessage

Constants

OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError

Public Class methods

new(secret, cipher = 'aes-256-cbc')

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_encryptor.rb, line 15
15:     def initialize(secret, cipher = 'aes-256-cbc')
16:       @secret = secret
17:       @cipher = cipher
18:     end

Public Instance methods

decrypt(encrypted_message)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_encryptor.rb, line 35
35:     def decrypt(encrypted_message)
36:       cipher = new_cipher
37:       encrypted_data, iv = encrypted_message.split("--").map {|v| ActiveSupport::Base64.decode64(v)}
38:
39:       cipher.decrypt
40:       cipher.key = @secret
41:       cipher.iv  = iv
42:
43:       decrypted_data = cipher.update(encrypted_data)
44:       decrypted_data << cipher.final
45:
46:       Marshal.load(decrypted_data)
47:     rescue OpenSSLCipherError, TypeError
48:       raise InvalidMessage
49:     end
decrypt_and_verify(value)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_encryptor.rb, line 55
55:     def decrypt_and_verify(value)
56:       decrypt(verifier.verify(value))
57:     end
encrypt(value)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_encryptor.rb, line 20
20:     def encrypt(value)
21:       cipher = new_cipher
22:       # Rely on OpenSSL for the initialization vector
23:       iv = cipher.random_iv
24:
25:       cipher.encrypt
26:       cipher.key = @secret
27:       cipher.iv  = iv
28:
29:       encrypted_data = cipher.update(Marshal.dump(value))
30:       encrypted_data << cipher.final
31:
32:       [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
33:     end
encrypt_and_sign(value)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_encryptor.rb, line 51
51:     def encrypt_and_sign(value)
52:       verifier.generate(encrypt(value))
53:     end


Class: ActiveSupport::MessageEncryptor::InvalidMessage

Class | ActiveSupport::MessageEncryptor::InvalidMessage
In: | vendor/rails/activesupport/lib/active_support/message_encryptor.rb
Parent: | StandardError


Class: ActiveSupport::MessageVerifier

Class | ActiveSupport::MessageVerifier
In: | vendor/rails/activesupport/lib/active_support/message_verifier.rb
Parent: | Object

MessageVerifier makes it easy to generate and verify messages which are signed to prevent tampering.

This is useful for cases like remember-me tokens and auto-unsubscribe links where the session store isn‘t suitable or available.

Remember Me:

  cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])

In the authentication filter:

  id, time = @verifier.verify(cookies[:remember_me])
  if time < Time.now
    self.current_user = User.find(id)
  end

Methods

generate new verify

Classes and Modules

Class ActiveSupport::MessageVerifier::InvalidSignature

Public Class methods

new(secret, digest = 'SHA1')

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_verifier.rb, line 21
21:     def initialize(secret, digest = 'SHA1')
22:       @secret = secret
23:       @digest = digest
24:     end

Public Instance methods

generate(value)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_verifier.rb, line 35
35:     def generate(value)
36:       data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
37:       "#{data}--#{generate_digest(data)}"
38:     end
verify(signed_message)

[Source]

    # File vendor/rails/activesupport/lib/active_support/message_verifier.rb, line 26
26:     def verify(signed_message)
27:       data, digest = signed_message.split("--")
28:       if digest != generate_digest(data)
29:         raise InvalidSignature
30:       else
31:         Marshal.load(ActiveSupport::Base64.decode64(data))
32:       end
33:     end


Class: ActiveSupport::MessageVerifier::InvalidSignature

Class | ActiveSupport::MessageVerifier::InvalidSignature
In: | vendor/rails/activesupport/lib/active_support/message_verifier.rb
Parent: | StandardError


Class: ActiveSupport::ModelName

Class | ActiveSupport::ModelName
In: | vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb
Parent: | String

Methods

new

Attributes

cache_key | [R]
partial_path | [R]
plural | [R]
singular | [R]

Public Class methods

new(name)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb, line 5
 5:     def initialize(name)
 6:       super
 7:       @singular = underscore.tr('/', '_').freeze
 8:       @plural = @singular.pluralize.freeze
 9:       @cache_key = tableize.freeze
10:       @partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze
11:     end


Class: ActiveSupport::Multibyte::Chars

Class | ActiveSupport::Multibyte::Chars
In: | vendor/rails/activesupport/lib/active_support/multibyte/chars.rb
Parent: | Object

Chars enables you to work transparently with UTF-8 encoding in the Ruby String class without having extensive knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an encoding safe manner. All the normal String methods are also implemented on the proxy.

String methods are proxied through the Chars object, and can be accessed through the mb_chars method. Methods which would normally return a String object now return a Chars object so methods can be chained.

  "The Perfect String  ".mb_chars.downcase.strip.normalize #=> "the perfect string"

Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. If certain methods do explicitly check the class, call to_s before you pass chars objects to them.

  bad.explicit_checking_method "T".mb_chars.downcase.to_s

The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different encodings you can write your own multibyte string handler and configure it through ActiveSupport::Multibyte.proxy_class.

  class CharsForUTF32
    def size
      @wrapped_string.size / 4
    end

    def self.accepts?(string)
      string.length % 4 == 0
    end
  end

  ActiveSupport::Multibyte.proxy_class = CharsForUTF32

Methods

+ <=> =~ [] []= acts_like_string? capitalize center compose compose_codepoints consumes? decompose decompose_codepoints downcase g_length g_pack g_unpack in_char_class? include? index insert length ljust lstrip method_missing new normalize ord reorder_characters respond_to? reverse rjust rstrip size slice slice! split strip tidy_bytes tidy_bytes u_unpack upcase wants?

Included Modules

Comparable

Constants

HANGUL_SBASE | = | 0xAC00 | Hangul character boundaries and properties
HANGUL_LBASE | = | 0x1100
HANGUL_VBASE | = | 0x1161
HANGUL_TBASE | = | 0x11A7
HANGUL_LCOUNT | = | 19
HANGUL_VCOUNT | = | 21
HANGUL_TCOUNT | = | 28
HANGUL_NCOUNT | = | HANGUL_VCOUNT * HANGUL_TCOUNT
HANGUL_SCOUNT | = | 11172
HANGUL_SLAST | = | HANGUL_SBASE + HANGUL_SCOUNT
HANGUL_JAMO_FIRST | = | 0x1100
HANGUL_JAMO_LAST | = | 0x11FF
UNICODE_WHITESPACE | = | [ (0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D> 0x0020, # White_Space # Zs SPACE 0x0085, # White_Space # Cc <control-0085> 0x00A0, # White_Space # Zs NO-BREAK SPACE 0x1680, # White_Space # Zs OGHAM SPACE MARK 0x180E, # White_Space # Zs MONGOLIAN VOWEL SEPARATOR (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE 0x2028, # White_Space # Zl LINE SEPARATOR 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE ].flatten.freeze | All the unicode whitespace
UNICODE_LEADERS_AND_TRAILERS | = | UNICODE_WHITESPACE + [65279] | BOM (byte order mark) can also be seen as whitespace, it‘s a non-rendering character used to distinguish between little and big endian. This is not an issue in utf-8, so it must be ignored.
UNICODE_TRAILERS_PAT | = | /(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+\Z/
UNICODE_LEADERS_PAT | = | /\A(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+/
UTF8_PAT | = | /\A(?: [\x00-\x7f] | [\xc2-\xdf] [\x80-\xbf] | \xe0 [\xa0-\xbf] [\x80-\xbf] | [\xe1-\xef] [\x80-\xbf] [\x80-\xbf] | \xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] | [\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] | \xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf] )*\z/xn | Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site)

External Aliases

wrapped_string | -> | to_s
wrapped_string | -> | to_str

Attributes

wrapped_string [R]

Public Class methods

compose_codepoints(codepoints)

Compose decomposed characters to the composed form.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 571
571:         def compose_codepoints(codepoints)
572:           pos = 0
573:           eoa = codepoints.length - 1
574:           starter_pos = 0
575:           starter_char = codepoints[0]
576:           previous_combining_class = -1
577:           while pos < eoa
578:             pos += 1
579:             lindex = starter_char - HANGUL_LBASE
580:             # -- Hangul
581:             if 0 <= lindex and lindex < HANGUL_LCOUNT
582:               vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
583:               if 0 <= vindex and vindex < HANGUL_VCOUNT
584:                 tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
585:                 if 0 <= tindex and tindex < HANGUL_TCOUNT
586:                   j = starter_pos + 2
587:                   eoa -= 2
588:                 else
589:                   tindex = 0
590:                   j = starter_pos + 1
591:                   eoa -= 1
592:                 end
593:                 codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
594:               end
595:               starter_pos += 1
596:               starter_char = codepoints[starter_pos]
597:             # -- Other characters
598:             else
599:               current_char = codepoints[pos]
600:               current = UCD.codepoints[current_char]
601:               if current.combining_class > previous_combining_class
602:                 if ref = UCD.composition_map[starter_char]
603:                   composition = ref[current_char]
604:                 else
605:                   composition = nil
606:                 end
607:                 unless composition.nil?
608:                   codepoints[starter_pos] = composition
609:                   starter_char = composition
610:                   codepoints.delete_at pos
611:                   eoa -= 1
612:                   pos -= 1
613:                   previous_combining_class = -1
614:                 else
615:                   previous_combining_class = current.combining_class
616:                 end
617:               else
618:                 previous_combining_class = current.combining_class
619:               end
620:               if current.combining_class == 0
621:                 starter_pos = pos
622:                 starter_char = codepoints[pos]
623:               end
624:             end
625:           end
626:           codepoints
627:         end
consumes?(string)

Returns true when the proxy class can handle the string. Returns false otherwise.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 132
132:       def self.consumes?(string)
133:         # Unpack is a little bit faster than regular expressions.
134:         string.unpack('U*')
135:         true
136:       rescue ArgumentError
137:         false
138:       end
decompose_codepoints(type, codepoints)

Decompose composed characters to the decomposed form.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 550
550:         def decompose_codepoints(type, codepoints)
551:           codepoints.inject([]) do |decomposed, cp|
552:             # if it's a hangul syllable starter character
553:             if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
554:               sindex = cp - HANGUL_SBASE
555:               ncp = [] # new codepoints
556:               ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
557:               ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
558:               tindex = sindex % HANGUL_TCOUNT
559:               ncp << (HANGUL_TBASE + tindex) unless tindex == 0
560:               decomposed.concat ncp
561:             # if the codepoint is decomposable in with the current decomposition type
562:             elsif (ncp = UCD.codepoints[cp].decomp_mapping) and (!UCD.codepoints[cp].decomp_type || type == :compatability)
563:               decomposed.concat decompose_codepoints(type, ncp.dup)
564:             else
565:               decomposed << cp
566:             end
567:           end
568:         end
g_pack(unpacked)

Reverse operation of g_unpack.

Example:

  Chars.g_pack(Chars.g_unpack('क्षि')) #=> 'क्षि'

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 521
521:         def g_pack(unpacked)
522:           (unpacked.flatten).pack('U*')
523:         end
g_unpack(string)

Unpack the string at grapheme boundaries. Returns a list of character lists.

Example:

  Chars.g_unpack('क्षि') #=> [[2325, 2381], [2359], [2367]]
  Chars.g_unpack('Café') #=> [[67], [97], [102], [233]]

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 487
487:         def g_unpack(string)
488:           codepoints = u_unpack(string)
489:           unpacked = []
490:           pos = 0
491:           marker = 0
492:           eoc = codepoints.length
493:           while(pos < eoc)
494:             pos += 1
495:             previous = codepoints[pos-1]
496:             current = codepoints[pos]
497:             if (
498:                 # CR X LF
499:                 one = ( previous == UCD.boundary[:cr] and current == UCD.boundary[:lf] ) or
500:                 # L X (L|V|LV|LVT)
501:                 two = ( UCD.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
502:                 # (LV|V) X (V|T)
503:                 three = ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
504:                 # (LVT|T) X (T)
505:                 four = ( in_char_class?(previous, [:lvt,:t]) and UCD.boundary[:t] === current ) or
506:                 # X Extend
507:                 five = (UCD.boundary[:extend] === current)
508:               )
509:             else
510:               unpacked << codepoints[marker..pos-1]
511:               marker = pos
512:             end
513:           end
514:           unpacked
515:         end
in_char_class?(codepoint, classes)

Detect whether the codepoint is in a certain character class. Returns true when it‘s in the specified character class and false otherwise. Valid character classes are: :cr, :lf, :l, :v, :lv, :lvt and :t.

Primarily used by the grapheme cluster support.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 478
478:         def in_char_class?(codepoint, classes)
479:           classes.detect { |c| UCD.boundary[c] === codepoint } ? true : false
480:         end
new(string)

Creates a new Chars instance by wrapping string.

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 93
93:         def initialize(string)
94:           @wrapped_string = string
95:           @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
96:         end
reorder_characters(codepoints)

Re-order codepoints so the string becomes canonical.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 534
534:         def reorder_characters(codepoints)
535:           length = codepoints.length- 1
536:           pos = 0
537:           while pos < length do
538:             cp1, cp2 = UCD.codepoints[codepoints[pos]], UCD.codepoints[codepoints[pos+1]]
539:             if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
540:               codepoints[pos..pos+1] = cp2.code, cp1.code
541:               pos += (pos > 0 ? -1 : 1)
542:             else
543:               pos += 1
544:             end
545:           end
546:           codepoints
547:         end
tidy_bytes(string)

Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 630
630:         def tidy_bytes(string)
631:           string.split(//u).map do |c|
632:             c.force_encoding(Encoding::ASCII) if c.respond_to?(:force_encoding)
633:
634:             if !UTF8_PAT.match(c)
635:               n = c.unpack('C')[0]
636:               n < 128 ? n.chr :
637:               n < 160 ? [UCD.cp1252[n] || n].pack('U') :
638:               n < 192 ? "\xC2" + n.chr : "\xC3" + (n-64).chr
639:             else
640:               c
641:             end
642:           end.join
643:         end
u_unpack(string)

Unpack the string at codepoints boundaries. Raises an EncodingError when the encoding of the string isn‘t valid UTF-8.

Example:

  Chars.u_unpack('Café') #=> [67, 97, 102, 233]

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 465
465:         def u_unpack(string)
466:           begin
467:             string.unpack 'U*'
468:           rescue ArgumentError
469:             raise EncodingError, 'malformed UTF-8 character'
470:           end
471:         end
wants?(string)

Returns true if the Chars class can and should act as a proxy for the string string. Returns false otherwise.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 127
127:       def self.wants?(string)
128:         $KCODE == 'UTF8' && consumes?(string)
129:       end

Public Instance methods

+(other)

Returns a new Chars object containing the other object concatenated to the string.

Example:

  ('Café'.mb_chars + ' périferôl').to_s #=> "Café périferôl"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 156
156:       def +(other)
157:         self << other
158:       end
<=>(other)

Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the object on the right side of the operation. It accepts any object that implements to_s. See String#<=> for more details.

Example:

  'é'.mb_chars <=> 'ü'.mb_chars #=> -1

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 148
148:       def <=>(other)
149:         @wrapped_string <=> other.to_s
150:       end
=~(other)

Like String#=~ only it returns the character offset (in codepoints) instead of the byte offset.

Example:

  'Café périferôl'.mb_chars =~ /ô/ #=> 12

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 164
164:       def =~(other)
165:         translate_offset(@wrapped_string =~ other)
166:       end
[](*args)

Alias for slice

[]=(*args)

Like String#[]=, except instead of byte offsets you specify character offsets.

Example:

  s = "Müller"
  s.mb_chars[2] = "e" # Replace character with offset 2
  s
  #=> "Müeler"

  s = "Müller"
  s.mb_chars[1, 2] = "ö" # Replace 2 characters at character offset 1
  s
  #=> "Möler"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 225
225:       def []=(*args)
226:         replace_by = args.pop
227:         # Indexed replace with regular expressions already works
228:         if args.first.is_a?(Regexp)
229:           @wrapped_string[*args] = replace_by
230:         else
231:           result = self.class.u_unpack(@wrapped_string)
232:           if args[0].is_a?(Fixnum)
233:             raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length
234:             min = args[0]
235:             max = args[1].nil? ? min : (min + args[1] - 1)
236:             range = Range.new(min, max)
237:             replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum)
238:           elsif args.first.is_a?(Range)
239:             raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length
240:             range = args[0]
241:           else
242:             needle = args[0].to_s
243:             min = index(needle)
244:             max = min + self.class.u_unpack(needle).length - 1
245:             range = Range.new(min, max)
246:           end
247:           result[range] = self.class.u_unpack(replace_by)
248:           @wrapped_string.replace(result.pack('U*'))
249:         end
250:       end
acts_like_string?()

Enable more predictable duck-typing on String-like classes. See Object#acts_like?.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 121
121:       def acts_like_string?
122:         true
123:       end
capitalize()

Converts the first character to uppercase and the remainder to lowercase.

Example:

 'über'.mb_chars.capitalize.to_s #=> "Über"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 387
387:       def capitalize
388:         (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase
389:       end
center(integer, padstr=' ')

Works just like String#center, only integer specifies characters instead of bytes.

Example:

  "¾ cup".mb_chars.center(8).to_s
  #=> " ¾ cup  "

  "¾ cup".mb_chars.center(8, " ").to_s # Use non-breaking whitespace
  #=> " ¾ cup  "

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 287
287:       def center(integer, padstr=' ')
288:         justify(integer, :center, padstr)
289:       end
compose()

Performs composition on all the characters.

Example:

  'é'.length #=> 3
  'é'.mb_chars.compose.to_s.length #=> 2

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 429
429:       def compose
430:         chars(self.class.compose_codepoints(self.class.u_unpack(@wrapped_string)).pack('U*'))
431:       end
decompose()

Performs canonical decomposition on all the characters.

Example:

  'é'.length #=> 2
  'é'.mb_chars.decompose.to_s.length #=> 3

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 420
420:       def decompose
421:         chars(self.class.decompose_codepoints(:canonical, self.class.u_unpack(@wrapped_string)).pack('U*'))
422:       end
downcase()

Convert characters in the string to lowercase.

Example:

  'VĚDA A VÝZKUM'.mb_chars.downcase.to_s #=> "věda a výzkum"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 379
379:       def downcase
380:         apply_mapping :lowercase_mapping
381:       end
g_length()

Returns the number of grapheme clusters in the string.

Example:

  'क्षि'.mb_chars.length #=> 4
  'क्षि'.mb_chars.g_length #=> 3

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 438
438:       def g_length
439:         self.class.g_unpack(@wrapped_string).length
440:       end
include?(other)

Returns true if contained string contains other. Returns false otherwise.

Example:

  'Café'.mb_chars.include?('é') #=> true

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 197
197:       def include?(other)
198:         # We have to redefine this method because Enumerable defines it.
199:         @wrapped_string.include?(other)
200:       end
index(needle, offset=0)

Returns the position needle in the string, counting in codepoints. Returns nil if needle isn‘t found.

Example:

  'Café périferôl'.mb_chars.index('ô') #=> 12
  'Café périferôl'.mb_chars.index(/\w/u) #=> 0

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 207
207:       def index(needle, offset=0)
208:         index = @wrapped_string.index(needle, offset)
209:         index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
210:       end
insert(offset, fragment)

Inserts the passed string at specified codepoint offsets.

Example:

  'Café'.mb_chars.insert(4, ' périferôl').to_s #=> "Café périferôl"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 181
181:       def insert(offset, fragment)
182:         unpacked = self.class.u_unpack(@wrapped_string)
183:         unless offset > unpacked.length
184:           @wrapped_string.replace(
185:             self.class.u_unpack(@wrapped_string).insert(offset, *self.class.u_unpack(fragment)).pack('U*')
186:           )
187:         else
188:           raise IndexError, "index #{offset} out of string"
189:         end
190:         self
191:       end
length()

Alias for size

ljust(integer, padstr=' ')

Works just like String#ljust, only integer specifies characters instead of bytes.

Example:

  "¾ cup".mb_chars.rjust(8).to_s
  #=> "¾ cup   "

  "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace
  #=> "¾ cup   "

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 274
274:       def ljust(integer, padstr=' ')
275:         justify(integer, :left, padstr)
276:       end
lstrip()

Strips entire range of Unicode whitespace from the left of the string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 297
297:       def lstrip
298:         chars(@wrapped_string.gsub(UNICODE_LEADERS_PAT, ''))
299:       end
method_missing(method, *args, &block)

Forward all undefined methods to the wrapped string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 104
104:       def method_missing(method, *args, &block)
105:         if method.to_s =~ /!$/
106:           @wrapped_string.__send__(method, *args, &block)
107:           self
108:         else
109:           result = @wrapped_string.__send__(method, *args, &block)
110:           result.kind_of?(String) ? chars(result) : result
111:         end
112:       end
normalize(form=ActiveSupport::Multibyte.default_normalization_form)

Returns the KC normalization of the string by default. NFKC is considered the best normalization form for passing strings to databases and validations.

  • str - The string to perform normalization on.
  • form - The form you want to normalize in. Should be one of the following: :c, :kc, :d, or :kd. Default is ActiveSupport::Multibyte.default_normalization_form

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 398
398:       def normalize(form=ActiveSupport::Multibyte.default_normalization_form)
399:         # See http://www.unicode.org/reports/tr15, Table 1
400:         codepoints = self.class.u_unpack(@wrapped_string)
401:         chars(case form
402:           when :d
403:             self.class.reorder_characters(self.class.decompose_codepoints(:canonical, codepoints))
404:           when :c
405:             self.class.compose_codepoints(self.class.reorder_characters(self.class.decompose_codepoints(:canonical, codepoints)))
406:           when :kd
407:             self.class.reorder_characters(self.class.decompose_codepoints(:compatability, codepoints))
408:           when :kc
409:             self.class.compose_codepoints(self.class.reorder_characters(self.class.decompose_codepoints(:compatability, codepoints)))
410:           else
411:             raise ArgumentError, "#{form} is not a valid normalization variant", caller
412:         end.pack('U*'))
413:       end
ord()

Returns the codepoint of the first character in the string.

Example:

  'こんにちは'.mb_chars.ord #=> 12371

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 363
363:       def ord
364:         self.class.u_unpack(@wrapped_string)[0]
365:       end
respond_to?(method, include_private=false)

Returns true if obj responds to the given method. Private methods are included in the search only if the optional second parameter evaluates to true.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 116
116:       def respond_to?(method, include_private=false)
117:         super || @wrapped_string.respond_to?(method, include_private) || false
118:       end
reverse()

Reverses all characters in the string.

Example:

  'Café'.mb_chars.reverse.to_s #=> 'éfaC'

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 316
316:       def reverse
317:         chars(self.class.u_unpack(@wrapped_string).reverse.pack('U*'))
318:       end
rjust(integer, padstr=' ')

Works just like String#rjust, only integer specifies characters instead of bytes.

Example:

  "¾ cup".mb_chars.rjust(8).to_s
  #=> "   ¾ cup"

  "¾ cup".mb_chars.rjust(8, " ").to_s # Use non-breaking whitespace
  #=> "   ¾ cup"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 261
261:       def rjust(integer, padstr=' ')
262:         justify(integer, :right, padstr)
263:       end
rstrip()

Strips entire range of Unicode whitespace from the right of the string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 292
292:       def rstrip
293:         chars(@wrapped_string.gsub(UNICODE_TRAILERS_PAT, ''))
294:       end
size()

Returns the number of codepoints in the string

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 307
307:       def size
308:         self.class.u_unpack(@wrapped_string).size
309:       end
slice(*args)

Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that character.

Example:

  'こんにちは'.mb_chars.slice(2..3).to_s #=> "にち"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 325
325:       def slice(*args)
326:         if args.size > 2
327:           raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" # Do as if we were native
328:         elsif (args.size == 2 && !(args.first.is_a?(Numeric) || args.first.is_a?(Regexp)))
329:           raise TypeError, "cannot convert #{args.first.class} into Integer" # Do as if we were native
330:         elsif (args.size == 2 && !args[1].is_a?(Numeric))
331:           raise TypeError, "cannot convert #{args[1].class} into Integer" # Do as if we were native
332:         elsif args[0].kind_of? Range
333:           cps = self.class.u_unpack(@wrapped_string).slice(*args)
334:           result = cps.nil? ? nil : cps.pack('U*')
335:         elsif args[0].kind_of? Regexp
336:           result = @wrapped_string.slice(*args)
337:         elsif args.size == 1 && args[0].kind_of?(Numeric)
338:           character = self.class.u_unpack(@wrapped_string)[args[0]]
339:           result = character.nil? ? nil : [character].pack('U')
340:         else
341:           result = self.class.u_unpack(@wrapped_string).slice(*args).pack('U*')
342:         end
343:         result.nil? ? nil : chars(result)
344:       end
slice!(*args)

Like String#slice!, except instead of byte offsets you specify character offsets.

Example:

  s = 'こんにちは'
  s.mb_chars.slice!(2..3).to_s #=> "にち"
  s #=> "こんは"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 353
353:       def slice!(*args)
354:         slice = self[*args]
355:         self[*args] = ''
356:         slice
357:       end
split(*args)

Works just like String#split, with the exception that the items in the resulting list are Chars instances instead of String. This makes chaining methods easier.

Example:

  'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } #=> ["CAF", " P", "RIFERÔL"]

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 173
173:       def split(*args)
174:         @wrapped_string.split(*args).map { |i| i.mb_chars }
175:       end
strip()

Strips entire range of Unicode whitespace from the right and left of the string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 302
302:       def strip
303:         rstrip.lstrip
304:       end
tidy_bytes()

Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 443
443:       def tidy_bytes
444:         chars(self.class.tidy_bytes(@wrapped_string))
445:       end
upcase()

Convert characters in the string to uppercase.

Example:

  'Laurent, òu sont les tests?'.mb_chars.upcase.to_s #=> "LAURENT, ÒU SONT LES TESTS?"

[Source]

     # File vendor/rails/activesupport/lib/active_support/multibyte/chars.rb, line 371
371:       def upcase
372:         apply_mapping :uppercase_mapping
373:       end


Class: ActiveSupport::Multibyte::Codepoint

Class | ActiveSupport::Multibyte::Codepoint
In: | vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb
Parent: | Object

Holds data about a codepoint in the Unicode database

Attributes

code | [RW]
combining_class | [RW]
decomp_mapping | [RW]
decomp_type | [RW]
lowercase_mapping | [RW]
uppercase_mapping | [RW]


Class: ActiveSupport::Multibyte::EncodingError

Class | ActiveSupport::Multibyte::EncodingError
In: | vendor/rails/activesupport/lib/active_support/multibyte/exceptions.rb
Parent: | StandardError

Raised when a problem with the encoding was found.


Class: ActiveSupport::Multibyte::UnicodeDatabase

Class | ActiveSupport::Multibyte::UnicodeDatabase
In: | vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb
Parent: | Object

Holds static data from the Unicode database

Methods

=== dirname filename load new

Constants

ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252

Public Class methods

dirname()

Returns the directory in which the data files are stored

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb, line 59
59:       def self.dirname
60:         File.dirname(__FILE__) + '/../values/'
61:       end
filename()

Returns the filename for the data file for this version

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb, line 64
64:       def self.filename
65:         File.expand_path File.join(dirname, "unicode_tables.dat")
66:       end
new()

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb, line 16
16:       def initialize
17:         @codepoints = Hash.new(Codepoint.new)
18:         @composition_exclusion = []
19:         @composition_map = {}
20:         @boundary = {}
21:         @cp1252 = {}
22:       end

Public Instance methods

===(other)

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb, line 46
46:             def ===(other)
47:               detect { |i| i === other } ? true : false
48:             end
load()

Loads the Unicode database and returns all the internal objects of UnicodeDatabase.

[Source]

    # File vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb, line 36
36:       def load
37:         begin
38:           @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
39:         rescue Exception => e
40:             raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
41:         end
42:
43:         # Redefine the === method so we can write shorter rules for grapheme cluster breaks
44:         @boundary.each do |k,_|
45:           @boundary[k].instance_eval do
46:             def ===(other)
47:               detect { |i| i === other } ? true : false
48:             end
49:           end if @boundary[k].kind_of?(Array)
50:         end
51:
52:         # define attr_reader methods for the instance variables
53:         class << self
54:           attr_reader(*ATTRIBUTES)
55:         end
56:       end


Module: ActiveSupport::Rescuable

Module | ActiveSupport::Rescuable
In: | vendor/rails/activesupport/lib/active_support/rescuable.rb

Rescuable module adds support for easier exception handling.

Methods

handler_for_rescue rescue_with_handler

Classes and Modules

Module ActiveSupport::Rescuable::ClassMethods

Public Instance methods

handler_for_rescue(exception)

[Source]

     # File vendor/rails/activesupport/lib/active_support/rescuable.rb, line 78
 78:     def handler_for_rescue(exception)
 79:       # We go from right to left because pairs are pushed onto rescue_handlers
 80:       # as rescue_from declarations are found.
 81:       _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
 82:         # The purpose of allowing strings in rescue_from is to support the
 83:         # declaration of handler associations for exception classes whose
 84:         # definition is yet unknown.
 85:         #
 86:         # Since this loop needs the constants it would be inconsistent to
 87:         # assume they should exist at this point. An early raised exception
 88:         # could trigger some other handler and the array could include
 89:         # precisely a string whose corresponding constant has not yet been
 90:         # seen. This is why we are tolerant to unknown constants.
 91:         #
 92:         # Note that this tolerance only matters if the exception was given as
 93:         # a string, otherwise a NameError will be raised by the interpreter
 94:         # itself when rescue_from CONSTANT is executed.
 95:         klass = self.class.const_get(klass_name) rescue nil
 96:         klass ||= klass_name.constantize rescue nil
 97:         exception.is_a?(klass) if klass
 98:       end
 99:
100:       case rescuer
101:       when Symbol
102:         method(rescuer)
103:       when Proc
104:         rescuer.bind(self)
105:       end
106:     end
rescue_with_handler(exception)

Tries to rescue the exception by looking up and calling a registered handler.

[Source]

    # File vendor/rails/activesupport/lib/active_support/rescuable.rb, line 71
71:     def rescue_with_handler(exception)
72:       if handler = handler_for_rescue(exception)
73:         handler.arity != 0 ? handler.call(exception) : handler.call
74:         true # don't rely on the return value of the handler
75:       end
76:     end


Module: ActiveSupport::Rescuable::ClassMethods

Module | ActiveSupport::Rescuable::ClassMethods
In: | vendor/rails/activesupport/lib/active_support/rescuable.rb

Methods

rescue_from

Public Instance methods

rescue_from(*klasses, &block)

Rescue exceptions raised in controller actions.

rescue_from receives a series of exception classes or class names, and a trailing :with option with the name of a method or a Proc object to be called to handle them. Alternatively a block can be given.

Handlers that take one argument will be called with the exception, so that the exception can be inspected when dealing with it.

Handlers are inherited. They are searched from right to left, from bottom to top, and up the hierarchy. The handler of the first class for which exception.is_a?(klass) holds true is the one invoked, if any.

  class ApplicationController < ActionController::Base
    rescue_from User::NotAuthorized, :with => :deny_access # self defined exception
    rescue_from ActiveRecord::RecordInvalid, :with => :show_errors

    rescue_from 'MyAppError::Base' do |exception|
      render :xml => exception, :status => 500
    end

    protected
      def deny_access
        ...
      end

      def show_errors(exception)
        exception.record.new_record? ? ...
      end
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/rescuable.rb, line 44
44:       def rescue_from(*klasses, &block)
45:         options = klasses.extract_options!
46:
47:         unless options.has_key?(:with)
48:           if block_given?
49:             options[:with] = block
50:           else
51:             raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument."
52:           end
53:         end
54:
55:         klasses.each do |klass|
56:           key = if klass.is_a?(Class) && klass <= Exception
57:             klass.name
58:           elsif klass.is_a?(String)
59:             klass
60:           else
61:             raise ArgumentError, "#{klass} is neither an Exception nor a String"
62:           end
63:
64:           # put the new handler at the end because the list is read in reverse
65:           rescue_handlers << [key, options[:with]]
66:         end
67:       end


Module: ActiveSupport::SecureRandom

Module | ActiveSupport::SecureRandom
In: | vendor/rails/activesupport/lib/active_support/secure_random.rb

Secure random number generator interface.

This library is an interface for secure random number generator which is suitable for generating session key in HTTP cookies, etc.

It supports following secure random number generators.

  • openssl
  • /dev/urandom
  • Win32

Note: This module is based on the SecureRandom library from Ruby 1.9, revision 18786, August 23 2008. It‘s 100% interface-compatible with Ruby 1.9‘s SecureRandom library.

Example

 # random hexadecimal string.
 p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
 p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
 p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
 p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
 p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
 ...

 # random base64 string.
 p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
 p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
 p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
 p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
 p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
 p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="
 ...

 # random binary string.
 p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
 p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
 ...

Methods

base64 hex random_bytes random_number

Public Class methods

base64(n=nil)

SecureRandom.base64 generates a random base64 string.

The argument n specifies the length of the random length. The length of the result string is about 4/3 of n.

If n is not specified, 16 is assumed. It may be larger in future.

If secure random number generator is not available, NotImplementedError is raised.

[Source]

     # File vendor/rails/activesupport/lib/active_support/secure_random.rb, line 151
151:       def self.base64(n=nil)
152:         [random_bytes(n)].pack("m*").delete("\n")
153:       end
hex(n=nil)

SecureRandom.hex generates a random hex string.

The argument n specifies the length of the random length. The length of the result string is twice of n.

If n is not specified, 16 is assumed. It may be larger in future.

If secure random number generator is not available, NotImplementedError is raised.

[Source]

     # File vendor/rails/activesupport/lib/active_support/secure_random.rb, line 137
137:       def self.hex(n=nil)
138:         random_bytes(n).unpack("H*")[0]
139:       end
random_bytes(n=nil)

SecureRandom.random_bytes generates a random binary string.

The argument n specifies the length of the result string.

If n is not specified, 16 is assumed. It may be larger in future.

If secure random number generator is not available, NotImplementedError is raised.

[Source]

     # File vendor/rails/activesupport/lib/active_support/secure_random.rb, line 59
 59:       def self.random_bytes(n=nil)
 60:         n ||= 16
 61:
 62:         unless defined? OpenSSL
 63:           begin
 64:             require 'openssl'
 65:           rescue LoadError
 66:           end
 67:         end
 68:
 69:         if defined? OpenSSL::Random
 70:           return OpenSSL::Random.random_bytes(n)
 71:         end
 72:
 73:         if !defined?(@has_urandom) || @has_urandom
 74:           flags = File::RDONLY
 75:           flags |= File::NONBLOCK if defined? File::NONBLOCK
 76:           flags |= File::NOCTTY if defined? File::NOCTTY
 77:           flags |= File::NOFOLLOW if defined? File::NOFOLLOW
 78:           begin
 79:             File.open("/dev/urandom", flags) {|f|
 80:               unless f.stat.chardev?
 81:                 raise Errno::ENOENT
 82:               end
 83:               @has_urandom = true
 84:               ret = f.readpartial(n)
 85:               if ret.length != n
 86:                 raise NotImplementedError, "Unexpected partial read from random device"
 87:               end
 88:               return ret
 89:             }
 90:           rescue Errno::ENOENT
 91:             @has_urandom = false
 92:           end
 93:         end
 94:
 95:         if !defined?(@has_win32)
 96:           begin
 97:             require 'Win32API'
 98:
 99:             crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", 'PPPII', 'L')
100:             @crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", 'LIP', 'L')
101:
102:             hProvStr = " " * 4
103:             prov_rsa_full = 1
104:             crypt_verifycontext = 0xF0000000
105:
106:             if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, crypt_verifycontext) == 0
107:               raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
108:             end
109:             @hProv, = hProvStr.unpack('L')
110:
111:             @has_win32 = true
112:           rescue LoadError
113:             @has_win32 = false
114:           end
115:         end
116:         if @has_win32
117:           bytes = " " * n
118:           if @crypt_gen_random.call(@hProv, bytes.size, bytes) == 0
119:             raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
120:           end
121:           return bytes
122:         end
123:
124:         raise NotImplementedError, "No random device"
125:       end
random_number(n=0)

SecureRandom.random_number generates a random number.

If an positive integer is given as n, SecureRandom.random_number returns an integer: 0 <= SecureRandom.random_number(n) < n.

If 0 is given or an argument is not given, SecureRandom.random_number returns an float: 0.0 <= SecureRandom.random_number() < 1.0.

[Source]

     # File vendor/rails/activesupport/lib/active_support/secure_random.rb, line 164
164:       def self.random_number(n=0)
165:         if 0 < n
166:           hex = n.to_s(16)
167:           hex = '0' + hex if (hex.length & 1) == 1
168:           bin = [hex].pack("H*")
169:           mask = bin[0]
170:           mask |= mask >> 1
171:           mask |= mask >> 2
172:           mask |= mask >> 4
173:           begin
174:             rnd = SecureRandom.random_bytes(bin.length)
175:             rnd[0] = rnd[0] & mask
176:           end until rnd < bin
177:           rnd.unpack("H*")[0].hex
178:         else
179:           # assumption: Float::MANT_DIG <= 64
180:           i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
181:           Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
182:         end
183:       end


Class: ActiveSupport::StringInquirer

Class | ActiveSupport::StringInquirer
In: | vendor/rails/activesupport/lib/active_support/string_inquirer.rb
Parent: | String

Wrapping a string in this class gives you a prettier way to test for equality. The value returned by Rails.env is wrapped in a StringInquirer object so instead of calling this:

  Rails.env == "production"

you can call this:

  Rails.env.production?

Methods

method_missing

Public Instance methods

method_missing(method_name, *arguments)

[Source]

    # File vendor/rails/activesupport/lib/active_support/string_inquirer.rb, line 13
13:     def method_missing(method_name, *arguments)
14:       if method_name.to_s[-1,1] == "?"
15:         self == method_name.to_s[0..-2]
16:       else
17:         super
18:       end
19:     end


Class: ActiveSupport::TestCase

Class | ActiveSupport::TestCase
In: | vendor/rails/railties/lib/test_help.rb vendor/rails/activesupport/lib/active_support/test_case.rb
Parent: | Object

Included Modules

ActiveRecord::TestFixtures
Rails::BacktraceFilterForTestUnit
ActiveSupport::Testing::Default
ActiveSupport::Testing::SetupAndTeardown
ActiveSupport::Testing::Assertions
ActiveSupport::Testing::Deprecation

Constants

Assertion | = | MiniTest::Assertion
Assertion | = | Test::Unit::AssertionFailedError


Module: ActiveSupport::Testing

Module | ActiveSupport::Testing
In: | vendor/rails/activesupport/lib/active_support/testing/assertions.rb vendor/rails/activesupport/lib/active_support/testing/declarative.rb vendor/rails/activesupport/lib/active_support/testing/default.rb vendor/rails/activesupport/lib/active_support/testing/deprecation.rb vendor/rails/activesupport/lib/active_support/testing/performance.rb vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb

Methods

full_test_name included run run_profile run_test run_warmup

Classes and Modules

Module ActiveSupport::Testing::Assertions
Module ActiveSupport::Testing::Declarative
Module ActiveSupport::Testing::Metrics
Module ActiveSupport::Testing::Performance
Module ActiveSupport::Testing::SetupAndTeardown
Class ActiveSupport::Testing::Benchmarker
Class ActiveSupport::Testing::Performer
Class ActiveSupport::Testing::Profiler

Public Class methods

included(base)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 26
26:       def self.included(base)
27:         base.superclass_delegating_accessor :profile_options
28:         base.profile_options = DEFAULTS
29:       end

Public Instance methods

full_test_name()

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 31
31:       def full_test_name
32:         "#{self.class.name}##{method_name}"
33:       end
run(result) {|self.class::STARTED, name| ...}

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 35
35:       def run(result)
36:         return if method_name =~ /^default_test$/
37:
38:         yield(self.class::STARTED, name)
39:         @_result = result
40:
41:         run_warmup
42:         if profile_options && metrics = profile_options[:metrics]
43:           metrics.each do |metric_name|
44:             if klass = Metrics[metric_name.to_sym]
45:               run_profile(klass.new)
46:               result.add_run
47:             end
48:           end
49:         end
50:
51:         yield(self.class::FINISHED, name)
52:       end
run_test(metric, mode)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 54
54:       def run_test(metric, mode)
55:         run_callbacks :setup
56:         setup
57:         metric.send(mode) { __send__ @method_name }
58:       rescue ::Test::Unit::AssertionFailedError => e
59:         add_failure(e.message, e.backtrace)
60:       rescue StandardError, ScriptError
61:         add_error($!)
62:       ensure
63:         begin
64:           teardown
65:           run_callbacks :teardown, :enumerator => :reverse_each
66:         rescue ::Test::Unit::AssertionFailedError => e
67:           add_failure(e.message, e.backtrace)
68:         rescue StandardError, ScriptError
69:           add_error($!)
70:         end
71:       end

Protected Instance methods

run_profile(metric)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 84
84:         def run_profile(metric)
85:           klass = profile_options[:benchmark] ? Benchmarker : Profiler
86:           performer = klass.new(self, metric)
87:
88:           performer.run
89:           puts performer.report
90:           performer.record
91:         end
run_warmup()

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 74
74:         def run_warmup
75:           GC.start
76:
77:           time = Metrics::Time.new
78:           run_test(time, :benchmark)
79:           puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
80:
81:           GC.start
82:         end


Module: ActiveSupport::Testing::Assertions

Module | ActiveSupport::Testing::Assertions
In: | vendor/rails/activesupport/lib/active_support/testing/assertions.rb

Methods

assert_difference assert_no_difference

Public Instance methods

assert_difference(expression, difference = 1, message = nil) {|| ...}

Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.

  assert_difference 'Article.count' do
    post :create, :article => {...}
  end

An arbitrary expression is passed in and evaluated.

  assert_difference 'assigns(:article).comments(:reload).size' do
    post :create, :comment => {...}
  end

An arbitrary positive or negative difference can be specified. The default is +1.

  assert_difference 'Article.count', -1 do
    post :delete, :id => ...
  end

An array of expressions can also be passed in and evaluated.

  assert_difference [ 'Article.count', 'Post.count' ], +2 do
    post :create, :article => {...}
  end

A error message can be specified.

  assert_difference 'Article.count', -1, "An Article should be destroyed" do
    post :delete, :id => ...
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/assertions.rb, line 34
34:       def assert_difference(expression, difference = 1, message = nil, &block)
35:         b = block.send(:binding)
36:         exps = Array.wrap(expression)
37:         before = exps.map { |e| eval(e, b) }
38:
39:         yield
40:
41:         exps.each_with_index do |e, i|
42:           error = "#{e.inspect} didn't change by #{difference}"
43:           error = "#{message}.\n#{error}" if message
44:           assert_equal(before[i] + difference, eval(e, b), error)
45:         end
46:       end
assert_no_difference(expression, message = nil, &block)

Assertion that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.

  assert_no_difference 'Article.count' do
    post :create, :article => invalid_attributes
  end

A error message can be specified.

  assert_no_difference 'Article.count', "An Article should not be destroyed" do
    post :create, :article => invalid_attributes
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/assertions.rb, line 60
60:       def assert_no_difference(expression, message = nil, &block)
61:         assert_difference expression, 0, message, &block
62:       end


Class: ActiveSupport::Testing::Benchmarker

Class | ActiveSupport::Testing::Benchmarker
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Performer

Methods

environment output_filename record run with_output_file

Constants

HEADER = 'measurement,created_at,app,rails,ruby,platform'

Public Instance methods

environment()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 125
125:         def environment
126:           unless defined? @env
127:             app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
128:
129:             rails = Rails::VERSION::STRING
130:             if File.directory?('vendor/rails/.git')
131:               Dir.chdir('vendor/rails') do
132:                 rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
133:               end
134:             end
135:
136:             ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
137:             ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
138:
139:             @env = [app, rails, ruby, RUBY_PLATFORM] * ','
140:           end
141:
142:           @env
143:         end
record()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 117
117:         def record
118:           avg = @metric.total / profile_options[:runs].to_i
119:           now = Time.now.utc.xmlschema
120:           with_output_file do |file|
121:             file.puts "#{avg},#{now},#{environment}"
122:           end
123:         end
run()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 112
112:         def run
113:           profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
114:           @total = @metric.total
115:         end

Protected Instance methods

output_filename()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 161
161:           def output_filename
162:             "#{super}.csv"
163:           end
with_output_file() {|file| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 148
148:           def with_output_file
149:             fname = output_filename
150:
151:             if new = !File.exist?(fname)
152:               FileUtils.mkdir_p(File.dirname(fname))
153:             end
154:
155:             File.open(fname, 'ab') do |file|
156:               file.puts(HEADER) if new
157:               yield file
158:             end
159:           end


Module: ActiveSupport::Testing::Declarative

Module | ActiveSupport::Testing::Declarative
In: | vendor/rails/activesupport/lib/active_support/testing/declarative.rb

Methods

test

Public Instance methods

test(name, &block)

test "verify something" do

  ...

end

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/declarative.rb, line 7
 7:       def test(name, &block)
 8:         test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
 9:         defined = instance_method(test_name) rescue false
10:         raise "#{test_name} is already defined in #{self}" if defined
11:         if block_given?
12:           define_method(test_name, &block)
13:         else
14:           define_method(test_name) do
15:             flunk "No implementation provided for #{name}"
16:           end
17:         end
18:       end


Module: ActiveSupport::Testing::Metrics

Module | ActiveSupport::Testing::Metrics
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb

Methods

[]

Classes and Modules

Class ActiveSupport::Testing::Metrics::Base
Class ActiveSupport::Testing::Metrics::CpuTime
Class ActiveSupport::Testing::Metrics::GcRuns
Class ActiveSupport::Testing::Metrics::GcTime
Class ActiveSupport::Testing::Metrics::Memory
Class ActiveSupport::Testing::Metrics::Objects
Class ActiveSupport::Testing::Metrics::ProcessTime
Class ActiveSupport::Testing::Metrics::Time
Class ActiveSupport::Testing::Metrics::WallTime

Public Class methods

[](name)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 221
221:         def self.[](name)
222:           const_get(name.to_s.camelize)
223:         rescue NameError
224:           nil
225:         end


Class: ActiveSupport::Testing::Metrics::Base

Class | ActiveSupport::Testing::Metrics::Base
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Object

Methods

benchmark measure measure_mode name new profile with_gc_stats with_gc_stats with_gc_stats

Attributes

total [R]

Public Class methods

new()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 230
230:           def initialize
231:             @total = 0
232:           end

Public Instance methods

benchmark() {|| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 246
246:           def benchmark
247:             with_gc_stats do
248:               before = measure
249:               yield
250:               @total += (measure - before)
251:             end
252:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 242
242:           def measure
243:             0
244:           end
measure_mode()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 238
238:           def measure_mode
239:             self.class::Mode
240:           end
name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 234
234:           def name
235:             @name ||= self.class.name.demodulize.underscore
236:           end
profile() {|| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 254
254:           def profile
255:             RubyProf.resume
256:             yield
257:           ensure
258:             RubyProf.pause
259:           end

Protected Instance methods

with_gc_stats() {|| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 270
270:               def with_gc_stats
271:                 GC.start
272:                 GC.disable
273:                 GC::Profiler.enable
274:                 yield
275:               ensure
276:                 GC::Profiler.disable
277:                 GC.enable
278:               end
with_gc_stats() {|| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 263
263:               def with_gc_stats
264:                 GC.enable_stats
265:                 yield
266:               ensure
267:                 GC.disable_stats
268:               end
with_gc_stats() {|| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 280
280:               def with_gc_stats
281:                 yield
282:               end


Class: ActiveSupport::Testing::Metrics::CpuTime

Class | ActiveSupport::Testing::Metrics::CpuTime
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Time

Methods

measure new

Constants

Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)

Public Class methods

new(*args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 319
319:           def initialize(*args)
320:             # FIXME: yeah my CPU is 2.33 GHz
321:             RubyProf.cpu_frequency = 2.33e9
322:             super
323:           end

Public Instance methods

measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 325
325:           def measure
326:             RubyProf.measure_cpu_time
327:           end


Class: ActiveSupport::Testing::Metrics::GcRuns

Class | ActiveSupport::Testing::Metrics::GcRuns
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Base

Methods

format measure measure measure

Constants

Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)

Public Instance methods

format(measurement)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 427
427:           def format(measurement)
428:             measurement.to_i.to_s
429:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 422
422:             def measure
423:               GC.heap_info['num_gc_passes']
424:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 418
418:             def measure
419:               GC.collections
420:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 414
414:             def measure
415:               RubyProf.measure_gc_runs
416:             end


Class: ActiveSupport::Testing::Metrics::GcTime

Class | ActiveSupport::Testing::Metrics::GcTime
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Base

Methods

format measure measure

Constants

Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)

Public Instance methods

format(measurement)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 445
445:           def format(measurement)
446:             '%d ms' % (measurement / 1000)
447:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 440
440:             def measure
441:               GC.time
442:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 436
436:             def measure
437:               RubyProf.measure_gc_time
438:             end


Class: ActiveSupport::Testing::Metrics::Memory

Class | ActiveSupport::Testing::Metrics::Memory
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Base

Methods

format measure measure measure measure measure measure

Constants

Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)

Public Instance methods

format(measurement)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 374
374:           def format(measurement)
375:             '%.2f KB' % measurement
376:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 353
353:             def measure
354:               GC.total_malloc_allocated_size / 1024.0
355:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 347
347:             def measure
348:               GC.heap_info['heap_current_memory'] / 1024.0
349:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 341
341:             def measure
342:               GC.allocated_size / 1024.0
343:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 359
359:             def measure
360:               GC.malloc_allocated_size / 1024.0
361:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 365
365:             def measure
366:               GC.enable
367:               GC.start
368:               kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0
369:               GC.disable
370:               kb
371:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 335
335:             def measure
336:               RubyProf.measure_memory / 1024.0
337:             end


Class: ActiveSupport::Testing::Metrics::Objects

Class | ActiveSupport::Testing::Metrics::Objects
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Base

Methods

format measure measure measure

Constants

Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)

Public Instance methods

format(measurement)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 405
405:           def format(measurement)
406:             measurement.to_i.to_s
407:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 395
395:             def measure
396:               GC.enable
397:               GC.start
398:               last = GC::Profiler.data.last
399:               count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
400:               GC.disable
401:               count
402:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 389
389:             def measure
390:               ObjectSpace.allocated_objects
391:             end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 383
383:             def measure
384:               RubyProf.measure_allocations
385:             end


Class: ActiveSupport::Testing::Metrics::ProcessTime

Class | ActiveSupport::Testing::Metrics::ProcessTime
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Time

Methods

measure

Constants

Mode = RubyProf::PROCESS_TIME

Public Instance methods

measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 303
303:           def measure
304:             RubyProf.measure_process_time
305:           end


Class: ActiveSupport::Testing::Metrics::Time

Class | ActiveSupport::Testing::Metrics::Time
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Base

Methods

format measure

Public Instance methods

format(measurement)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 291
291:           def format(measurement)
292:             if measurement < 2
293:               '%d ms' % (measurement * 1000)
294:             else
295:               '%.2f sec' % measurement
296:             end
297:           end
measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 287
287:           def measure
288:             ::Time.now.to_f
289:           end


Class: ActiveSupport::Testing::Metrics::WallTime

Class | ActiveSupport::Testing::Metrics::WallTime
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Time

Methods

measure

Constants

Mode = RubyProf::WALL_TIME

Public Instance methods

measure()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 311
311:           def measure
312:             RubyProf.measure_wall_time
313:           end


Module: ActiveSupport::Testing::Performance

Module | ActiveSupport::Testing::Performance
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb

Constants

DEFAULTS = if benchmark = ARGV.include?('--benchmark')


Class: ActiveSupport::Testing::Performer

Class | ActiveSupport::Testing::Performer
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Object

Methods

new output_filename report

Public Class methods

new(harness, metric)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 96
96:         def initialize(harness, metric)
97:           @harness, @metric = harness, metric
98:         end

Public Instance methods

report()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 100
100:         def report
101:           rate = @total / profile_options[:runs]
102:           '%20s: %s' % [@metric.name, @metric.format(rate)]
103:         end

Protected Instance methods

output_filename()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 106
106:           def output_filename
107:             "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
108:           end


Class: ActiveSupport::Testing::Profiler

Class | ActiveSupport::Testing::Profiler
In: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Parent: | Performer

Methods

new output_filename record report run

Public Class methods

new(*args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 167
167:         def initialize(*args)
168:           super
169:           @supported = @metric.measure_mode rescue false
170:         end

Public Instance methods

record()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 191
191:         def record
192:           return unless @supported
193:
194:           klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
195:
196:           klasses.each do |klass|
197:             fname = output_filename(klass)
198:             FileUtils.mkdir_p(File.dirname(fname))
199:             File.open(fname, 'wb') do |file|
200:               klass.new(@data).print(file, profile_options.slice(:min_percent))
201:             end
202:           end
203:         end
report()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 183
183:         def report
184:           if @supported
185:             super
186:           else
187:             '%20s: unsupported' % @metric.name
188:           end
189:         end
run()

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 172
172:         def run
173:           return unless @supported
174:
175:           RubyProf.measure_mode = @metric.measure_mode
176:           RubyProf.start
177:           RubyProf.pause
178:           profile_options[:runs].to_i.times { run_test(@metric, :profile) }
179:           @data = RubyProf.stop
180:           @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
181:         end

Protected Instance methods

output_filename(printer_class)

[Source]

     # File vendor/rails/activesupport/lib/active_support/testing/performance.rb, line 206
206:           def output_filename(printer_class)
207:             suffix =
208:               case printer_class.name.demodulize
209:                 when 'FlatPrinter'; 'flat.txt'
210:                 when 'GraphPrinter'; 'graph.txt'
211:                 when 'GraphHtmlPrinter'; 'graph.html'
212:                 when 'CallTreePrinter'; 'tree.txt'
213:                 else printer_class.name.sub(/Printer$/, '').underscore
214:               end
215:
216:             "#{super()}_#{suffix}"
217:           end


Module: ActiveSupport::Testing::SetupAndTeardown

Module | ActiveSupport::Testing::SetupAndTeardown
In: | vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb

Methods

included

Included Modules

ActiveSupport::Callbacks ForMiniTest ForClassicTestUnit

Classes and Modules

Module ActiveSupport::Testing::SetupAndTeardown::ForClassicTestUnit
Module ActiveSupport::Testing::SetupAndTeardown::ForMiniTest

Public Class methods

included(base)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb, line 6
 6:       def self.included(base)
 7:         base.class_eval do
 8:           include ActiveSupport::Callbacks
 9:           define_callbacks :setup, :teardown
10:
11:           if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
12:             include ForMiniTest
13:           else
14:             include ForClassicTestUnit
15:           end
16:         end
17:       end


Module: ActiveSupport::Testing::SetupAndTeardown::ForClassicTestUnit

Module | ActiveSupport::Testing::SetupAndTeardown::ForClassicTestUnit
In: | vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb

Methods

run

Constants

PASSTHROUGH_EXCEPTIONS = Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS rescue [NoMemoryError, SignalException, Interrupt, SystemExit] For compatibility with Ruby < 1.8.6

Public Instance methods

run(result) {|Test::Unit::TestCase::STARTED, name| ...}

This redefinition is unfortunate but test/unit shows us no alternative. Doubly unfortunate: hax to support Mocha‘s hax.

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb, line 44
44:         def run(result)
45:           return if @method_name.to_s == "default_test"
46:
47:           if using_mocha = respond_to?(:mocha_verify)
48:             assertion_counter_klass = if defined?(Mocha::TestCaseAdapter::AssertionCounter)
49:                                         Mocha::TestCaseAdapter::AssertionCounter
50:                                       else
51:                                         Mocha::Integration::TestUnit::AssertionCounter
52:                                       end
53:             assertion_counter = assertion_counter_klass.new(result)
54:           end
55:
56:           yield(Test::Unit::TestCase::STARTED, name)
57:           @_result = result
58:           begin
59:             begin
60:               run_callbacks :setup
61:               setup
62:               __send__(@method_name)
63:               mocha_verify(assertion_counter) if using_mocha
64:             rescue Mocha::ExpectationError => e
65:               add_failure(e.message, e.backtrace)
66:             rescue Test::Unit::AssertionFailedError => e
67:               add_failure(e.message, e.backtrace)
68:             rescue Exception => e
69:               raise if PASSTHROUGH_EXCEPTIONS.include?(e.class)
70:               add_error(e)
71:             ensure
72:               begin
73:                 teardown
74:                 run_callbacks :teardown, :enumerator => :reverse_each
75:               rescue Test::Unit::AssertionFailedError => e
76:                 add_failure(e.message, e.backtrace)
77:               rescue Exception => e
78:                 raise if PASSTHROUGH_EXCEPTIONS.include?(e.class)
79:                 add_error(e)
80:               end
81:             end
82:           ensure
83:             mocha_teardown if using_mocha
84:           end
85:           result.add_run
86:           yield(Test::Unit::TestCase::FINISHED, name)
87:         end


Module: ActiveSupport::Testing::SetupAndTeardown::ForMiniTest

Module | ActiveSupport::Testing::SetupAndTeardown::ForMiniTest
In: | vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb

Methods

run

Public Instance methods

run(runner)

[Source]

    # File vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb, line 20
20:         def run(runner)
21:           result = '.'
22:           begin
23:             run_callbacks :setup
24:             result = super
25:           rescue Exception => e
26:             result = runner.puke(self.class, self.name, e)
27:           ensure
28:             begin
29:               run_callbacks :teardown, :enumerator => :reverse_each
30:             rescue Exception => e
31:               result = runner.puke(self.class, self.name, e)
32:             end
33:           end
34:           result
35:         end


Class: ActiveSupport::TimeWithZone

Class | ActiveSupport::TimeWithZone
In: | vendor/rails/activesupport/lib/active_support/time_with_zone.rb
Parent: | Object

A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are limited to UTC and the system‘s ENV[‘TZ’] zone.

You shouldn‘t ever need to create a TimeWithZone instance directly via new — instead, Rails provides the methods local, parse, at and now on TimeZone instances, and in_time_zone on Time and DateTime instances, for a more user-friendly syntax. Examples:

  Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.parse('2007-02-01 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00

See TimeZone and ActiveSupport::CoreExtensions::Time::Zones for further documentation for these methods.

TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangable. Examples:

  t = Time.zone.now                     # => Sun, 18 May 2008 13:27:25 EDT -04:00
  t.hour                                # => 13
  t.dst?                                # => true
  t.utc_offset                          # => -14400
  t.zone                                # => "EDT"
  t.to_s(:rfc822)                       # => "Sun, 18 May 2008 13:27:25 -0400"
  t + 1.day                             # => Mon, 19 May 2008 13:27:25 EDT -04:00
  t.beginning_of_year                   # => Tue, 01 Jan 2008 00:00:00 EST -05:00
  t > Time.utc(1999)                    # => true
  t.is_a?(Time)                         # => true
  t.is_a?(ActiveSupport::TimeWithZone)  # => true

Methods

+ - <=> acts_like_time? advance ago between? comparable_time dst? eql? formatted_offset freeze future? getgm getlocal getutc gmt? gmt_offset gmtime gmtoff hash httpdate in_time_zone inspect is_a? isdst iso8601 kind_of? localtime marshal_dump marshal_load method_missing new past? period respond_to? rfc2822 rfc822 since strftime time to_a to_datetime to_f to_formatted_s to_i to_json to_s to_time to_yaml today? tv_sec usec utc utc? utc_offset xmlschema zone

Included Modules

Comparable

Attributes

time_zone [R]

Public Class methods

new(utc_time, time_zone, local_time = nil, period = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 37
37:     def initialize(utc_time, time_zone, local_time = nil, period = nil)
38:       @utc, @time_zone, @time = utc_time, time_zone, local_time
39:       @period = @utc ? period : get_period_and_ensure_valid_local_time
40:     end

Public Instance methods

+(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 192
192:     def +(other)
193:       # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
194:       # otherwise move forward from #utc, for accuracy when moving across DST boundaries
195:       if duration_of_variable_length?(other)
196:         method_missing(:+, other)
197:       else
198:         result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
199:         result.in_time_zone(time_zone)
200:       end
201:     end
-(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 203
203:     def -(other)
204:       # If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
205:       # otherwise move backwards #utc, for accuracy when moving across DST boundaries
206:       if other.acts_like?(:time)
207:         utc.to_f - other.to_f
208:       elsif duration_of_variable_length?(other)
209:         method_missing(:-, other)
210:       else
211:         result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
212:         result.in_time_zone(time_zone)
213:       end
214:     end
<=>(other)

Use the time in UTC for comparisons.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 168
168:     def <=>(other)
169:       utc <=> other
170:     end
acts_like_time?()

So that self acts_like?(:time).

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 277
277:     def acts_like_time?
278:       true
279:     end
advance(options)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 230
230:     def advance(options)
231:       # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
232:       # otherwise advance from #utc, for accuracy when moving across DST boundaries
233:       if options.values_at(:years, :weeks, :months, :days).any?
234:         method_missing(:advance, options)
235:       else
236:         utc.advance(options).in_time_zone(time_zone)
237:       end
238:     end
ago(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 226
226:     def ago(other)
227:       since(-other)
228:     end
between?(min, max)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 172
172:     def between?(min, max)
173:       utc.between?(min, max)
174:     end
comparable_time()

Alias for utc

dst?()

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 73
73:     def dst?
74:       period.dst?
75:     end
eql?(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 188
188:     def eql?(other)
189:       utc == other
190:     end
formatted_offset(colon = true, alternate_utc_string = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 89
89:     def formatted_offset(colon = true, alternate_utc_string = nil)
90:       utc? && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
91:     end
freeze()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 287
287:     def freeze
288:       period; utc; time # preload instance variables before freezing
289:       super
290:     end
future?()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 184
184:     def future?
185:       utc.future?
186:     end
getgm()

Alias for utc

getlocal()

Alias for localtime

getutc()

Alias for utc

gmt?()

Alias for utc?

gmt_offset()

Alias for utc_offset

gmtime()

Alias for utc

gmtoff()

Alias for utc_offset

hash()

Alias for to_i

httpdate()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 139
139:     def httpdate
140:       utc.httpdate
141:     end
in_time_zone(new_zone = ::Time.zone)

Returns the simultaneous time in Time.zone, or the specified zone.

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 62
62:     def in_time_zone(new_zone = ::Time.zone)
63:       return self if time_zone == new_zone
64:       utc.in_time_zone(new_zone)
65:     end
inspect()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 98
 98:     def inspect
 99:       "#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
100:     end
is_a?(klass)

Say we‘re a Time to thwart type checking.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 282
282:     def is_a?(klass)
283:       klass == ::Time || super
284:     end
isdst()

Alias for dst?

iso8601(fraction_digits = 0)

Alias for xmlschema

kind_of?(klass)

Alias for is_a?

localtime()

Returns a Time.local() instance of the simultaneous time in your system‘s ENV[‘TZ’] zone

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 68
68:     def localtime
69:       utc.getlocal
70:     end
marshal_dump()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 292
292:     def marshal_dump
293:       [utc, time_zone.name, time]
294:     end
marshal_load(variables)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 296
296:     def marshal_load(variables)
297:       initialize(variables[0].utc, ::Time.__send__(:get_zone, variables[1]), variables[2].utc)
298:     end
method_missing(sym, *args, &block)

Send the missing method to time instance, and wrap result in a new TimeWithZone with the existing time_zone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 308
308:     def method_missing(sym, *args, &block)
309:       result = time.__send__(sym, *args, &block)
310:       result.acts_like?(:time) ? self.class.new(nil, time_zone, result) : result
311:     end
past?()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 176
176:     def past?
177:       utc.past?
178:     end
period()

Returns the underlying TZInfo::TimezonePeriod.

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 57
57:     def period
58:       @period ||= time_zone.period_for_utc(@utc)
59:     end
respond_to?(sym, include_priv = false)

Ensure proxy class responds to all methods that underlying time instance responds to.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 301
301:     def respond_to?(sym, include_priv = false)
302:       # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
303:       return false if sym.to_s == 'acts_like_date?'
304:       super || time.respond_to?(sym, include_priv)
305:     end
rfc2822()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 143
143:     def rfc2822
144:       to_s(:rfc822)
145:     end
rfc822()

Alias for rfc2822

since(other)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 216
216:     def since(other)
217:       # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
218:       # otherwise move forward from #utc, for accuracy when moving across DST boundaries
219:       if duration_of_variable_length?(other)
220:         method_missing(:since, other)
221:       else
222:         utc.since(other).in_time_zone(time_zone)
223:       end
224:     end
strftime(format)

Replaces %Z and %z directives with zone and formatted_offset, respectively, before passing to Time#strftime, so that zone information is correct

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 162
162:     def strftime(format)
163:       format = format.gsub('%Z', zone).gsub('%z', formatted_offset(false))
164:       time.strftime(format)
165:     end
time()

Returns a Time or DateTime instance that represents the time in time_zone.

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 43
43:     def time
44:       @time ||= period.to_local(@utc)
45:     end
to_a()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 253
253:     def to_a
254:       [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
255:     end
to_datetime()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 272
272:     def to_datetime
273:       utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
274:     end
to_f()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 257
257:     def to_f
258:       utc.to_f
259:     end
to_formatted_s(format = :default)

Alias for to_s

to_i()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 261
261:     def to_i
262:       utc.to_i
263:     end
to_json(options = nil)

Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to true, the ISO 8601 format is used.

Examples

  # With ActiveSupport.use_standard_json_time_format = true
  Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
  # => "2005-02-01T15:15:10Z"

  # With ActiveSupport.use_standard_json_time_format = false
  Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
  # => "2005/02/01 15:15:10 +0000"

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 123
123:     def to_json(options = nil)
124:       if ActiveSupport.use_standard_json_time_format
125:         xmlschema.inspect
126:       else
127:         %("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
128:       end
129:     end
to_s(format = :default)

:db format outputs time in UTC; all others output time in local. Uses TimeWithZone‘s strftime, so %Z and %z work correctly.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 150
150:     def to_s(format = :default)
151:       return utc.to_s(format) if format == :db
152:       if formatter = ::Time::DATE_FORMATS[format]
153:         formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
154:       else
155:         "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
156:       end
157:     end
to_time()

A TimeWithZone acts like a Time, so just return self.

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 268
268:     def to_time
269:       self
270:     end
to_yaml(options = {})

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 131
131:     def to_yaml(options = {})
132:       if options.kind_of?(YAML::Emitter)
133:         utc.to_yaml(options)
134:       else
135:         time.to_yaml(options).gsub('Z', formatted_offset(true, 'Z'))
136:       end
137:     end
today?()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 180
180:     def today?
181:       time.today?
182:     end
tv_sec()

Alias for to_i

usec()

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 249
249:     def usec
250:       time.respond_to?(:usec) ? time.usec : 0
251:     end
utc()

Returns a Time or DateTime instance that represents the time in UTC.

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 48
48:     def utc
49:       @utc ||= period.to_utc(@time)
50:     end
utc?()

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 78
78:     def utc?
79:       time_zone.name == 'UTC'
80:     end
utc_offset()

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 83
83:     def utc_offset
84:       period.utc_total_offset
85:     end
xmlschema(fraction_digits = 0)

[Source]

     # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 102
102:     def xmlschema(fraction_digits = 0)
103:       fraction = if fraction_digits > 0
104:         ".%i" % time.usec.to_s[0, fraction_digits]
105:       end
106:
107:       "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
108:     end
zone()

Time uses zone to display the time zone abbreviation, so we‘re duck-typing it.

[Source]

    # File vendor/rails/activesupport/lib/active_support/time_with_zone.rb, line 94
94:     def zone
95:       period.zone_identifier.to_s
96:     end


Class: ActiveSupport::TimeZone

Class | ActiveSupport::TimeZone
In: | vendor/rails/activesupport/lib/active_support/values/time_zone.rb
Parent: | Object

Methods

<=> =~ [] all at formatted_offset local local_to_utc new new now parse period_for_local period_for_utc to_s today tzinfo us_zones utc_offset utc_to_local

Included Modules

Comparable

Constants

MAPPING = { "International Date Line West" => "Pacific/Midway", "Midway Island" => "Pacific/Midway", "Samoa" => "Pacific/Pago_Pago", "Hawaii" => "Pacific/Honolulu", "Alaska" => "America/Juneau", "Pacific Time (US & Canada)" => "America/Los_Angeles", "Tijuana" => "America/Tijuana", "Mountain Time (US & Canada)" => "America/Denver", "Arizona" => "America/Phoenix", "Chihuahua" => "America/Chihuahua", "Mazatlan" => "America/Mazatlan", "Central Time (US & Canada)" => "America/Chicago", "Saskatchewan" => "America/Regina", "Guadalajara" => "America/Mexico_City", "Mexico City" => "America/Mexico_City", "Monterrey" => "America/Monterrey", "Central America" => "America/Guatemala", "Eastern Time (US & Canada)" => "America/New_York", "Indiana (East)" => "America/Indiana/Indianapolis", "Bogota" => "America/Bogota", "Lima" => "America/Lima", "Quito" => "America/Lima", "Atlantic Time (Canada)" => "America/Halifax", "Caracas" => "America/Caracas", "La Paz" => "America/La_Paz", "Santiago" => "America/Santiago", "Newfoundland" => "America/St_Johns", "Brasilia" => "America/Sao_Paulo", "Buenos Aires" => "America/Argentina/Buenos_Aires", "Georgetown" => "America/Argentina/San_Juan", "Greenland" => "America/Godthab", "Mid-Atlantic" => "Atlantic/South_Georgia", "Azores" => "Atlantic/Azores", "Cape Verde Is." => "Atlantic/Cape_Verde", "Dublin" => "Europe/Dublin", "Edinburgh" => "Europe/Dublin", "Lisbon" => "Europe/Lisbon", "London" => "Europe/London", "Casablanca" => "Africa/Casablanca", "Monrovia" => "Africa/Monrovia", "UTC" => "Etc/UTC", "Belgrade" => "Europe/Belgrade", "Bratislava" => "Europe/Bratislava", "Budapest" => "Europe/Budapest", "Ljubljana" => "Europe/Ljubljana", "Prague" => "Europe/Prague", "Sarajevo" => "Europe/Sarajevo", "Skopje" => "Europe/Skopje", "Warsaw" => "Europe/Warsaw", "Zagreb" => "Europe/Zagreb", "Brussels" => "Europe/Brussels", "Copenhagen" => "Europe/Copenhagen", "Madrid" => "Europe/Madrid", "Paris" => "Europe/Paris", "Amsterdam" => "Europe/Amsterdam", "Berlin" => "Europe/Berlin", "Bern" => "Europe/Berlin", "Rome" => "Europe/Rome", "Stockholm" => "Europe/Stockholm", "Vienna" => "Europe/Vienna", "West Central Africa" => "Africa/Algiers", "Bucharest" => "Europe/Bucharest", "Cairo" => "Africa/Cairo", "Helsinki" => "Europe/Helsinki", "Kyev" => "Europe/Kiev", "Riga" => "Europe/Riga", "Sofia" => "Europe/Sofia", "Tallinn" => "Europe/Tallinn", "Vilnius" => "Europe/Vilnius", "Athens" => "Europe/Athens", "Istanbul" => "Europe/Istanbul", "Minsk" => "Europe/Minsk", "Jerusalem" => "Asia/Jerusalem", "Harare" => "Africa/Harare", "Pretoria" => "Africa/Johannesburg", "Moscow" => "Europe/Moscow", "St. Petersburg" => "Europe/Moscow", "Volgograd" => "Europe/Moscow", "Kuwait" => "Asia/Kuwait", "Riyadh" => "Asia/Riyadh", "Nairobi" => "Africa/Nairobi", "Baghdad" => "Asia/Baghdad", "Tehran" => "Asia/Tehran", "Abu Dhabi" => "Asia/Muscat", "Muscat" => "Asia/Muscat", "Baku" => "Asia/Baku", "Tbilisi" => "Asia/Tbilisi", "Yerevan" => "Asia/Yerevan", "Kabul" => "Asia/Kabul", "Ekaterinburg" => "Asia/Yekaterinburg", "Islamabad" => "Asia/Karachi", "Karachi" => "Asia/Karachi", "Tashkent" => "Asia/Tashkent", "Chennai" => "Asia/Kolkata", "Kolkata" => "Asia/Kolkata", "Mumbai" => "Asia/Kolkata", "New Delhi" => "Asia/Kolkata", "Kathmandu" => "Asia/Katmandu", "Astana" => "Asia/Dhaka", "Dhaka" => "Asia/Dhaka", "Sri Jayawardenepura" => "Asia/Colombo", "Almaty" => "Asia/Almaty", "Novosibirsk" => "Asia/Novosibirsk", "Rangoon" => "Asia/Rangoon", "Bangkok" => "Asia/Bangkok", "Hanoi" => "Asia/Bangkok", "Jakarta" => "Asia/Jakarta", "Krasnoyarsk" => "Asia/Krasnoyarsk", "Beijing" => "Asia/Shanghai", "Chongqing" => "Asia/Chongqing", "Hong Kong" => "Asia/Hong_Kong", "Urumqi" => "Asia/Urumqi", "Kuala Lumpur" => "Asia/Kuala_Lumpur", "Singapore" => "Asia/Singapore", "Taipei" => "Asia/Taipei", "Perth" => "Australia/Perth", "Irkutsk" => "Asia/Irkutsk", "Ulaan Bataar" => "Asia/Ulaanbaatar", "Seoul" => "Asia/Seoul", "Osaka" => "Asia/Tokyo", "Sapporo" => "Asia/Tokyo", "Tokyo" => "Asia/Tokyo", "Yakutsk" => "Asia/Yakutsk", "Darwin" => "Australia/Darwin", "Adelaide" => "Australia/Adelaide", "Canberra" => "Australia/Melbourne", "Melbourne" => "Australia/Melbourne", "Sydney" => "Australia/Sydney", "Brisbane" => "Australia/Brisbane", "Hobart" => "Australia/Hobart", "Vladivostok" => "Asia/Vladivostok", "Guam" => "Pacific/Guam", "Port Moresby" => "Pacific/Port_Moresby", "Magadan" => "Asia/Magadan", "Solomon Is." => "Asia/Magadan", "New Caledonia" => "Pacific/Noumea", "Fiji" => "Pacific/Fiji", "Kamchatka" => "Asia/Kamchatka", "Marshall Is." => "Pacific/Majuro", "Auckland" => "Pacific/Auckland", "Wellington" => "Pacific/Auckland", "Nuku'alofa" => "Pacific/Tongatapu" Keys are Rails TimeZone names, values are TZInfo identifiers
ZONES = []
ZONES_MAP = {}
US_ZONES = ZONES.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }

External Aliases

new -> create

Attributes

name [R]

Public Class methods

[](arg)

Locate a specific time zone object. If the argument is a string, it is interpreted to mean the name of the timezone to locate. If it is a numeric value it is either the hour offset, or the second offset, of the timezone to find. (The first one with that offset will be returned.) Returns nil if no such time zone is known to the system.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 385
385:       def [](arg)
386:         case arg
387:           when String
388:             ZONES_MAP[arg]
389:           when Numeric, ActiveSupport::Duration
390:             arg *= 3600 if arg.abs <= 13
391:             all.find { |z| z.utc_offset == arg.to_i }
392:           else
393:             raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
394:         end
395:       end
all()

Return an array of all TimeZone objects. There are multiple TimeZone objects per time zone, in many cases, to make it easier for users to find their own time zone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 376
376:       def all
377:         ZONES
378:       end
new(name, utc_offset, tzinfo = nil)

Create a new TimeZone object with the given name and offset. The offset is the number of seconds that this time zone is offset from UTC (GMT). Seconds were chosen as the offset unit because that is the unit that Ruby uses to represent time zone offsets (see Time#utc_offset).

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 180
180:     def initialize(name, utc_offset, tzinfo = nil)
181:       @name = name
182:       @utc_offset = utc_offset
183:       @tzinfo = tzinfo
184:     end
new(name)

Return a TimeZone instance with the given name, or nil if no such TimeZone instance exists. (This exists to support the use of this class with the composed_of macro.)

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 369
369:       def new(name)
370:         self[name]
371:       end
us_zones()

A convenience method for returning a collection of TimeZone objects for time zones in the USA.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 399
399:       def us_zones
400:         US_ZONES
401:       end

Public Instance methods

<=>(zone)

Compare this time zone to the parameter. The two are comapred first on their offsets, and then by name.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 198
198:     def <=>(zone)
199:       result = (utc_offset <=> zone.utc_offset)
200:       result = (name <=> zone.name) if result == 0
201:       result
202:     end
=~(re)

Compare name and TZInfo identifier to a supplied regexp, returning true if a match is found.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 206
206:     def =~(re)
207:       return true if name =~ re || MAPPING[name] =~ re
208:     end
at(secs)

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from number of seconds since the Unix epoch. Example:

  Time.zone = "Hawaii"        # => "Hawaii"
  Time.utc(2000).to_f         # => 946684800.0
  Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 229
229:     def at(secs)
230:       utc = Time.at(secs).utc rescue DateTime.civil(1970).since(secs)
231:       utc.in_time_zone(self)
232:     end
formatted_offset(colon=true, alternate_utc_string = nil)

Returns the offset of this time zone as a formatted string, of the format "+HH:MM".

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 192
192:     def formatted_offset(colon=true, alternate_utc_string = nil)
193:       utc_offset == 0 && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
194:     end
local(*args)

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from given values. Example:

  Time.zone = "Hawaii"                      # => "Hawaii"
  Time.zone.local(2007, 2, 1, 15, 30, 45)   # => Thu, 01 Feb 2007 15:30:45 HST -10:00

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 219
219:     def local(*args)
220:       time = Time.utc_time(*args)
221:       ActiveSupport::TimeWithZone.new(nil, self, time)
222:     end
local_to_utc(time, dst=true)

Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 275
275:     def local_to_utc(time, dst=true)
276:       tzinfo.local_to_utc(time, dst)
277:     end
now()

Returns an ActiveSupport::TimeWithZone instance representing the current time in the time zone represented by self. Example:

  Time.zone = 'Hawaii'  # => "Hawaii"
  Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 259
259:     def now
260:       Time.now.utc.in_time_zone(self)
261:     end
parse(str, now=now)

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from parsed string. Example:

  Time.zone = "Hawaii"                      # => "Hawaii"
  Time.zone.parse('1999-12-31 14:00:00')    # => Fri, 31 Dec 1999 14:00:00 HST -10:00

If upper components are missing from the string, they are supplied from TimeZone#now:

  Time.zone.now                 # => Fri, 31 Dec 1999 14:00:00 HST -10:00
  Time.zone.parse('22:30:00')   # => Fri, 31 Dec 1999 22:30:00 HST -10:00

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 243
243:     def parse(str, now=now)
244:       date_parts = Date._parse(str)
245:       return if date_parts.blank?
246:       time = Time.parse(str, now) rescue DateTime.parse(str)
247:       if date_parts[:offset].nil?
248:         ActiveSupport::TimeWithZone.new(nil, self, time)
249:       else
250:         time.in_time_zone(self)
251:       end
252:     end
period_for_local(time, dst=true)

Available so that TimeZone instances respond like TZInfo::Timezone instances

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 285
285:     def period_for_local(time, dst=true)
286:       tzinfo.period_for_local(time, dst)
287:     end
period_for_utc(time)

Available so that TimeZone instances respond like TZInfo::Timezone instances

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 280
280:     def period_for_utc(time)
281:       tzinfo.period_for_utc(time)
282:     end
to_s()

Returns a textual representation of this time zone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 211
211:     def to_s
212:       "(GMT#{formatted_offset}) #{name}"
213:     end
today()

Return the current date in this time zone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 264
264:     def today
265:       tzinfo.now.to_date
266:     end
tzinfo()

TODO: Preload instead of lazy load for thread safety

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 290
290:     def tzinfo
291:       require 'tzinfo' unless defined?(TZInfo)
292:       @tzinfo ||= TZInfo::Timezone.get(MAPPING[name])
293:     end
utc_offset()

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 186
186:     def utc_offset
187:       @utc_offset ||= tzinfo.current_period.utc_offset
188:     end
utc_to_local(time)

Adjust the given time to the simultaneous time in the time zone represented by self. Returns a Time.utc() instance — if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.

[Source]

     # File vendor/rails/activesupport/lib/active_support/values/time_zone.rb, line 270
270:     def utc_to_local(time)
271:       tzinfo.utc_to_local(time)
272:     end


Module: ActiveSupport::XmlMini

Module | ActiveSupport::XmlMini
In: | vendor/rails/activesupport/lib/active_support/xml_mini.rb

XmlMini

To use the much faster libxml parser:

  gem 'libxml-ruby', '=0.9.7'
  XmlMini.backend = 'LibXML'

Methods

backend= with_backend

Attributes

backend [R]

Public Instance methods

backend=(name)

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini.rb, line 13
13:     def backend=(name)
14:       if name.is_a?(Module)
15:         @backend = name
16:       else
17:         require "active_support/xml_mini/#{name.to_s.downcase}.rb"
18:         @backend = ActiveSupport.const_get("XmlMini_#{name}")
19:       end
20:     end
with_backend(name) {|| ...}

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini.rb, line 22
22:     def with_backend(name)
23:       old_backend, self.backend = backend, name
24:       yield
25:     ensure
26:       self.backend = old_backend
27:     end


Module: ActiveSupport::XmlMini_Nokogiri::Conversions

Module | ActiveSupport::XmlMini_Nokogiri::Conversions
In: | vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb

Classes and Modules

Module ActiveSupport::XmlMini_Nokogiri::Conversions::Document
Module ActiveSupport::XmlMini_Nokogiri::Conversions::Node


Module: ActiveSupport::XmlMini_Nokogiri::Conversions::Document

Module | ActiveSupport::XmlMini_Nokogiri::Conversions::Document
In: | vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb

Methods

to_hash

Public Instance methods

to_hash()

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb, line 23
23:         def to_hash
24:           root.to_hash
25:         end


Module: ActiveSupport::XmlMini_Nokogiri::Conversions::Node

Module | ActiveSupport::XmlMini_Nokogiri::Conversions::Node
In: | vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb

Methods

attributes_as_hash to_hash

Constants

CONTENT_ROOT = '__content__'

Public Instance methods

attributes_as_hash()

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb, line 66
66:         def attributes_as_hash
67:           Hash[*(attribute_nodes.map { |node|
68:             [node.node_name, node.value]
69:           }.flatten)]
70:         end
to_hash(hash = {})

Convert XML document to hash

hash: Hash to merge the converted element into.

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb, line 35
35:         def to_hash(hash = {})
36:           hash[name] ||= attributes_as_hash
37:
38:           walker = lambda { |memo, parent, child, callback|
39:             next if child.blank? && 'file' != parent['type']
40:
41:             if child.text?
42:               (memo[CONTENT_ROOT] ||= '') << child.content
43:               next
44:             end
45:
46:             name = child.name
47:
48:             child_hash = child.attributes_as_hash
49:             if memo[name]
50:               memo[name] = [memo[name]].flatten
51:               memo[name] << child_hash
52:             else
53:               memo[name] = child_hash
54:             end
55:
56:             # Recusively walk children
57:             child.children.each { |c|
58:               callback.call(child_hash, child, c, callback)
59:             }
60:           }
61:
62:           children.each { |c| walker.call(hash[name], self, c, walker) }
63:           hash
64:         end


File: backtrace_cleaner.rb

backtrace_cleaner.rb

Path: | vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: base64.rb

base64.rb

Path: | vendor/rails/activesupport/lib/active_support/base64.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

base64


File: basic_object.rb

basic_object.rb

Path: | vendor/rails/activesupport/lib/active_support/basic_object.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

A base class with no predefined methods that tries to behave like Builder‘s BlankSlate in Ruby 1.9. In Ruby pre-1.9, this is actually the Builder::BlankSlate class.

Ruby 1.9 introduces BasicObject which differs slightly from Builder‘s BlankSlate that has been used so far. ActiveSupport::BasicObject provides a barebones base class that emulates Builder::BlankSlate while still relying on Ruby 1.9‘s BasicObject in Ruby 1.9.

Required files

blankslate


File: buffered_logger.rb

buffered_logger.rb

Path: | vendor/rails/activesupport/lib/active_support/buffered_logger.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: cache.rb

cache.rb

Path: | vendor/rails/activesupport/lib/active_support/cache.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

benchmark


File: compressed_mem_cache_store.rb

compressed_mem_cache_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: drb_store.rb

drb_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/drb_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

drb


File: file_store.rb

file_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/file_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: mem_cache_store.rb

mem_cache_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/mem_cache_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

memcache


File: memory_store.rb

memory_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/memory_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: local_cache.rb

local_cache.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: synchronized_memory_store.rb

synchronized_memory_store.rb

Path: | vendor/rails/activesupport/lib/active_support/cache/synchronized_memory_store.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: callbacks.rb

callbacks.rb

Path: | vendor/rails/activesupport/lib/active_support/callbacks.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: core_ext.rb

core_ext.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: array.rb

array.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/array/access active_support/core_ext/array/conversions active_support/core_ext/array/extract_options active_support/core_ext/array/grouping active_support/core_ext/array/random_access active_support/core_ext/array/wrapper


File: access.rb

access.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/access.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder


File: extract_options.rb

extract_options.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/extract_options.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: grouping.rb

grouping.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/grouping.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

enumerator


File: random_access.rb

random_access.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/random_access.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: wrapper.rb

wrapper.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/array/wrapper.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: base64.rb

base64.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/base64.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/base64 active_support/core_ext/base64/encoding


File: encoding.rb

encoding.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/base64/encoding.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: benchmark.rb

benchmark.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

benchmark


File: bigdecimal.rb

bigdecimal.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/bigdecimal.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

bigdecimal active_support/core_ext/bigdecimal/conversions


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

yaml


File: blank.rb

blank.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/blank.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: cgi.rb

cgi.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/cgi.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/cgi/escape_skipping_slashes


File: escape_skipping_slashes.rb

escape_skipping_slashes.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: class.rb

class.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/class.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/class/attribute_accessors active_support/core_ext/class/inheritable_attributes active_support/core_ext/class/removal active_support/core_ext/class/delegating_attributes


File: attribute_accessors.rb

attribute_accessors.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Extends the class object with class and instance accessors for class attributes, just like the native attr* accessors for instance attributes.

 class Person
   cattr_accessor :hair_colors
 end

 Person.hair_colors = [:brown, :black, :blonde, :red]


File: delegating_attributes.rb

delegating_attributes.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

These class attributes behave something like the class inheritable accessors. But instead of copying the hash over at the time the subclass is first defined, the accessors simply delegate to their superclass unless they have been given a specific value. This stops the strange situation where values set after class definition don‘t get applied to subclasses.


File: inheritable_attributes.rb

inheritable_attributes.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Retain for backward compatibility. Methods are now included in Class.


File: removal.rb

removal.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/class/removal.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: date.rb

date.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date active_support/core_ext/date/behavior active_support/core_ext/date/calculations active_support/core_ext/date/conversions


File: behavior.rb

behavior.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date/behavior.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date


File: calculations.rb

calculations.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date/calculations.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: date_time.rb

date_time.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date_time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date active_support/core_ext/time/behavior active_support/core_ext/time/zones active_support/core_ext/date_time/calculations active_support/core_ext/date_time/conversions


File: calculations.rb

calculations.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rational


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/date_time/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: duplicable.rb

duplicable.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/duplicable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: enumerable.rb

enumerable.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/ordered_hash


File: exception.rb

exception.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/exception.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: file.rb

file.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/file.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/file/atomic


File: atomic.rb

atomic.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/file/atomic.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tempfile


File: float.rb

float.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/float.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/float/rounding active_support/core_ext/float/time


File: rounding.rb

rounding.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/float/rounding.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: time.rb

time.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/float/time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: hash.rb

hash.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date builder


File: deep_merge.rb

deep_merge.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: diff.rb

diff.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/diff.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: except.rb

except.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/except.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

set


File: indifferent_access.rb

indifferent_access.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

This class has dubious semantics and we only have it so that people can write params[:key] instead of params[‘key’] and they get the same value for both keys.


File: keys.rb

keys.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: reverse_merge.rb

reverse_merge.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: slice.rb

slice.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/hash/slice.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: integer.rb

integer.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/integer.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/integer/even_odd active_support/core_ext/integer/inflections active_support/core_ext/integer/time


File: even_odd.rb

even_odd.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: inflections.rb

inflections.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/inflector


File: time.rb

time.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/integer/time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: kernel.rb

kernel.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/kernel/daemonizing active_support/core_ext/kernel/reporting active_support/core_ext/kernel/agnostics active_support/core_ext/kernel/requires active_support/core_ext/kernel/debugger


File: agnostics.rb

agnostics.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/agnostics.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: daemonizing.rb

daemonizing.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: debugger.rb

debugger.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: reporting.rb

reporting.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: requires.rb

requires.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/requires.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rubygems


File: load_error.rb

load_error.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/load_error.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: logger.rb

logger.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/logger.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Adds the ‘around_level’ method to Logger.

Required files

logger


File: module.rb

module.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/module/inclusion active_support/core_ext/module/attribute_accessors active_support/core_ext/module/attr_internal active_support/core_ext/module/attr_accessor_with_default active_support/core_ext/module/delegation active_support/core_ext/module/introspection active_support/core_ext/module/loading active_support/core_ext/module/aliasing active_support/core_ext/module/model_naming active_support/core_ext/module/synchronization


File: aliasing.rb

aliasing.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/aliasing.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: attr_accessor_with_default.rb

attr_accessor_with_default.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: attr_internal.rb

attr_internal.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/attr_internal.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: attribute_accessors.rb

attribute_accessors.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Extends the module object with module and instance accessors for class attributes, just like the native attr* accessors for instance attributes.

 module AppConfiguration
   mattr_accessor :google_api_key
   self.google_api_key = "123456789"

   mattr_accessor :paypal_url
   self.paypal_url = "www.sandbox.paypal.com"
 end

 AppConfiguration.google_api_key = "overriding the api key!"


File: delegation.rb

delegation.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: inclusion.rb

inclusion.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/inclusion.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: introspection.rb

introspection.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: loading.rb

loading.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/loading.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: model_naming.rb

model_naming.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/model_naming.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: synchronization.rb

synchronization.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/module/synchronization.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: name_error.rb

name_error.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/name_error.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Add a missing_name method to NameError instances.


File: numeric.rb

numeric.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/numeric.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/numeric/time active_support/core_ext/numeric/bytes active_support/core_ext/numeric/conversions


File: bytes.rb

bytes.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: time.rb

time.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: object.rb

object.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/object/conversions active_support/core_ext/object/extending active_support/core_ext/object/instance_variables active_support/core_ext/object/metaclass active_support/core_ext/object/misc


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

cgi


File: extending.rb

extending.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object/extending.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: instance_variables.rb

instance_variables.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object/instance_variables.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: metaclass.rb

metaclass.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object/metaclass.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: misc.rb

misc.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: pathname.rb

pathname.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/pathname.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

pathname active_support/core_ext/pathname/clean_within


File: clean_within.rb

clean_within.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/pathname/clean_within.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: proc.rb

proc.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/proc.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: process.rb

process.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/process.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/process/daemon


File: daemon.rb

daemon.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/process/daemon.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: range.rb

range.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/range.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/core_ext/range/conversions active_support/core_ext/range/overlaps active_support/core_ext/range/include_range active_support/core_ext/range/blockless_step


File: blockless_step.rb

blockless_step.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/range/blockless_step.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: include_range.rb

include_range.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/range/include_range.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: overlaps.rb

overlaps.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/range/overlaps.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: rexml.rb

rexml.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Fixes the rexml vulnerability disclosed at: www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/ This fix is identical to rexml-expansion-fix version 1.0.1

Required files

rexml/rexml rexml/document rexml/entity


File: string.rb

string.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8

Required files

active_support/core_ext/string/inflections active_support/core_ext/string/conversions active_support/core_ext/string/access active_support/core_ext/string/starts_ends_with active_support/core_ext/string/iterators active_support/core_ext/string/multibyte active_support/core_ext/string/xchar active_support/core_ext/string/filters active_support/core_ext/string/behavior


File: access.rb

access.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: behavior.rb

behavior.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/behavior.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date


File: filters.rb

filters.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/filters.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: inflections.rb

inflections.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/inflector


File: iterators.rb

iterators.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/iterators.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

strscan


File: multibyte.rb

multibyte.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/multibyte.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8


File: starts_ends_with.rb

starts_ends_with.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: xchar.rb

xchar.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/string/xchar.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

fast_xs


File: symbol.rb

symbol.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/symbol.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: time.rb

time.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date time active_support/core_ext/time/behavior active_support/core_ext/time/calculations active_support/core_ext/time/conversions active_support/core_ext/time/zones


File: behavior.rb

behavior.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/time/behavior.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: calculations.rb

calculations.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/duration


File: conversions.rb

conversions.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: zones.rb

zones.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/time/zones.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: try.rb

try.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/try.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: uri.rb

uri.rb

Path: | vendor/rails/activesupport/lib/active_support/core_ext/uri.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

uri

Methods

unescape

Public Instance methods

unescape(str, escaped = @regexp[:ESCAPED])

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/uri.rb, line 10
10:       def unescape(str, escaped = @regexp[:ESCAPED])
11:         enc = (str.encoding == Encoding::US_ASCII) ? Encoding::UTF_8 : str.encoding
12:         str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
13:       end


File: dependencies.rb

dependencies.rb

Path: | vendor/rails/activesupport/lib/active_support/dependencies.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: deprecation.rb

deprecation.rb

Path: | vendor/rails/activesupport/lib/active_support/deprecation.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

yaml


File: duration.rb

duration.rb

Path: | vendor/rails/activesupport/lib/active_support/duration.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/basic_object


File: gzip.rb

gzip.rb

Path: | vendor/rails/activesupport/lib/active_support/gzip.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

zlib stringio


File: inflections.rb

inflections.rb

Path: | vendor/rails/activesupport/lib/active_support/inflections.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: inflector.rb

inflector.rb

Path: | vendor/rails/activesupport/lib/active_support/inflector.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8

Required files

singleton iconv active_support/inflections active_support/core_ext/string/inflections


File: json.rb

json.rb

Path: | vendor/rails/activesupport/lib/active_support/json.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/json/encoding active_support/json/decoding


File: decoding.rb

decoding.rb

Path: | vendor/rails/activesupport/lib/active_support/json/decoding.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

yaml strscan


File: date.rb

date.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/date.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: date_time.rb

date_time.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: enumerable.rb

enumerable.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: false_class.rb

false_class.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/false_class.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: hash.rb

hash.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/hash.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: nil_class.rb

nil_class.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/nil_class.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: numeric.rb

numeric.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/numeric.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: object.rb

object.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/object.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: regexp.rb

regexp.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/regexp.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: string.rb

string.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/string.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: symbol.rb

symbol.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/symbol.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: time.rb

time.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/time.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: true_class.rb

true_class.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoders/true_class.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: encoding.rb

encoding.rb

Path: | vendor/rails/activesupport/lib/active_support/json/encoding.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/json/variable active_support/json/encoders/date active_support/json/encoders/date_time active_support/json/encoders/enumerable active_support/json/encoders/false_class active_support/json/encoders/hash active_support/json/encoders/nil_class active_support/json/encoders/numeric active_support/json/encoders/object active_support/json/encoders/regexp active_support/json/encoders/string active_support/json/encoders/symbol active_support/json/encoders/time active_support/json/encoders/true_class


File: variable.rb

variable.rb

Path: | vendor/rails/activesupport/lib/active_support/json/variable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: memoizable.rb

memoizable.rb

Path: | vendor/rails/activesupport/lib/active_support/memoizable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: message_encryptor.rb

message_encryptor.rb

Path: | vendor/rails/activesupport/lib/active_support/message_encryptor.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

openssl


File: message_verifier.rb

message_verifier.rb

Path: | vendor/rails/activesupport/lib/active_support/message_verifier.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

openssl


File: multibyte.rb

multibyte.rb

Path: | vendor/rails/activesupport/lib/active_support/multibyte.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8

Required files

active_support/multibyte/chars active_support/multibyte/exceptions active_support/multibyte/unicode_database


File: chars.rb

chars.rb

Path: | vendor/rails/activesupport/lib/active_support/multibyte/chars.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8


File: exceptions.rb

exceptions.rb

Path: | vendor/rails/activesupport/lib/active_support/multibyte/exceptions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8


File: unicode_database.rb

unicode_database.rb

Path: | vendor/rails/activesupport/lib/active_support/multibyte/unicode_database.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8


File: option_merger.rb

option_merger.rb

Path: | vendor/rails/activesupport/lib/active_support/option_merger.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: ordered_hash.rb

ordered_hash.rb

Path: | vendor/rails/activesupport/lib/active_support/ordered_hash.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

OrderedHash is namespaced to prevent conflicts with other implementations


File: ordered_options.rb

ordered_options.rb

Path: | vendor/rails/activesupport/lib/active_support/ordered_options.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: rescuable.rb

rescuable.rb

Path: | vendor/rails/activesupport/lib/active_support/rescuable.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: secure_random.rb

secure_random.rb

Path: | vendor/rails/activesupport/lib/active_support/secure_random.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

securerandom openssl Win32API


File: string_inquirer.rb

string_inquirer.rb

Path: | vendor/rails/activesupport/lib/active_support/string_inquirer.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: test_case.rb

test_case.rb

Path: | vendor/rails/activesupport/lib/active_support/test_case.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

mocha test/unit/testcase active_support/testing/setup_and_teardown active_support/testing/assertions active_support/testing/deprecation active_support/testing/declarative rails/backtrace_cleaner active_support/testing/default


File: assertions.rb

assertions.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/assertions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: declarative.rb

declarative.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/declarative.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: default.rb

default.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/default.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: deprecation.rb

deprecation.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

test/unit/error


File: performance.rb

performance.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/performance.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rubygems ruby-prof fileutils rails/version


File: setup_and_teardown.rb

setup_and_teardown.rb

Path: | vendor/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

active_support/callbacks


File: time_with_zone.rb

time_with_zone.rb

Path: | vendor/rails/activesupport/lib/active_support/time_with_zone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo


File: time_zone.rb

time_zone.rb

Path: | vendor/rails/activesupport/lib/active_support/values/time_zone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:

  • Limit the set of zones provided by TZInfo to a meaningful subset of 142 zones.
  • Retrieve and display zones with a friendlier name (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
  • Lazily load TZInfo::Timezone instances only when they‘re needed.
  • Create ActiveSupport::TimeWithZone instances via TimeZone‘s local, parse, at and now methods.

If you set config.time_zone in the Rails Initializer, you can access this TimeZone object via Time.zone:

  # environment.rb:
  Rails::Initializer.run do |config|
    config.time_zone = "Eastern Time (US & Canada)"
  end

  Time.zone       # => #<TimeZone:0x514834...>
  Time.zone.name  # => "Eastern Time (US & Canada)"
  Time.zone.now   # => Sun, 18 May 2008 14:30:44 EDT -04:00

The version of TZInfo bundled with Active Support only includes the definitions necessary to support the zones defined by the TimeZone class. If you need to use zones that aren‘t defined by TimeZone, you‘ll need to install the TZInfo gem (if a recent version of the gem is installed locally, this will be used instead of the bundled version.)

Required files

tzinfo


File: vendor.rb

vendor.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Prefer gems to the bundled libs.

Required files

rubygems builder i18n


File: blankslate.rb

blankslate.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: builder.rb

builder.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder/xmlmarkup builder/xmlevents


File: blankslate.rb

blankslate.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

blankslate


File: css.rb

css.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder/blankslate


File: xchar.rb

xchar.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

The XChar library is provided courtesy of Sam Ruby (See intertwingly.net/stories/2005/09/28/xchar.rb)


File: xmlbase.rb

xmlbase.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder/blankslate builder/xchar


File: xmlevents.rb

xmlevents.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder/xmlmarkup


File: xmlmarkup.rb

xmlmarkup.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

builder/xmlbase


File: i18n.rb

i18n.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009
Authors: | Matt Aimonetti (railsontherun.com/), Sven Fuchs (www.artweb-design.de), Joshua Harvey (www.workingwithrails.com/person/759-joshua-harvey), Saimon Moore (saimonmoore.net), Stephan Soller (www.arkanis-development.de/)
Copyright: | Copyright (c) 2008 The Ruby i18n Team
License: | MIT

Required files

i18n/backend/simple i18n/exceptions


File: simple.rb

simple.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

yaml


File: exceptions.rb

exceptions.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: all.rb

all.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: i18n_exceptions_test.rb

i18n_exceptions_test.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rubygems test/unit mocha i18n active_support


File: i18n_test.rb

i18n_test.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rubygems test/unit mocha i18n active_support


File: en.rb

en.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: simple_backend_test.rb

simple_backend_test.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

encoding: utf-8

Required files

rubygems test/unit mocha i18n time yaml


File: memcache.rb

memcache.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

socket thread timeout zlib digest/sha1


File: tzinfo.rb

tzinfo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone tzinfo/data_timezone tzinfo/linked_timezone


File: data_timezone.rb

data_timezone.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/info_timezone


File: data_timezone_info.rb

data_timezone_info.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/time_or_datetime tzinfo/timezone_info tzinfo/timezone_offset_info tzinfo/timezone_period tzinfo/timezone_transition_info


File: Algiers.rb

Algiers.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Cairo.rb

Cairo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Casablanca.rb

Casablanca.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Harare.rb

Harare.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Johannesburg.rb

Johannesburg.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Monrovia.rb

Monrovia.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Nairobi.rb

Nairobi.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Buenos_Aires.rb

Buenos_Aires.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: San_Juan.rb

San_Juan.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Bogota.rb

Bogota.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Caracas.rb

Caracas.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Chicago.rb

Chicago.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Chihuahua.rb

Chihuahua.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Denver.rb

Denver.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Godthab.rb

Godthab.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Guatemala.rb

Guatemala.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Halifax.rb

Halifax.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Indianapolis.rb

Indianapolis.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Juneau.rb

Juneau.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: La_Paz.rb

La_Paz.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Lima.rb

Lima.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Los_Angeles.rb

Los_Angeles.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Mazatlan.rb

Mazatlan.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Mexico_City.rb

Mexico_City.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Monterrey.rb

Monterrey.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: New_York.rb

New_York.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Phoenix.rb

Phoenix.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Regina.rb

Regina.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Santiago.rb

Santiago.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Sao_Paulo.rb

Sao_Paulo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: St_Johns.rb

St_Johns.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tijuana.rb

Tijuana.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Almaty.rb

Almaty.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Baghdad.rb

Baghdad.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Baku.rb

Baku.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Bangkok.rb

Bangkok.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Chongqing.rb

Chongqing.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Colombo.rb

Colombo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Dhaka.rb

Dhaka.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Hong_Kong.rb

Hong_Kong.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Irkutsk.rb

Irkutsk.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Jakarta.rb

Jakarta.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Jerusalem.rb

Jerusalem.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kabul.rb

Kabul.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kamchatka.rb

Kamchatka.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Karachi.rb

Karachi.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Katmandu.rb

Katmandu.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kolkata.rb

Kolkata.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Krasnoyarsk.rb

Krasnoyarsk.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kuala_Lumpur.rb

Kuala_Lumpur.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kuwait.rb

Kuwait.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Magadan.rb

Magadan.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Muscat.rb

Muscat.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Novosibirsk.rb

Novosibirsk.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Rangoon.rb

Rangoon.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Riyadh.rb

Riyadh.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Seoul.rb

Seoul.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Shanghai.rb

Shanghai.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Singapore.rb

Singapore.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Taipei.rb

Taipei.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tashkent.rb

Tashkent.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tbilisi.rb

Tbilisi.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tehran.rb

Tehran.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tokyo.rb

Tokyo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Ulaanbaatar.rb

Ulaanbaatar.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Urumqi.rb

Urumqi.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Vladivostok.rb

Vladivostok.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Yakutsk.rb

Yakutsk.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Yekaterinburg.rb

Yekaterinburg.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Yerevan.rb

Yerevan.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Azores.rb

Azores.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Cape_Verde.rb

Cape_Verde.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: South_Georgia.rb

South_Georgia.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Adelaide.rb

Adelaide.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Brisbane.rb

Brisbane.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Darwin.rb

Darwin.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Hobart.rb

Hobart.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Melbourne.rb

Melbourne.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Perth.rb

Perth.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Sydney.rb

Sydney.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: UTC.rb

UTC.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Amsterdam.rb

Amsterdam.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Athens.rb

Athens.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Belgrade.rb

Belgrade.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Berlin.rb

Berlin.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Bratislava.rb

Bratislava.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Brussels.rb

Brussels.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Bucharest.rb

Bucharest.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Budapest.rb

Budapest.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Copenhagen.rb

Copenhagen.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Dublin.rb

Dublin.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Helsinki.rb

Helsinki.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Istanbul.rb

Istanbul.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Kiev.rb

Kiev.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Lisbon.rb

Lisbon.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Ljubljana.rb

Ljubljana.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: London.rb

London.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Madrid.rb

Madrid.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Minsk.rb

Minsk.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Moscow.rb

Moscow.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Paris.rb

Paris.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Prague.rb

Prague.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Riga.rb

Riga.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Rome.rb

Rome.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Sarajevo.rb

Sarajevo.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Skopje.rb

Skopje.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Sofia.rb

Sofia.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Stockholm.rb

Stockholm.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tallinn.rb

Tallinn.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Vienna.rb

Vienna.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Vilnius.rb

Vilnius.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Warsaw.rb

Warsaw.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Zagreb.rb

Zagreb.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Auckland.rb

Auckland.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Fiji.rb

Fiji.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Guam.rb

Guam.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Honolulu.rb

Honolulu.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Majuro.rb

Majuro.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Midway.rb

Midway.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Noumea.rb

Noumea.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Pago_Pago.rb

Pago_Pago.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Port_Moresby.rb

Port_Moresby.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: Tongatapu.rb

Tongatapu.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_definition


File: info_timezone.rb

info_timezone.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone


File: linked_timezone.rb

linked_timezone.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/info_timezone


File: linked_timezone_info.rb

linked_timezone_info.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/timezone_info


File: offset_rationals.rb

offset_rationals.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

rational tzinfo/ruby_core_support


File: ruby_core_support.rb

ruby_core_support.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date rational


File: time_or_datetime.rb

time_or_datetime.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date time tzinfo/offset_rationals


File: timezone.rb

timezone.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date tzinfo/time_or_datetime tzinfo/timezone_period tzinfo/indexes/timezones


File: timezone_definition.rb

timezone_definition.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/data_timezone_info tzinfo/linked_timezone_info


File: timezone_info.rb

timezone_info.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: timezone_offset_info.rb

timezone_offset_info.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: timezone_period.rb

timezone_period.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

tzinfo/offset_rationals tzinfo/time_or_datetime


File: timezone_transition_info.rb

timezone_transition_info.rb

Path: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

date tzinfo/time_or_datetime


File: version.rb

version.rb

Path: | vendor/rails/activesupport/lib/active_support/version.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: whiny_nil.rb

whiny_nil.rb

Path: | vendor/rails/activesupport/lib/active_support/whiny_nil.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Extensions to nil which allow for more helpful error messages for people who are new to Rails.

Ruby raises NoMethodError if you invoke a method on an object that does not respond to it:

  $ ruby -e nil.destroy
  -e:1: undefined method `destroy' for nil:NilClass (NoMethodError)

With these extensions, if the method belongs to the public interface of the classes in NilClass::WHINERS the error message suggests which could be the actual intended class:

  $ script/runner nil.destroy
  ...
  You might have expected an instance of ActiveRecord::Base.
  ...

NilClass#id exists in Ruby 1.8 (though it is deprecated). Since id is a fundamental method of Active Record models NilClass#id is redefined as well to raise a RuntimeError and warn the user. She probably wanted a model database identifier and the 4 returned by the original method could result in obscure bugs.

The flag config.whiny_nils determines whether this feature is enabled. By default it is on in development and test modes, and it is off in production mode.


File: xml_mini.rb

xml_mini.rb

Path: | vendor/rails/activesupport/lib/active_support/xml_mini.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009


File: libxml.rb

libxml.rb

Path: | vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

libxml


File: nokogiri.rb

nokogiri.rb

Path: | vendor/rails/activesupport/lib/active_support/xml_mini/nokogiri.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

Required files

nokogiri


File: rexml.rb

rexml.rb

Path: | vendor/rails/activesupport/lib/active_support/xml_mini/rexml.rb
Last Update: | Sun Mar 15 23:31:36 -0500 2009

XmlMini ReXML implementation

Required files

rexml/document


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/activesupport/CHANGELOG
Last Update: | Sun Mar 15 23:31:36 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • XmlMini supports LibXML and Nokogiri backends. 2084, 2190 [Bart ten Brinke, Aaron Patterson]
      Example: XmlMini.backend = 'Nokogiri'
  • Vendorize i18n 0.1.3 gem (fixes issues with incompatible character encodings in Ruby 1.9) 2038 [Akira Matsuda]
  • Update bundled memcache-client from 1.5.0.5 to 1.6.4.99. See www.mikeperham.com/2009/02/15/memcache-client-performance/ [Mike Perham]
  • Ruby 1.9.1p0 fix: URI.unescape can decode multibyte chars. 2033 [MOROHASHI Kyosuke]
  • Time#to_s(:rfc822) uses formatted_offset instead of unreliable and non-standard %z directive 1899 [Zachary Zolton]
  • Make TimeWithZone#to_formatted_s an alias to TimeWithZone#to_s 1796 [Levin Alexander]
  • Introduce Array.wrap(foo) to wrap the argument in an array unless it‘s already an array. Wraps nil as an empty array. Use instead of Array(foo) and foo.to_a since they treat String as Enumerable. [Jeremy Kemper]
  • TimeWithZone#xmlschema accepts optional fraction_digits argument [1725 state:resolved] [Nicholas Dainty]
  • Object#tap shim for Ruby < 1.8.7. Similar to Object#returning, tap yields self then returns self. [Jeremy Kemper]
      array.select { ... }.tap(&:inspect).map { ... }
  • TimeWithZone#- gives correct result with wrapped DateTime, and with DateTime argument [Geoff Buesing]
  • Updated i18n gem to version 0.1.1 1635 [Yaroslav Markin]
  • Add :allow_nil option to delegate. 1127 [Sergio Gil]
  • Add Benchmark.ms convenience method to benchmark realtime in milliseconds. [Jeremy Kemper]
  • Updated included memcache-client to the 1.5.0.5 version which includes fixes from fiveruns and 37signals to deal with failover and timeouts 1535 [Joshua Sierles]
  • Multibyte: add multibyte-safe Chars#ord rather than falling back to String#ord. 1483 [Jason Cheow]
  • I18n support for Array#to_sentence. Introduces support.array.words_connector, .two_words_connector, and .last_word_connector translation keys. 1397 [Akira Matsuda]
  • Added ActiveSupport::OrderedHash#each_key and ActiveSupport::OrderedHash#each_value 1410 [Christoffer Sawicki]
  • Added ActiveSupport::MessageVerifier and MessageEncryptor to aid users who need to store signed and/or encrypted messages. [Michael Koziarski]
  • Added ActiveSupport::BacktraceCleaner to cut down on backtrace noise according to filters and silencers [David Heinemeier Hansson]
  • Added Object#try. ( Taken from ozmm.org/posts/try.html ) [Chris Wanstrath]
  • Added Enumerable#none? to check that none of the elements match the block 1408 [Damian Janowski]
  • TimeZone offset tests: use current_period, to ensure TimeZone#utc_offset is up-to-date [Geoff Buesing]
  • Update bundled TZInfo to 0.3.12 [Geoff Buesing]
  • Added lambda merging to OptionMerger (especially useful with named_scope and with_options) 726 [Paweł Kondzior]

*2.2.1 [RC2] (November 14th, 2008)*

  • Increment the version of our altered memcache-client to prevent confusion caused when the 1.5.0 gem is installed.
  • Fixed the option merging in Array#to_xml 1126 [Rudolf Gavlas]
  • Make I18n::Backend::Simple reload its translations in development mode [David Heinemeier Hansson/Sven Fuchs]

*2.2.0 [RC1] (October 24th, 2008)*

  • TimeWithZone#freeze: preload instance variables so that we can actually freeze [Geoff Buesing]
  • Fix Brasilia timezone 1180 [Marcus Derencius, Kane]
  • Time#advance recognizes fractional days and weeks. Deprecate Durations of fractional months and years 970 [Tom Lea]
  • Add ActiveSupport::Rescuable module abstracting ActionController::Base rescue_from features. [Norbert Crombach, Pratik Naik]
  • Switch from String#chars to String#mb_chars for the unicode proxy. [Manfred Stienstra]

    This helps with 1.8.7 compatibility and also improves performance for some operations by reducing indirection.

  • TimeWithZone wday, yday and to_date avoid trip through method_missing [Geoff Buesing]
  • Added Time, Date, DateTime and TimeWithZone past?, future? and today? 720 [Clemens Kofler, Geoff Buesing]
  • Fixed Sri Jayawardenepura time zone to map to Asia/Colombo [Jamis Buck]
  • Added Inflector#parameterize for easy slug generation ("Donald E. Knuth".parameterize => "donald-e-knuth") 713 [Matt Darby]
  • Changed cache benchmarking to be reported in milliseconds [David Heinemeier Hansson]
  • Fix Ruby‘s Time marshaling bug in pre-1.9 versions of Ruby: utc instances are now correctly unmarshaled with a utc zone instead of the system local zone [900 state:resolved] [Luca Guidi, Geoff Buesing]
  • Add Array#in_groups which splits or iterates over the array in specified number of groups. 579. [Adrian Mugnolo] Example:

    a = (1..10).to_a a.in_groups(3) #=> [[1, 2, 3, 4], [5, 6, 7, nil], [8, 9, 10, nil]] a.in_groups(3, false) #=> [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]

  • Fix TimeWithZone unmarshaling: coerce unmarshaled Time instances to utc, because Ruby‘s marshaling of Time instances doesn‘t respect the zone [Geoff Buesing]
  • Added Memoizable mixin for caching simple lazy loaded attributes [Josh Peek]
  • Move the test related core_ext stuff out of core_ext so it‘s only loaded by the test helpers. [Michael Koziarski]
  • Add Inflection rules for String#humanize. 535 [Dan Manges]

    ActiveSupport::Inflector.inflections do |inflect|

      inflect.human(/_cnt$/i, '\1_count')

    end

    ‘jargon_cnt’.humanize # => ‘Jargon count‘

  • TimeWithZone: when crossing DST boundary, treat Durations of days, months or years as variable-length, and all other values as absolute length. A time + 24.hours will advance exactly 24 hours, but a time + 1.day will advance 23-25 hours, depending on the day. Ensure consistent behavior across all advancing methods [Geoff Buesing]
  • Added TimeZone #=~, to support matching zones by regex in time_zone_select. 195 [Ernie Miller]
  • Added Array#second through Array#fifth as aliases for Array#[1] through Array#[4] + Array#forty_two as alias for Array[41] [David Heinemeier Hansson]
  • Added test/do declaration style testing to ActiveSupport::TestCase [DHH via Jay Fields]
  • Added Object#present? which is equivalent to !Object#blank? [David Heinemeier Hansson]
  • Added Enumberable#many? to encapsulate collection.size > 1 [David Heinemeier Hansson/Damian Janowski]
  • Add more standard Hash methods to ActiveSupport::OrderedHash [Steve Purcell]
  • Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under ActiveSupport [Josh Peek]
  • Added StringInquirer for doing things like
StringInquirer.new("production").production? # => true and
StringInquirer.new("production").development? # => false
[David Heinemeier Hansson]
  • Fixed Date#end_of_quarter to not blow up on May 31st [289 state:resolved] (Danger)

*2.1.0 (May 31st, 2008)*

  • TimeZone#to_s shows offset as GMT instead of UTC, because GMT will be more familiar to end users (see time zone selects used by Windows OS, google.com and yahoo.com.) Reverts [8370] [Geoff Buesing]
  • Hash.from_xml: datetime xml types overflow to Ruby DateTime class when out of range of Time. Adding tests for utc offsets [Geoff Buesing]
  • TimeWithZone #+ and #- : ensure overflow to DateTime with Numeric arg [Geoff Buesing]
  • Time#to_json: don‘t convert to utc before encoding. References 175 [Geoff Buesing]
  • Remove unused JSON::RESERVED_WORDS, JSON.valid_identifier? and JSON.reserved_word? methods. Resolves 164. [Cheah Chu Yeow]
  • Adding Date.current, which returns Time.zone.today if config.time_zone is set; otherwise returns Date.today [Geoff Buesing]
  • TimeWithZone: date part getter methods (year mon day etc) are defined on class; no longer relying on method_missing [Geoff Buesing]
  • Time.zone.parse return nil for strings with no date information [Geoff Buesing]
  • Time.zone.parse respects offset information in string. Resolves 105. [Scott Fleckenstein, Geoff Buesing]
  • Added Ruby 1.8 implementation of Process.daemon
  • Duration since and ago with no argument (e.g., 5.days.ago) return TimeWithZone when config.time_zone is set. Introducing Time.current, which returns Time.zone.now if config.time_zone is set, otherwise just returns Time.now [Geoff Buesing]
  • Time#since behaves correctly when passed a Duration. Closes 11527 [kemiller]
  • Add getutc alias for DateTime#utc [Geoff Buesing]
  • Refactor TimeWithZone: don‘t send since, ago, #+, #-, advance through method_missing [Geoff Buesing]
  • TimeWithZone respects config.active_support.use_standard_json_time_format [Geoff Buesing]
  • Add config.active_support.escape_html_entities_in_json to allow disabling of html entity escaping. [Rick Olson]
  • Improve documentation. [Xavier Noria]
  • Modified ActiveSupport::Callbacks::Callback#call to accept multiple arguments.
  • Time yesterday and tomorrow behave correctly crossing DST boundary. Closes 7399 [sblackstone]
  • TimeWithZone: Adding tests for dst and leap day edge cases when advancing time [Geoff Buesing]
  • TimeWithZone#method_missing: send to utc to advance with dst correctness, otherwise send to time. Adding tests for time calculations methods [Geoff Buesing]
  • Add config.active_support.use_standard_json_time_format setting so that Times and Dates export to ISO 8601 dates. [Rick Olson]
  • TZInfo: Removing unneeded TimezoneProxy class [Geoff Buesing]
  • TZInfo: Removing unneeded TimezoneIndexDefinition, since we‘re not including Indexes::Timezones [Geoff Buesing]
  • Removing unnecessary uses_tzinfo helper from tests, given that TZInfo is now bundled [Geoff Buesing]
  • Bundling abbreviated version of TZInfo gem 0.3.8: only the classes and zone definitions required to support Rails time zone features are included. If a recent version of the full TZInfo gem is installed, this will take precedence over the bundled version [Geoff Buesing]
  • TimeWithZone#marshal_load does zone lookup via Time.get_zone, so that tzinfo/Olson identifiers are handled [Geoff Buesing]
  • Time.zone= accepts TZInfo::Timezone instances and Olson identifiers; wraps result in TimeZone instance [Geoff Buesing]
  • TimeWithZone time conversions don‘t need to be wrapped in TimeOrDateTime, because TZInfo does this internally [Geoff Buesing]
  • TimeWithZone#usec returns 0 instead of error when DateTime is wrapped [Geoff Buesing]
  • Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert]
  • Ensure that TimeWithZone#to_yaml works when passed a YAML::Emitter. [Rick Olson]
  • Ensure correct TimeWithZone#to_date [Geoff Buesing]
  • Make TimeWithZone work with tzinfo 0.2.x: use TZInfo::Timezone#zone_identifier alias for abbreviation, silence warnings on tests. Raise LoadError when TZInfo version is < 0.2 by sniffing for TZInfo::TimeOrDateTime constant. Move all tzinfo-dependent TimeZone tests into uses_tzinfo block [Geoff Buesing]
  • Time, DateTime and TimeWithZone in_time_zone defaults to Time.zone. Removing now unneeded in_current_time_zone [Geoff Buesing]
  • TZInfo caches Timezone instances in its own internal hash cache, so TimeZone::MAPPING doesn‘t need to cache them as well [Geoff Buesing]
  • Adding TimeZone#parse [Geoff Buesing]
  • Adding TimeZone#at and DateTime#to_f [Geoff Buesing]
  • TimeWithZone responds to Ruby 1.9 weekday-named query methods [Geoff Buesing]
  • TimeWithZone caches TZInfo::TimezonePeriod used for time conversion so that it can be reused, and enforces DST rules correctly when instance is created from a local time [Geoff Buesing]
  • Fixed that BufferedLogger should create its own directory if one doesn‘t already exist 11285 [lotswholetime]
  • Fix Numeric time tests broken by DST change by anchoring them to fixed times instead of Time.now. Anchor TimeZone#now DST test to time specified with Time.at instead of Time.local to work around platform differences with Time.local and DST representation [Geoff Buesing]
  • Removing unneeded change_time_zone method from Time, DateTime and TimeWithZone [Geoff Buesing]
  • TimeZone local and now correctly enforce DST rules [Geoff Buesing]
  • TimeWithZone instances correctly enforce DST rules. Adding TimeZone#period_for_utc [Geoff Buesing]
  • test_time_with_datetime_fallback expects DateTime.local_offset instead of DateTime.now.offset [Geoff Buesing]
  • Adding TimeWithZone marshal_dump and marshal_load [Geoff Buesing]
  • Add OrderedHash#to_hash [Josh Peek]
  • Adding Time#end_of_day, _quarter, _week, and _year. 9312 [Juanjo Bazan, Tarmo Tänav, BigTitus]
  • Adding TimeWithZone#between? [Geoff Buesing]
  • Time.=== returns true for TimeWithZone instances [Geoff Buesing]
  • TimeWithZone #+ and #- behave consistently with numeric arguments regardless of whether wrapped time is a Time or DateTime; consistenty answers false to acts_like?(:date) [Geoff Buesing]
  • Add String#squish and String#squish! to remove consecutive chunks of whitespace. 11123 [Jordi Bunster, Henrik N]
  • Serialize BigDecimals as Floats when using to_yaml. 8746 [Ernesto Jimenez]
  • Adding TimeWithZone to_yaml, to_datetime, eql? and method aliases for duck-typing compatibility with Time [Geoff Buesing]
  • TimeWithZone in_time_zone returns self if zone argument is the same as time_zone [Geoff Buesing]
  • Adding TimeWithZone to_a, to_f, to_i, httpdate, rfc2822 [Geoff Buesing]
  • Pruning unneeded TimeWithZone#change_time_zone_to_current [Geoff Buesing]
  • Time#zone=, in_time_zone and change_time_zone accept a Duration [Geoff Buesing]
  • Time#in_time_zone handles Time.local instances correctly [Geoff Buesing]
  • Pruning unneeded Time#change_time_zone_to_current. Enhanced docs to change_time_zone to explain the difference between this method and in_time_zone [Geoff Buesing]
  • TimeZone#new method renamed local; when used with Time.zone, constructor now reads: Time.zone.local() [Geoff Buesing]
  • Added Base64.encode64s to encode values in base64 without the newlines. This makes the values immediately usable as URL parameters or memcache keys without further processing [David Heinemeier Hansson]
  • Remove :nodoc: entries around the ActiveSupport test/unit assertions. 10946 [dancroak, jamesh]
  • Add Time.zone_default accessor for setting the default time zone. Rails::Configuration.time_zone sets this. 10982 [Geoff Buesing]
  • cache.fetch(key, :force => true) to force a cache miss. [Jeremy Kemper]
  • Support retrieving TimeZones with a Duration. TimeZone[-28800] == TimeZone. [Rick Olson]
  • TimeWithZone#- added, so that #- can handle a Time or TimeWithZone argument correctly [Geoff Buesing]
  • with_timezone test helper renamed with_env_tz, to distinguish between setting ENV[‘TZ’] and setting Time.zone in tests [Geoff Buesing]
  • Time#- coerces TimeWithZone argument to a Time instance so that difference in seconds can be calculated. Closes 10914 [Geoff Buesing, yyyc514]
  • Adding UTC zone to TimeZone; TimeWithZone no longer has to fake UTC zone with nil [Geoff Buesing]
  • Time.get_zone refactored to private method, given that the encapsulated logic is only useful internally [Geoff Buesing]
  • Time.zone uses thread-local variable for thread safety. Adding Time.use_zone, for overriding Time.zone locally inside a block. Removing unneeded Time.zone_reset! [Geoff Buesing]
  • TimeZone#to_s uses UTC rather than GMT; reapplying change that was undone in [8679]. 1689 [Cheah Chu Yeow]
  • Time.days_in_month defaults to current year if no year is supplied as argument 10799 [Radar], uses Date.gregorian_leap? to determine leap year, and uses constant lookup to determine days in month [Geoff Buesing]
  • Adding Time and DateTime compare_with_coercion, which layers behavior on #<=> so that any combination of Time, DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared [Geoff Buesing]
  • TimeZone#now returns an ActiveSupport::TimeWithZone [Geoff Buesing]
  • Time in_current_time_zone and change_time_zone_to_current return self when Time.zone is nil [Geoff Buesing]
  • Remove unneeded to_datetime_default_s alias for DateTime#to_s, given that we inherit a to_default_s from Date that does exactly the same thing [Geoff Buesing]
  • Refactor Time and DateTime to_formatted_s: use ternary instead of nested if/else [Geoff Buesing]
  • Adding Time and DateTime formatted_offset, for outputting +HH:MM utc offset strings with cross-platform consistency [Geoff Buesing]
  • Adding alternate_utc_string option to TimeZone#formatted_offset. Removing unneeded TimeZone#offset. [Geoff Buesing]
  • Introduce ActiveSupport::TimeWithZone, for wrapping Time instances with a TimeZone. Introduce instance methods to Time for creating TimeWithZone instances, and class methods for managing a global time zone. [Geoff Buesing]
  • Replace non-dst-aware TimeZone class with dst-aware class from tzinfo_timezone plugin. TimeZone#adjust and unadjust are no longer available; tzinfo gem must now be present in order to perform time zone calculations, via local_to_utc and utc_to_local methods. [Geoff Buesing]
  • Extract ActiveSupport::Callbacks from Active Record, test case setup and teardown, and ActionController::Dispatcher. 10727 [Josh Peek]
  • Introducing DateTime utc, utc? and utc_offset, for duck-typing compatibility with Time. Closes 10002 [Geoff Buesing]
  • Time#to_json uses Numeric#to_utc_offset_s to output a cross-platform-consistent representation without having to convert to DateTime. References 9750 [Geoff Buesing]
  • Refactor number-to-HH:MM-string conversion logic from TimeZone#formatted_offset to a reusable Numeric#to_utc_offset_s method. [Geoff Buesing]
  • Continue evolution toward ActiveSupport::TestCase. 10679 [Josh Peek]
  • TestCase: introduce declared setup and teardown callbacks. Pass a list of methods and an optional block to call before setup or after teardown. Setup callbacks are run in the order declared; teardown callbacks are run in reverse. [Jeremy Kemper]
  • Added ActiveSupport::Gzip.decompress/compress(source) as an easy wrapper for Zlib [Tobias Lütke]
  • Included MemCache-Client to make the improved ActiveSupport::Cache::MemCacheStore work out of the box [Bob Cottrell, Eric Hodel]
  • Added ActiveSupport::Cache::*
framework as an extraction from ActionController::Caching::Fragments::*
[David Heinemeier Hansson]
  • Fixed String#titleize to work for strings with ‘s too 10571 [trek]
  • Changed the implementation of Enumerable#group_by to use a double array approach instead of a hash such that the insert order is honored [David Heinemeier Hansson/Marcel Molina Jr.]
  • remove multiple enumerations from ActiveSupport::JSON#convert_json_to_yaml when dealing with date/time values. [Rick Olson]
  • Hash#symbolize_keys skips keys that can‘t be symbolized. 10500 [Brad Greenlee]
  • Ruby 1.9 compatibility. 1689, 10466, 10468, 10554, 10594, 10632 [Cheah Chu Yeow, Pratik Naik, Jeremy Kemper, Dirkjan Bussink, Xavier Noria]
  • TimeZone#to_s uses UTC rather than GMT. 1689 [Cheah Chu Yeow]
  • Refactor of Hash#symbolize_keys! to use Hash#replace. Closes 10420 [ReinH]
  • Fix HashWithIndifferentAccess#to_options! so it doesn‘t clear the options hash. Closes 10419 [ReinH]

*2.0.1* (December 7th, 2007)

  • Added Array#from and Array#to that behaves just from String#from and String#to [David Heinemeier Hansson]
  • Fix that empty collections should be treated as empty arrays regardless of whitespace for Hash#from_xml 10255 [adamj]
  • Time#time_with_datetime_fallback, Time#to_datetime, Date#to_datetime and String#to_datetime honor Ruby‘s default calendar reform setting. 10201 [Geoff Buesing]
  • Change Time and DateTime end_of_month to return last second of month instead of beginning of last day of month. Closes 10200 [Geoff Buesing]
  • Speedup String#blank? [Jeremy Kemper, Michael Koziarski]
  • Add documentation for Hash#diff. Closes 9306 [Tarmo Tänav]
  • Add new superclass_delegating_accessors. Similar to class inheritable attributes but with subtly different semantics. [Michael Koziarski, Tarmo Tänav]
  • Change JSON to encode %w(< > &) as 4 digit hex codes to be in compliance with the JSON spec. Closes 9975 [Josh Peek, Cheah Chu Yeow, Tim Pope]
  • Fix JSON encoding/decoding bugs dealing with /’s. Closes 9990 [Rick Olson, theamazingrando]
  • Introduce a base class for all test cases used by rails applications. ActiveSupport::TestCase [Michael Koziarski]

    The intention is to use this to reduce the amount of monkeypatching / overriding that is done to test/unit‘s classes.

  • Document Enumerable and Hash to_json. 9970 [Cheah Chu Yeow]
  • Hash#to_xml handles symbol values. 9954 [Assaf]
  • Hash#symbolize_keys behaves well with integer keys. 9890 [PotatoSalad]
  • Multibyte: String#slice supports regexp argument. 9646 [yob]
  • object.duplicable? returns true if object.dup is safe. False for nil, true, false, symbols, and numbers; true otherwise. 9333 [sur]
  • Time, Date and DateTime advance accept :weeks option. 9866 [Geoff Buesing]
  • Fix Time#years_ago and years_since from leap days. 9865 [Geoff Buesing]
  • Time and DateTime#advance accept :hours, :minutes, and :seconds options. 9825 [Geoff Buesing]
  • Fix Date#years_ago and years_since from leap days. 9864 [Geoff Buesing]
  • Refactor Time and Date#months_since and months_ago to use advance. 9863 [Geoff Buesing]
  • Rebundle Builder 2.1.2 but prefer a newer RubyGem if available. [Jeremy Kemper]
  • Add Range#overlaps?(range), Range#include?(range), and Range#step without a block. [brandon]
  • Correct BufferedLogger#level? checks. 9806 [wildchild, Johan Sorensen]
  • String#to_xs uses Eric Wong‘s fast_xs extension, if available, for Builder speedup. bogomips.org/fast_xs/ [Jeremy Kemper]
  • Introduce BasicObject as Builder::BlankSlate for Ruby 1.9 forward compatibility. [Jeremy Kemper]
  • Unbundle Builder in favor of a gem dependency. [Jeremy Kemper]
  • Disambiguate Time, Date, and DateTime#to_json formatting. 9750 [Geoff Buesing, Cheah Chu Yeow]
  • Hash#to_json takes :only or :except options to specific or omit certain hash keys. Enumerable#to_json passes through its options to each element. 9751 [Cheah Chu Yeow]
  • BufferedLogger#auto_flushing = N flushes the log every N messages. Buffers with an array instead of string. Disabling auto_flushing still flushes when the buffer hits a maximum size, as a failsafe against memory-gobbling. [Jeremy Kemper]
  • Fixed Date#xmlschema for dates outside the range of what can be created with Time 9744 [Geoff Buesing]
  • Fixed that La Paz was included in -25200 and -14400 offsets when it should only be in -14400 9735 [bermi]
  • Fixed JSON encoding to use quoted keys according to the JSON standard. 8762 [choonkat, Cheah Chu Yeow]
  • Alias Object#send to send! for Ruby 1.9 forward compatibility. [Jeremy Kemper]
  • Backport Object#instance_variable_defined? for Ruby < 1.8.6. [Jeremy Kemper]
  • BufferedLogger#add converts the message to a string. 9702, 9724 [eigentone, DrMark, Tom Ward]
  • Added ActiveSupport::BufferedLogger as a duck-typing alternative (albeit with no formatter) to the Ruby Logger, which provides a very nice speed bump (inspired by Ezra‘s buffered logger) [David Heinemeier Hansson]
  • Object#instance_exec produces fewer garbage methods. [Mauricio Fernandez]
  • Decode json strings as Dates/Times if they‘re using a YAML-compatible format. Closes 9614 [Rick Olson]
  • Fixed cache_page to use the request url instead of the routing options when picking a save path. 8614 [Josh Peek]
  • Object.subclasses_of includes anonymous subclasses. [Jeremy Kemper]
  • Fixed that pluralizing an empty string should return the same empty string, not "s". 7720 [Josh Peek]
  • Added call to inspect on non-string classes for the logger 8533 [Coda Hale]
  • Deprecation: remove deprecated :mday option from Time, Date, and DateTime#change. [Jeremy Kemper]
  • Fix JSON decoder with nested quotes and commas. 9579 [Zach Dennis]
  • Hash#to_xml doesn‘t double-unescape. 8806 [Ezran]
  • Added Array#rand 9170 [Norbert Crombach]. Examples:
      [].rand       # => nil
  ['a'].rand    # => 'a'
  [1,2,3].rand  # => 1 or 2 or 3
  • Deprecation: removed Reloadable. [Jeremy Kemper]
  • Make the utf-handler return the correct value for non-matching regular expressions. Closes 9049 [Manfred Stienstra]
  • Add ljust, rjust and center to utf8-handler. Closes 9165 [Manfred Stienstra]
  • Fix Time#advance bug when trying to advance a year from leap day. Closes 8655 [Geoff Buesing]
  • Add support for []= on ActiveSupport::Multibyte::Chars. Closes 9142. [ewan, Manfred Stienstra]
  • Added Array#extract_options! to encapsulate the pattern of getting an options hash out of a variable number of parameters. 8759 [Norbert Crombach]
  • Let alias_attribute work with attributes with initial capital letters (legacy columns etc). Closes 8596 [mpalmer]
  • Added Hash#except which is the inverse of Hash#slice — return the hash except the keys that are specified [David Heinemeier Hansson]
  • Added support for pluralization with a different starting letter than the singular version (cow/kine) 4929 [norri_b/Josh Susser]
  • Demote Hash#to_xml to use XmlSimple#xml_in_string so it can‘t read files or stdin. 8453 [candlerb, Jeremy Kemper]
  • Backport clean_logger changes to support ruby 1.8.2 [Mislav Marohnić]
  • Added proper handling of arrays 8537 [Josh Susser]

    Before:

      Hash.from_xml '<images></images>'
  # => {:images => nil}

  Hash.from_xml '<images><image>foo.jpg</image></images>'
  # => {:images => {:image => "foo.jpg"}}

  Hash.from_xml '<images><image>foo.jpg</image><image>bar.jpg</image></images>'
  # => {:images => {:image => ["foo.jpg", "bar.jpg"]}}

    After:

      Hash.from_xml '<images type="array"></images>'
  # => {:images => []}

  Hash.from_xml '<images type="array"><image>foo.jpg</image></images>'
  # => {:images => ["foo.jpg"]}

  Hash.from_xml '<images type="array"><image>foo.jpg</image><image>bar.jpg</image></images>'
  # => {:images => ["foo.jpg", "bar.jpg"]}
  • Improve Time and Date test coverage. 8646 [Josh Peek]
  • Add Date#since, ago, beginning_of_day, and end_of_day. Date + seconds works now. 8575 [Geoff Buesing]
  • String#to_time overflows to DateTime. Add String#to_datetime. 8572 [Geoff Buesing]
  • Date.yesterday and .tomorrow. 8571 [Geoff Buesing]
  • Readable Date and DateTime#inspect. 8570 [Geoff Buesing]
  • Move common DateTime calculations to Date. 8536 [Geoff Buesing]
  • Added Date#change (like Time#change) [David Heinemeier Hansson]
  • DateTime#to_time converts to Time unless out of range. 8512 [Geoff Buesing]
  • Date#to_datetime, to_s(:rfc822). 8512 [Geoff Buesing]
  • Time durations use since instead of + for accuracy. 8513 [Geoff Buesing]
  • escape <’s and >’s in JSON strings. 8371 [Rick Olson]
  • Inflections: MatrixTest -> MatrixTests instead of MatricesTest. 8496 [jbwiv]
  • Multibyte strings respond_to the String methods they proxy so they can be duck-typed. 6549 [Tuxie]
  • Array#to_xml yields the builder just like Hash and ActiveRecord::Base. 8472 [seth]
  • Date, Time, and DateTime support formatting blocks in addition to strftime strings. Introduce :long_ordinal format, e.g. "February 21st, 2005". 8191 [Coda Hale]
  • Document Object#blank?. 6491 [Chris Mear]
  • Date, Time, and DateTime#to_json. 8399 [wycats]
  • Simplify API of assert_difference by passing in an expression that is evaluated before and after the passed in block. See documenation for examples of new API. [Marcel Molina Jr.]
  • Added assert_difference and assert_no_difference to test/unit assertions [Tobias Lütke]
  • Removed breakpointer and Binding.of_caller in favor of relying on ruby-debug by Kent Sibilev since the breakpointer has been broken since Ruby 1.8.4 and will not be coming back [David Heinemeier Hansson]
  • Added parsing of file type in Hash.xml_in so you can easily do file uploads with base64 from an API [David Heinemeier Hansson]
      <person>
    <name>David</name>
    <avatar type="file" name="me.jpg" content_type="image/jpg">R0lGODlhkACZAPUAAM5lcfjrtMQCG=\n</avatar>
  </person>

    …becomes:

      attributes = { :person => { :name => "David", :avatar => #<StringIO> } }
  attributes[:person][:avatar].content_type      # => "image/jpg"
  attributes[:person][:avatar].original_filename # => "me.jpg"
  attributes[:person][:avatar].read # => binary data of the file

    Which is duck-type compatible with the files that you get when doing multipart uploads through HTML.

  • Improved multibyte performance by relying less on exception raising 8159 [Blaine]
  • Use XSD-compatible type names for Hash#to_xml and make the converters extendable 8047 [Tim Pope]
  • Added yielding of builder in Hash#to_xml [David Heinemeier Hansson]
  • Hash#with_indifferent_access now also converts hashes kept in arrays to indifferent access (makes it easier to treat HTML and XML parameters the same) [David Heinemeier Hansson]
  • Hash#to_xml supports YAML attributes. 7502 [jonathan]
  • Refactor ActiveSupport::JSON to be less obtuse. Add support for JSON decoding by way of Syck with ActiveSupport::JSON.decode(json_string). Prevent hash keys that are JavaScript reserved words from being unquoted during encoding. [Sam Stephenson]
  • alias_method_chain preserves the original method‘s visibility. 7854 [Jonathan Viney]
  • Update Dependencies to ignore constants inherited from ancestors. Closes 6951. [Nicholas Seckar]
  • Array#to_query preserves its ordering. 7756 [Greg Spurrier]
  • Out-of-range Time calculations transparently overflow to DateTime. Introduce Time#to_datetime. 7706, 7715 [Geoff Buesing]
  • DateTime calculations analogous to the Date and Time extensions. 7693 [Geoff Buesing]
  • Give DateTime correct .to_s implementations, lets it play nice with ActiveRecord quoting. 7649 [Geoff Buesing]
  • Add File.atomic_write, allows you to write large files in an atomic manner, preventing users from seeing half written files. [Michael Koziarski]
  • Allow users to provide custom formatters to Logger. [Anthony Eden]
  • Hash#to_query CGI-escapes its keys. [Jeremy Kemper]
  • Optimize Class Inheritable Attributes so that unnecessary hashes are not created. Closes 7472 [Bruce Perens]
  • :db format for Date#to_s [Jeremy Kemper]
      Date.new(2007, 1, 27).to_s(:db) # => '2007-01-27'
  • Added :instance_writer option to mattr_writer/accessor, cattr_writer/accessor, and class_inheritable_writer to skip the creation of the instance writer. [Rick Olson]
  • Added Hash#to_query to turn a hash of values into a form-encoded query string [Nicholas Seckar]
  • Increase test coverage for subclasses_of. Closes 7335. [Roman2K, Nicholas Seckar]
  • Remove unused code from Duration#inspect. Closes 7180. [Rich Collins]
  • Added test coverage for Inflector.inflections.clear. Closes 7179. [Rich Collins]
  • ActiveSupport::Multibyte::Handlers::UTF8Handler should raise when a range and an integer are passed in (just like the native implementation). Closes 7176 [Rich Collins]
  • A couple extra tests for classify. Closes 7273. [Josh Susser]
  • Better docs for Object extensions [zackchandler, Jamis Buck]
  • Fix that Dates couldn‘t be subtracted from Dates after [5940]. [Sam Stephenson]
  • Add Object#acts_like? and Time#acts_like_time? and Date#acts_like_date? to facilitate duck-typing. [Jamis Buck]
  • Make 1.months and friends accurate by introducing a Duration class. 6835 [eventualbuddha]

*1.4.2* (March 12th, 2007)

  • Ruby 1.8.6 and 1.9 define private Time#to_date and to_datetime; make them

public for compatibility. [Jeremy Kemper]

  • Deprecation: warn on stderr if RAILS_DEFAULT_LOGGER isn‘t set yet. [Jeremy Kemper]

*1.4.1* (February 5th, 2007)

  • Optimize Class Inheritable Attributes so that unnecessary hashes are not created. Closes 7472 [Bruce Perens]
  • Added :instance_writer option to mattr_writer/accessor, cattr_writer/accessor, and class_inheritable_writer to skip the creation of the instance writer. [Rick Olson]
  • Full test coverage for Inflector. 7228 [Dan Kubb]

*1.4.0* (January 16th, 2007)

  • Document Inflector.ordinalize and merge docs from String inflections. 7023 [smeade]
  • Unbundle flexmock. [Jeremy Kemper]
  • Fix Dependencies.autoloaded? to ignore anonymous modules. Closes 6561. [Nicholas Seckar]
  • Update load once paths to prevent nested once constants from being detected and claimed by an external non-once load. [Nicholas Seckar]
  • Deprecation: silence warnings when reporting test errors. [Jeremy Kemper]
  • Hash#slice(*keys) returns a new hash with only the given keys. slice! replaces the hash with only the given keys. Works with HashWithIndifferentAccess also. [Jeremy Kemper]
  • HashWithIndifferentAccess#to_hash converts to a Hash with String keys and the same default value. [Jeremy Kemper]
  • Fix remove_constant to correctly handle constant names of the form "::A::…". References 6720. [Nicholas Seckar]
  • Fixed Array#to_xml when it contains a series of hashes (each piece would get its own XML declaration) 6610 [thkarcher/cyu]
  • Added Time#to_s(:time) which will just return H:M, like 17:44 [David Heinemeier Hansson]
  • Add Module#attr_accessor_with_default to initialize value of attribute before setting it. Closes 6538. [Stuart Halloway, Marcel Molina Jr.]
  • Hash#to_xml handles keys with the same name as Kernel methods. 6613 [Jonathan del Strother]
  • Added Time#end_of_day to get 23:59:59 of that day [David Heinemeier Hansson]
  • Don‘t quote hash keys in Hash#to_json if they‘re valid JavaScript identifiers. Disable this with ActiveSupport::JSON.unquote_hash_key_identifiers = false if you need strict JSON compliance. [Sam Stephenson]
  • Lazily load the Unicode Database in the UTF-8 Handler [Rick Olson]
  • Update dependencies to delete partially loaded constants. [Nicholas Seckar]
  • Fix unicode JSON regexp for Onigurama compatibility. 6494 [whitley]
  • update XmlSimple to 1.0.10. Closes 6532. [Nick Sieger]
  • Update dependencies to allow constants to be defined alongside their siblings. A common case for this is AR model classes with STI; user.rb might define User, Administrator and Guest for example. [Nicholas Seckar]
  • next_week respects DST changes. 6483, 5617, 2353, 2509, 4551 [marclove, Rob Biedenharn, rails@roetzel.de, jsolson@damogran.org, drbrain@segment7.net]
  • Expose methods added to Enumerable in the documentation, such as group_by. Closes 6170. [sergeykojin@gmail.com, Marcel Molina Jr.]
  • Ensure Chars#tidy_bytes only tidies broken bytes. Closes 6397 [Manfred Stienstra]
  • Add ‘unloadable’, a method used to mark any constant as requiring an unload after each request. [Nicholas Seckar]
  • Make core_ext/string/access.rb multibyte safe. Closes 6388 [Manfred Stienstra]
  • Make String#chars slicing behaviour consistent with String. Closes 6387 [Manfred Stienstra]
  • Pull in latest multibyte patch. Closes 6346 [Manfred Stienstra]
  • Add ActiveSupport::Multibyte. Provides String#chars which lets you deal with strings as a sequence of chars, not of bytes. Closes 6242 [Julian Tarkhanov, Manfred Stienstra, Thijs van der Vossen & Jan Behrens]
  • Fix issue with class_inheritable_accessor saving updates to the parent class when initialized with an Array or Hash [mojombo]
  • Hash#to_xml supports Bignum and BigDecimal. 6313 [edibiase]
  • Don‘t undefine class in OptionMerger [Rick Olson]
  • Hash.create_from_xml has been renamed to Hash.from_xml, alias will exist until Rails 2.0 [David Heinemeier Hansson]
  • alias_method_chain works with accessor= methods also. 6153 [Caio Chassot]
  • Fix loadable_constants_for_path to handle load paths that do not end with a slash. [Nicholas Seckar]
  • Fix logic error in determining what was loaded by a given file. Closes 6039. [Nicholas Seckar]
  • Equate Kernel.const_missing with Object.const_missing. Fixes 5988. [Nicholas Seckar]
  • Add ApplicationController special case to Dependencies. [Nicholas Seckar]
  • Don‘t pad remaining places with in_groups_of if specified padding value is false. [Marcel Molina Jr.]
  • Fix cases where empty xml nodes weren‘t being translated to nil in Hash.create_from_xml [Rick Olso n]

    <written-on type="date"></written-on> # => { :type => ‘date’ } # WRONG <written-on type="date"></written-on> # => nil # RIGHT

  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Inflections: don‘t singularize -ies plurals. [foamdino@gmail.com, Mark Van Holstyn]
  • Update Initializer to use load_once_paths to avoid plugin reloading. References 5852. [Nicholas Seckar]
  • Use Array#assoc in ActiveSupport::OrderedHash. [Mauricio Fernandez]
  • Greatly increased performance of String.to_json, which speeds up RJS considerably on large pages, fixes 3473 [Shugo Maeda]
  • Detect missing_constants calls from removed modules and fail accordingly. [Nicholas Seckar]
  • Stop using defined? in Dependencies.qualified_const_defined? since defined? may invoke const_missing. [Nicholas Seckar]
  • Dependencies can autoload directories of nested classes. [Jeremy Kemper]
      Example:
    invoice.rb            class Invoice
    invoice/lineitem.rb   class Invoice::Lineitem
  • Add Deprecation.silence so that Reloadable does not scold itself. [Nicholas Seckar]
  • Add debugging logging to Dependencies. Currently can be enabled with Dependencies.log_activity = true; adding to Initializer and documenting is forthcoming. [Nicholas Seckar]
  • Replace Reloadable with improvements to the Dependencies mechanism. [Nicholas Seckar]
  • DateTime#to_time gives hour/minute/second resolution. 5747 [jon.evans@pobox.com]
  • attr_internal to support namespacing and deprecation. Like attr_* except backed by internally-named instance variable. Set attr_internal_naming_format to change the format from the default ’@_%s’. [Jeremy Kemper]
      # def foo()   @foo__rofl      end
  # def foo=(v) @foo__rofl = v  end
  self.attr_internal_naming_format = '@%s__rofl'
  attr_internal :foo
  • Raise fully qualified names upon name errors. 5533 [Lars Pind, Nicholas Seckar]
  • Add extention to obtain the missing constant from NameError instances. [Nicholas Seckar]
  • Thoroughly document inflections. 5700 [petermichaux@gmail.com]
  • Added Module#alias_attribute [Jamis/David Heinemeier Hansson]. Example:
      class Content < ActiveRecord::Base
    # has a title attribute
  end

  class Email < ActiveRecord::Base
    alias_attribute :subject, :title
  end

  e = Email.find(1)
  e.title    # => "Superstars"
  e.subject  # => "Superstars"
  e.subject? # => true
  e.subject = "Megastars"
  e.title    # => "Megastars"
  • Deprecation: easier to work with warning behavior as procs; default behaviors for each environment so users needn‘t update env.rb; and testing pleasure with assert_deprecated, assert_not_deprecated. [Jeremy Kemper] By default, test prints to $stderr, dev logs, production ignores. Provide your own per-environment in e.g. config/environments/development.rb:
      ActiveSupport::Deprecation.behavior = Proc.new { |message| raise message }
  • First cut of the Rails Deprecation system. [Michael Koziarski]
  • Strip boolean XML content before checking for ‘true’ [Rick Olson]
  • Customize default BigDecimal formatting. References 5672 [Dave Thomas]
  • Correctly convert <foo nil="true"> to nil when using Hash.create_from_xml. [Rick Olson]
  • Optional identity for Enumerable#sum defaults to zero. 5657 [gensym@mac.com]
  • HashWithIndifferentAccess shouldn‘t confuse false and nil. 5601 [Shugo Maeda]
  • Fixed HashWithIndifferentAccess#default 5586 [chris@seagul.co.uk]
  • More compatible Hash.create_from_xml. 5523 [nunemaker@gmail.com]
  • Added Enumerable#sum for calculating a sum from the elements [David Heinemeier Hansson, jonathan@daikini.com]. Examples:
      [1, 2, 3].sum
  payments.sum { |p| p.price * p.tax_rate }
  payments.sum(&:price)

    This is instead of payments.inject(0) { |sum, p| sum + p.price }

  • Correct and clarify Array#to_sentence docs. 5458 [brad@madriska.com]
  • alias_method_chain preserves method punctuation so foo, foo?, and foo! may be chained with the same feature. [Jeremy Kemper]
      Example:
    alias_method_chain :save!, :validation
  is equivalent to
    alias_method :save_without_validation!, :save!
    alias_method :save!, :save_with_validation!
  • Enhance Symbol#to_proc so it works with list objects, such as multi-dimensional arrays. Closes 5295 [nov@yo.rim.or.jp]. Example:
      {1 => "one", 2 => "two", 3 => "three"}.sort_by(&:first).map(&:last)
  #=> ["one", "two", "three"]
  • Added Hash.create_from_xml(string) which will create a hash from a XML string and even typecast if possible [David Heinemeier Hansson]. Example:
      Hash.create_from_xml <<-EOT
    <note>
      <title>This is a note</title>
      <created-at type="date">2004-10-10</created-at>
    </note>
  EOT

    …would return:

      { :note => { :title => "This is a note", :created_at => Date.new(2004, 10, 10) } }
  • Added Jim Weirich‘s excellent FlexMock class to vendor (Copyright 2003, 2004 by Jim Weirich (jim@weriichhouse.org)) — it‘s not automatically required, though, so require ‘flexmock’ is still necessary [David Heinemeier Hansson]
  • Fixed that Module#alias_method_chain should work with both foo? foo! and foo at the same time 4954 [anna@wota.jp]
  • to_xml fixes, features, and speedup: introduce :dasherize option that converts updated_at to updated-at if true (the existing default); binary columns get encoding="base64" attribute; nil values get nil="true" attribute to distinguish empty values; add type information for float columns; allow arbitrarily deep :include; include SQL type information as the type attribute. 4989 [Blair Zajac <blair@orcaware.com>]
  • Add OrderedHash#values. [Sam Stephenson]
  • Added Array#to_s(:db) that‘ll produce a comma-separated list of ids [David Heinemeier Hansson]. Example:
      Purchase.find(:all, :conditions => "product_id IN (#{shops.products.to_s(:db)})"
  • Normalize classify‘s argument to a String so that it plays nice with Symbols. [Marcel Molina Jr.]
  • Strip out leading schema name in classify. References 5139. [Michael Schoen]
  • Remove Enumerable#first_match since break(value) handles the use case well enough. [Nicholas Seckar]

    Enumerable#first_match was like detect, but instead of returning the matching element, the yielded value returned. For example:

      user_xml = adapters(:from => User, :to => Xml).first_match do |adapter|
    adapter.adapt @user
  end

    But this is just as easily done with:

      user_xml = adapters(:from => User, :to => Xml).each do
    break adapter.adapt(@user)
  end
  • Make Array#in_groups_of just return the grouped collection if a block isn‘t given. [Marcel Molina Jr.]
  • Don‘t destroy a HashWithIndifferentAccess if symbolize_keys! or stringify_keys! is called on it. Closes 5076. [Marcel Molina Jr., guy.naor@famundo.com]
  • Document Module::delegate. 5002 [pergesu@gmail.com]
  • Replace alias method chaining with Module#alias_method_chain. [Marcel Molina Jr.]
  • Strip out punctuation on predicates or bang methods being aliased with alias_method_chain since target?_without_feature is not a valid method name. Add tests for Module#alias_method_chain. [Marcel Molina Jr.]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Allow default options in with_options to be overridden. Closes 4480. [murphy@cYcnus.de]
  • Added Module#alias_method_chain [Jamis Buck]
  • Updated to Builder 2.0 [David Heinemeier Hansson]
  • Add Array#split for dividing arrays into one or more subarrays by value or block. [Sam Stephenson]

*1.3.1* (April 6th, 2006)

  • Clean paths inside of exception messages and traces. [Nicholas Seckar]
  • Add Pathname.clean_within for cleaning all the paths inside of a string. [Nicholas Seckar]
  • provide an empty Dependencies::LoadingModule.load which prints deprecation warnings. Lets 1.0 applications function with .13-style environment.rb.

*1.3.0* (March 27th, 2006)

  • When possible, avoid incorrectly obtaining constants from parent modules. Fixes 4221. [Nicholas Seckar]
  • Add more tests for dependencies; refactor existing cases. [Nicholas Seckar]
  • Move Module#parent and Module#as_load_path into core_ext. Add Module#parent. [Nicholas Seckar]
  • Add CachingTools::HashCaching to simplify the creation of nested, autofilling hashes. [Nicholas Seckar]
  • Remove a hack intended to avoid unloading the same class twice, but which would not work anyways. [Nicholas Seckar]
  • Update Object.subclasses_of to locate nested classes. This affects Object.remove_subclasses_of in that nested classes will now be unloaded. [Nicholas Seckar]
  • Update Object.remove_subclasses_of to use Class.remove_class, reducing duplication. [Nicholas Seckar]
  • Added Fixnum#seconds for consistency, so you can say 5.minutes + 30.seconds instead of 5.minutes + 30 4389 [François Beausoleil]
  • Added option to String#camelize to generate lower-cased camel case by passing in :lower, like "super_man".camelize(:lower) # => "superMan" [David Heinemeier Hansson]
  • Added Hash#diff to show the difference between two hashes [Chris McGrath]
  • Added Time#advance to do precise time time calculations for cases where a month being approximated to 30 days won‘t do 1860 [Rick Olson]
  • Enhance Inflector.underscore to convert ’-’ into ‘_’ (as the inverse of Inflector.dasherize) [Jamis Buck]
  • Switched to_xml to use the xml schema format for datetimes. This allows the encoding of time zones and should improve operability. [Michael Koziarski]
  • Added a note to the documentation for the Date related Numeric extensions to indicate that they‘re

approximations and shouldn‘t be used for critical calculations. [Michael Koziarski]

  • Added Hash#to_xml and Array#to_xml that makes it much easier to produce XML from basic structures [David Heinemeier Hansson]. Examples:
      { :name => "David", :street_name => "Paulina", :age => 26, :moved_on => Date.new(2005, 11, 15) }.to_xml

    …returns:

        <person>
      <street-name>Paulina</street-name>
      <name>David</name>
      <age type="integer">26</age>
      <moved-on type="date">2005-11-15</moved-on>
    </person>
  • Moved Jim Weirich‘s wonderful Builder from Action Pack to Active Support (it‘s simply too useful to be stuck in AP) [David Heinemeier Hansson]
  • Fixed that Array#to_sentence will return "" on an empty array instead of ", and" 3842, 4031 [rubyonrails@beautifulpixel.com]
  • Add Enumerable#group_by for grouping collections based on the result of some block. Useful, for example, for grouping records by date.

    ex.

       latest_transcripts.group_by(&:day).each do |day, transcripts|
     p "#{day} -> #{transcripts.map(&:class) * ', '}"
   end
   "2006-03-01 -> Transcript"
   "2006-02-28 -> Transcript"
   "2006-02-27 -> Transcript, Transcript"
   "2006-02-26 -> Transcript, Transcript"

    Add Array#in_groups_of, for iterating over an array in groups of a certain size.

    ex.

       %w(1 2 3 4 5 6 7).in_groups_of(3) {|g| p g}
   ["1", "2", "3"]
   ["4", "5", "6"]
   ["7", nil, nil]

    [Marcel Molina Jr., Sam Stephenson]

  • Added Kernel#daemonize to turn the current process into a daemon that can be killed with a TERM signal [David Heinemeier Hansson]
  • Add ‘around’ methods to Logger, to make it easy to log before and after messages for a given block as requested in 3809. [Michael Koziarski] Example:

    logger.around_info("Start rendering component (#{options.inspect}): ",

                       "\n\nEnd of component rendering") { yield }
  • Added Time#beginning_of_quarter 3607 [cohen.jeff@gmail.com]
  • Fix Object.subclasses_of to only return currently defined objects [Jonathan Viney <jonathan@bluewire.net.nz>]
  • Fix constantize to properly handle names beginning with ’::’. [Nicholas Seckar]
  • Make String#last return the string instead of nil when it is shorter than the limit [Scott Barron].
  • Added delegation support to Module that allows multiple delegations at once (unlike Forwardable in the stdlib) [David Heinemeier Hansson]. Example:
      class Account < ActiveRecord::Base
    has_one :subscription
    delegate :free?, :paying?, :to => :subscription
    delegate :overdue?, :to => "subscription.last_payment"
  end

  account.free?    # => account.subscription.free?
  account.overdue? # => account.subscription.last_payment.overdue?
  • Fix Reloadable to handle the case where a class that has been ‘removed’ has not yet been garbage collected. [Nicholas Seckar]
  • Don‘t allow Reloadable to be included into Modules.
  • Remove LoadingModule. [Nicholas Seckar]
  • Add documentation for Reloadable::Subclasses. [Nicholas Seckar]
  • Add Reloadable::Subclasses which handles the common case where a base class should not be reloaded, but its subclasses should be. [Nicholas Seckar]
  • Further improvements to reloading code [Nicholas Seckar, Trevor Squires]
    • All classes/modules which include Reloadable can define reloadable? for fine grained control of reloading
    • Class.remove_class uses Module#parent to access the parent module
    • Class.remove_class expanded to handle multiple classes in a single call
    • LoadingModule.clear! has been removed as it is no longer required
    • Module#remove_classes_including has been removed in favor of Reloadable.reloadable_classes
  • Added reusable reloading support through the inclusion of the Relodable module that all subclasses of ActiveRecord::Base, ActiveRecord::Observer, ActiveController::Base, and ActionMailer::Base automatically gets. This means that these classes will be reloaded by the dispatcher when Dependencies.mechanism = :load. You can make your own models reloadable easily:
      class Setting
    include Reloadable
  end

    Reloading a class is done by removing its constant which will cause it to be loaded again on the next reference. [David Heinemeier Hansson]

  • Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar]
  • Add Object#instance_exec, like instance_eval but passes its arguments to the block. (Active Support will not override the Ruby 1.9 implementation of this method.) [Sam Stephenson]
  • Add Proc#bind(object) for changing a proc or block‘s self by returning a Method bound to the given object. Based on why the lucky stiff‘s "cloaker" method. [Sam Stephenson]
  • Fix merge and dup for hashes with indifferent access 3404 [Ken Miller]
  • Fix the requires in option_merger_test to unbreak AS tests. [Sam Stephenson]
  • Make HashWithIndifferentAccess#update behave like Hash#update by returning the hash. 3419, 3425 [asnem@student.ethz.ch, JanPrill@blauton.de, Marcel Molina Jr.]
  • Add ActiveSupport::JSON and Object#to_json for converting Ruby objects to JSON strings. [Sam Stephenson]
  • Add Object#with_options for DRYing up multiple calls to methods having shared options. [Sam Stephenson] Example:

    ActionController::Routing::Routes.draw do |map|

      # Account routes
  map.with_options(:controller => 'account') do |account|
    account.home   '',       :action => 'dashboard'
    account.signup 'signup', :action => 'new'
    account.logout 'logout', :action => 'logout'
  end

    end

  • Introduce Dependencies.warnings_on_first_load setting. If true, enables warnings on first load of a require_dependency. Otherwise, loads without warnings. Disabled (set to false) by default. [Jeremy Kemper]
  • Active Support is warnings-safe. 1792 [Eric Hodel]
  • Introduce enable_warnings counterpart to silence_warnings. Turn warnings on when loading a file for the first time if Dependencies.mechanism == :load. Common mistakes such as redefined methods will print warnings to stderr. [Jeremy Kemper]
  • Add Symbol#to_proc, which allows for, e.g. [:foo, :bar].map(&:to_s). [Marcel Molina Jr.]
  • Added the following methods [Marcel Molina Jr., Sam Stephenson]:
    • Object#copy_instance_variables_from(object) to copy instance variables from one object to another
    • Object#extended_by to get an instance‘s included/extended modules
    • Object#extend_with_included_modules_from(object) to extend an instance with the modules from another instance

*1.2.5* (December 13th, 2005)

  • Become part of Rails 1.0
  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]

*1.2.3* (November 7th, 2005)

  • Change Inflector#constantize to use eval instead of const_get. [Nicholas Seckar]
  • Fix const_missing handler to ignore the trailing ’.rb’ on files when comparing paths. [Nicholas Seckar]
  • Define kernel.rb methods in "class Object" instead of "module Kernel" to work around a Windows peculiarity [Sam Stephenson]
  • Fix broken tests caused by incomplete loading of active support. [Nicholas Seckar]
  • Fix status pluralization bug so status_codes doesn‘t get pluralized as statuses_code. 2758 [keithm@infused.org]
  • Added Kernel#silence_stderr to silence stderr for the duration of the given block [Sam Stephenson]
  • Changed Kernel#` to print a message to stderr (like Unix) instead of raising Errno::ENOENT on Win32 [Sam Stephenson]
  • Changed 0.blank? to false rather than true since it violates everyone‘s expectation of blankness. 2518, 2705 [rails@jeffcole.net]
  • When loading classes using const_missing, raise a NameError if and only if the file we tried to load was not present. [Nicholas Seckar]
  • Added petabytes and exebytes to numeric extensions 2397 [timct@mac.com]
  • Added Time#end_of_month to accompany Time#beginning_of_month 2514 [Jens-Christian Fischer]

*1.2.2* (October 26th, 2005)

  • Set Logger.silencer = false to disable Logger#silence. Useful for debugging fixtures.
  • Add title case method to String to do, e.g., ‘action_web_service’.titlecase # => ‘Action Web Service’. [Marcel Molina Jr.]

*1.2.1* (October 19th, 2005)

  • Classify generated routing code as framework code to avoid appearing in application traces. [Nicholas Seckar]
  • Show all framework frames in the framework trace. [Nicholas Seckar]

*1.2.0* (October 16th, 2005)

  • Update Exception extension to show the first few framework frames in an application trace. [Nicholas Seckar]
  • Added Exception extension to provide support for clean backtraces. [Nicholas Seckar]
  • Updated whiny nil to be more concise and useful. [Nicholas Seckar]
  • Added Enumerable#first_match [Nicholas Seckar]
  • Fixed that Time#change should also reset usec when also resetting minutes 2459 [ikeda@dream.big.or.jp]
  • Fix Logger compatibility for distributions that don‘t keep Ruby and its standard library in sync.
  • Replace ’%e’ from long and short time formats as Windows does not support it. 2344. [Tom Ward <tom@popdog.net>]
  • Added to_s(:db) to Range, so you can get "BETWEEN ‘2005-12-10’ AND ‘2005-12-12’" from Date.new(2005, 12, 10)..Date.new(2005, 12, 12) (and likewise with Times)
  • Moved require_library_or_gem into Kernel. 1992 [Michael Schuerig <michael@schuerig.de>]
  • Add :rfc822 as an option for Time#to_s (to get rfc822-formatted times)
  • Chain the const_missing hook to any previously existing hook so rails can play nicely with rake
  • Clean logger is compatible with both 1.8.2 and 1.8.3 Logger. 2263 [Michael Schuerig <michael@schuerig.de>]
  • Added native, faster implementations of .blank? for the core types 2286 [skae]
  • Fixed clean logger to work with Ruby 1.8.3 Logger class 2245
  • Fixed memory leak with Active Record classes when Dependencies.mechanism = :load 1704 [Chris McGrath]
  • Fixed Inflector.underscore for use with acronyms, so HTML becomes html instead of htm_l 2173 [k@v2studio.com]
  • Fixed dependencies related infinite recursion bug when a controller file does not contain a controller class. Closes 1760. [rcolli2@tampabay.rr.com]
  • Fixed inflections for status, quiz, move 2056 [deirdre@deirdre.net]
  • Added Hash#reverse_merge, Hash#reverse_merge!, and Hash#reverse_update to ease the use of default options
  • Added Array#to_sentence that‘ll turn [‘one’, ‘two’, ‘three’] into "one, two, and three" 2157 [Manfred Stienstra]
  • Added Kernel#silence_warnings to turn off warnings temporarily for the passed block
  • Added String#starts_with? and String#ends_with? 2118 [Thijs van der Vossen]
  • Added easy extendability to the inflector through Inflector.inflections (using the Inflector::Inflections singleton class). Examples:
      Inflector.inflections do |inflect|
    inflect.plural /^(ox)$/i, '\1\2en'
    inflect.singular /^(ox)en/i, '\1'

    inflect.irregular 'octopus', 'octopi'

    inflect.uncountable "equipment"
  end
  • Added String#at, String#from, String#to, String#first, String#last in ActiveSupport::CoreExtensions::String::Access to ease access to individual characters and substrings in a string serving basically as human names for range access.
  • Make Time#last_month work when invoked on the 31st of a month.
  • Add Time.days_in_month, and make Time#next_month work when invoked on the 31st of a month
  • Fixed that Time#midnight would have a non-zero usec on some platforms 1836
  • Fixed inflections of "index/indices" 1766 [damn_pepe@gmail.com]
  • Added stripping of _id to String#humanize, so "employee_id" becomes "Employee" 1574 [Justin French]
  • Factor Fixnum and Bignum extensions into Integer extensions [Nicholas Seckar]
  • Hooked ordinalize into Fixnum and Bignum classes. [Nicholas Seckar, danp]
  • Added Fixnum#ordinalize to turn 1.ordinalize to "1st", 3.ordinalize to "3rd", and 10.ordinalize to "10th" and so on 1724 [paul@cnt.org]

*1.1.1* (11 July, 2005)

  • Added more efficient implementation of the development mode reset of classes 1638 [Chris McGrath]

*1.1.0* (6 July, 2005)

  • Fixed conflict with Glue gem 1606 [Rick Olson]
  • Added new rules to the Inflector to deal with more unusual plurals mouse/louse => mice/lice, information => information, ox => oxen, virus => viri, archive => archives 1571, 1583, 1490, 1599, 1608 [foamdino@gmail.com/others]
  • Fixed memory leak with Object#remove_subclasses_of, which inflicted a Rails application running in development mode with a ~20KB leak per request 1289 [Chris McGrath]
  • Made 1.year == 365.25.days to account for leap years. This allows you to do User.find(:all, :conditions => [‘birthday > ?’, 50.years.ago]) without losing a lot of days. 1488 [tuxie@dekadance.se]
  • Added an exception if calling id on nil to WhinyNil 584 [kevin-temp@writesoon.com]
  • Added Fix/Bignum#multiple_of? which returns true on 14.multiple_of?(7) and false on 16.multiple_of?(7) 1464 [Thomas Fuchs]
  • Added even? and odd? to work with Bignums in addition to Fixnums 1464 [Thomas Fuchs]
  • Fixed Time#at_beginning_of_week returned the next Monday instead of the previous one when called on a Sunday 1403 [jean.helou@gmail.com]
  • Increased the speed of indifferent hash access by using Hash#default. 1436 [Nicholas Seckar]
  • Added that " " is now also blank? (using strip if available)
  • Fixed Dependencies so all modules are able to load missing constants 1173 [Nicholas Seckar]
  • Fixed the Inflector to underscore strings containing numbers, so Area51Controller becomes area51_controller 1176 [Nicholas Seckar]
  • Fixed that HashWithIndifferentAccess stringified all keys including symbols, ints, objects, and arrays 1162 [Nicholas Seckar]
  • Fixed Time#last_year to go back in time, not forward 1278 [fabien@odilat.com]
  • Fixed the pluralization of analysis to analyses 1295 [seattle@rootimage.msu.edu]
  • Fixed that Time.local(2005,12).months_since(1) would raise "ArgumentError: argument out of range" 1311 [jhahn@niveon.com]
  • Added silencing to the default Logger class

*1.0.4* (19th April, 2005)

  • Fixed that in some circumstances controllers outside of modules may have hidden ones inside modules. For example, admin/content might have been hidden by /content. 1075 [Nicholas Seckar]
  • Fixed inflection of perspectives and similar words 1045 [Thijs van der Vossen]
  • Added Fixnum#even? and Fixnum#odd?
  • Fixed problem with classes being required twice. Object#const_missing now uses require_dependency to load files. It used to use require_or_load which would cause models to be loaded twice, which was not good for validations and other class methods 971 [Nicholas Seckar]

*1.0.3* (27th March, 2005)

  • Fixed Inflector.pluralize to handle capitalized words 932 [Jeremy Kemper]
  • Added Object#suppress which allows you to make a saner choice around with exceptions to swallow 980. Example:
      suppress(ZeroDivisionError) { 1/0 }

    …instead of:

      1/0 rescue nil # BAD, EVIL, DIRTY.

*1.0.2* (22th March, 2005)

  • Added Kernel#returning — a Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.
      def foo
    returning values = [] do
      values << 'bar'
      values << 'baz'
    end
  end

  foo # => ['bar', 'baz']

*1.0.1* (7th March, 2005)

  • Fixed Hash#indifferent_access to also deal with include? and fetch and nested hashes 726 [Nicholas Seckar]
  • Added Object#blank? — see redhanded.hobix.com/inspect/objectBlank.html 783 [_why the lucky stiff]
  • Added inflection rules for "sh" words, like "wish" and "fish" 755 [phillip@pjbsoftware.com]
  • Fixed an exception when using Ajax based requests from Safari because Safari appends a \000 to the post body. Symbols can‘t have \000 in them so indifferent access would throw an exception in the constructor. Indifferent hashes now use strings internally instead. 746 [Tobias Lütke]
  • Added String#to_time and String#to_date for wrapping ParseDate

*1.0.0* (24th February, 2005)

  • Added TimeZone as the first of a number of value objects that among others Active Record can use rich value objects using composed_of 688 [Jamis Buck]
  • Added Date::Conversions for getting dates in different convenient string representations and other objects
  • Added Time::Conversions for getting times in different convenient string representations and other objects
  • Added Time::Calculations to ask for things like Time.now.tomorrow, Time.now.yesterday, Time.now.months_ago(4) 580 [DP|Flurin]. Examples:
      "Later today"         => now.in(3.hours),
  "Tomorrow morning"    => now.tomorrow.change(:hour => 9),
  "Tomorrow afternoon"  => now.tomorrow.change(:hour => 14),
  "In a couple of days" => now.tomorrow.tomorrow.change(:hour => 9),
  "Next monday"         => now.next_week.change(:hour => 9),
  "In a month"          => now.next_month.change(:hour => 9),
  "In 6 months"         => now.months_since(6).change(:hour => 9),
  "In a year"           => now.in(1.year).change(:hour => 9)
  • Upgraded to breakpoint 92 which fixes:
      * overload IRB.parse_opts(), fixes #443
    => breakpoints in tests work even when running them via rake
  * untaint handlers, might fix an issue discussed on the Rails ML
  * added verbose mode to breakpoint_client
  * less noise caused by breakpoint_client by default
  * ignored TerminateLineInput exception in signal handler
    => quiet exit on Ctrl-C
  • Fixed Inflector for words like "news" and "series" that are the same in plural and singular 603 [echion], 615 [marcenuc]
  • Added Hash#stringify_keys and Hash#stringify_keys!
  • Added IndifferentAccess as a way to wrap a hash by a symbol-based store that also can be accessed by string keys
  • Added Inflector.constantize to turn "Admin::User" into a reference for the constant Admin::User
  • Added that Inflector.camelize and Inflector.underscore can deal with modules like turning "Admin::User" into "admin/user" and back
  • Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR.
  • Added availability of class inheritable attributes to the masses 477 [Jeremy Kemper]
      class Foo
    class_inheritable_reader :read_me
    class_inheritable_writer :write_me
    class_inheritable_accessor :read_and_write_me
    class_inheritable_array :read_and_concat_me
    class_inheritable_hash :read_and_update_me
  end

  # Bar gets a clone of (not a reference to) Foo's attributes.
  class Bar < Foo
  end

  Bar.read_and_write_me == Foo.read_and_write_me
  Bar.read_and_write_me = 'bar'
  Bar.read_and_write_me != Foo.read_and_write_me
  • Added Inflections as an extension on String, so Inflector.pluralize(Inflector.classify(name)) becomes name.classify.pluralize 476 [Jeremy Kemper]
  • Added Byte operations to Numeric, so 5.5.megabytes + 200.kilobytes 461 [Marcel Molina Jr.]
  • Fixed that Dependencies.reload can‘t load the same file twice 420 [Kent Sibilev]
  • Added Fixnum#ago/until, Fixnum#since/from_now 450 [Jeremy Kemper]
  • Added that Inflector now accepts Symbols and Classes by calling .to_s on the word supplied
  • Added time unit extensions to Fixnum that‘ll return the period in seconds, like 2.days + 4.hours.


File: README

README

Path: | vendor/rails/railties/README
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Welcome to Rails

Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Control pattern.

This pattern splits the view (also called the presentation) into "dumb" templates that are primarily responsible for inserting pre-built data in between HTML tags. The model contains the "smart" domain objects (such as Account, Product, Person, Post) that holds all the business logic and knows how to persist themselves to a database. The controller handles the incoming requests (such as Save New Account, Update Product, Show Post) by manipulating the model and directing data to the view.

In Rails, the model is handled by what‘s called an object-relational mapping layer entitled Active Record. This layer allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in files/vendor/rails/activerecord/README.html.

The controller and view are handled by the Action Pack, which handles both layers by its two parts: Action View and Action Controller. These two layers are bundled in a single package due to their heavy interdependence. This is unlike the relationship between the Active Record and Action Pack that is much more separate. Each of these packages can be used independently outside of Rails. You can read more about Action Pack in files/vendor/rails/actionpack/README.html.

Getting Started

  1. At the command prompt, start a new Rails application using the rails command and your application name. Ex: rails myapp
  2. Change directory into myapp and start the web server: script/server (run with —help for options)
  3. Go to localhost:3000/ and get "Welcome aboard: You‘re riding the Rails!"
  4. Follow the guidelines to start developing your application

Web Servers

By default, Rails will try to use Mongrel if it‘s are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails with a variety of other web servers.

Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is suitable for development and deployment of Rails applications. If you have Ruby Gems installed, getting up and running with mongrel is as easy as: gem install mongrel. More info at: mongrel.rubyforge.org

Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.

Apache .htaccess example for FCGI/CGI

# General Apache options AddHandler fastcgi-script .fcgi AddHandler cgi-script .cgi Options +FollowSymLinks +ExecCGI

# If you don‘t want Rails to look in certain directories, # use the following rewrite rules so that Apache won‘t rewrite certain requests # # Example: # RewriteCond %{REQUEST_URI} ^/notrails.* # RewriteRule .* - [L]

# Redirect all requests not available on the filesystem to Rails # By default the cgi dispatcher is used which is very slow # # For better performance replace the dispatcher with the fastcgi one # # Example: # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] RewriteEngine On

# If your Rails application is accessed via an Alias directive, # then you MUST also set the RewriteBase in this htaccess file. # # Example: # Alias /myrailsapp /path/to/myrailsapp/public # RewriteBase /myrailsapp

RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

# In case Rails experiences terminal errors # Instead of displaying this message you can supply a file here which will be rendered instead # # Example: # ErrorDocument 500 /500.html

ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"

Debugging Rails

Sometimes your application goes wrong. Fortunately there are a lot of tools that will help you debug it and get it back on the rails.

First area to check is the application log files. Have "tail -f" commands running on the server.log and development.log. Rails will automatically display debugging and runtime information to these files. Debugging info will also be shown in the browser on requests from 127.0.0.1.

You can also log your own messages directly into the log file from your code using the Ruby logger class from inside your controllers. Example:

  class WeblogController < ActionController::Base
    def destroy
      @weblog = Weblog.find(params[:id])
      @weblog.destroy
      logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
    end
  end

The result will be a message in your log file along the lines of:

  Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1

More information on how to use the logger is at www.ruby-doc.org/core/

Also, Ruby documentation can be found at www.ruby-lang.org/ including:

  • The Learning Ruby (Pickaxe) Book: www.ruby-doc.org/docs/ProgrammingRuby/
  • Learn to Program: pine.fm/LearnToProgram/ (a beginners guide)

These two online (and free) books will bring you up to speed on the Ruby language and also on programming in general.

Debugger

Debugger support is available through the debugger command when you start your Mongrel or Webrick server with —debugger. This means that you can break out of execution at any point in the code, investigate and change the model, AND then resume execution! You need to install ruby-debug to run the server in debugging mode. With gems, use ‘gem install ruby-debug’ Example:

  class WeblogController < ActionController::Base
    def index
      @posts = Post.find(:all)
      debugger
    end
  end

So the controller will accept the action, run the first line, then present you with a IRB prompt in the server window. Here you can do things like:

  >> @posts.inspect
  => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
       #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
  >> @posts.first.title = "hello from a debugger"
  => "hello from a debugger"

…and even better is that you can examine how your runtime objects actually work:

  >> f = @posts.first
  => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
  >> f.
  Display all 152 possibilities? (y or n)

Finally, when you‘re ready to resume execution, you enter "cont"

Console

You can interact with the domain model by starting the console through script/console. Here you‘ll have all parts of the application configured, just like it is when the application is running. You can inspect domain models, change values, and save to the database. Starting the script without arguments will launch it in the development environment. Passing an argument will specify a different environment, like script/console production.

To reload your controllers and models after launching the console run reload!

dbconsole

You can go to the command line of your database directly through script/dbconsole. You would be connected to the database with the credentials defined in database.yml. Starting the script without arguments will connect you to the development database. Passing an argument will connect you to a different database, like script/dbconsole production. Currently works for mysql, postgresql and sqlite.

Description of Contents

app

  Holds all the code that's specific to this particular application.

app/controllers

  Holds controllers that should be named like weblogs_controller.rb for
  automated URL mapping. All controllers should descend from ApplicationController
  which itself descends from ActionController::Base.

app/models

  Holds models that should be named like post.rb.
  Most models will descend from ActiveRecord::Base.

app/views

  Holds the template files for the view that should be named like
  weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
  syntax.

app/views/layouts

  Holds the template files for layouts to be used with views. This models the common
  header/footer method of wrapping views. In your views, define a layout using the
  <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
  call <% yield %> to render the view using this layout.

app/helpers

  Holds view helpers that should be named like weblogs_helper.rb. These are generated
  for you automatically when using script/generate for controllers. Helpers can be used to
  wrap functionality for your views into methods.

config

  Configuration files for the Rails environment, the routing map, the database, and other dependencies.

db

  Contains the database schema in schema.rb.  db/migrate contains all
  the sequence of Migrations for your schema.

doc

  This directory is where your application documentation will be stored when generated
  using <tt>rake doc:app</tt>

lib

  Application specific libraries. Basically, any kind of custom code that doesn't
  belong under controllers, models, or helpers. This directory is in the load path.

public

  The directory available for the web server. Contains subdirectories for images, stylesheets,
  and javascripts. Also contains the dispatchers and the default HTML files. This should be
  set as the DOCUMENT_ROOT of your web server.

script

  Helper scripts for automation and generation.

test

  Unit and functional tests along with fixtures. When using the script/generate scripts, template
  test files will be generated for you and placed in this directory.

vendor

  External libraries that the application depends on. Also includes the plugins subdirectory.
  If the app has frozen rails, those gems also go here, under vendor/rails/.
  This directory is in the load path.


Class: Rails::Configuration

Class | Rails::Configuration
In: | vendor/rails/railties/lib/initializer.rb
Parent: | Object

The Configuration class holds all the parameters for the Initializer and ships with defaults that suites most Rails applications. But it‘s possible to overwrite everything. Usually, you‘ll create an Configuration file implicitly through the block running on the Initializer, but it‘s also possible to create the Configuration instance in advance and pass it in like this:

  config = Rails::Configuration.new
  Rails::Initializer.run(:process, config)

Methods

after_initialize after_initialize_blocks breakpoint_server breakpoint_server= builtin_directories database_configuration environment environment_path framework_paths gem middleware new plugins= reload_plugins? set_root_path! threadsafe! to_prepare

Attributes

action_controller | [RW] | A stub for setting options on ActionController::Base.
action_mailer | [RW] | A stub for setting options on ActionMailer::Base.
action_view | [RW] | A stub for setting options on ActionView::Base.
active_record | [RW] | A stub for setting options on ActiveRecord::Base.
active_resource | [RW] | A stub for setting options on ActiveResource::Base.
active_support | [RW] | A stub for setting options on ActiveSupport.
cache_classes | [RW] | Whether or not classes should be cached (set to false if you want application classes to be reloaded on each request)
cache_store | [RW] | The specific cache store to use. By default, the ActiveSupport::Cache::Store will be used.
controller_paths | [RW] | The list of paths that should be searched for controllers. (Defaults to app/controllers.)
database_configuration_file | [RW] | The path to the database configuration file to use. (Defaults to config/database.yml.)
dependency_loading [RW] Enables or disables dependency loading during the request cycle. Setting dependency_loading to true will allow new classes to be loaded during a request. Setting it to false will disable this behavior.

Those who want to run in a threaded environment should disable this option and eager load or require all there classes on initialization.

If cache_classes is disabled, dependency loaded will always be on.

eager_load_paths | [RW] | An array of paths from which Rails will eager load on boot if cache classes is enabled. All elements of this array must also be in load_paths.
frameworks | [RW] | The list of rails framework components that should be loaded. (Defaults to :active_record, :action_controller, :action_view, :action_mailer, and :active_resource).
gems [RW] An array of gems that this rails application depends on. Rails will automatically load these gems during installation, and allow you to install any missing gems with:
  rake gems:install

You can add gems with the gem method.

i18n | [RW] | Accessor for i18n settings.
load_once_paths | [RW] | An array of paths from which Rails will automatically load from only once. All elements of this array must also be in load_paths.
load_paths | [RW] | An array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
log_level | [RW] | The log level to use for the default Rails logger. In production mode, this defaults to :info. In development mode, it defaults to :debug.
log_path | [RW] | The path to the log file to use. Defaults to log/#{environment}.log (e.g. log/development.log or log/production.log).
logger | [RW] | The specific logger to use. By default, a logger will be created and initialized using log_path and log_level, but a programmer may specifically set the logger to use via this accessor and it will be used directly.
metals | [RW] | The list of metals to load. If this is set to nil, all metals will be loaded in alphabetical order. If this is set to [], no metals will be loaded. Otherwise metals will be loaded in the order specified
plugin_loader | [RW] | The class that handles loading each plugin. Defaults to Rails::Plugin::Loader, but a sub class would have access to fine grained modification of the loading behavior. See the implementation of Rails::Plugin::Loader for more details.
plugin_locators | [RW] | The classes that handle finding the desired plugins that you‘d like to load for your application. By default it is the Rails::Plugin::FileSystemLocator which finds plugins to load in vendor/plugins. You can hook into gem location by subclassing Rails::Plugin::Locator and adding it onto the list of plugin_locators.
plugin_paths | [RW] | The path to the root of the plugins directory. By default, it is in vendor/plugins.
plugins | [R] | The list of plugins to load. If this is set to nil, all plugins will be loaded. If this is set to [], no plugins will be loaded. Otherwise, plugins will be loaded in the order specified.
preload_frameworks | [RW] | Whether to preload all frameworks at startup.
reload_plugins [RW] Enables or disables plugin reloading. You can get around this setting per plugin. If reload_plugins? is false, add this to your plugin‘s init.rb to make it reloadable:
  ActiveSupport::Dependencies.load_once_paths.delete lib_path

If reload_plugins? is true, add this to your plugin‘s init.rb to only load it once:

  ActiveSupport::Dependencies.load_once_paths << lib_path
root_path | [R] | The application‘s base directory.
routes_configuration_file | [RW] | The path to the routes configuration file to use. (Defaults to config/routes.rb.)
time_zone | [RW] | Sets the default time_zone. Setting this will enable time_zone awareness for Active Record models and set the Active Record default timezone to :utc.
view_path | [RW] | The root of the application‘s views. (Defaults to app/views.)
whiny_nils | [RW] | Set to true if you want to be warned (noisily) when you try to invoke any method of nil. Set to false for the standard Ruby behavior.

Public Class methods

new()

Create a new Configuration instance, initialized with the default values.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 815
815:     def initialize
816:       set_root_path!
817:
818:       self.frameworks                   = default_frameworks
819:       self.load_paths                   = default_load_paths
820:       self.load_once_paths              = default_load_once_paths
821:       self.eager_load_paths             = default_eager_load_paths
822:       self.log_path                     = default_log_path
823:       self.log_level                    = default_log_level
824:       self.view_path                    = default_view_path
825:       self.controller_paths             = default_controller_paths
826:       self.preload_frameworks           = default_preload_frameworks
827:       self.cache_classes                = default_cache_classes
828:       self.dependency_loading           = default_dependency_loading
829:       self.whiny_nils                   = default_whiny_nils
830:       self.plugins                      = default_plugins
831:       self.plugin_paths                 = default_plugin_paths
832:       self.plugin_locators              = default_plugin_locators
833:       self.plugin_loader                = default_plugin_loader
834:       self.database_configuration_file  = default_database_configuration_file
835:       self.routes_configuration_file    = default_routes_configuration_file
836:       self.gems                         = default_gems
837:       self.i18n                         = default_i18n
838:
839:       for framework in default_frameworks
840:         self.send("#{framework}=", Rails::OrderedOptions.new)
841:       end
842:       self.active_support = Rails::OrderedOptions.new
843:     end

Public Instance methods

after_initialize(&after_initialize_block)

Adds a block which will be executed after rails has been fully initialized. Useful for per-environment configuration which depends on the framework being fully initialized.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 900
900:     def after_initialize(&after_initialize_block)
901:       after_initialize_blocks << after_initialize_block if after_initialize_block
902:     end
after_initialize_blocks()

Returns the blocks added with Configuration#after_initialize

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 905
905:     def after_initialize_blocks
906:       @after_initialize_blocks ||= []
907:     end
breakpoint_server(_ = nil)

Deprecated options:

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 796
796:     def breakpoint_server(_ = nil)
797:       $stderr.puts %(
798:       *******************************************************************
799:       * config.breakpoint_server has been deprecated and has no effect. *
800:       *******************************************************************
801:       )
802:     end
breakpoint_server=(_ = nil)

Alias for breakpoint_server

builtin_directories()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 925
925:     def builtin_directories
926:       # Include builtins only in the development environment.
927:       (environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
928:     end
database_configuration()

Loads and returns the contents of the database_configuration_file. The contents of the file are processed via ERB before being sent through YAML::load.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 880
880:     def database_configuration
881:       require 'erb'
882:       YAML::load(ERB.new(IO.read(database_configuration_file)).result)
883:     end
environment()

Return the currently selected environment. By default, it returns the value of the RAILS_ENV constant.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 893
893:     def environment
894:       ::RAILS_ENV
895:     end
environment_path()

The path to the current environment‘s file (development.rb, etc.). By default the file is at config/environments/#{environment}.rb.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 887
887:     def environment_path
888:       "#{root_path}/config/environments/#{environment}.rb"
889:     end
framework_paths()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 930
930:     def framework_paths
931:       paths = %w(railties railties/lib activesupport/lib)
932:       paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view)
933:
934:       [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
935:         paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework)
936:       end
937:
938:       paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
939:     end
gem(name, options = {})

Adds a single Gem dependency to the rails application. By default, it will require the library with the same name as the gem. Use :lib to specify a different name.

  # gem 'aws-s3', '>= 0.4.0'
  # require 'aws/s3'
  config.gem 'aws-s3', :lib => 'aws/s3', :version => '>= 0.4.0',      #     :source => "http://code.whytheluckystiff.net"

To require a library be installed, but not attempt to load it, pass :lib => false

  config.gem 'qrp', :version => '0.4.1', :lib => false

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 791
791:     def gem(name, options = {})
792:       @gems << Rails::GemDependency.new(name, options)
793:     end
middleware()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 920
920:     def middleware
921:       require 'action_controller'
922:       ActionController::Dispatcher.middleware
923:     end
plugins=(plugins)

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 719
719:     def plugins=(plugins)
720:       @plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym }
721:     end
reload_plugins?()

Returns true if plugin reloading is enabled.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 757
757:     def reload_plugins?
758:       !!@reload_plugins
759:     end
set_root_path!()

Set the root_path to RAILS_ROOT and canonicalize it.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 846
846:     def set_root_path!
847:       raise 'RAILS_ROOT is not set' unless defined?(::RAILS_ROOT)
848:       raise 'RAILS_ROOT is not a directory' unless File.directory?(::RAILS_ROOT)
849:
850:       @root_path =
851:         # Pathname is incompatible with Windows, but Windows doesn't have
852:         # real symlinks so File.expand_path is safe.
853:         if RUBY_PLATFORM =~ /(:?mswin|mingw)/
854:           File.expand_path(::RAILS_ROOT)
855:
856:         # Otherwise use Pathname#realpath which respects symlinks.
857:         else
858:           Pathname.new(::RAILS_ROOT).realpath.to_s
859:         end
860:
861:       Object.const_set(:RELATIVE_RAILS_ROOT, ::RAILS_ROOT.dup) unless defined?(::RELATIVE_RAILS_ROOT)
862:       ::RAILS_ROOT.replace @root_path
863:     end
threadsafe!()

Enable threaded mode. Allows concurrent requests to controller actions and multiple database connections. Also disables automatic dependency loading after boot, and disables reloading code on every request, as these are fundamentally incompatible with thread safety.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 869
869:     def threadsafe!
870:       self.preload_frameworks = true
871:       self.cache_classes = true
872:       self.dependency_loading = false
873:       self.action_controller.allow_concurrency = true
874:       self
875:     end
to_prepare(&callback)

Add a preparation callback that will run before every request in development mode, or before the first request in production.

See Dispatcher#to_prepare.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 913
913:     def to_prepare(&callback)
914:       after_initialize do
915:         require 'dispatcher' unless defined?(::Dispatcher)
916:         Dispatcher.to_prepare(&callback)
917:       end
918:     end


Module: Rails::Generator

Module | Rails::Generator
In: | vendor/rails/railties/lib/rails_generator/base.rb vendor/rails/railties/lib/rails_generator/commands.rb vendor/rails/railties/lib/rails_generator/generated_attribute.rb vendor/rails/railties/lib/rails_generator/lookup.rb vendor/rails/railties/lib/rails_generator/manifest.rb vendor/rails/railties/lib/rails_generator/options.rb vendor/rails/railties/lib/rails_generator/scripts.rb vendor/rails/railties/lib/rails_generator/simple_logger.rb vendor/rails/railties/lib/rails_generator/spec.rb

Rails::Generator is a code generation platform tailored for the Rails web application framework. Generators are easily invoked within Rails applications to add and remove components such as models and controllers. New generators are easy to create and may be distributed as RubyGems, tarballs, or Rails plugins for inclusion system-wide, per-user, or per-application.

For actual examples see the rails_generator/generators directory in the Rails source (or the railties directory if you have frozen the Rails source in your application).

Generators may subclass other generators to provide variations that require little or no new logic but replace the template files.

For a RubyGem, put your generator class and templates in the lib directory. For a Rails plugin, make a generators directory at the root of your plugin.

The layout of generator files can be seen in the built-in controller generator:

  generators/
    components/
      controller/
        controller_generator.rb
        templates/
          controller.rb
          functional_test.rb
          helper.rb
          view.html.erb

The directory name (controller) matches the name of the generator file (controller_generator.rb) and class (ControllerGenerator). The files that will be copied or used as templates are stored in the templates directory.

The filenames of the templates don‘t matter, but choose something that will be self-explanatory since you will be referencing these in the manifest method inside your generator subclass.

Classes and Modules

Module Rails::Generator::Commands
Module Rails::Generator::Lookup
Module Rails::Generator::Options
Module Rails::Generator::Scripts
Class Rails::Generator::AbstractGemSource
Class Rails::Generator::Base
Class Rails::Generator::GemGeneratorSource
Class Rails::Generator::GemPathSource
Class Rails::Generator::GeneratedAttribute
Class Rails::Generator::GeneratorError
Class Rails::Generator::Manifest
Class Rails::Generator::NamedBase
Class Rails::Generator::PathSource
Class Rails::Generator::Source
Class Rails::Generator::Spec
Class Rails::Generator::UsageError


Class: Rails::Generator::AbstractGemSource

Class | Rails::Generator::AbstractGemSource
In: | vendor/rails/railties/lib/rails_generator/lookup.rb
Parent: | Source

Methods

new

Public Class methods

new()

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 201
201:       def initialize
202:         super :RubyGems
203:       end


Class: Rails::Generator::Base

Class | Rails::Generator::Base
In: | vendor/rails/railties/lib/rails_generator/base.rb
Parent: | Object

The base code generator is bare-bones. It sets up the source and destination paths and tells the logger whether to keep its trap shut.

It‘s useful for copying files such as stylesheets, images, or javascripts.

For more comprehensive template-based passive code generation with arguments, you‘ll want Rails::Generator::NamedBase.

Generators create a manifest of the actions they perform then hand the manifest to a command which replays the actions to do the heavy lifting (such as checking for existing files or creating directories if needed). Create, destroy, and list commands are included. Since a single manifest may be used by any command, creating new generators is as simple as writing some code templates and declaring what you‘d like to do with them.

The manifest method must be implemented by subclasses, returning a Rails::Generator::Manifest. The record method is provided as a convenience for manifest creation. Example:

  class StylesheetGenerator < Rails::Generator::Base
    def manifest
      record do |m|
        m.directory('public/stylesheets')
        m.file('application.css', 'public/stylesheets/application.css')
      end
    end
  end

See Rails::Generator::Commands::Create for a list of methods available to the manifest.

Methods

after_generate banner destination_path manifest new record source_path usage_message

Included Modules

Options

Attributes

args | [R]
destination_root | [R]
source_root | [R]

Public Class methods

new(runtime_args, runtime_options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 101
101:       def initialize(runtime_args, runtime_options = {})
102:         @args = runtime_args
103:         parse!(@args, runtime_options)
104:
105:         # Derive source and destination paths.
106:         @source_root = options[:source] || File.join(spec.path, 'templates')
107:         if options[:destination]
108:           @destination_root = options[:destination]
109:         elsif defined? ::RAILS_ROOT
110:           @destination_root = ::RAILS_ROOT
111:         end
112:
113:         # Silence the logger if requested.
114:         logger.quiet = options[:quiet]
115:
116:         # Raise usage error if help is requested.
117:         usage if options[:help]
118:       end

Public Instance methods

after_generate()

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 157
157:       def after_generate
158:       end
destination_path(relative_destination)

Return the full path from the destination root for the given path. Example for destination_root = ’/dest’:

  destination_path('some/path.rb') == '/dest/some/path.rb'

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 153
153:       def destination_path(relative_destination)
154:         File.join(destination_root, relative_destination)
155:       end
manifest()

Generators must provide a manifest. Use the record method to create a new manifest and record your generator‘s actions.

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 122
122:       def manifest
123:         raise NotImplementedError, "No manifest for '#{spec.name}' generator."
124:       end
source_path(relative_source)

Return the full path from the source root for the given path. Example for source_root = ’/source’:

  source_path('some/path.rb') == '/source/some/path.rb'

The given path may include a colon ’:’ character to indicate that the file belongs to another generator. This notation allows any generator to borrow files from another. Example:

  source_path('model:fixture.yml') = '/model/source/path/fixture.yml'

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 134
134:       def source_path(relative_source)
135:         # Check whether we're referring to another generator's file.
136:         name, path = relative_source.split(':', 2)
137:
138:         # If not, return the full path to our source file.
139:         if path.nil?
140:           File.join(source_root, name)
141:
142:         # Otherwise, ask our referral for the file.
143:         else
144:           # FIXME: this is broken, though almost always true.  Others'
145:           # source_root are not necessarily the templates dir.
146:           File.join(self.class.lookup(name).path, 'templates', path)
147:         end
148:       end

Protected Instance methods

banner()

Override with your own usage banner.

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 167
167:         def banner
168:           "Usage: #{$0} #{spec.name} [options]"
169:         end
record() {|m| ...}

Convenience method for generator subclasses to record a manifest.

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 162
162:         def record
163:           Rails::Generator::Manifest.new(self) { |m| yield m }
164:         end
usage_message()

Read USAGE from file in generator base path.

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 172
172:         def usage_message
173:           File.read(File.join(spec.path, 'USAGE')) rescue ''
174:         end


Module: Rails::Generator::Commands

Module | Rails::Generator::Commands
In: | vendor/rails/railties/lib/rails_generator/commands.rb

Methods

included instance

Classes and Modules

Class Rails::Generator::Commands::Base
Class Rails::Generator::Commands::Create
Class Rails::Generator::Commands::Destroy
Class Rails::Generator::Commands::List
Class Rails::Generator::Commands::RewindBase
Class Rails::Generator::Commands::Update

Public Class methods

included(base)

Even more convenient access to commands. Include Commands in the generator Base class to get a nice command instance method which returns a delegate for the requested command.

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 20
20:       def self.included(base)
21:         base.send(:define_method, :command) do |command|
22:           Commands.instance(command, self)
23:         end
24:       end
instance(command, generator)

Here‘s a convenient way to get a handle on generator commands. Command.instance(‘destroy’, my_generator) instantiates a Destroy delegate of my_generator ready to do your dirty work.

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 13
13:       def self.instance(command, generator)
14:         const_get(command.to_s.camelize).new(generator)
15:       end


Class: Rails::Generator::Commands::Base

Class | Rails::Generator::Commands::Base
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | DelegateClass(Rails::Generator::Base)

Generator commands delegate Rails::Generator::Base and implement a standard set of actions. Their behavior is defined by the way they respond to these actions: Create brings life; Destroy brings death; List passively observes.

Commands are invoked by replaying (or rewinding) the generator‘s manifest of actions. See Rails::Generator::Manifest and Rails::Generator::Base#manifest method that generator subclasses are required to override.

Commands allows generators to "plug in" invocation behavior, which corresponds to the GoF Strategy pattern.

Methods

class_collisions current_migration_number dependency existing_migrations gsub_file invoke! migration_directory migration_exists? next_migration_number next_migration_string readme

Public Instance methods

class_collisions(*class_names)

Does nothing for all commands except Create.

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 53
53:         def class_collisions(*class_names)
54:         end
dependency(generator_name, args, runtime_options = {})

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 46
46:         def dependency(generator_name, args, runtime_options = {})
47:           logger.dependency(generator_name) do
48:             self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke!
49:           end
50:         end
invoke!()

Replay action manifest. RewindBase subclass rewinds manifest.

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 41
41:         def invoke!
42:           manifest.replay(self)
43:           after_generate
44:         end
readme(*args)

Does nothing for all commands except Create.

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 57
57:         def readme(*args)
58:         end

Protected Instance methods

current_migration_number()

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 61
61:           def current_migration_number
62:             Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path|
63:               n = File.basename(file_path).split('_', 2).first.to_i
64:               if n > max then n else max end
65:             end
66:           end
existing_migrations(file_name)

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 76
76:           def existing_migrations(file_name)
77:             Dir.glob("#{@migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/)
78:           end
gsub_file(relative_destination, regexp, *args, &block)

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 92
92:           def gsub_file(relative_destination, regexp, *args, &block)
93:             path = destination_path(relative_destination)
94:             content = File.read(path).gsub(regexp, *args, &block)
95:             File.open(path, 'wb') { |file| file.write(content) }
96:           end
migration_directory(relative_path)

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 72
72:           def migration_directory(relative_path)
73:             directory(@migration_directory = relative_path)
74:           end
migration_exists?(file_name)

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 80
80:           def migration_exists?(file_name)
81:             not existing_migrations(file_name).empty?
82:           end
next_migration_number()

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 68
68:           def next_migration_number
69:             current_migration_number + 1
70:           end
next_migration_string(padding = 3)

[Source]

    # File vendor/rails/railties/lib/rails_generator/commands.rb, line 84
84:           def next_migration_string(padding = 3)
85:             if ActiveRecord::Base.timestamped_migrations
86:               Time.now.utc.strftime("%Y%m%d%H%M%S")
87:             else
88:               "%.#{padding}d" % next_migration_number
89:             end
90:           end


Class: Rails::Generator::Commands::Create

Class | Rails::Generator::Commands::Create
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | Base

Create is the premier generator command. It copies files, creates directories, renders templates, and more.

Methods

class_collisions complex_template directory file identical? migration_template readme route_resources template

Constants

SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/perl/webwn?s=%s"

Public Instance methods

class_collisions(*class_names)

Check whether the given class names are already taken by Ruby or Rails. In the future, expand to check other namespaces such as the rest of the user‘s app.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 173
173:         def class_collisions(*class_names)
174:           path = class_names.shift
175:           class_names.flatten.each do |class_name|
176:             # Convert to string to allow symbol arguments.
177:             class_name = class_name.to_s
178:
179:             # Skip empty strings.
180:             next if class_name.strip.empty?
181:
182:             # Split the class from its module nesting.
183:             nesting = class_name.split('::')
184:             name = nesting.pop
185:
186:             # Hack to limit const_defined? to non-inherited on 1.9.
187:             extra = []
188:             extra << false unless Object.method(:const_defined?).arity == 1
189:
190:             # Extract the last Module in the nesting.
191:             last = nesting.inject(Object) { |last, nest|
192:               break unless last.const_defined?(nest, *extra)
193:               last.const_get(nest)
194:             }
195:
196:             # If the last Module exists, check whether the given
197:             # class exists and raise a collision if so.
198:             if last and last.const_defined?(name.camelize, *extra)
199:               raise_class_collision(class_name)
200:             end
201:           end
202:         end
complex_template(relative_source, relative_destination, template_options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 310
310:         def complex_template(relative_source, relative_destination, template_options = {})
311:           options = template_options.dup
312:           options[:assigns] ||= {}
313:           options[:assigns]['template_for_inclusion'] = render_template_part(template_options)
314:           template(relative_source, relative_destination, options)
315:         end
directory(relative_path)

Create a directory including any missing parent directories. Always skips directories which exist.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 319
319:         def directory(relative_path)
320:           path = destination_path(relative_path)
321:           if File.exist?(path)
322:             logger.exists relative_path
323:           else
324:             logger.create relative_path
325:             unless options[:pretend]
326:               FileUtils.mkdir_p(path)
327:               # git doesn't require adding the paths, adding the files later will
328:               # automatically do a path add.
329:
330:               # Subversion doesn't do path adds, so we need to add
331:               # each directory individually.
332:               # So stack up the directory tree and add the paths to
333:               # subversion in order without recursion.
334:               if options[:svn]
335:                 stack = [relative_path]
336:                 until File.dirname(stack.last) == stack.last # dirname('.') == '.'
337:                   stack.push File.dirname(stack.last)
338:                 end
339:                 stack.reverse_each do |rel_path|
340:                   svn_path = destination_path(rel_path)
341:                   system("svn add -N #{svn_path}") unless File.directory?(File.join(svn_path, '.svn'))
342:                 end
343:               end
344:             end
345:           end
346:         end
file(relative_source, relative_destination, file_options = {}, &block)

Copy a file from source to destination with collision checking.

The file_options hash accepts :chmod and :shebang and :collision options. :chmod sets the permissions of the destination file:

  file 'config/empty.log', 'log/test.log', :chmod => 0664

:shebang sets the #!/usr/bin/ruby line for scripts

  file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'

:collision sets the collision option only for the destination file:

  file 'settings/server.yml', 'config/server.yml', :collision => :skip

Collisions are handled by checking whether the destination file exists and either skipping the file, forcing overwrite, or asking the user what to do.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 217
217:         def file(relative_source, relative_destination, file_options = {}, &block)
218:           # Determine full paths for source and destination files.
219:           source              = source_path(relative_source)
220:           destination         = destination_path(relative_destination)
221:           destination_exists  = File.exist?(destination)
222:
223:           # If source and destination are identical then we're done.
224:           if destination_exists and identical?(source, destination, &block)
225:             return logger.identical(relative_destination)
226:           end
227:
228:           # Check for and resolve file collisions.
229:           if destination_exists
230:
231:             # Make a choice whether to overwrite the file.  :force and
232:             # :skip already have their mind made up, but give :ask a shot.
233:             choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask
234:               when :ask   then force_file_collision?(relative_destination, source, destination, file_options, &block)
235:               when :force then :force
236:               when :skip  then :skip
237:               else raise "Invalid collision option: #{options[:collision].inspect}"
238:             end
239:
240:             # Take action based on our choice.  Bail out if we chose to
241:             # skip the file; otherwise, log our transgression and continue.
242:             case choice
243:               when :force then logger.force(relative_destination)
244:               when :skip  then return(logger.skip(relative_destination))
245:               else raise "Invalid collision choice: #{choice}.inspect"
246:             end
247:
248:           # File doesn't exist so log its unbesmirched creation.
249:           else
250:             logger.create relative_destination
251:           end
252:
253:           # If we're pretending, back off now.
254:           return if options[:pretend]
255:
256:           # Write destination file with optional shebang.  Yield for content
257:           # if block given so templaters may render the source file.  If a
258:           # shebang is requested, replace the existing shebang or insert a
259:           # new one.
260:           File.open(destination, 'wb') do |dest|
261:             dest.write render_file(source, file_options, &block)
262:           end
263:
264:           # Optionally change permissions.
265:           if file_options[:chmod]
266:             FileUtils.chmod(file_options[:chmod], destination)
267:           end
268:
269:           # Optionally add file to subversion or git
270:           system("svn add #{destination}") if options[:svn]
271:           system("git add -v #{relative_destination}") if options[:git]
272:         end
identical?(source, destination) {|sf| ...}

Checks if the source and the destination file are identical. If passed a block then the source file is a template that needs to first be evaluated before being compared to the destination.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 277
277:         def identical?(source, destination, &block)
278:           return false if File.directory? destination
279:           source      = block_given? ? File.open(source) {|sf| yield(sf)} : IO.read(source)
280:           destination = IO.read(destination)
281:           source == destination
282:         end
migration_template(relative_source, relative_destination, template_options = {})

When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 357
357:         def migration_template(relative_source, relative_destination, template_options = {})
358:           migration_directory relative_destination
359:           migration_file_name = template_options[:migration_file_name] || file_name
360:           raise "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name)
361:           template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
362:         end
readme(*relative_sources)

Display a README.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 349
349:         def readme(*relative_sources)
350:           relative_sources.flatten.each do |relative_source|
351:             logger.readme relative_source
352:             puts File.read(source_path(relative_source)) unless options[:pretend]
353:           end
354:         end
route_resources(*resources)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 364
364:         def route_resources(*resources)
365:           resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
366:           sentinel = 'ActionController::Routing::Routes.draw do |map|'
367:
368:           logger.route "map.resources #{resource_list}"
369:           unless options[:pretend]
370:             gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
371:               "#{match}\n  map.resources #{resource_list}\n"
372:             end
373:           end
374:         end
template(relative_source, relative_destination, template_options = {})

Generate a file for a Rails application using an ERuby template. Looks up and evaluates a template by name and writes the result.

The ERB template uses explicit trim mode to best control the proliferation of whitespace in generated code. <%- trims leading whitespace; -%> trims trailing whitespace including one newline.

A hash of template options may be passed as the last argument. The options accepted by the file are accepted as well as :assigns, a hash of variable bindings. Example:

  template 'foo', 'bar', :assigns => { :action => 'view' }

Template is implemented in terms of file. It calls file with a block which takes a file handle and returns its rendered contents.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 298
298:         def template(relative_source, relative_destination, template_options = {})
299:           file(relative_source, relative_destination, template_options) do |file|
300:             # Evaluate any assignments in a temporary, throwaway binding.
301:             vars = template_options[:assigns] || {}
302:             b = template_options[:binding] || binding
303:             vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
304:
305:             # Render the source file with the temporary binding.
306:             ERB.new(file.read, nil, '-').result(b)
307:           end
308:         end


Class: Rails::Generator::Commands::Destroy

Class | Rails::Generator::Commands::Destroy
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | RewindBase

Undo the actions performed by a generator. Rewind the action manifest and attempt to completely erase the results of each action.

Methods

complex_template directory file migration_template route_resources template

Public Instance methods

complex_template(*args)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 514
514:         def complex_template(*args)
515:           # nothing should be done here
516:         end
directory(relative_path)

Remove each directory in the given path from right to left. Remove each subdirectory if it exists and is a directory.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 478
478:         def directory(relative_path)
479:           parts = relative_path.split('/')
480:           until parts.empty?
481:             partial = File.join(parts)
482:             path = destination_path(partial)
483:             if File.exist?(path)
484:               if Dir[File.join(path, '*')].empty?
485:                 logger.rmdir partial
486:                 unless options[:pretend]
487:                   if options[:svn]
488:                     # If the directory has been marked to be added
489:                     # but has not yet been checked in, revert and delete
490:                     if options[:svn][relative_path]
491:                       system("svn revert #{path}")
492:                       FileUtils.rmdir(path)
493:                     else
494:                     # If the directory is not in the status list, it
495:                     # has no modifications so we can simply remove it
496:                       system("svn rm #{path}")
497:                     end
498:                   # I don't think git needs to remove directories?..
499:                   # or maybe they have special consideration...
500:                   else
501:                     FileUtils.rmdir(path)
502:                   end
503:                 end
504:               else
505:                 logger.notempty partial
506:               end
507:             else
508:               logger.missing partial
509:             end
510:             parts.pop
511:           end
512:         end
file(relative_source, relative_destination, file_options = {})

Remove a file if it exists and is a file.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 433
433:         def file(relative_source, relative_destination, file_options = {})
434:           destination = destination_path(relative_destination)
435:           if File.exist?(destination)
436:             logger.rm relative_destination
437:             unless options[:pretend]
438:               if options[:svn]
439:                 # If the file has been marked to be added
440:                 # but has not yet been checked in, revert and delete
441:                 if options[:svn][relative_destination]
442:                   system("svn revert #{destination}")
443:                   FileUtils.rm(destination)
444:                 else
445:                 # If the directory is not in the status list, it
446:                 # has no modifications so we can simply remove it
447:                   system("svn rm #{destination}")
448:                 end
449:               elsif options[:git]
450:                 if options[:git][:new][relative_destination]
451:                   # file has been added, but not committed
452:                   system("git reset HEAD #{relative_destination}")
453:                   FileUtils.rm(destination)
454:                 elsif options[:git][:modified][relative_destination]
455:                   # file is committed and modified
456:                   system("git rm -f #{relative_destination}")
457:                 else
458:                   # If the directory is not in the status list, it
459:                   # has no modifications so we can simply remove it
460:                   system("git rm #{relative_destination}")
461:                 end
462:               else
463:                 FileUtils.rm(destination)
464:               end
465:             end
466:           else
467:             logger.missing relative_destination
468:             return
469:           end
470:         end
migration_template(relative_source, relative_destination, template_options = {})

When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}".

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 519
519:         def migration_template(relative_source, relative_destination, template_options = {})
520:           migration_directory relative_destination
521:
522:           migration_file_name = template_options[:migration_file_name] || file_name
523:           unless migration_exists?(migration_file_name)
524:             puts "There is no migration named #{migration_file_name}"
525:             return
526:           end
527:
528:
529:           existing_migrations(migration_file_name).each do |file_path|
530:             file(relative_source, file_path, template_options)
531:           end
532:         end
route_resources(*resources)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 534
534:         def route_resources(*resources)
535:           resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
536:           look_for = "\n  map.resources #{resource_list}\n"
537:           logger.route "map.resources #{resource_list}"
538:           gsub_file 'config/routes.rb', /(#{look_for})/mi, ''
539:         end
template(relative_source, relative_destination, file_options = {})

Alias for file


Class: Rails::Generator::Commands::List

Class | Rails::Generator::Commands::List
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | Base

List a generator‘s action manifest.

Methods

class_collisions complex_template dependency directory file migration_template readme route_resources template

Public Instance methods

class_collisions(*class_names)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 549
549:         def class_collisions(*class_names)
550:           logger.class_collisions class_names.join(', ')
551:         end
complex_template(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 561
561:         def complex_template(relative_source, relative_destination, options = {})
562:           logger.template "#{options[:insert]} inside #{relative_destination}"
563:         end
dependency(generator_name, args, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 545
545:         def dependency(generator_name, args, options = {})
546:           logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})"
547:         end
directory(relative_path)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 565
565:         def directory(relative_path)
566:           logger.directory "#{destination_path(relative_path)}/"
567:         end
file(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 553
553:         def file(relative_source, relative_destination, options = {})
554:           logger.file relative_destination
555:         end
migration_template(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 573
573:         def migration_template(relative_source, relative_destination, options = {})
574:           migration_directory relative_destination
575:           logger.migration_template file_name
576:         end
readme(*args)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 569
569:         def readme(*args)
570:           logger.readme args.join(', ')
571:         end
route_resources(*resources)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 578
578:         def route_resources(*resources)
579:           resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
580:           logger.route "map.resources #{resource_list}"
581:         end
template(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 557
557:         def template(relative_source, relative_destination, options = {})
558:           logger.template relative_destination
559:         end


Class: Rails::Generator::Commands::RewindBase

Class | Rails::Generator::Commands::RewindBase
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | Base

Base class for commands which handle generator actions in reverse, such as Destroy.

Methods

invoke!

Public Instance methods

invoke!()

Rewind action manifest.

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 160
160:         def invoke!
161:           manifest.rewind(self)
162:         end


Class: Rails::Generator::Commands::Update

Class | Rails::Generator::Commands::Update
In: | vendor/rails/railties/lib/rails_generator/commands.rb
Parent: | Create

Update generator‘s action manifest.

Methods

complex_template directory file template

Public Instance methods

complex_template(relative_source, relative_destination, template_options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 594
594:         def complex_template(relative_source, relative_destination, template_options = {})
595:
596:            begin
597:              dest_file = destination_path(relative_destination)
598:              source_to_update = File.readlines(dest_file).join
599:            rescue Errno::ENOENT
600:              logger.missing relative_destination
601:              return
602:            end
603:
604:            logger.refreshing "#{template_options[:insert].gsub(/\.erb/,'')} inside #{relative_destination}"
605:
606:            begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id]))
607:            end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id]))
608:
609:            # Refreshing inner part of the template with freshly rendered part.
610:            rendered_part = render_template_part(template_options)
611:            source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part)
612:
613:            File.open(dest_file, 'w') { |file| file.write(source_to_update) }
614:         end
directory(relative_path)

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 616
616:         def directory(relative_path)
617:           # logger.directory "#{destination_path(relative_path)}/"
618:         end
file(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 586
586:         def file(relative_source, relative_destination, options = {})
587:           # logger.file relative_destination
588:         end
template(relative_source, relative_destination, options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/commands.rb, line 590
590:         def template(relative_source, relative_destination, options = {})
591:           # logger.template relative_destination
592:         end


Class: Rails::Generator::GemGeneratorSource

Class | Rails::Generator::GemGeneratorSource
In: | vendor/rails/railties/lib/rails_generator/lookup.rb
Parent: | AbstractGemSource

GemGeneratorSource hits the mines to quarry for generators. The latest versions of gems named *_generator are selected.

Methods

each

Public Instance methods

each() {|Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label)| ...}

Yield latest versions of generator gems.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 210
210:       def each
211:         dependency = Gem::Dependency.new(/_generator$/, Gem::Requirement.default)
212:         Gem::cache.search(dependency).inject({}) { |latest, gem|
213:           hem = latest[gem.name]
214:           latest[gem.name] = gem if hem.nil? or gem.version > hem.version
215:           latest
216:         }.values.each { |gem|
217:           yield Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label)
218:         }
219:       end


Class: Rails::Generator::GemPathSource

Class | Rails::Generator::GemPathSource
In: | vendor/rails/railties/lib/rails_generator/lookup.rb
Parent: | AbstractGemSource

GemPathSource looks for generators within any RubyGem‘s /rails_generators/<generator_name>_generator.rb file.

Methods

each

Public Instance methods

each() {|Spec.new(File.basename(generator).sub(/_generator.rb$/, ''), File.dirname(generator), label)| ...}

Yield each generator within rails_generator subdirectories.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 225
225:       def each
226:         generator_full_paths.each do |generator|
227:           yield Spec.new(File.basename(generator).sub(/_generator.rb$/, ''), File.dirname(generator), label)
228:         end
229:       end


Class: Rails::Generator::GeneratedAttribute

Class | Rails::Generator::GeneratedAttribute
In: | vendor/rails/railties/lib/rails_generator/generated_attribute.rb
Parent: | Object

Methods

default field_type new reference?

Attributes

column | [RW]
name | [RW]
type | [RW]

Public Class methods

new(name, type)

[Source]

    # File vendor/rails/railties/lib/rails_generator/generated_attribute.rb, line 8
 8:       def initialize(name, type)
 9:         @name, @type = name, type.to_sym
10:         @column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type)
11:       end

Public Instance methods

default()

[Source]

    # File vendor/rails/railties/lib/rails_generator/generated_attribute.rb, line 26
26:       def default
27:         @default ||= case type
28:           when :integer                     then 1
29:           when :float                       then 1.5
30:           when :decimal                     then "9.99"
31:           when :datetime, :timestamp, :time then Time.now.to_s(:db)
32:           when :date                        then Date.today.to_s(:db)
33:           when :string                      then "MyString"
34:           when :text                        then "MyText"
35:           when :boolean                     then false
36:           else
37:             ""
38:         end
39:       end
field_type()

[Source]

    # File vendor/rails/railties/lib/rails_generator/generated_attribute.rb, line 13
13:       def field_type
14:         @field_type ||= case type
15:           when :integer, :float, :decimal   then :text_field
16:           when :datetime, :timestamp, :time then :datetime_select
17:           when :date                        then :date_select
18:           when :string                      then :text_field
19:           when :text                        then :text_area
20:           when :boolean                     then :check_box
21:           else
22:             :text_field
23:         end
24:       end
reference?()

[Source]

    # File vendor/rails/railties/lib/rails_generator/generated_attribute.rb, line 41
41:       def reference?
42:         [ :references, :belongs_to ].include?(self.type)
43:       end


Class: Rails::Generator::GeneratorError

Class | Rails::Generator::GeneratorError
In: | vendor/rails/railties/lib/rails_generator/base.rb
Parent: | StandardError


Module: Rails::Generator::Lookup

Module | Rails::Generator::Lookup
In: | vendor/rails/railties/lib/rails_generator/lookup.rb

Generator lookup is managed by a list of sources which return specs describing where to find and how to create generators. This module provides class methods for manipulating the source list and looking up generator specs, and an instance wrapper for quickly instantiating generators by name.

A spec is not a generator: it‘s a description of where to find the generator and how to create it. A source is anything that yields generators from each. PathSource and GemGeneratorSource are provided.

Methods

included instance

Classes and Modules

Module Rails::Generator::Lookup::ClassMethods

Public Class methods

included(base)

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 53
53:       def self.included(base)
54:         base.extend(ClassMethods)
55:         base.use_component_sources!
56:       end

Public Instance methods

instance(generator_name, args, runtime_options = {})

Convenience method to instantiate another generator.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 59
59:       def instance(generator_name, args, runtime_options = {})
60:         self.class.instance(generator_name, args, runtime_options)
61:       end


Module: Rails::Generator::Lookup::ClassMethods

Module | Rails::Generator::Lookup::ClassMethods
In: | vendor/rails/railties/lib/rails_generator/lookup.rb

Methods

append_sources instance lookup prepend_sources reset_sources sources use_application_sources! use_component_sources!

Public Instance methods

append_sources(*args)

Add a source to the end of the list.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 70
70:         def append_sources(*args)
71:           sources.concat(args.flatten)
72:           invalidate_cache!
73:         end
instance(generator_name, args = [], runtime_options = {})

Convenience method to lookup and instantiate a generator.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 139
139:         def instance(generator_name, args = [], runtime_options = {})
140:           lookup(generator_name).klass.new(args, full_options(runtime_options))
141:         end
lookup(generator_name)

Lookup knows how to find generators’ Specs from a list of Sources. Searches the sources, in order, for the first matching name.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 124
124:         def lookup(generator_name)
125:           @found ||= {}
126:           generator_name = generator_name.to_s.downcase
127:           @found[generator_name] ||= cache.find { |spec| spec.name == generator_name }
128:           unless @found[generator_name]
129:             chars = generator_name.scan(/./).map{|c|"#{c}.*?"}
130:             rx = /^#{chars}$/
131:             gns = cache.select{|spec| spec.name =~ rx }
132:             @found[generator_name] ||= gns.first if gns.length == 1
133:             raise GeneratorError, "Pattern '#{generator_name}' matches more than one generator: #{gns.map{|sp|sp.name}.join(', ')}" if gns.length > 1
134:           end
135:           @found[generator_name] or raise GeneratorError, "Couldn't find '#{generator_name}' generator"
136:         end
prepend_sources(*args)

Add a source to the beginning of the list.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 76
76:         def prepend_sources(*args)
77:           write_inheritable_array(:sources, args.flatten + sources)
78:           invalidate_cache!
79:         end
reset_sources()

Reset the source list.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 82
82:         def reset_sources
83:           write_inheritable_attribute(:sources, [])
84:           invalidate_cache!
85:         end
sources()

The list of sources where we look, in order, for generators.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 65
65:         def sources
66:           read_inheritable_attribute(:sources) or use_component_sources!
67:         end
use_application_sources!()

Use application generators (app, ?).

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 88
88:         def use_application_sources!
89:           reset_sources
90:           sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/applications")
91:         end
use_component_sources!()

Use component generators (model, controller, etc).

  1. Rails application. If RAILS_ROOT is defined we know we‘re generating in the context of a Rails application, so search RAILS_ROOT/generators.
  2. Look in plugins, either for generators/ or rails_generators/ directories within each plugin
  3. User home directory. Search ~/.rails/generators.
  4. RubyGems. Search for gems named *_generator, and look for generators within any RubyGem‘s /rails_generators/<generator_name>_generator.rb file.
  5. Builtins. Model, controller, mailer, scaffold, and so on.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 104
104:         def use_component_sources!
105:           reset_sources
106:           if defined? ::RAILS_ROOT
107:             sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators")
108:             sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators")
109:             Rails.configuration.plugin_paths.each do |path|
110:               relative_path = Pathname.new(File.expand_path(path)).relative_path_from(Pathname.new(::RAILS_ROOT))
111:               sources << PathSource.new("plugins (#{relative_path})""plugins (#{relative_path})", "#{path}/*/**/{,rails_}generators")
112:             end
113:           end
114:           sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
115:           if Object.const_defined?(:Gem)
116:             sources << GemGeneratorSource.new
117:             sources << GemPathSource.new
118:           end
119:           sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components")
120:         end


Class: Rails::Generator::Manifest

Class | Rails::Generator::Manifest
In: | vendor/rails/railties/lib/rails_generator/manifest.rb
Parent: | Object

Manifest captures the actions a generator performs. Instantiate a manifest with an optional target object, hammer it with actions, then replay or rewind on the object of your choice.

Example:

  manifest = Manifest.new { |m|
    m.make_directory '/foo'
    m.create_file '/foo/bar.txt'
  }
  manifest.replay(creator)
  manifest.rewind(destroyer)

Methods

erase method_missing new replay rewind

Attributes

target [R]

Public Class methods

new(target = nil) {|self if block_given?| ...}

Take a default action target. Yield self if block given.

[Source]

    # File vendor/rails/railties/lib/rails_generator/manifest.rb, line 19
19:       def initialize(target = nil)
20:         @target, @actions = target, []
21:         yield self if block_given?
22:       end

Public Instance methods

erase()

Erase recorded actions.

[Source]

    # File vendor/rails/railties/lib/rails_generator/manifest.rb, line 40
40:       def erase
41:         @actions = []
42:       end
method_missing(action, *args, &block)

Record an action.

[Source]

    # File vendor/rails/railties/lib/rails_generator/manifest.rb, line 25
25:       def method_missing(action, *args, &block)
26:         @actions << [action, args, block]
27:       end
replay(target = nil)

Replay recorded actions.

[Source]

    # File vendor/rails/railties/lib/rails_generator/manifest.rb, line 30
30:       def replay(target = nil)
31:         send_actions(target || @target, @actions)
32:       end
rewind(target = nil)

Rewind recorded actions.

[Source]

    # File vendor/rails/railties/lib/rails_generator/manifest.rb, line 35
35:       def rewind(target = nil)
36:         send_actions(target || @target, @actions.reverse)
37:       end


Class: Rails::Generator::NamedBase

Class | Rails::Generator::NamedBase
In: | vendor/rails/railties/lib/rails_generator/base.rb
Parent: | Base

The base generator for named components: models, controllers, mailers, etc. The target name is taken as the first argument and inflected to singular, plural, class, file, and table forms for your convenience. The remaining arguments are aliased to actions as an array for controller and mailer convenience.

Several useful local variables and methods are populated in the initialize method. See below for a list of Attributes and External Aliases available to both the manifest and to all templates.

If no name is provided, the generator raises a usage error with content optionally read from the USAGE file in the generator‘s base path.

For example, the controller generator takes the first argument as the name of the class and subsequent arguments as the names of actions to be generated:

  ./script/generate controller Article index new create

See Rails::Generator::Base for a discussion of manifests, Rails::Generator::Commands::Create for methods available to the manifest, and Rails::Generator for a general discussion of generators.

Methods

attributes banner new

External Aliases

singular_name | -> | file_name
args | -> | actions

Attributes

class_name | [R]
class_nesting | [R]
class_nesting_depth | [R]
class_path | [R]
file_path | [R]
name | [R]
plural_name | [R]
singular_name | [R]
table_name | [R]

Public Class methods

new(runtime_args, runtime_options = {})

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 206
206:       def initialize(runtime_args, runtime_options = {})
207:         super
208:
209:         # Name argument is required.
210:         usage if runtime_args.empty?
211:
212:         @args = runtime_args.dup
213:         base_name = @args.shift
214:         assign_names!(base_name)
215:       end

Protected Instance methods

attributes()

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 223
223:         def attributes
224:           @attributes ||= @args.collect do |attribute|
225:             Rails::Generator::GeneratedAttribute.new(*attribute.split(":"))
226:           end
227:         end
banner()

Override with your own usage banner.

[Source]

     # File vendor/rails/railties/lib/rails_generator/base.rb, line 219
219:         def banner
220:           "Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]"
221:         end


Module: Rails::Generator::Options

Module | Rails::Generator::Options
In: | vendor/rails/railties/lib/rails_generator/options.rb

Methods

add_general_options! add_options! banner default_options full_options included mandatory_options options parse! usage usage_message

Classes and Modules

Module Rails::Generator::Options::ClassMethods

Attributes

options [W]

Public Class methods

included(base)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 6
 6:       def self.included(base)
 7:         base.extend(ClassMethods)
 8:         class << base
 9:           if respond_to?(:inherited)
10:             alias_method :inherited_without_options, :inherited
11:           end
12:           alias_method :inherited, :inherited_with_options
13:         end
14:       end

Public Instance methods

options()

Each instance has an options hash that‘s populated by parse.

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 49
49:       def options
50:         @options ||= {}
51:       end

Protected Instance methods

add_general_options!(opt)

Adds general options like -h and —quiet. Usually don‘t override.

[Source]

     # File vendor/rails/railties/lib/rails_generator/options.rb, line 119
119:         def add_general_options!(opt)
120:           opt.separator ''
121:           opt.separator 'Rails Info:'
122:           opt.on('-v', '--version', 'Show the Rails version number and quit.')
123:           opt.on('-h', '--help', 'Show this help message and quit.') { |v| options[:help] = v }
124:
125:           opt.separator ''
126:           opt.separator 'General Options:'
127:
128:           opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v }
129:           opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
130:           opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
131:           opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v }
132:           opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v }
133:           opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do
134:             options[:svn] = `svn status`.inject({}) do |opt, e|
135:               opt[e.chomp[7..-1]] = true
136:               opt
137:             end
138:           end
139:           opt.on('-g', '--git', 'Modify files with git. (Note: git must be in path)') do
140:             options[:git] = `git status`.inject({:new => {}, :modified => {}}) do |opt, e|
141:               opt[:new][e.chomp[14..-1]] = true if e =~ /new file:/
142:               opt[:modified][e.chomp[14..-1]] = true if e =~ /modified:/
143:               opt
144:             end
145:           end
146:         end
add_options!(opt)

Override to add your options to the parser:

  def add_options!(opt)
    opt.on('-v', '--verbose') { |value| options[:verbose] = value }
  end

[Source]

     # File vendor/rails/railties/lib/rails_generator/options.rb, line 115
115:         def add_options!(opt)
116:         end
banner()

Override with your own usage banner.

[Source]

     # File vendor/rails/railties/lib/rails_generator/options.rb, line 107
107:         def banner
108:           "Usage: #{$0} [options]"
109:         end
default_options()

Convenient access to class default options.

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 61
61:         def default_options
62:           self.class.default_options
63:         end
full_options(runtime_options = {})

Merge together our instance options. In increasing precedence:

  default_options   (class default options)
  options           (instance options)
  runtime_options   (provided as argument)
  mandatory_options (class mandatory options)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 70
70:         def full_options(runtime_options = {})
71:           self.class.full_options(options.merge(runtime_options))
72:         end
mandatory_options()

Convenient access to class mandatory options.

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 56
56:         def mandatory_options
57:           self.class.mandatory_options
58:         end
parse!(args, runtime_options = {})

Parse arguments into the options hash. Classes may customize parsing behavior by overriding these methods:

  #banner                 Usage: ./script/generate [options]
  #add_options!           Options:
                            some options..
  #add_general_options!   General Options:
                            general options..

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 81
81:         def parse!(args, runtime_options = {})
82:           self.options = {}
83:
84:           @option_parser = OptionParser.new do |opt|
85:             opt.banner = banner
86:             add_options!(opt)
87:             add_general_options!(opt)
88:             opt.parse!(args)
89:           end
90:
91:           return args
92:         ensure
93:           self.options = full_options(runtime_options)
94:         end
usage(message = usage_message)

Raise a usage error. Override usage_message to provide a blurb after the option parser summary.

[Source]

     # File vendor/rails/railties/lib/rails_generator/options.rb, line 98
 98:         def usage(message = usage_message)
 99:           raise UsageError, "#{@option_parser}\n#{message}"
100:         end
usage_message()

[Source]

     # File vendor/rails/railties/lib/rails_generator/options.rb, line 102
102:         def usage_message
103:           ''
104:         end


Module: Rails::Generator::Options::ClassMethods

Module | Rails::Generator::Options::ClassMethods
In: | vendor/rails/railties/lib/rails_generator/options.rb

Methods

default_options full_options inherited_with_options mandatory_options

Public Instance methods

default_options(options = nil)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 30
30:         def default_options(options = nil)
31:           if options
32:             write_inheritable_attribute(:default_options, options)
33:           else
34:             read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {})
35:           end
36:         end
full_options(runtime_options = {})

Merge together our class options. In increasing precedence:

  default_options   (class default options)
  runtime_options   (provided as argument)
  mandatory_options (class mandatory options)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 42
42:         def full_options(runtime_options = {})
43:           default_options.merge(runtime_options).merge(mandatory_options)
44:         end
inherited_with_options(sub)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 17
17:         def inherited_with_options(sub)
18:           inherited_without_options(sub) if respond_to?(:inherited_without_options)
19:           sub.extend(Rails::Generator::Options::ClassMethods)
20:         end
mandatory_options(options = nil)

[Source]

    # File vendor/rails/railties/lib/rails_generator/options.rb, line 22
22:         def mandatory_options(options = nil)
23:           if options
24:             write_inheritable_attribute(:mandatory_options, options)
25:           else
26:             read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {})
27:           end
28:         end


Class: Rails::Generator::PathSource

Class | Rails::Generator::PathSource
In: | vendor/rails/railties/lib/rails_generator/lookup.rb
Parent: | Source

PathSource looks for generators in a filesystem directory.

Methods

each new

Attributes

path [R]

Public Class methods

new(label, path)

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 185
185:       def initialize(label, path)
186:         super label
187:         @path = path
188:       end

Public Instance methods

each() {|Spec.new(File.basename(dir), dir, label)| ...}

Yield each eligible subdirectory.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 191
191:       def each
192:         Dir["#{path}/[a-z]*"].each do |dir|
193:           if File.directory?(dir)
194:             yield Spec.new(File.basename(dir), dir, label)
195:           end
196:         end
197:       end


Module: Rails::Generator::Scripts

Module | Rails::Generator::Scripts
In: | vendor/rails/railties/lib/rails_generator/scripts.rb

Classes and Modules

Class Rails::Generator::Scripts::Base


Class: Rails::Generator::Scripts::Base

Class | Rails::Generator::Scripts::Base
In: | vendor/rails/railties/lib/rails_generator/scripts.rb
Parent: | Object

Generator scripts handle command-line invocation. Each script responds to an invoke! class method which handles option parsing and generator invocation.

Methods

banner run usage_message

Included Modules

Options

Public Instance methods

run(args = [], runtime_options = {})

Run the generator script. Takes an array of unparsed arguments and a hash of parsed arguments, takes the generator as an option or first remaining argument, and invokes the requested command.

[Source]

    # File vendor/rails/railties/lib/rails_generator/scripts.rb, line 17
17:         def run(args = [], runtime_options = {})
18:           begin
19:             parse!(args.dup, runtime_options)
20:           rescue OptionParser::InvalidOption => e
21:             # Don't cry, script. Generators want what you think is invalid.
22:           end
23:
24:           # Generator name is the only required option.
25:           unless options[:generator]
26:             usage if args.empty?
27:             options[:generator] ||= args.shift
28:           end
29:
30:           # Look up generator instance and invoke command on it.
31:           Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
32:         rescue => e
33:           puts e
34:           puts "  #{e.backtrace.join("\n  ")}\n" if options[:backtrace]
35:           raise SystemExit
36:         end

Protected Instance methods

banner()

Override with your own script usage banner.

[Source]

    # File vendor/rails/railties/lib/rails_generator/scripts.rb, line 40
40:           def banner
41:             "Usage: #{$0} generator [options] [args]"
42:           end
usage_message()

[Source]

    # File vendor/rails/railties/lib/rails_generator/scripts.rb, line 44
44:           def usage_message
45:             usage = "\nInstalled Generators\n"
46:             Rails::Generator::Base.sources.inject([]) do |mem, source|
47:               # Using an association list instead of a hash to preserve order,
48:               # for aesthetic reasons more than anything else.
49:               label = source.label.to_s.capitalize
50:               pair = mem.assoc(label)
51:               mem << (pair = [label, []]) if pair.nil?
52:               pair[1] |= source.names
53:               mem
54:             end.each do |label, names|
55:               usage << "  #{label}: #{names.join(', ')}\n" unless names.empty?
56:             end
57:
58:             usage << "\nMore are available at http://wiki.rubyonrails.org/rails/pages/AvailableGenerators\n  1. Download, for example, login_generator.zip\n  2. Unzip to directory \#{Dir.user_home}/.rails/generators/login\n     to use the generator with all your Rails apps\n"
59:
60:             if Object.const_defined?(:RAILS_ROOT)
61:               usage << "     or to \#{File.expand_path(RAILS_ROOT)}/lib/generators/login\n     to use with this app only.\n"
62:             end
63:
64:             usage << "  3. Run generate with no arguments for usage information\n       \#{$0} login\n\nGenerator gems are also available:\n  1. gem search -r generator\n  2. gem install login_generator\n  3. \#{$0} login\n\n"
65:             return usage
66:           end


Class: Rails::Generator::Source

Class | Rails::Generator::Source
In: | vendor/rails/railties/lib/rails_generator/lookup.rb
Parent: | Object

Sources enumerate (yield from each) generator specs which describe where to find and how to create generators. Enumerable is mixed in so, for example, source.collect will retrieve every generator. Sources may be assigned a label to distinguish them.

Methods

each names new

Included Modules

Enumerable

Attributes

label [R]

Public Class methods

new(label)

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 164
164:       def initialize(label)
165:         @label = label
166:       end

Public Instance methods

each()

The each method must be implemented in subclasses. The base implementation raises an error.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 170
170:       def each
171:         raise NotImplementedError
172:       end
names()

Return a convenient sorted list of all generator names.

[Source]

     # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 175
175:       def names
176:         map { |spec| spec.name }.sort
177:       end


Class: Rails::Generator::Spec

Class | Rails::Generator::Spec
In: | vendor/rails/railties/lib/rails_generator/spec.rb
Parent: | Object

A spec knows where a generator was found and how to instantiate it. Metadata include the generator‘s name, its base path, and the source which yielded it (PathSource, GemPathSource, etc.)

Methods

class_file class_name klass new

Attributes

name | [R]
path | [R]
source | [R]

Public Class methods

new(name, path, source)

[Source]

    # File vendor/rails/railties/lib/rails_generator/spec.rb, line 9
 9:       def initialize(name, path, source)
10:         @name, @path, @source = name, path, source
11:       end

Public Instance methods

class_file()

[Source]

    # File vendor/rails/railties/lib/rails_generator/spec.rb, line 24
24:       def class_file
25:         "#{path}/#{name}_generator.rb"
26:       end
class_name()

[Source]

    # File vendor/rails/railties/lib/rails_generator/spec.rb, line 28
28:       def class_name
29:         "#{name.camelize}Generator"
30:       end
klass()

Look up the generator class. Require its class file, find the class in ObjectSpace, tag it with this spec, and return.

[Source]

    # File vendor/rails/railties/lib/rails_generator/spec.rb, line 15
15:       def klass
16:         unless @klass
17:           require class_file
18:           @klass = lookup_class
19:           @klass.spec = self
20:         end
21:         @klass
22:       end


Class: Rails::Generator::UsageError

Class | Rails::Generator::UsageError
In: | vendor/rails/railties/lib/rails_generator/base.rb
Parent: | GeneratorError


Class: Rails::Initializer

Class | Rails::Initializer
In: | vendor/rails/railties/lib/initializer.rb
Parent: | Object

The Initializer is responsible for processing the Rails configuration, such as setting the $LOAD_PATH, requiring the right frameworks, initializing logging, and more. It can be run either as a single command that‘ll just use the default configuration, like this:

  Rails::Initializer.run

But normally it‘s more interesting to pass in a custom configuration through the block running:

  Rails::Initializer.run do |config|
    config.frameworks -= [ :action_mailer ]
  end

This will use the default configuration options from Rails::Configuration, but allow for overwriting on select areas.

Methods

add_gem_load_paths add_plugin_load_paths add_support_load_paths after_initialize check_gem_dependencies check_ruby_version disable_dependency_loading initialize_cache initialize_database initialize_database_middleware initialize_dependency_mechanism initialize_encoding initialize_framework_caches initialize_framework_logging initialize_framework_settings initialize_framework_views initialize_i18n initialize_logger initialize_metal initialize_routing initialize_time_zone initialize_whiny_nils install_gem_spec_stubs load_application_classes load_application_initializers load_environment load_gems load_observers load_plugins load_view_paths new plugin_loader preload_frameworks prepare_dispatcher process require_frameworks run set_autoload_paths set_load_path

Attributes

configuration | [R] | The Configuration instance used by this Initializer instance.
gems_dependencies_loaded | [R] | Whether or not all the gem dependencies have been met
loaded_plugins | [R] | The set of loaded plugins.

Public Class methods

new(configuration)

Create a new Initializer instance that references the given Configuration instance.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 119
119:     def initialize(configuration)
120:       @configuration = configuration
121:       @loaded_plugins = []
122:     end
run(command = :process, configuration = Configuration.new) {|configuration if block_given?| ...}

Runs the initializer. By default, this will invoke the process method, which simply executes all of the initialization routines. Alternately, you can specify explicitly which initialization routine you want:

  Rails::Initializer.run(:set_load_path)

This is useful if you only want the load path initialized, without incurring the overhead of completely loading the entire environment.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 110
110:     def self.run(command = :process, configuration = Configuration.new)
111:       yield configuration if block_given?
112:       initializer = new configuration
113:       initializer.send(command)
114:       initializer
115:     end

Public Instance methods

add_gem_load_paths()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 296
296:     def add_gem_load_paths
297:       Rails::GemDependency.add_frozen_gem_path
298:       unless @configuration.gems.empty?
299:         require "rubygems"
300:         @configuration.gems.each { |gem| gem.add_load_paths }
301:       end
302:     end
add_plugin_load_paths()

Adds all load paths from plugins to the global set of load paths, so that code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 292
292:     def add_plugin_load_paths
293:       plugin_loader.add_plugin_load_paths
294:     end
add_support_load_paths()

Add the load paths used by support functions such as the info controller

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 287
287:     def add_support_load_paths
288:     end
after_initialize()

Fires the user-supplied after_initialize block (Configuration#after_initialize)

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 591
591:     def after_initialize
592:       if gems_dependencies_loaded
593:         configuration.after_initialize_blocks.each do |block|
594:           block.call
595:         end
596:       end
597:     end
check_gem_dependencies()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 310
310:     def check_gem_dependencies
311:       unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
312:       if unloaded_gems.size > 0
313:         @gems_dependencies_loaded = false
314:         # don't print if the gems rake tasks are being run
315:         unless $gems_rake_task
316:           abort "Missing these required gems:\n\#{unloaded_gems.map { |gem| \"\#{gem.name}  \#{gem.requirement}\" } * \"\\n  \"}\n\nYou're running:\nruby \#{Gem.ruby_version} at \#{Gem.ruby}\nrubygems \#{Gem::RubyGemsVersion} at \#{Gem.path * ', '}\n\nRun `rake gems:install` to install the missing gems.\n"
317:         end
318:       else
319:         @gems_dependencies_loaded = true
320:       end
321:     end
check_ruby_version()

Check for valid Ruby version This is done in an external file, so we can use it from the `rails` program as well without duplication.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 207
207:     def check_ruby_version
208:       require 'ruby_version_check'
209:     end
disable_dependency_loading()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 614
614:     def disable_dependency_loading
615:       if configuration.cache_classes && !configuration.dependency_loading
616:         ActiveSupport::Dependencies.unhook!
617:       end
618:     end
initialize_cache()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 435
435:     def initialize_cache
436:       unless defined?(RAILS_CACHE)
437:         silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
438:
439:         if RAILS_CACHE.respond_to?(:middleware)
440:           # Insert middleware to setup and teardown local cache for each request
441:           configuration.middleware.insert_after("ActionController::Failsafe""ActionController::Failsafe", RAILS_CACHE.middleware)
442:         end
443:       end
444:     end
initialize_database()

This initialization routine does nothing unless :active_record is one of the frameworks to load (Configuration#frameworks). If it is, this sets the database configuration from Configuration#database_configuration and then establishes the connection.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 416
416:     def initialize_database
417:       if configuration.frameworks.include?(:active_record)
418:         ActiveRecord::Base.configurations = configuration.database_configuration
419:         ActiveRecord::Base.establish_connection
420:       end
421:     end
initialize_database_middleware()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 423
423:     def initialize_database_middleware
424:       if configuration.frameworks.include?(:active_record)
425:         if ActionController::Base.session_store == ActiveRecord::SessionStore
426:           configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
427:           configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::QueryCache
428:         else
429:           configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
430:           configuration.middleware.use ActiveRecord::QueryCache
431:         end
432:       end
433:     end
initialize_dependency_mechanism()

Sets the dependency loading mechanism based on the value of Configuration#cache_classes.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 522
522:     def initialize_dependency_mechanism
523:       ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
524:     end
initialize_encoding()

For Ruby 1.8, this initialization sets $KCODE to ‘u’ to enable the multibyte safe operations. Plugin authors supporting other encodings should override this behaviour and set the relevant default_charset on ActionController::Base.

For Ruby 1.9, this does nothing. Specify the default encoding in the Ruby shebang line if you don‘t want UTF-8.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 408
408:     def initialize_encoding
409:       $KCODE='u' if RUBY_VERSION < '1.9'
410:     end
initialize_framework_caches()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 446
446:     def initialize_framework_caches
447:       if configuration.frameworks.include?(:action_controller)
448:         ActionController::Base.cache_store ||= RAILS_CACHE
449:       end
450:     end
initialize_framework_logging()

Sets the logger for Active Record, Action Controller, and Action Mailer (but only for those frameworks that are to be loaded). If the framework‘s logger is already set, it is not changed, otherwise it is set to use RAILS_DEFAULT_LOGGER.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 488
488:     def initialize_framework_logging
489:       for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
490:         framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
491:       end
492:
493:       ActiveSupport::Dependencies.logger ||= Rails.logger
494:       Rails.cache.logger ||= Rails.logger
495:     end
initialize_framework_settings()

Initializes framework-specific settings for each of the loaded frameworks (Configuration#frameworks). The available settings map to the accessors on each of the corresponding Base classes.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 577
577:     def initialize_framework_settings
578:       configuration.frameworks.each do |framework|
579:         base_class = framework.to_s.camelize.constantize.const_get("Base")
580:
581:         configuration.send(framework).each do |setting, value|
582:           base_class.send("#{setting}=", value)
583:         end
584:       end
585:       configuration.active_support.each do |setting, value|
586:         ActiveSupport.send("#{setting}=", value)
587:       end
588:     end
initialize_framework_views()

Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+ (but only for those frameworks that are to be loaded). If the framework‘s paths have already been set, it is not changed, otherwise it is set to use Configuration#view_path.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 501
501:     def initialize_framework_views
502:       if configuration.frameworks.include?(:action_view)
503:         view_path = ActionView::PathSet.type_cast(configuration.view_path)
504:         ActionMailer::Base.template_root  = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
505:         ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
506:       end
507:     end
initialize_i18n()

Set the i18n configuration from config.i18n but special-case for the load_path which should be appended to what‘s already set instead of overwritten.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 555
555:     def initialize_i18n
556:       configuration.i18n.each do |setting, value|
557:         if setting == :load_path
558:           I18n.load_path += value
559:         else
560:           I18n.send("#{setting}=", value)
561:         end
562:       end
563:     end
initialize_logger()

If the RAILS_DEFAULT_LOGGER constant is already set, this initialization routine does nothing. If the constant is not set, and Configuration#logger is not nil, this also does nothing. Otherwise, a new logger instance is created at Configuration#log_path, with a default log level of Configuration#log_level.

If the log could not be created, the log will be set to output to STDERR, with a log level of WARN.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 460
460:     def initialize_logger
461:       # if the environment has explicitly defined a logger, use it
462:       return if Rails.logger
463:
464:       unless logger = configuration.logger
465:         begin
466:           logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
467:           logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
468:           if configuration.environment == "production"
469:             logger.auto_flushing = false
470:           end
471:         rescue StandardError => e
472:           logger = ActiveSupport::BufferedLogger.new(STDERR)
473:           logger.level = ActiveSupport::BufferedLogger::WARN
474:           logger.warn(
475:             "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
476:             "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
477:           )
478:         end
479:       end
480:
481:       silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
482:     end
initialize_metal()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 565
565:     def initialize_metal
566:       Rails::Rack::Metal.requested_metals = configuration.metals
567:       Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
568:
569:       configuration.middleware.insert_before(
570:         "ActionController::RewindableInput""ActionController::RewindableInput",
571:         Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
572:     end
initialize_routing()

If Action Controller is not one of the loaded frameworks (Configuration#frameworks) this does nothing. Otherwise, it loads the routing definitions and sets up loading module used to lazily load controllers (Configuration#controller_paths).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 512
512:     def initialize_routing
513:       return unless configuration.frameworks.include?(:action_controller)
514:
515:       ActionController::Routing.controller_paths += configuration.controller_paths
516:       ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
517:       ActionController::Routing::Routes.reload!
518:     end
initialize_time_zone()

Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes. If assigned value cannot be matched to a TimeZone, an exception will be raised.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 534
534:     def initialize_time_zone
535:       if configuration.time_zone
536:         zone_default = Time.__send__(:get_zone, configuration.time_zone)
537:
538:         unless zone_default
539:           raise \
540:             'Value assigned to config.time_zone not recognized.' +
541:             'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
542:         end
543:
544:         Time.zone_default = zone_default
545:
546:         if configuration.frameworks.include?(:active_record)
547:           ActiveRecord::Base.time_zone_aware_attributes = true
548:           ActiveRecord::Base.default_timezone = :utc
549:         end
550:       end
551:     end
initialize_whiny_nils()

Loads support for "whiny nil" (noisy warnings when methods are invoked on nil values) if Configuration#whiny_nils is true.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 528
528:     def initialize_whiny_nils
529:       require('active_support/whiny_nil') if configuration.whiny_nils
530:     end
install_gem_spec_stubs()

If Rails is vendored and RubyGems is available, install stub GemSpecs for Rails, Active Support, Active Record, Action Pack, Action Mailer, and Active Resource. This allows Gem plugins to depend on Rails even when the Gem version of Rails shouldn‘t be loaded.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 215
215:     def install_gem_spec_stubs
216:       unless Rails.respond_to?(:vendor_rails?)
217:         abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
218:       end
219:
220:       if Rails.vendor_rails?
221:         begin; require "rubygems"; rescue LoadError; return; end
222:
223:         stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
224:         stubs.reject! { |s| Gem.loaded_specs.key?(s) }
225:
226:         stubs.each do |stub|
227:           Gem.loaded_specs[stub] = Gem::Specification.new do |s|
228:             s.name = stub
229:             s.version = Rails::VERSION::STRING
230:             s.loaded_from = ""
231:           end
232:         end
233:       end
234:     end
load_application_classes()

Eager load application classes

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 389
389:     def load_application_classes
390:       return if $rails_rake_task
391:       if configuration.cache_classes
392:         configuration.eager_load_paths.each do |load_path|
393:           matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
394:           Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
395:             require_dependency file.sub(matcher, '\1')
396:           end
397:         end
398:       end
399:     end
load_application_initializers()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 599
599:     def load_application_initializers
600:       if gems_dependencies_loaded
601:         Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
602:           load(initializer)
603:         end
604:       end
605:     end
load_environment()

Loads the environment specified by Configuration#environment_path, which is typically one of development, test, or production.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 359
359:     def load_environment
360:       silence_warnings do
361:         return if @environment_loaded
362:         @environment_loaded = true
363:
364:         config = configuration
365:         constants = self.class.constants
366:
367:         eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
368:
369:         (self.class.constants - constants).each do |const|
370:           Object.const_set(const, self.class.const_get(const))
371:         end
372:       end
373:     end
load_gems()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 304
304:     def load_gems
305:       unless $gems_build_rake_task
306:         @configuration.gems.each { |gem| gem.load }
307:       end
308:     end
load_observers()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 375
375:     def load_observers
376:       if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
377:         ActiveRecord::Base.instantiate_observers
378:       end
379:     end
load_plugins()

Loads all plugins in config.plugin_paths. plugin_paths defaults to vendor/plugins but may also be set to a list of paths, such as

  config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]

In the default implementation, as each plugin discovered in plugin_paths is initialized:

  • its lib directory, if present, is added to the load path (immediately after the applications lib directory)
  • init.rb is evaluated, if present

After all plugins are loaded, duplicates are removed from the load path. If an array of plugin names is specified in config.plugins, only those plugins will be loaded and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical order.

if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other plugins will be loaded in alphabetical order

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 349
349:     def load_plugins
350:       plugin_loader.load_plugins
351:     end
load_view_paths()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 381
381:     def load_view_paths
382:       if configuration.frameworks.include?(:action_view)
383:         ActionController::Base.view_paths.load! if configuration.frameworks.include?(:action_controller)
384:         ActionMailer::Base.view_paths.load! if configuration.frameworks.include?(:action_mailer)
385:       end
386:     end
plugin_loader()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 353
353:     def plugin_loader
354:       @plugin_loader ||= configuration.plugin_loader.new(self)
355:     end
preload_frameworks()

Preload all frameworks specified by the Configuration#frameworks. Used by Passenger to ensure everything‘s loaded before forking and to avoid autoload race conditions in JRuby.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 276
276:     def preload_frameworks
277:       if configuration.preload_frameworks
278:         configuration.frameworks.each do |framework|
279:           # String#classify and #constantize aren't available yet.
280:           toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
281:           toplevel.load_all! if toplevel.respond_to?(:load_all!)
282:         end
283:       end
284:     end
prepare_dispatcher()

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 607
607:     def prepare_dispatcher
608:       return unless configuration.frameworks.include?(:action_controller)
609:       require 'dispatcher' unless defined?(::Dispatcher)
610:       Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
611:       Dispatcher.run_prepare_callbacks
612:     end
process()

Sequentially step through all of the available initialization routines, in order (view execution order in source).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 126
126:     def process
127:       Rails.configuration = configuration
128:
129:       check_ruby_version
130:       install_gem_spec_stubs
131:       set_load_path
132:       add_gem_load_paths
133:
134:       require_frameworks
135:       set_autoload_paths
136:       add_plugin_load_paths
137:       load_environment
138:       preload_frameworks
139:
140:       initialize_encoding
141:       initialize_database
142:
143:       initialize_cache
144:       initialize_framework_caches
145:
146:       initialize_logger
147:       initialize_framework_logging
148:
149:       initialize_dependency_mechanism
150:       initialize_whiny_nils
151:
152:       initialize_time_zone
153:       initialize_i18n
154:
155:       initialize_framework_settings
156:       initialize_framework_views
157:
158:       initialize_metal
159:
160:       add_support_load_paths
161:
162:       load_gems
163:       load_plugins
164:
165:       # pick up any gems that plugins depend on
166:       add_gem_load_paths
167:       load_gems
168:       check_gem_dependencies
169:
170:       # bail out if gems are missing - note that check_gem_dependencies will have
171:       # already called abort() unless $gems_rake_task is set
172:       return unless gems_dependencies_loaded
173:
174:       load_application_initializers
175:
176:       # the framework is now fully initialized
177:       after_initialize
178:
179:       # Setup database middleware after initializers have run
180:       initialize_database_middleware
181:
182:       # Prepare dispatcher callbacks and run 'prepare' callbacks
183:       prepare_dispatcher
184:
185:       # Routing must be initialized after plugins to allow the former to extend the routes
186:       initialize_routing
187:
188:       # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
189:       load_observers
190:
191:       # Load view path cache
192:       load_view_paths
193:
194:       # Load application classes
195:       load_application_classes
196:
197:       # Disable dependency loading during request cycle
198:       disable_dependency_loading
199:
200:       # Flag initialized
201:       Rails.initialized = true
202:     end
require_frameworks()

Requires all frameworks specified by the Configuration#frameworks list. By default, all frameworks (Active Record, Active Support, Action Pack, Action Mailer, and Active Resource) are loaded.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 266
266:     def require_frameworks
267:       configuration.frameworks.each { |framework| require(framework.to_s) }
268:     rescue LoadError => e
269:       # Re-raise as RuntimeError because Mongrel would swallow LoadError.
270:       raise e.to_s
271:     end
set_autoload_paths()

Set the paths from which Rails will automatically load source files, and the load_once paths.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 246
246:     def set_autoload_paths
247:       ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
248:       ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
249:
250:       extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
251:       unless extra.empty?
252:         abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
253:       end
254:
255:       # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
256:       configuration.load_once_paths.freeze
257:     end
set_load_path()

Set the $LOAD_PATH based on the value of Configuration#load_paths. Duplicates are removed.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 238
238:     def set_load_path
239:       load_paths = configuration.load_paths + configuration.framework_paths
240:       load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
241:       $LOAD_PATH.uniq!
242:     end


Class: Rails::SecretKeyGenerator

Class | Rails::SecretKeyGenerator
In: | vendor/rails/railties/lib/rails_generator/secret_key_generator.rb
Parent: | Object

A class for creating random secret keys. This class will do its best to create a random secret key that‘s as secure as possible, using whatever methods are available on the current platform. For example:

  generator = Rails::SecretKeyGenerator("some unique identifier, such as the application name")
  generator.generate_secret     # => "f3f1be90053fa851... (some long string)"

This class is deprecated in Rails 2.2 in favor of ActiveSupport::SecureRandom. It is currently a wrapper around ActiveSupport::SecureRandom.

Methods

generate_secret new

Public Class methods

new(identifier)

[Source]

    # File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 14
14:     def initialize(identifier)
15:     end

Public Instance methods

generate_secret()

Generate a random secret key with the best possible method available on the current platform.

[Source]

    # File vendor/rails/railties/lib/rails_generator/secret_key_generator.rb, line 19
19:     def generate_secret
20:       ActiveSupport::SecureRandom.hex(64)
21:     end


Module: Rails

Module | Rails
In: | vendor/rails/railties/lib/initializer.rb vendor/rails/railties/lib/rails_generator/base.rb vendor/rails/railties/lib/rails_generator/commands.rb vendor/rails/railties/lib/rails_generator/generated_attribute.rb vendor/rails/railties/lib/rails_generator/lookup.rb vendor/rails/railties/lib/rails_generator/manifest.rb vendor/rails/railties/lib/rails_generator/options.rb vendor/rails/railties/lib/rails_generator/scripts.rb vendor/rails/railties/lib/rails_generator/secret_key_generator.rb vendor/rails/railties/lib/rails_generator/simple_logger.rb vendor/rails/railties/lib/rails_generator/spec.rb

Methods

backtrace_cleaner cache configuration configuration= env initialized= initialized? logger public_path public_path= root version

Classes and Modules

Module Rails::Generator
Class Rails::Configuration
Class Rails::Initializer
Class Rails::SecretKeyGenerator

Public Class methods

backtrace_cleaner()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 43
43:     def backtrace_cleaner
44:       @@backtrace_cleaner ||= begin
45:         # Relies on ActiveSupport, so we have to lazy load to postpone definition until AS has been loaded
46:         require 'rails/backtrace_cleaner'
47:         Rails::BacktraceCleaner.new
48:       end
49:     end
cache()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 59
59:     def cache
60:       RAILS_CACHE
61:     end
configuration()

The Configuration instance used to configure the Rails environment

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 19
19:     def configuration
20:       @@configuration
21:     end
configuration=(configuration)

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 23
23:     def configuration=(configuration)
24:       @@configuration = configuration
25:     end
env()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 55
55:     def env
56:       @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
57:     end
initialized=(initialized)

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 31
31:     def initialized=(initialized)
32:       @initialized ||= initialized
33:     end
initialized?()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 27
27:     def initialized?
28:       @initialized || false
29:     end
logger()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 35
35:     def logger
36:       if defined?(RAILS_DEFAULT_LOGGER)
37:         RAILS_DEFAULT_LOGGER
38:       else
39:         nil
40:       end
41:     end
public_path()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 67
67:     def public_path
68:       @@public_path ||= self.root ? File.join(self.root, "public") : "public"
69:     end
public_path=(path)

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 71
71:     def public_path=(path)
72:       @@public_path = path
73:     end
root()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 51
51:     def root
52:       Pathname.new(RAILS_ROOT) if defined?(RAILS_ROOT)
53:     end
version()

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 63
63:     def version
64:       VERSION::STRING
65:     end


File: code_statistics.rb

code_statistics.rb

Path: | vendor/rails/railties/lib/code_statistics.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: commands.rb

commands.rb

Path: | vendor/rails/railties/lib/commands.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: about.rb

about.rb

Path: | vendor/rails/railties/lib/commands/about.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

rails/info


File: console.rb

console.rb

Path: | vendor/rails/railties/lib/commands/console.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

optparse ruby-debug


File: dbconsole.rb

dbconsole.rb

Path: | vendor/rails/railties/lib/commands/dbconsole.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

erb yaml optparse

Methods

find_cmd

Public Instance methods

find_cmd(*commands)

[Source]

    # File vendor/rails/railties/lib/commands/dbconsole.rb, line 33
33: def find_cmd(*commands)
34:   dirs_on_path = ENV['PATH'].to_s.split(File::PATH_SEPARATOR)
35:   commands += commands.map{|cmd| "#{cmd}.exe"} if RUBY_PLATFORM =~ /win32/
36:   commands.detect do |cmd|
37:     dirs_on_path.detect do |path|
38:       File.executable? File.join(path, cmd)
39:     end
40:   end || abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
41: end


File: destroy.rb

destroy.rb

Path: | vendor/rails/railties/lib/commands/destroy.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

rails_generator rails_generator/scripts/destroy


File: generate.rb

generate.rb

Path: | vendor/rails/railties/lib/commands/generate.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

rails_generator rails_generator/scripts/generate


File: plugin.rb

plugin.rb

Path: | vendor/rails/railties/lib/commands/plugin.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Rails Plugin Manager.

Listing available plugins:

  $ ./script/plugin list
  continuous_builder            http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder
  asset_timestamping            http://svn.aviditybytes.com/rails/plugins/asset_timestamping
  enumerations_mixin            http://svn.protocool.com/rails/plugins/enumerations_mixin/trunk
  calculations                  http://techno-weenie.net/svn/projects/calculations/
  ...

Installing plugins:

  $ ./script/plugin install continuous_builder asset_timestamping

Finding Repositories:

  $ ./script/plugin discover

Adding Repositories:

  $ ./script/plugin source http://svn.protocool.com/rails/plugins/

How it works:

  * Maintains a list of subversion repositories that are assumed to have
    a plugin directory structure. Manage them with the (source, unsource,
    and sources commands)

  * The discover command scrapes the following page for things that
    look like subversion repositories with plugins:
    http://wiki.rubyonrails.org/rails/pages/Plugins

  * Unless you specify that you want to use svn, script/plugin uses plain old
    HTTP for downloads.  The following bullets are true if you specify
    that you want to use svn.

  * If `vendor/plugins` is under subversion control, the script will
    modify the svn:externals property and perform an update. You can
    use normal subversion commands to keep the plugins up to date.

  * Or, if `vendor/plugins` is not under subversion control, the
    plugin is pulled via `svn checkout` or `svn export` but looks
    exactly the same.

Specifying revisions:

  * Subversion revision is a single integer.

  * Git revision format:
    - full - 'refs/tags/1.8.0' or 'refs/heads/experimental'
    - short: 'experimental' (equivalent to 'refs/heads/experimental')
             'tag 1.8.0' (equivalent to 'refs/tags/1.8.0')

This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com) and is licensed MIT: (www.opensource.org/licenses/mit-license.php)

Required files

open-uri fileutils tempfile active_support/core_ext/kernel optparse open-uri

Included Modules

FileUtils


File: runner.rb

runner.rb

Path: | vendor/rails/railties/lib/commands/runner.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

optparse


File: server.rb

server.rb

Path: | vendor/rails/railties/lib/commands/server.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_support action_controller fileutils optparse


File: update.rb

update.rb

Path: | vendor/rails/railties/lib/commands/update.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

rails_generator rails_generator/scripts/update


File: console_app.rb

console_app.rb

Path: | vendor/rails/railties/lib/console_app.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

active_support/test_case action_controller

Methods

app new_session reload!

Public Instance methods

app(create=false)

reference the global "app" instance, created on demand. To recreate the instance, pass a non-false value as the parameter.

[Source]

    # File vendor/rails/railties/lib/console_app.rb, line 9
 9: def app(create=false)
10:   @app_integration_instance = nil if create
11:   @app_integration_instance ||= new_session do |sess|
12:     sess.host! "www.example.com"
13:   end
14: end
new_session() {|session if block_given?| ...}

create a new session. If a block is given, the new session will be yielded to the block before being returned.

[Source]

    # File vendor/rails/railties/lib/console_app.rb, line 18
18: def new_session
19:   session = ActionController::Integration::Session.new
20:   yield session if block_given?
21:   session
22: end
reload!()

reloads the environment

[Source]

    # File vendor/rails/railties/lib/console_app.rb, line 25
25: def reload!
26:   puts "Reloading..."
27:   Dispatcher.cleanup_application
28:   Dispatcher.reload_application
29:   true
30: end


File: console_sandbox.rb

console_sandbox.rb

Path: | vendor/rails/railties/lib/console_sandbox.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: console_with_helpers.rb

console_with_helpers.rb

Path: | vendor/rails/railties/lib/console_with_helpers.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Methods

helper

Public Instance methods

helper()

[Source]

   # File vendor/rails/railties/lib/console_with_helpers.rb, line 1
1: def helper
2:   @helper ||= ApplicationController.helpers
3: end


File: dispatcher.rb

dispatcher.rb

Path: | vendor/rails/railties/lib/dispatcher.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

action_controller/dispatcher

Constants

Dispatcher = ActionController::Dispatcher


File: fcgi_handler.rb

fcgi_handler.rb

Path: | vendor/rails/railties/lib/fcgi_handler.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

fcgi logger dispatcher rbconfig


File: initializer.rb

initializer.rb

Path: | vendor/rails/railties/lib/initializer.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

logger set pathname railties_path rails/version rails/plugin/locator rails/plugin/loader rails/gem_dependency rails/rack rails/backtrace_cleaner ruby_version_check rubygems rubygems active_support/whiny_nil dispatcher erb dispatcher action_controller

Constants

RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)


File: performance_test_help.rb

performance_test_help.rb

Path: | vendor/rails/railties/lib/performance_test_help.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

action_controller/performance_test


File: rails_generator.rb

rails_generator.rb

Path: | vendor/rails/railties/lib/rails_generator.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Required files

active_support rubygems rails_generator/base rails_generator/lookup rails_generator/commands rails_generator/simple_logger


File: base.rb

base.rb

Path: | vendor/rails/railties/lib/rails_generator/base.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009


File: commands.rb

commands.rb

Path: | vendor/rails/railties/lib/rails_generator/commands.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

delegate optparse fileutils tempfile erb open-uri timeout


File: generated_attribute.rb

generated_attribute.rb

Path: | vendor/rails/railties/lib/rails_generator/generated_attribute.rb
Last Update: | Sun Mar 15 23:31:37 -0500 2009

Required files

optparse


File: lookup.rb

lookup.rb

Path: | vendor/rails/railties/lib/rails_generator/lookup.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Required files

pathname


File: manifest.rb

manifest.rb

Path: | vendor/rails/railties/lib/rails_generator/manifest.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009


File: options.rb

options.rb

Path: | vendor/rails/railties/lib/rails_generator/options.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Required files

optparse


File: scripts.rb

scripts.rb

Path: | vendor/rails/railties/lib/rails_generator/scripts.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009


File: secret_key_generator.rb

secret_key_generator.rb

Path: | vendor/rails/railties/lib/rails_generator/secret_key_generator.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Required files

active_support/deprecation


File: simple_logger.rb

simple_logger.rb

Path: | vendor/rails/railties/lib/rails_generator/simple_logger.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009


File: spec.rb

spec.rb

Path: | vendor/rails/railties/lib/rails_generator/spec.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009


File: railties_path.rb

railties_path.rb

Path: | vendor/rails/railties/lib/railties_path.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Constants

RAILTIES_PATH = File.join(File.dirname(__FILE__), '..')


File: ruby_version_check.rb

ruby_version_check.rb

Path: | vendor/rails/railties/lib/ruby_version_check.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009


File: rubyprof_ext.rb

rubyprof_ext.rb

Path: | vendor/rails/railties/lib/rubyprof_ext.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Required files

prof


File: source_annotation_extractor.rb

source_annotation_extractor.rb

Path: | vendor/rails/railties/lib/source_annotation_extractor.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Implements the logic behind the rake tasks for annotations like

  rake notes
  rake notes:optimize

and friends. See rake -T notes and railties/lib/tasks/annotations.rake.

Annotation objects are triplets :line, :tag, :text that represent the line where the annotation lives, its tag, and its text. Note the filename is not stored.

Annotations are looked for in comments and modulus whitespace they have to start with the tag optionally followed by a colon. Everything up to the end of the line (or closing ERb comment tag) is considered to be their text.


File: test_help.rb

test_help.rb

Path: | vendor/rails/railties/lib/test_help.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Make double-sure the RAILS_ENV is set to test, so fixtures are loaded to the right database

Required files

test/unit action_controller/test_case action_view/test_case action_controller/integration action_mailer/test_case active_record/test_case active_record/fixtures

Methods

create_fixtures

Constants

RAILS_ENV = "test" }

Public Instance methods

create_fixtures(*table_names, &block)

[Source]

    # File vendor/rails/railties/lib/test_help.rb, line 24
24:   def create_fixtures(*table_names, &block)
25:     Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block)
26:   end


File: webrick_server.rb

webrick_server.rb

Path: | vendor/rails/railties/lib/webrick_server.rb
Last Update: | Sun Mar 15 23:31:38 -0500 2009

Donated by Florian Gross

Required files

webrick cgi stringio dispatcher

Included Modules

WEBrick


File: CHANGELOG

CHANGELOG

Path: | vendor/rails/railties/CHANGELOG
Last Update: | Sun Mar 15 23:31:37 -0500 2009

*2.3.2 [Final] (March 15, 2009)*

  • Allow metal to live in plugins 2045 [Matthew Rudy]
  • Added metal [Josh Peek]
  • Remove script/performance/request in favour of the performance integration tests. [Pratik Naik]

    To continue using script/performance/request, install the request_profiler plugin :

      script/plugin install git://github.com/rails/request_profiler.git
  • Add a rake task to apply a template to an existing application : rake rails:template LOCATION=~/template.rb [Pratik Naik]
  • Add "-m/—template" option to Rails generator to apply a template to the generated application. [Jeremy McAnally]
      This has been extracted from rg - http://github.com/jeremymcanally/rg

  Example:

      # template.rb

      # Install plugins from git or svn
      plugin "will-paginate", :git => "git://github.com/mislav/will_paginate.git"
      plugin "old-restful-auth", :svn => "http://svn.techno-weenie.net/projects/plugins/restful_authentication/"

      # Add gems to environment.rb
      gem "jeremymcanally-context"
      gem "bluecloth"

      # Vendor file. Data in a string or...
      vendor("borrowed.rb", <<CODE
        def helpful_method
          do_something_helpful_here
        end
      CODE

      # ...file data from block return value.
      # #initializer creates a new initializer file
      initializer("crypto.rb") do
        salt = "--#{Time.now}--#{rand}--#{srand(Time.now.to_i)}"

        "SPECIAL_SALT = '#{salt}'"
      end

  Usage:

    To use a template, provide a file path or URL:

    1. Using a local file :

      rails <application name> -m /path/to/my/template.rb

    2. Or directly from a URL :

      rails <application name> --template=http://gist.github.com/31208.txt
  • Extracted the process scripts (inspector, reaper, spawner) into the plugin irs_process_scripts [David Heinemeier Hansson]
  • Changed Rails.root to return a Pathname object (allows for Rails.root.join(‘app’, ‘controllers’) => "#{RAILS_ROOT}/app/controllers") 1482 [Damian Janowski/?]
  • Added view path support for engines [David Heinemeier Hansson]
  • Added that config/routes.rb files in engine plugins are automatically loaded (and reloaded when they change in dev mode) [David Heinemeier Hansson]
  • Added app/[models|controllers|helpers] to the load path for plugins that has an app directory (go engines ;)) [David Heinemeier Hansson]
  • Add config.preload_frameworks to load all frameworks at startup. Default to false so Rails autoloads itself as it‘s used. Turn this on for Passenger and JRuby. Also turned on by config.threadsafe! [Jeremy Kemper]
  • Add a rake task to generate dispatchers : rake rails:generate_dispatchers [Pratik Naik]
  • "rails <app>" will not generate public/dispatch.cgi/fcgi/rb files by default now. Please use "—with-dispatchers" option if you need them. [Yaroslav Markin, Pratik Naik]
  • Added rake rails:update:application_controller to renamed application.rb to application_controller.rb — included in rake rails:update so upgrading to 2.3 will automatically trigger it 1439 [kastner]
  • Added Rails.backtrace_cleaner as an accessor for the Rails::BacktraceCleaner instance used by the framework to cut down on backtrace noise and config/initializers/backtrace_silencers.rb to add your own (or turn them all off) [David Heinemeier Hansson]
  • Switch from Test::Unit::TestCase to ActiveSupport::TestCase. [Jeremy Kemper]
  • Added config.i18n settings gatherer to config/environment, auto-loading of all locales in config/locales/*.rb,yml, and config/locales/en.yml as a sample locale [David Heinemeier Hansson]
  • BACKWARDS INCOMPATIBLE: Renamed application.rb to application_controller.rb and removed all the special casing that was in place to support the former. You must do this rename in your own application when you upgrade to this version [David Heinemeier Hansson]

*2.2.1 [RC2] (November 14th, 2008)*

  • Fixed plugin generator so that generated unit tests would subclass ActiveSupport::TestCase, also introduced a helper script to reduce the needed require statements 1137 [Mathias Meyer]
  • Update Prototype to 1.6.0.3 [sam]

*2.2.0 [RC1] (October 24th, 2008)*

  • Fixed that sqlite would report "db/development.sqlite3 already exists" whether true or not on db:create 614 [Antonio Cangiano]
  • Added config.threadsafe! to toggle allow concurrency settings and disable the dependency loader [Josh Peek]
  • Turn cache_classes on by default [Josh Peek]
  • Added configurable eager load paths. Defaults to app/models, app/controllers, and app/helpers [Josh Peek]
  • Introduce simple internationalization support. [Ruby i18n team]
  • Make script/plugin install <plugin> -r <revision> option work with git based plugins. 257. [Tim Pope Jakub Kuźma]. Example:

    script/plugin install git://github.com/mislav/will_paginate.git -r agnostic # Installs ‘agnostic’ branch script/plugin install git://github.com/dchelimsky/rspec.git -r ‘tag 1.1.4‘

  • Added Rails.initialized? flag [Josh Peek]
  • Make rake test:uncommitted work with Git. [Tim Pope]
  • Added Thin support to script/server. 488 [Bob Klosinski]
  • Fix script/about in production mode. 370 [Cheah Chu Yeow, Xavier Noria, David Krmpotic]
  • Add the gem load paths before the framework is loaded, so certain gems like RedCloth and BlueCloth can be frozen.
  • Fix discrepancies with loading rails/init.rb from gems.
  • Plugins check for the gem init path (rails/init.rb) before the standard plugin init path (init.rb) [Jacek Becela]
  • Changed all generated tests to use the test/do declaration style [David Heinemeier Hansson]
  • Wrapped Rails.env in StringInquirer so you can do Rails.env.development? [David Heinemeier Hansson]
  • Fixed that RailsInfoController wasn‘t considering all requests local in development mode (Edgard Castro) [310 state:resolved]

*2.1.0 (May 31st, 2008)*

  • script/dbconsole fires up the command-line database client. 102 [Steve Purcell]
  • Fix bug where plugin init.rb files from frozen gem specs weren‘t being run. (pjb3) [122 state:resolved]
  • Made the location of the routes file configurable with config.routes_configuration_file (Scott Fleckenstein) [88]
  • Rails Edge info returns the latest git commit hash [Francesc Esplugas]
  • Added Rails.public_path to control where HTML and assets are expected to be loaded from (defaults to Rails.root + "/public") 11581 [Nick Sieger]
  • rake time:zones:local finds correct base utc offset for zones in the Southern Hemisphere [Geoff Buesing]
  • Don‘t require rails/gem_builder during rails initialization, it‘s only needed for the gems:build task. [Rick Olson]
  • script/performance/profiler compatibility with the ruby-prof >= 0.5.0. Closes 9176. [Jonathan del Strother]
  • Flesh out rake gems:unpack to unpack all gems, and add rake gems:build for native extensions. 11513 [ddollar]

    rake gems:unpack # unpacks all gems rake gems:unpack GEM=mygem # unpacks only the gem ‘mygem‘

    rake gems:build # builds all unpacked gems rake gems:build GEM=mygem # builds only the gem ‘mygem‘

  • Add config.active_support for future configuration options. Also, add more new Rails 3 config settings to new_rails_defaults.rb [Rick Olson]
  • Add Rails.logger, Rails.root, Rails.env and Rails.cache shortcuts for RAILS_* constants [Pratik Naik]
  • Allow files in plugins to be reloaded like the rest of the application. [Rick Olson]

    Enables or disables plugin reloading.

      config.reload_plugins = true

    You can get around this setting per plugin. If reload_plugins? == false (DEFAULT), add this to your plugin‘s init.rb to make it reloadable:

      Dependencies.load_once_paths.delete lib_path

    If reload_plugins? == true, add this to your plugin‘s init.rb to only load it once:

      Dependencies.load_once_paths << lib_path
  • Small tweak to allow plugins to specify gem dependencies. [Rick Olson]

    # OLD open_id_authentication plugin init.rb require ‘yadis’ require ‘openid’ ActionController::Base.send :include, OpenIdAuthentication

    # NEW config.gem "ruby-openid", :lib => "openid", :version => "1.1.4" config.gem "ruby-yadis", :lib => "yadis", :version => "0.3.4"

    config.after_initialize do

      ActionController::Base.send :include, OpenIdAuthentication

    end

  • Added config.gem for specifying which gems are required by the application, as well as rake tasks for installing and freezing gems. [Rick Olson]

    Rails::Initializer.run do |config|

      config.gem "bj"
  config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
  config.gem "aws-s3", :lib => "aws/s3"

    end

    # List required gems. rake gems

    # Install all required gems: rake gems:install

    # Unpack specified gem to vendor/gems/gem_name-x.x.x rake gems:unpack GEM=bj

  • Removed the default .htaccess configuration as there are so many good deployment options now (kept it as an example in README) [David Heinemeier Hansson]
  • config.time_zone accepts TZInfo::Timezone identifiers as well as Rails TimeZone identifiers [Geoff Buesing]
  • Rails::Initializer#initialize_time_zone raises an error if value assigned to config.time_zone is not recognized. Rake time zone tasks only require ActiveSupport instead of entire environment [Geoff Buesing]
  • Stop adding the antiquated test/mocks/* directories and only add them to the path if they‘re still there for legacy reasons [David Heinemeier Hansson]
  • Added that gems can now be plugins if they include rails/init.rb 11444 [John Barnette]
  • Added Plugin#about method to programmatically access the about.yml in a plugin 10979 [James Adam]
      plugin = Rails::Plugin.new(path_to_my_plugin)
  plugin.about["author"] # => "James Adam"
  plugin.about["url"] # => "http://interblah.net"
  • Improve documentation. [Ryan Bigg, Jan De Poorter, Cheah Chu Yeow, Xavier Shay, Jack Danger Canty, Emilio Tagua, Xavier Noria, Sunny Ripert]
  • Added config.time_zone = ‘UTC’ in the default environment.rb [Geoff Buesing]
  • Added rake tasks time:zones:all, time:zones:us and time:zones:local for finding time zone names for config.time_zone option [Geoff Buesing]
  • Add config.time_zone for configuring the default Time.zone value. 10982 [Geoff Buesing]
  • Added support for installing plugins hosted at git repositories 11294 [Jack Danger Canty]
  • Fixed that script/generate would not look for plugin generators in plugin_paths 11000 [glv]
  • Fixed database rake tasks to work with charset/collation and show proper error messages on failure. Closes 11301 [matt]
  • Added a -e/—export to script/plugin install, uses svn export. 10847 [jon@blankpad.net)]
  • Reshuffle load order so that routes and observers are initialized after plugins and app initializers. Closes 10980 [Rick Olson]
  • Git support for script/generate. 10690 [ssoroka]
  • Update scaffold to use labels instead of bold tags. Closes 10757 [zach-inglis-lt3]
  • Resurrect WordNet synonym lookups. 10710 [tom./, matt]
  • Added config.cache_store to environment options to control the default cache store (default is FileStore if tmp/cache is present, otherwise MemoryStore is used) [David Heinemeier Hansson]
  • Added that rails:update is run when you do rails:freeze:edge to ensure you also get the latest JS and config files 10565 [jeff]
  • SQLite: db:drop:all doesn‘t fail silently if the database is already open. 10577 [Cheah Chu Yeow, mrichman]
  • Introduce native mongrel handler and push mutex into dispatcher. [Jeremy Kemper]
  • Ruby 1.9 compatibility. 1689, 10546 [Cheah Chu Yeow, frederico]

*2.0.2* (December 16th, 2007)

  • Changed the default database from mysql to sqlite3, so now running "rails myapp" will have a config/database.yml that‘s setup for SQLite3 (which in OS X Leopard is installed by default, so is the gem, so everything Just Works with no database configuration at all). To get a Rails application preconfigured for MySQL, just run "rails -d mysql myapp" [David Heinemeier Hansson]
  • Turned on ActionView::Base.cache_template_loading by default in config/environments/production.rb to prevent file system stat calls for every template loading to see if it changed (this means that you have to restart the application to see template changes in production mode) [David Heinemeier Hansson]
  • Introduce `rake secret` to output a crytographically secure secret key for use with cookie sessions 10363 [revans]
  • Fixed that local database creation should consider 127.0.0.1 local 9026 [parcelbrat]
  • Fixed that functional tests generated for scaffolds should use fixture calls instead of hard-coded IDs 10435 [boone]
  • Added db:migrate:redo and db:migrate:reset for rerunning existing migrations 10431, 10432 [matt]
  • RAILS_GEM_VERSION may be double-quoted also. 10443 [James Cox]
  • Update rails:freeze:gems to work with RubyGems 0.9.5. [Jeremy Kemper]

*2.0.1* (December 7th, 2007)

  • Fixed Active Record bug

*2.0.0* (December 6th, 2007)

  • The test task stops with a warning if you have pending migrations. 10377 [Josh Knowles]
  • Add warning to documentation about using transactional fixtures when the code under test uses transactions itself. Closes 7548 [Thijs van der Vossen]
  • Update Prototype to 1.6.0.1. [sam]
  • Update script.aculo.us to 1.8.0.1. [madrobby]
  • Added db:fixtures:identity as a way of locating what ID a foxy fixture was assigned 10332 [John Barnette]
  • Generated fixtures should not specify ids since theyre expected to be foxy fixtures 10330 [John Barnette]
  • Update to Prototype -r8232. [sam]
  • Introduce SecretKeyGenerator for more secure session secrets than CGI::Session‘s pseudo-random id generator. Consider extracting to Active Support later. 10286 [Hongli Lai (Phusion)]
  • RAILS_GEM_VERSION may be set to any valid gem version specifier. 10057 [Chad Woolley, Cheah Chu Yeow]
  • Load config/preinitializer.rb, if present, before loading the environment. 9943 [Chad Woolley]
  • FastCGI handler ignores unsupported signals like USR2 on Windows. [Grzegorz Derebecki]
  • Only load ActionMailer::TestCase if ActionMailer is loaded. Closes 10137 [defunkt]
  • Fixed that db:reset would use migrations instead of loading db/schema.rb [David Heinemeier Hansson]
  • Ensure the plugin loader only loads plugins once. Closes 10102 [haruki_zaemon]
  • Refactor Plugin Loader. Add plugin lib paths early, and add lots of tests. Closes 9795 [James Adam]
  • Added —skip-timestamps to generators that produce models 10036 [Tim Pope]
  • Update Prototype to 1.6.0 and script.aculo.us to 1.8.0. [sam, madrobby]
  • Added db:rollback to rollback the schema one version (or multiple as specified by STEP) [Jeffrey Allan Hardy]
  • Fix typo in test_helper. Closes 9925 [viktor tron]
  • Request profiler. [Jeremy Kemper]
  • config/boot.rb correctly detects RAILS_GEM_VERSION. 9834 [alexch, thewoolleyman]
  • Fixed incorrect migration number if script/generate executed outside of Rails root 7080 [Jeremy McAnally]
  • Update Prototype to 1.6.0_rc1 and script.aculo.us to 1.8.0 preview 0. [sam, madrobby]
  • Generated fixtures use the actual primary key instead of id. 4343 [Frederick Ros, Tarmo Tänav]
  • Extend the console helper method to allow you to include custom helpers. e.g: >> helper :posts >> helper.some_method_from_posts_helper(Post.find(1))
  • db:create works with remote databases whereas db:create:all only creates

databases on localhost. 9753 [Trevor Wennblom]

  • Removed calls to fixtures in generated tests as fixtures :all is now present by default in test_helper.rb [David Heinemeier Hansson]
  • Add —prefix option to script/server when using mongrel. [dacat]

*2.0.0 [Preview Release]* (September 29th, 2007) [Includes duplicates of changes from 1.1.4 - 1.2.3]

  • Fixed that installing plugins from SVN repositories that use trunk/ will work 8188 [evan]
  • Moved the SourceAnnotationExtractor to a separate file in case libraries try to load the rails rake tasks twice. [Rick Olson]
  • Moved Dispatcher to ActionController::Dispatcher. [Jeremy Kemper]
  • Changed the default logger from Ruby‘s own Logger with the clean_logger extensions to ActiveSupport::BufferedLogger for performance reasons [David Heinemeier Hansson]. (You can change it back with config.logger = Logger.new("/path/to/log", level).)
  • Added a default 422.html page to be rendered when ActiveRecord::RecordInvalid, ActiveRecord::RecordNotSaved, or ActionController::InvalidAuthenticityToken is raised [David Heinemeier Hansson]
  • Added —skip-fixture option to script/generate model 6862 [sandofsky]
  • Print Rails version when starting console 7440 [eyematz]
  • Fixed the placement of fixture files for nested models when generating through script/generate model 7547 [jkit]
  • Added TEMPLATE option to rake doc:app to set a custom output template 7737 [Jakob Skjerning]
  • Added VERBOSE option to rake db:migrate to turn off output 8204 [John Barnette]
  • Fixed that rake doc:app should use UTF-8 8906 [farzy]
  • Fixes rake annotations to search erb and builder files as well 9150 [m.langenberg]
  • Removed web_service generator [Michael Koziarski]
  • Added the :all option to config.plugins that‘ll include the rest of the plugins not already explicitly named 9613 [Frederick Cheung]. Example:
      # Loads :classic_pagination before all the other plugins
  config.plugins = [ :classic_pagination, :all ]
  • Added symbols as a legal way of specifying plugins in config.plugins 9629 [tom]
  • Removed deprecated task names, like clear_logs, in favor of the new namespaced style [David Heinemeier Hansson]
  • Support multiple config.after_initialize blocks so plugins and apps can more easily cooperate. 9582 [Zach Dennis]
  • Added db:drop:all to drop all databases declared in config/database.yml [David Heinemeier Hansson]
  • Use attribute pairs instead of the migration name to create add and remove column migrations. Closes 9166 [Pratik Naik]
          For example:

      ruby script/generation migration AddSomeStuffToCustomers first_name:string last_name:string

      or

      ruby script/generation migration RemoveSomeStuffFromCustomers first_name:string last_name:string
  • Add ActiveResource to Rails::Info. Closes 8741 [Chris Kampmeier]
  • use Gem.find_name instead of search when freezing gems. Prevent false positives for other gems with rails in the name. Closes 8729 [wselman]
  • Automatically generate add/remove column commands in specially named migrations like AddLocationToEvent. Closes 9006 [Ryan Davis]
  • Default to plural table name in Rails Generator if ActiveRecord is not present. Closes 8963 [evan]
  • Added rake routes for listing all the defined routes in the system. 8795 [Josh Peek]
  • db:create creates the database for the current environment if it‘s on localhost. db:create:all creates local databases for all environments. 8783 [matt]
  • Generators: look for generators in all gems, not just those suffixed with _generator, in the gem‘s generators or rails_generators directory. Allow use of the rails_generators directory instead of the standard generators directory in plugins also. 8730 [Dr Nic, topfunky]
  • MySQL, PostgreSQL: database.yml defaults to utf-8. 8701 [matt]
  • Added db:version to get the current schema number [via Err The Blog]
  • Added —skip-migration option to scaffold and resource generators 8656 [Michael Glaesemann]
  • Fix that FCGIs would leave log files open when asked to shut down by USR2. 3028 [Sebastian Kanthak, Josh Peek]
  • Fixed that dispatcher preparation callbacks only run once in production mode. Mock Routes.reload so that dispatcher preparation callback tests run. [Rick Olson]
  • Fix syntax error in dispatcher than wrecked failsafe responses. 8625 [mtitorenko]
  • Scaffolded validation errors set the appropriate HTTP status for XML responses. 6946, 8622 [Manfred Stienstra, mmmultiworks]
  • Sexy migrations for the session_migration generator. 8561 [Vladislav]
  • Console reload! runs to_prepare callbacks also. 8393 [f.svehla]
  • Generated migrations include timestamps by default. 8501 [Shane Vitarana]
  • Drop Action Web Service from rails:freeze:edge. [Jeremy Kemper]
  • Add db:create, drop, reset, charset, and collation tasks. 8448 [matt]
  • Scaffold generator depends on model generator instead of duplicating it. 7222 [bscofield]
  • Scaffold generator tests. 8443 [pelle]
  • Generated scaffold functional tests use assert_difference. 8421 [Norbert Crombach]
  • Update to Prototype 1.5.1. [Sam Stephenson]
  • Update to script.aculo.us 1.7.1_beta3. [Thomas Fuchs]
  • Generators use *.html.erb view template naming. 8278 [Tim Pope]
  • Updated resource_scaffold and model generators to use short-hand style migrations [David Heinemeier Hansson]
  • Updated initializer to only load #{RAILS_ENV}.rb once. Added deprecation warning for config.breakpoint_server. [Nicholas Seckar]
  • Removed breakpointer and Binding.of_caller in favor of relying on ruby-debug by Kent Sibilev since the breakpointer has been broken since Ruby 1.8.4 and will not be coming back [David Heinemeier Hansson]

    To use the new debugger, start your server with script/server —debugger and insert a call to ‘debugger’ (instead of ‘breakpoint’) where you want to jump into the debugger.

    BACKWARDS INCOMPATIBILITY NOTE: You must remove the default line 12 from config/environments/development.rb:

      config.breakpoint_server = true

    This configuration option is no longer available. Rails will fail to start in development mode as long as that‘s still present.

  • Resource scaffolding returns the created entity.to_xml. [Jeremy Kemper]
  • Resource scaffolding responds to new.xml. 8185 [Eric Mill]
  • Include Active Resource in rails:freeze:edge rake task. [Thomas Fuchs]
  • Include Active Resource instead of Action Web Service [David Heinemeier Hansson] You can add AWS back with this in config/environment.rb:
      config.load_paths += %W( #{RAILS_ROOT}/vendor/rails/actionwebservice/lib )

    …or just gem ‘actionwebservice‘

  • Give generate scaffold a more descriptive database message. Closes 7316 [Jeremy McAnally]
  • Canonicalize RAILS_ROOT by using File.expand_path on Windows, which doesn‘t have to worry about symlinks, and Pathname#realpath elsewhere, which respects symlinks in relative paths but is incompatible with Windows. 6755 [Jeremy Kemper, trevor]
  • Deprecation: remove components from controller paths. [Jeremy Kemper]
  • Add environment variable RAILS_DEFAULT_DATABASE, which allows the builtin default of ‘mysql’ to be overridden. [Nicholas Seckar]
  • Windows: include MinGW in RUBY_PLATFORM check. 2982 [okkez000@gmail.com, Kaspar Schiess]
  • Split out the basic plugin locator functionality into an abstract super class. Add a FileSystemLocator to do the job of checking the plugin_paths for plugins. Add plugin_locators configuration option which will iterate over the set of plugin locators and load each of the plugin loaders they return. Rename locater everywhere to locator. [Marcel Molina Jr.]
  • Split plugin location and loading out of the initializer and into a new Plugin namespace, which includes Plugin::Locater and Plugin::Loader. The loader class that is used can be customized using the config.plugin_loader option. Those monkey patching the plugin loading subsystem take note, the internals changing here will likely break your modifications. The good news is that it should be substantially easier to hook into the plugin locating and loading process now. [Marcel Molina Jr.]
  • Added assumption that all plugin creators desire to be sharing individuals and release their work under the MIT license [David Heinemeier Hansson]
  • Added source-annotations extractor tasks to rake [Jamis Buck]. This allows you to add FIXME, OPTIMIZE, and TODO comments to your source code that can then be extracted in concert with rake notes (shows all), rake notes:fixme, rake notes:optimize and rake notes:todo.
  • Added fixtures :all to test_helper.rb to assume that most people just want all their fixtures loaded all the time [David Heinemeier Hansson]
  • Added config/initializers where all ruby files within it are automatically loaded after the Rails configuration is done, so you don‘t have to litter the environment.rb file with a ton of mixed stuff [David Heinemeier Hansson]
  • For new apps, generate a random secret for the cookie-based session store. [Jeremy Kemper]
  • Stop swallowing errors during rake test [Michael Koziarski]
  • Update Rails Initializer to use ActionController::Base#view_paths [Rick Olson]
  • Fix gem deprecation warnings, which also means depending on RubyGems 0.9.0+ [Chad Fowler]
  • Plugins may be symlinked in vendor/plugins. 4245 [brandon, progrium@gmail.com]
  • Resource generator depends on the model generator rather than duplicating it. 7269 [bscofield]
  • Add/Update usage documentation for script/destroy, resource generator and scaffold_resource generator. Closes 7092, 7271, 7267. [bscofield]
  • Update to script.aculo.us 1.7.0. [Thomas Fuchs]
  • Update to Prototype 1.5.0. [Sam Stephenson]
  • Generator: use destination path for diff tempfiles. 7015 [alfeld]
  • Fixed that webrick would strip leading newlines and hang connection 4156 [psross]
  • Ensure plugins are in the Dependencies.load_once_paths collection by default. [Rick Olson] If you really want your plugins to reload, add this to the very top of init.rb:
      Dependencies.load_once_paths.delete(lib_path)
  • Allow config.to_prepare to work, make the dispatcher safe to ‘re require’. [Michael Koziarski, Nicholas Seckar]
  • Fix scaffold_resource generator so it respects the —pretend argument when creating the routes file. Closes 6852 [fearoffish]
  • Fix Webrick Daemon dispatching bug regarding a bad current working directory. Closes 4899 [Rick Olson]
  • Make config.plugins affect the load path and the dependencies system. Allows you to control plugin loading order, and keep disabled plugins off the load path. [James Adam]
  • Don‘t generate a components directory in new Rails apps. [Jeremy Kemper]
  • Fixed script/process/spawner to work properly with Mongrel including in -r (daemonize mode) [David Heinemeier Hansson]
  • Added one-letter aliases for the three default environments to script/console, so script/console p will load the production environment (t for test, d for development) [David Heinemeier Hansson]
  • Fixed that script/server running against Mongrel should tail the proper log regardless of the environment [David Heinemeier Hansson]
  • Update initializer to load Rails::VERSION as soon as possible. Closes 6698. [Nicholas Seckar]
  • Added ActiveRecord::Base.clear_active_connections! in development mode so the database connection is not carried over from request to request. Some databases won‘t reread the schema if that doesn‘t happen (I‘m looking at you SQLite), so you have to restart the server after each migration (= no fun) [David Heinemeier Hansson]
  • Made RAILS_GEM_VERSION work for beta gems too, so specifying 1.1.6 will give you 1.1.6.4520 if available [David Heinemeier Hansson]
  • Update to Prototype and script.aculo.us [5579]. [Thomas Fuchs]
  • Made script/server work with -e and -d when using Mongrel [David Heinemeier Hansson]
  • Update to Prototype 1.5.0_rc2 [5550] which makes it work in Opera again [Thomas Fuchs]
  • Make sure that exceptions which are thrown outside of the user code try their best to be handeled in ApplicationController#rescue_action [Tobias Lütke]
  • Rails::VERSION::STRING should always be available without having to require ‘rails/version’. 6244 [fearoffish]
  • Update to Prototype 1.5.0_rc2. [Sam Stephenson]
  • Add grep-based fallback to reaper, to work in pidless setups [Jamis Buck]
  • Only wrap request processing with our USR1 signal handler so FastCGI can trap it and raise an exception while waiting for connections. Idle processes exit immediately rather than waiting for another request; active processes gracefully exit when the request is finished. [Jeremy Kemper]
  • Alter prior change to use require_dependency instead of require_or_load. Causes ApplicationController to be reloaded again. Closes 6587. [Nicholas Seckar]
  • Rake: use absolute paths to load lib and vendor tasks so they may be run outside of RAILS_ROOT. 6584 [jchris]
  • Remove temporary crutch to help ApplicationController be unloaded. Closes 6496. [Nicholas Seckar]
  • scaffold_resource generator uses _path named routes and head instead of render :nothing => true. 6545 [Josh Susser]
  • Generator can show diff on file collision to help you decide whether to skip or overwrite. 6364 [jeffw, Jeremy Kemper]
  • Generated directories are recursively svn added, like mkdir -p. 6416 [NeilW]
  • resource and scaffold_resource generators add a restful route to config/routes.rb [Jeremy Kemper]
  • Revert environment changes for autoload_paths. [Michael Koziarski]
  • Update to latest Prototype, which doesn‘t serialize disabled form elements, adds clone() to arrays, empty/non-string Element.update() and adds a fixes excessive error reporting in WebKit beta versions [Thomas Fuchs]
  • Clean up the output of rake stats, de-emphasise components and apis, and remove the indents for tests [Michael Koziarski]
  • Added option to script/process/spawner of specifying the binding address 5133 [Dee Zsombor]
  • Update environment.rb comments to include config.autoload_paths. Closes 6478 [caio]
  • Update scaffold to use new form_tag block functionality. Closes 6480. [Bob Silva]
  • Plugin generator: check for class collisions. 4833 [vinbarnes@gmail.com]
  • Mailer generator: handle mailers in modules, set mime_version in unit test. [Jeremy Kemper]
  • Set $KCODE to ‘u’ by default to enable the multibyte safe String#chars proxy. [Michael Koziarski]
  • Added config.plugins to control which plugins are loaded 6269 [Stefan Kaes]. By default, everything in vendor/plugins will be loaded, but if you specify config.plugins, only those will be loaded. Example:
      config.plugins = %w[ routing_navigator simply_helpful ]
  • Clean up html on included error pages. [Tim Lucas]
  • Fixed default 404.html and 500.htmls to remove extreme ugliness and include human language [David Heinemeier Hansson]
  • Update to latest Prototype and script.aculo.us trunk versions [Thomas Fuchs]
  • PostgreSQL: db:test:purge closes open database connections first. 6236 [alex]
  • Fixed test:uncommitted on Windows (backslash issue) 4999 [paul@paulbutcher.com]
  • Fixed migration creation to work with namespaced models, so script/generate model Gallery::Image will use create_table :gallery_images 6327 [Bob Silva]
  • Fixed rename_table on SQLite tables with indexes defined 5942 [brandon@opensoul.org]
  • Added default timeout setting of 5 seconds to SQLite3 database.yml configurations [David Heinemeier Hansson]
  • Added generated attribute options to script/generate model, like the one found in scaffold_resource and resource [David Heinemeier Hansson]. Examples:
      ./script/generate model post title:string created_on:date body:text published:boolean
  • Added script/generate resource which works just like scaffold_resource, but creates empty placeholders instead of predefined [David Heinemeier Hansson]
  • script/runner can run files, pass on arguments, and be used as a shebang. 6286 [Tuxie, dlpond]
      #!/usr/bin/env /path/to/my/app/script/runner
  # Example: just start using your models as if you are in script/console
  Product.find(:all).each { |product| product.check_inventory }
  • Look for rake tasks in plugin subdirs. 6259 [obrie]
  • Added map.connect ’:controller/:action/:id.:format’ as a default route to config/routes.rb [David Heinemeier Hansson]
  • Updated prototype.js to 1.5.0_rc1 with latest fixes. [Rick Olson]
    • XPATH support
    • Make Form.getElements() return elements in the correct order
    • fix broken Form.serialize return
  • session_migration generator adds an index on updated_at. 6207 [grg]
  • script/server creates the tmp/pids directory. 6204 [jonathan]
  • Fix script/console —sandbox for internal transactions changes. 5738 [Chris McGrath, charles.gerungan@gmail.com]
  • Remove the uncanny default of adding all app/models/*/ directories to the load path. This change will break application which expect the current behavior. As

documented in initializer.rb, the workaround is:

  config.autoload_paths += Dir[RAILS_ROOT + '/app/models/*/']

References 6031. [Nicholas Seckar]

  • Update to script.aculo.us 1.6.3 [Thomas Fuchs]
  • Update to Prototype 1.5.0_rc1 [sam]
  • Formally Deprecate the old rake tasks. [Michael Koziarski]
  • Thoroughly test the FCGI dispatcher. 5970 [Kevin Clark]
  • Remove Dir.chdir in the Webrick DispatchServlet#initialize method. Fix bad path errors when trying to load config/routes.rb. [Rick Olson]
  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Cleaning up tests. [Kevin Clark, Jeremy Kemper]
  • Add Dependencies.load_once_paths. [Nicholas Seckar]
  • Updated to script.aculo.us 1.6.2 [Thomas Fuchs]
  • Assign Routing.controller_paths; fix script/about and rails info controller. [Nicholas Seckar]
  • Don‘t warn dispatcher of Reloadable deprecations. [Nicholas Seckar]
  • Rearrange application resetting and preparation, fix bug with leaking subclasses hash in ActiveRecord::Base [Rick Olson]

    ActiveRecord::Base.reset_subclasses is called before Dependencies are cleared and classes removed. ActiveRecord::Base.instantiate_observers is called during a Dispatcher preparation callback.

  • Add missing mock directories from the autoload_paths configuration. [Rick Olson]
  • Nested controller scaffolding also nests the generated layout. [iain d broadfoot]
  • Add "require ‘dispatcher’" to webrick server in the continuing quest to squash webrick weirdness. [Nicholas Seckar]
  • Add autoload_paths support to Initializer. [Nicholas Seckar]
  • Fix Dispatcher.reset_application! so that AR subclasses are removed and Observers re-initialized after Reloadable classes are removed. Closes 5743. [Rick Olson]
  • Clarify usage of script/plugin source. Closes 5344. [James Adam]
  • Add Dispatcher.to_prepare and config.to_prepare to provide a pre-request hook. [Nicholas Seckar]
  • Tweak the Rails load order so observers are loaded after plugins, and reloaded in development mode. Closed 5279. [Rick Olson]
  • Added that you can change the web server port in config/lighttpd.conf from script/server —port/-p 5465 [mats@imediatec.co.uk]
  • script/performance/profiler compatibility with the new ruby-prof, including an option to choose the results printer. 5679 [Shugo Maeda]
  • Fixed the failsafe response so it uses either the current recognized controller or ApplicationController. [Rick Olson]
  • Make sure script/reaper only reaps dispatcher pids by default, and not the spawner‘s pid. [Jamis Buck]
  • Fix script/plugin about so it uses about.yml and not meta.yml. [James Adam]
  • Dispatcher processes rescued actions with the same controller that processed the request. 4625 [sd@notso.net]
  • rails -d frontbase to create a new project with a frontbase database.yml. 4945 [mlaster@metavillage.com]
  • Ensure the logger is initialized. 5629 [mike@clarkware.com]
  • Added Mongrel-spawning capabilities to script/process/spawner. Mongrel will be the default choice if installed, otherwise FCGI is tried [David Heinemeier Hansson]. Examples:
      spawner               # starts instances on 8000, 8001, and 8002 using Mongrel if available
  spawner fcgi          # starts instances on 8000, 8001, and 8002 using FCGI
  spawner mongrel -i 5  # starts instances on 8000, 8001, 8002, 8003, and 8004 using Mongrel
  spawner -p 9100 -i 10 # starts 10 instances counting from 9100 to 9109 using Mongrel if available
  spawner -p 9100 -r 5  # starts 3 instances counting from 9100 to 9102 and attempts start them every 5 seconds

    Also note that script/process/reaper is Mongrel capable. So the combination of spawner and reaper is a built-in alternative to something like mongrel_cluster.

  • Update scaffolding functional tests to use :id => people(:first) instead of :id => 1. 5612 [evan@protest.net]
  • db:test:clone should remove existing tables before reloading the schema. 5607 [sveit@tradeharbor.com]
  • Fixed migration generation for class names like ACLController 5197 [brad@madriska.com]
  • Added show_source_list and show_call_stack to breakpoints to make it easier to get context 5476 [takiuchi@drecom.co.jp]. Examples:
      irb(#<TopController:0x40822a68>):002:0> show_source_list
  0001  class TopController < ApplicationController
  0002    def show
  0003->    breakpoint
  0004    end
  0005
  0006    def index
  0007    end
  0008
  => "/path/to/rails/root/app/controllers/top_controller.rb"

  irb(#<TopController:0x40822a68>):004:0> show_call_stack 3
  vendor/rails/railties/lib/breakpoint.rb:536:in `breakpoint'
  vendor/rails/railties/lib/breakpoint.rb:536:in `breakpoint'
  app/controllers/top_controller.rb:3:in `show'
  => "/path/to/rails/root/app/controllers/top_controller.rb:3"
  • Generate scaffold layout in subdirectory appropriate to its module nesting. 5511 [nils@alumni.rice.edu]
  • Mongrel: script/server tails the rails log like it does with lighttpd. Prefer mongrel over lighttpd. 5541 [mike@clarkware.com]
  • Don‘t assume Active Record is available. 5497 [bob@sporkmonger.com]
  • Mongrel: script/server works on Win32. 5499 [jeremydurham@gmail.com]
  • Remove opts.on { |options[:option_name] } style hash assignment. Closes 4440. [Nick Sieger]
  • Mongrel support for script/server. 5475 [jeremydurham@gmail.com]
  • Fix script/plugin so it doesn‘t barf on invalid URLs [Rick Olson]
  • Fix plugin install bug at dir with space. (closes 5359) [Yoshimasa NIWA]
  • Fix bug with ‘script/plugin install’ so it reports unknown plugin names correctly. [Rick Olson]
  • Added uninstall.rb hook to plugin handling, such that plugins have a way of removing assets and other artifacts on removal 5003 [takiuchi@drecom.co.jp]
  • Create temporary dirs relative to RAILS_ROOT when running script/server 5014 [elliot@townx.org]
  • Minor tweak to dispatcher to use recognize instead of recognize!, as per the new routes. [Jamis Buck]
  • Make "script/plugin install" work with svn+ssh URLs. [Sam Stephenson]
  • Added lib/ to the directories that will get application docs generated [David Heinemeier Hansson]
  • Add observer generator. Closes 5167. [François Beausoleil]
  • Session migration generator obeys pluralize_table_names. 5145 [James Adam]
  • rake test:recent understands subdirectories. 2925 [jerrett@bravenet.com]
  • The app generator detects the XAMPP package‘s MySQL socket location. 3832 [elliot@townx.org]
  • The app generator sets a session key in application.rb so apps running on the same host may distinguish their cookies. 2967 [rcoder, rails-bug@owl.me.uk]
  • Distinguish the spawners for different processes [David Heinemeier Hansson]
  • Added -n/—process to script/process/spawner name the process pid (default is dispatch) [David Heinemeier Hansson]
  • Namespaced OrderedHash so the Rails implementation does not clash with any others. (fixes 4911) [Julian Tarkhanov]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Added script/process/inspector to do simple process status information on Rails dispatchers keeping pid files in tmp/pids [David Heinemeier Hansson]
  • Added pid file usage to script/process/spawner and script/process/reaper along with a directive in default config/lighttpd.conf file to record the pid. They will all save their pid file in tmp/pids [David Heinemeier Hansson]

*1.2.3* (March 12th, 2007)

  • Ruby 1.8.6 compatibility
  • Windows: include MinGW in RUBY_PLATFORM check. 2982 [okkez000@gmail.com, Kaspar Schiess]
  • Stop swallowing errors during rake test [Michael Koziarski]

*1.2.2* (February 5th, 2007)

  • Fix gem deprecation warnings, which also means depending on RubyGems 0.9.0+ [Chad Fowler]
  • Require the dispatcher for Rails::Configuration#to_prepare. [Rick Olson]

*1.2.1* (January 16th, 2007)

  • Updated to Active Record 1.15.1, Action Pack 1.13.1, Action Mailer 1.3.1, Action Web Service 1.2.1

*1.2.0* (January 16th, 2007)

  • Update to Prototype 1.5.0. [Sam Stephenson]
  • Generator: use destination path for diff tempfiles. 7015 [alfeld]
  • Fixed that webrick would strip leading newlines and hang connection 4156 [psross]
  • Ensure plugins are in the Dependencies.load_once_paths collection by default. [Rick Olson] If you really want your plugins to reload, add this to the very top of init.rb:
      Dependencies.load_once_paths.delete(lib_path)
  • Fix scaffold_resource generator so it respects the —pretend argument when creating the routes file. Closes 6852 [fearoffish]
  • Fix Webrick Daemon dispatching bug regarding a bad current working directory. Closes 4899 [Rick Olson]
  • Make config.plugins affect the load path and the dependencies system. Allows you to control plugin loading order, and keep disabled plugins off the load path. [James Adam]
  • Don‘t generate a components directory in new Rails apps. [Jeremy Kemper]
  • Fixed script/process/spawner to work properly with Mongrel including in -r (daemonize mode) [David Heinemeier Hansson]
  • Deprecated the name route "root" as it‘ll be used as a shortcut for map.connect ’’ in Rails 2.0 [David Heinemeier Hansson]
  • Fixed that script/server running against Mongrel should tail the proper log regardless of the environment [David Heinemeier Hansson]
  • Update initializer to load Rails::VERSION as soon as possible. Closes 6698. [Nicholas Seckar]
  • Added ActiveRecord::Base.clear_active_connections! in development mode so the database connection is not carried over from request to request. Some databases won‘t reread the schema if that doesn‘t happen (I‘m looking at you SQLite), so you have to restart the server after each migration (= no fun) [David Heinemeier Hansson]
  • Made RAILS_GEM_VERSION work for beta gems too, so specifying 1.1.6 will give you 1.1.6.4520 if available [David Heinemeier Hansson]
  • Update to Prototype and script.aculo.us [5579]. [Sam Stephenson, Thomas Fuchs]
  • Made script/server work with -e and -d when using Mongrel [David Heinemeier Hansson]
  • Make sure that exceptions which are thrown outside of the user code try their best to be handeled in ApplicationController#rescue_action [Tobias Lütke]
  • Rails::VERSION::STRING should always be available without having to require ‘rails/version’. 6244 [fearoffish]
  • Add grep-based fallback to reaper, to work in pidless setups [Jamis Buck]
  • Only wrap request processing with our USR1 signal handler so FastCGI can trap it and raise an exception while waiting for connections. Idle processes exit immediately rather than waiting for another request; active processes gracefully exit when the request is finished. [Jeremy Kemper]
  • Alter prior change to use require_dependency instead of require_or_load. Causes ApplicationController to be reloaded again. Closes 6587. [Nicholas Seckar]
  • Rake: use absolute paths to load lib and vendor tasks so they may be run outside of RAILS_ROOT. 6584 [jchris]
  • scaffold_resource generator uses _path named routes and head instead of render :nothing => true. 6545 [Josh Susser]
  • Generator can show diff on file collision to help you decide whether to skip or overwrite. 6364 [jeffw, Jeremy Kemper]
  • Generated directories are recursively svn added, like mkdir -p. 6416 [NeilW]
  • resource and scaffold_resource generators add a restful route to config/routes.rb [Jeremy Kemper]
  • Revert environment changes for autoload_paths. [Michael Koziarski]
  • Clean up the output of rake stats, de-emphasise components and apis, and remove the indents for tests [Michael Koziarski]
  • Added option to script/process/spawner of specifying the binding address 5133 [Dee Zsombor]
  • Update environment.rb comments to include config.autoload_paths. Closes 6478 [caio]
  • Update scaffold to use new form_tag block functionality. Closes 6480. [Bob Silva]
  • Plugin generator: check for class collisions. 4833 [vinbarnes@gmail.com]
  • Mailer generator: handle mailers in modules, set mime_version in unit test. [Jeremy Kemper]
  • Set $KCODE to ‘u’ by default to enable the multibyte safe String#chars proxy. [Michael Koziarski]
  • Added config.plugins to control which plugins are loaded 6269 [Stefan Kaes]. By default, everything in vendor/plugins will be loaded, but if you specify config.plugins, only those will be loaded. Example:
      config.plugins = %w[ routing_navigator simply_helpful ]
  • Clean up html on included error pages. [Tim Lucas]
  • Fixed default 404.html and 500.htmls to remove extreme ugliness and include human language [David Heinemeier Hansson]
  • Update to latest Prototype and script.aculo.us trunk versions [Thomas Fuchs]
  • PostgreSQL: db:test:purge closes open database connections first. 6236 [alex]
  • Fixed test:uncommitted on Windows (backslash issue) 4999 [paul@paulbutcher.com]
  • Fixed migration creation to work with namespaced models, so script/generate model Gallery::Image will use create_table :gallery_images 6327 [Bob Silva]
  • Fixed rename_table on SQLite tables with indexes defined 5942 [brandon@opensoul.org]
  • Added default timeout setting of 5 seconds to SQLite3 database.yml configurations [David Heinemeier Hansson]
  • Added generated attribute options to script/generate model, like the one found in scaffold_resource and resource [David Heinemeier Hansson]. Examples:
      ./script/generate model post title:string created_on:date body:text published:boolean
  • Added script/generate resource which works just like scaffold_resource, but creates empty placeholders instead of predefined [David Heinemeier Hansson]
  • script/runner can run files, pass on arguments, and be used as a shebang. 6286 [Tuxie, dlpond]
      #!/usr/bin/env /path/to/my/app/script/runner
  # Example: just start using your models as if you are in script/console
  Product.find(:all).each { |product| product.check_inventory }
  • Look for rake tasks in plugin subdirs. 6259 [obrie]
  • Added map.connect ’:controller/:action/:id.:format’ as a default route to config/routes.rb [David Heinemeier Hansson]
  • session_migration generator adds an index on updated_at. 6207 [grg]
  • script/server creates the tmp/pids directory. 6204 [jonathan]
  • Fix script/console —sandbox for internal transactions changes. 5738 [Chris McGrath, charles.gerungan@gmail.com]
  • Remove the uncanny default of adding all app/models/*/ directories to the load path. This change will break application which expect the current behavior. As

documented in initializer.rb, the workaround is:

  config.autoload_paths += Dir[RAILS_ROOT + '/app/models/*/']

References 6031. [Nicholas Seckar]

  • Update to script.aculo.us 1.6.3 [Thomas Fuchs]
  • Formally Deprecate the old rake tasks. [Michael Koziarski]
  • Thoroughly test the FCGI dispatcher. 5970 [Kevin Clark]
  • Remove Dir.chdir in the Webrick DispatchServlet#initialize method. Fix bad path errors when trying to load config/routes.rb. [Rick Olson]
  • Tighten rescue clauses. 5985 [james@grayproductions.net]
  • Cleaning up tests. [Kevin Clark, Jeremy Kemper]
  • Add Dependencies.load_once_paths. [Nicholas Seckar]
  • Assign Routing.controller_paths; fix script/about and rails info controller. [Nicholas Seckar]
  • Don‘t warn dispatcher of Reloadable deprecations. [Nicholas Seckar]
  • Rearrange application resetting and preparation, fix bug with leaking subclasses hash in ActiveRecord::Base [Rick Olson]

    ActiveRecord::Base.reset_subclasses is called before Dependencies are cleared and classes removed. ActiveRecord::Base.instantiate_observers is called during a Dispatcher preparation callback.

  • Add missing mock directories from the autoload_paths configuration. [Rick Olson]
  • Nested controller scaffolding also nests the generated layout. [iain d broadfoot]
  • Add "require ‘dispatcher’" to webrick server in the continuing quest to squash webrick weirdness. [Nicholas Seckar]
  • Add autoload_paths support to Initializer. [Nicholas Seckar]
  • Fix Dispatcher.reset_application! so that AR subclasses are removed and Observers re-initialized after Reloadable classes are removed. Closes 5743. [Rick Olson]
  • Clarify usage of script/plugin source. Closes 5344. [James Adam]
  • Add Dispatcher.to_prepare and config.to_prepare to provide a pre-request hook. [Nicholas Seckar]
  • Tweak the Rails load order so observers are loaded after plugins, and reloaded in development mode. Closed 5279. [Rick Olson]
  • Added that you can change the web server port in config/lighttpd.conf from script/server —port/-p 5465 [mats@imediatec.co.uk]
  • script/performance/profiler compatibility with the new ruby-prof, including an option to choose the results printer. 5679 [Shugo Maeda]
  • Fixed the failsafe response so it uses either the current recognized controller or ApplicationController. [Rick Olson]
  • Make sure script/reaper only reaps dispatcher pids by default, and not the spawner‘s pid. [Jamis Buck]
  • Fix script/plugin about so it uses about.yml and not meta.yml. [James Adam]
  • Dispatcher processes rescued actions with the same controller that processed the request. 4625 [sd@notso.net]
  • rails -d frontbase to create a new project with a frontbase database.yml. 4945 [mlaster@metavillage.com]
  • Ensure the logger is initialized. 5629 [mike@clarkware.com]
  • Added Mongrel-spawning capabilities to script/process/spawner. Mongrel will be the default choice if installed, otherwise FCGI is tried [David Heinemeier Hansson]. Examples:
      spawner               # starts instances on 8000, 8001, and 8002 using Mongrel if available
  spawner fcgi          # starts instances on 8000, 8001, and 8002 using FCGI
  spawner mongrel -i 5  # starts instances on 8000, 8001, 8002, 8003, and 8004 using Mongrel
  spawner -p 9100 -i 10 # starts 10 instances counting from 9100 to 9109 using Mongrel if available
  spawner -p 9100 -r 5  # starts 3 instances counting from 9100 to 9102 and attempts start them every 5 seconds

    Also note that script/process/reaper is Mongrel capable. So the combination of spawner and reaper is a built-in alternative to something like mongrel_cluster.

  • Update scaffolding functional tests to use :id => people(:first) instead of :id => 1. 5612 [evan@protest.net]
  • db:test:clone should remove existing tables before reloading the schema. 5607 [sveit@tradeharbor.com]
  • Fixed migration generation for class names like ACLController 5197 [brad@madriska.com]
  • Added show_source_list and show_call_stack to breakpoints to make it easier to get context 5476 [takiuchi@drecom.co.jp]. Examples:
      irb(#<TopController:0x40822a68>):002:0> show_source_list
  0001  class TopController < ApplicationController
  0002    def show
  0003->    breakpoint
  0004    end
  0005
  0006    def index
  0007    end
  0008
  => "/path/to/rails/root/app/controllers/top_controller.rb"

  irb(#<TopController:0x40822a68>):004:0> show_call_stack 3
  vendor/rails/railties/lib/breakpoint.rb:536:in `breakpoint'
  vendor/rails/railties/lib/breakpoint.rb:536:in `breakpoint'
  app/controllers/top_controller.rb:3:in `show'
  => "/path/to/rails/root/app/controllers/top_controller.rb:3"
  • Generate scaffold layout in subdirectory appropriate to its module nesting. 5511 [nils@alumni.rice.edu]
  • Mongrel: script/server tails the rails log like it does with lighttpd. Prefer mongrel over lighttpd. 5541 [mike@clarkware.com]
  • Don‘t assume Active Record is available. 5497 [bob@sporkmonger.com]
  • Mongrel: script/server works on Win32. 5499 [jeremydurham@gmail.com]
  • Remove opts.on { |options[:option_name] } style hash assignment. Closes 4440. [Nick Sieger]
  • Mongrel support for script/server. 5475 [jeremydurham@gmail.com]
  • Fix script/plugin so it doesn‘t barf on invalid URLs [Rick Olson]
  • Fix plugin install bug at dir with space. (closes 5359) [Yoshimasa NIWA]
  • Fix bug with ‘script/plugin install’ so it reports unknown plugin names correctly. [Rick Olson]
  • Added uninstall.rb hook to plugin handling, such that plugins have a way of removing assets and other artifacts on removal 5003 [takiuchi@drecom.co.jp]
  • Create temporary dirs relative to RAILS_ROOT when running script/server 5014 [elliot@townx.org]
  • Minor tweak to dispatcher to use recognize instead of recognize!, as per the new routes. [Jamis Buck]
  • Make "script/plugin install" work with svn+ssh URLs. [Sam Stephenson]
  • Added lib/ to the directories that will get application docs generated [David Heinemeier Hansson]
  • Add observer generator. Closes 5167. [François Beausoleil]
  • Session migration generator obeys pluralize_table_names. 5145 [James Adam]
  • rake test:recent understands subdirectories. 2925 [jerrett@bravenet.com]
  • The app generator detects the XAMPP package‘s MySQL socket location. 3832 [elliot@townx.org]
  • The app generator sets a session key in application.rb so apps running on the same host may distinguish their cookies. 2967 [rcoder, rails-bug@owl.me.uk]
  • Distinguish the spawners for different processes [David Heinemeier Hansson]
  • Added -n/—process to script/process/spawner name the process pid (default is dispatch) [David Heinemeier Hansson]
  • Namespaced OrderedHash so the Rails implementation does not clash with any others. (fixes 4911) [Julian Tarkhanov]
  • Replace Ruby‘s deprecated append_features in favor of included. [Marcel Molina Jr.]
  • Added script/process/inspector to do simple process status information on Rails dispatchers keeping pid files in tmp/pids [David Heinemeier Hansson]
  • Added pid file usage to script/process/spawner and script/process/reaper along with a directive in default config/lighttpd.conf file to record the pid. They will all save their pid file in tmp/pids [David Heinemeier Hansson]

*1.1.6* (August 10th, 2006)

  • Additional security patch

*1.1.5* (August 8th, 2006)

  • Mention in docs that config.frameworks doesn‘t work when getting Rails via Gems. 4857 [Alisdair McDiarmid]
  • Change the scaffolding layout to use yield rather than @content_for_layout. [Marcel Molina Jr.]
  • Includes critical security patch

*1.1.4* (June 29th, 2006)

  • Remove use of opts.on { |options[:name] } style hash assignment. References 4440. [headius@headius.com]
  • Updated to Action Pack 1.12.3, ActionWebService 1.1.4, ActionMailer 1.2.3

*1.1.3* (June 27th, 2006)

  • Updated to Active Record 1.14.3, Action Pack 1.12.2, ActionWebService 1.1.3, ActionMailer 1.2.2

*1.1.2* (April 9th, 2006)

  • Mention in docs that config.frameworks doesn‘t work when getting Rails via Gems. Closes 4857. [Alisdair McDiarmid]
  • Change the scaffolding layout to use yield rather than @content_for_layout. [Marcel Molina Jr.]
  • Added rake rails:update:configs to update config/boot.rb from the latest (also included in rake rails:update) [David Heinemeier Hansson]
  • Fixed that boot.rb would set RAILS_GEM_VERSION twice, not respect an uncommented RAILS_GEM_VERSION line, and not use require_gem [David Heinemeier Hansson]

*1.1.1* (April 6th, 2006)

  • Enhances plugin#discover allowing it to discover svn:// like URIs (closes 4565) [ruben.nine@gmail.com]
  • Update to Prototype 1.5.0_rc0 [Sam Stephenson]
  • Fixed that the -r/—ruby path option of the rails command was not being respected 4549 [ryan.raaum@gmail.com]
  • Added that Dispatcher exceptions should not be shown to the user unless a default log has not been configured. Instead show public/500.html [David Heinemeier Hansson]
  • Fixed that rake clone_structure_to_test should quit on pgsql if the dump is unsuccesful 4585 [augustz@augustz.com]
  • Fixed that rails —version should have the return code of 0 (success) 4560 [blair@orcaware.com]
  • Install alias so Rails::InfoController is accessible at /rails_info. Closes 4546. [Nicholas Seckar]
  • Fixed that spawner should daemonize if running in repeat mode [David Heinemeier Hansson]
  • Added TAG option for rake rails:freeze:edge, so you can say rake rails:freeze:edge TAG=rel_1-1-0 to lock to the 1.1.0 release [David Heinemeier Hansson]
  • Applied Prototype $() performance patches (4465, 4477) and updated script.aculo.us [Sam Stephenson, Thomas Fuchs]
  • Use —simple-prompt instead of —prompt-mode simple for console compatibility with Windows/Ruby 1.8.2 4532 [starr@starrnhorne.com]
  • Make Rails::VERSION implicitly loadable 4491. [Nicholas Seckar]
  • Fixed rake rails:freeze:gems 4518 [benji@silverinsanity.com]
  • Added -f/—freeze option to rails command for freezing the application to the Rails version it was generated with [David Heinemeier Hansson]
  • Added gem binding of apps generated through the rails command to the gems of they were generated with [Nicholas Seckar]
  • Added expiration settings for JavaScript, CSS, HTML, and images to default lighttpd.conf [David Heinemeier Hansson]
  • Added gzip compression for JavaScript, CSS, and HTML to default lighttpd.conf [David Heinemeier Hansson]
  • Avoid passing escapeHTML non-string in Rails’ info controller [Nicholas Seckar]

*1.1.0* (March 27th, 2006)

  • Allow db:fixtures:load to load a subset of the applications fixtures. [Chad Fowler]

    ex.

     rake db:fixtures:load FIXTURES=customers,plans
  • Update to Prototype 1.5.0_pre1 [Sam Stephenson]
  • Update to script.aculo.us 1.6 [Thomas Fuchs]
  • Add an integration_test generator [Jamis Buck]
  • Make all ActionView helpers available in the console from the helper method for debugging purposes. n.b.: Only an 80% solution. Some stuff won‘t work, most will. [Marcel Molina Jr.]

    ex.

      >> puts helper.options_for_select([%w(a 1), %w(b 2), %w(c 3)])
  <option value="1">a</option>
  <option value="2">b</option>
  <option value="3">c</option>
  => nil
  • Replaced old session rake tasks with db:sessions:create to generate a migration, and db:sessions:clear to remove sessions. [Rick Olson]
  • Reject Ruby 1.8.3 when loading Rails; extract version checking code. [Chad Fowler]
  • Remove explicit loading of RailsInfo and RailsInfoController. [Nicholas Seckar]
  • Move RailsInfo and RailsInfoController to Rails::Info and Rails::InfoController. [Nicholas Seckar]
  • Extend load path with Railties’ builtin directory to make adding support code easy. [Nicholas Seckar]
  • Fix the rails_info controller by explicitly loading it, and marking it as not reloadable. [Nicholas Seckar]
  • Fixed rails:freeze:gems for Windows 3274 [paul@paulbutcher.com]
  • Added ‘port open?’ check to the spawner when running in repeat mode so we don‘t needlessly boot the dispatcher if the port is already in use anyway 4089 [guy.naor@famundo.com]
  • Add verification to generated scaffolds, don‘t allow get for unsafe actions [Michael Koziarski]
  • Don‘t replace application.js in public/javascripts if it already exists [Cody Fauser]
  • Change test:uncommitted to delay execution of `svn status` by using internal Rake API‘s. [Nicholas Seckar]
  • Use require_library_or_gem to load rake in commands/server.rb. Closes 4205. [rob.rasmussen@gmail.com]
  • Use the Rake API instead of shelling out to create the tmp directory in commands/server.rb. [Chad Fowler]
  • Added a backtrace to the evil WSOD (White Screen of Death). Closes 4073. TODO: Clearer exceptions [Rick Olson]
  • Added tracking of database and framework versions in script/about 4088 [charles.gerungan@gmail.com/Rick Olson]
  • Added public/javascripts/application.js as a sample since it‘ll automatically be included in javascript_include_tag :defaults [David Heinemeier Hansson]
  • Added socket cleanup for lighttpd, both before and after [David Heinemeier Hansson]
  • Added automatic creation of tmp/ when running script/server [David Heinemeier Hansson]
  • Added silence_stream that‘ll work on both STDERR or STDOUT or any other stream and deprecated silence_stderr in the process [David Heinemeier Hansson]
  • Added reload! method to script/console to reload all models and others that include Reloadable without quitting the console 4056 [esad@esse.at]
  • Added that rake rails:freeze:edge will now just export all the contents of the frameworks instead of just lib, so stuff like rails:update:scripts, rails:update:javascripts, and script/server on lighttpd still just works 4047 [David Heinemeier Hansson]
  • Added fix for upload problems with lighttpd from Safari/IE to config/lighttpd.conf 3999 [Thijs van der Vossen]
  • Added test:uncommitted to test changes since last checkin to Subversion 4035 [technomancy@gmail.com]
  • Help script/about print the correct svn revision when in a non-English locale. 4026 [babie7a0@ybb.ne.jp]
  • Add ‘app’ accessor to script/console as an instance of Integration::Session [Jamis Buck]
  • Generator::Base#usage takes an optional message argument which defaults to Generator::Base#usage_message. [Jeremy Kemper]
  • Remove the extraneous AR::Base.threaded_connections setting from the webrick server. [Jeremy Kemper]
  • Add integration test support to app generation and testing [Jamis Buck]
  • Added namespaces to all tasks, so for example load_fixtures is now db:fixtures:load. All the old task names are still valid, they just point to the new namespaced names. "rake -T" will only show the namespaced ones, though [David Heinemeier Hansson]
  • CHANGED DEFAULT: ActiveRecord::Base.schema_format is now :ruby by default instead of :sql. This means that we‘ll assume you want to live in the world of db/schema.rb where the grass is green and the girls are pretty. If your schema contains un-dumpable elements, such as constraints or database-specific column types, you just got an invitation to either 1) patch the dumper to include foreign key support, 2) stop being db specific, or 3) just change the default in config/environment.rb to config.active_record.schema_format = :sql — we even include an example for that on new Rails skeletons now. Brought to you by the federation of opinionated framework builders! [David Heinemeier Hansson]
  • Added -r/—repeat option to script/process/spawner that offers the same loop protection as the spinner did. This deprecates the script/process/spinner, so it‘s no longer included in the default Rails skeleton, but still available for backwards compatibility 3461 [ror@andreas-s.net]
  • Added collision option to template generation in generators 3329 [anna@wota.jp]. Examples:
      m.template "stuff.config" , "config/stuff.config" , :collision => :skip
  m.template "auto-stamping", "config/generator.log", :collision => :force
  • Added more information to script/plugin‘s doings to ease debugging 3755 [Rick Olson]
  • Changed the default configuration for lighttpd to use tmp/sockets instead of log/ for the FastCGI sockets [David Heinemeier Hansson]
  • Added a default configuration of the FileStore for fragment caching if tmp/cache is available, which makes action/fragment caching ready to use out of the box with no additional configuration [David Heinemeier Hansson]
  • Changed the default session configuration to place sessions in tmp/sessions, if that directory is available, instead of /tmp (this essentially means a goodbye to 9/10 White Screen of Death errors and should have web hosting firms around the world cheering) [David Heinemeier Hansson]
  • Added tmp/sessions, tmp/cache, and tmp/sockets as default directories in the Rails skeleton [David Heinemeier Hansson]
  • Added that script/generate model will now automatically create a migration file for the model created. This can be turned off by calling the generator with —skip-migration [David Heinemeier Hansson]
  • Added -d/—database option to the rails command, so you can do "rails —database=sqlite2 myapp" to start a new application preconfigured to use SQLite2 as the database. Removed the configuration examples from SQLite and PostgreSQL from the default MySQL configuration [David Heinemeier Hansson]
  • Allow script/server -c /path/to/lighttpd.conf [Jeremy Kemper]
  • Remove hardcoded path to reaper script in script/server [Jeremy Kemper]
  • Update script.aculo.us to V1.5.3 [Thomas Fuchs]
  • Added SIGTRAP signal handler to RailsFCGIHandler that‘ll force the process into a breakpoint after the next request. This breakpoint can then be caught with script/breakpointer and give you access to the Ruby image inside that process. Useful for debugging memory leaks among other things [David Heinemeier Hansson]
  • Changed default lighttpd.conf to use CWD from lighttpd 1.4.10 that allows the same configuration to be used for both detach and not. Also ensured that auto-repeaping of FCGIs only happens when lighttpd is not detached. [David Heinemeier Hansson]
  • Added Configuration#after_initialize for registering a block which gets called after the framework is fully initialized. Useful for things like per-environment configuration of plugins. [Michael Koziarski]
  • Added check for RAILS_FRAMEWORK_ROOT constant that allows the Rails framework to be found in a different place than vendor/rails. Should be set in boot.rb. [David Heinemeier Hansson]
  • Fixed that static requests could unlock the mutex guarding dynamic requests in the WEBrick servlet 3433 [tom@craz8.com]
  • Fixed documentation tasks to work with Rake 0.7.0 3563 [kazuhiko@fdiary.net]
  • Update to Prototype 1.5.0_pre0 [Sam Stephenson]
  • Sort the list of plugins so we load in a consistent order [Rick Olson]
  • Show usage when script/plugin is called without arguments [tom@craz8.com]
  • Corrected problems with plugin loader where plugins set ‘name’ incorrectly 3297 [anna@wota.jp]
  • Make migration generator only report on exact duplicate names, not partial dupliate names. 3442 [jeremy@planetargon.com Marcel Molina Jr.]
  • Fix typo in mailer generator USAGE. 3458 [chriztian.steinmeier@gmail.com]
  • Ignore version mismatch between pg_dump and the database server. 3457 [Simon Stapleton]
  • Reap FCGI processes after lighttpd exits. [Sam Stephenson]
  • Honor ActiveRecord::Base.pluralize_table_names when creating and destroying session store table. 3204. [rails@bencurtis.com, Marcel Molina Jr.]

*1.0.0* (December 13th, 2005)

  • Update instructions on how to find and install generators. 3172. [Chad Fowler]
  • Generator looks in vendor/generators also. [Chad Fowler]
  • Generator copies files in binary mode. 3156 [minimudboy@gmail.com]
  • Add builtin/ to the gemspec. Closes 3047. [Nicholas Seckar, Sam Stephenson]
  • Add install.rb file to plugin generation which is loaded, if it exists, when you install a plugin. [Marcel Molina Jr.]
  • Run initialize_logger in script/lighttpd to ensure the log file exists before tailing it. [Sam Stephenson]
  • Make load_fixtures include csv fixtures. 3053. [me@mdaines.com]
  • Fix freeze_gems so that the latest rails version is dumped by default. [Nicholas Seckar]
  • script/plugin: handle root paths and plugin names which contain spaces. 2995 [justin@aspect.net]
  • Model generator: correct relative path to test_helper in unit test. [Jeremy Kemper]
  • Make the db_schema_dump task honor the SCHEMA environment variable if present the way db_schema_import does. 2931. [Blair Zajac]
  • Have the lighttpd server script report the actual ip to which the server is bound. 2903. [Adam]
  • Add plugin library directories to the load path after the lib directory so that libraries in the lib directory get precedence. 2910. [James Adam]
  • Make help for the console command more explicit about how to specify the desired environment in which to run the console. 2911. [anonymous]
  • PostgreSQL: the purge_test_database Rake task shouldn‘t explicitly specify the template0 template when creating a fresh test database. 2964 [Dreamer3]
  • Introducing the session_migration generator. Creates an add_session_table migration. Allows generator to specify migrations directory. 2958, 2960 [Rick Olson]
  • script/console uses RAILS_ENV environment variable if present. 2932 [Blair Zajac <blair@orcaware.com>
  • Windows: eliminate the socket option in database.yml. 2924 [Wayne Vucenic <waynev@gmail.com>]
  • Eliminate nil from newly generated logfiles. 2927 [Blair Zajac <blair@orcaware.com>]
  • Rename Version constant to VERSION. 2802 [Marcel Molina Jr.]
  • Eliminate Subversion dependencies in scripts/plugin. Correct install options. Introduce —force option to reinstall a plugin. Remove useless —long option for list. Use —quiet to quiet the download output and —revision to update to a specific svn revision. 2842 [Chad Fowler, Rick Olson]
  • SQLite: the clone_structure_to_test and purge_test_database Rake tasks should always use the test environment. 2846 [Rick Olson]
  • Make sure that legacy db tasks also reference :database for SQLite 2830 [kazuhiko@fdiary.net]
  • Pass FILE when evaluating plugins’ init.rb. 2817 [James Adam]
  • Better svn status matching for generators. 2814 [François Beausoleil <francois.beausoleil@gmail.com>, Blair Zajac <blair@orcaware.com>]
  • Don‘t reload routes until plugins have been loaded so they have a chance to extend the routing capabilities [David Heinemeier Hansson]
  • Don‘t detach or fork for script/server tailing [Nicholas Seckar]
  • Changed all script/* to use #!/usr/bin/env ruby instead of hard-coded Ruby path. public/dispatcher.* still uses the hard-coded path for compatibility with web servers that don‘t have Ruby in path [David Heinemeier Hansson]
  • Force RAILS_ENV to be "test" when running tests, so that ENV["RAILS_ENV"] = "production" in config/environment.rb doesn‘t wreck havok [David Heinemeier Hansson] 2660
  • Correct versioning in :freeze_gems Rake task. 2778 [Jakob Skjerning, Jeremy Kemper]
  • Added an omnipresent RailsInfoController with a properties action that delivers an HTML rendering of Rails::Info (but only when local_request? is true). Added a new default index.html which fetches this with Ajax. [Sam Stephenson]

*0.14.3 (RC4)* (November 7th, 2005)

  • Add ‘add_new_scripts’ rake task for adding new rails scripts to script/* [Jamis Buck]
  • Remove bogus hyphen from script/process/reaper calls to ‘ps’. 2767 [anonymous]
  • Copy lighttpd.conf when it is first needed, instead of on app creation [Jamis Buck]
  • Use require_library_or_gem ‘fcgi’ in script/server [Sam Stephenson]
  • Added default lighttpd config in config/lighttpd.conf and added a default runner for lighttpd in script/server (works like script/server, but using lighttpd and FastCGI). It will use lighttpd if available, otherwise WEBrick. You can force either or using ‘script/server lighttpd’ or ‘script/server webrick’ [David Heinemeier Hansson]
  • New configuration option config.plugin_paths which may be a single path like the default ‘vendor/plugins’ or an array of paths: [‘vendor/plugins’, ‘lib/plugins’]. [Jeremy Kemper]
  • Plugins are discovered in nested paths, so you can organize your plugins directory as you like. [Jeremy Kemper]
  • Refactor load_plugin from load_plugins. 2757 [alex.r.moon@gmail.com]
  • Make use of silence_stderr in script/lighttpd, script/plugin, and Rails::Info [Sam Stephenson]
  • Enable HTTP installation of plugins when svn isn‘t avaialable. Closes 2661. [Chad Fowler]
  • Added script/about to display formatted Rails::Info output [Sam Stephenson]
  • Added Rails::Info to catalog assorted information about a Rails application‘s environment [Sam Stephenson]
  • Tail the logfile when running script/server lighttpd in the foreground [Sam Stephenson]
  • Try to guess the port number from config/lighttpd.conf in script/server lighttpd [Sam Stephenson]
  • Don‘t reap spawn-fcgi. 2727 [matthew@walker.wattle.id.au]
  • Reaper knows how to find processes even if the dispatch path is very long. 2711 [matthew@walker.wattle.id.au]
  • Make fcgi handler respond to TERM signals with an explicit exit [Jamis Buck]
  • Added demonstration of fixture use to the test case generated by the model generator [David Heinemeier Hansson]
  • If specified, pass PostgreSQL client character encoding to createdb. 2703 [Kazuhiko <kazuhiko@fdiary.net>]
  • Catch CGI multipart parse errors. Wrap dispatcher internals in a failsafe response handler. [Jeremy Kemper]
  • The freeze_gems Rake task accepts the VERSION environment variable to decide which version of Rails to pull into vendor/rails. [Chad Fowler, Jeremy Kemper]
  • Removed script.aculo.us.js, builder.js and slider.js (preperation for move of scriptaculous extensions to plugins, core scriptaculous will remain in Railties) [Thomas Fuchs]
  • The freeze_edge Rake task does smarter svn detection and can export a specific revision by passing the REVISION environment variable. For example: rake freeze_edge REVISION=1234. 2663 [Rick Olson]
  • Comment database.yml and include PostgreSQL and SQLite examples. [Jeremy Kemper]
  • Improve script/plugin on Windows. 2646 [Chad Fowler]
  • The *_plugindoc Rake tasks look deeper into the plugins’ lib directories. 2652 [bellis@deepthought.org]
  • The PostgreSQL :db_structure_dump Rake task limits its dump to the schema search path in database.yml. [Anatol Pomozov <anatol.pomozov@gmail.com>]
  • Add task to generate rdoc for all installed plugins. [Marcel Molina Jr.]
  • Update script.aculo.us to V1.5_rc4 [Thomas Fuchs]
  • Add default Mac + DarwinPorts MySQL socket locations to the app generator. [Jeremy Kemper]
  • Migrations may be destroyed: script/destroy migration foo. 2635 [Charles M. Gerungan <charles.gerungan@gmail.com>, Jamis Buck, Jeremy Kemper]
  • Added that plugins can carry generators and that generator stub files can be created along with new plugins using script/generate plugin <name> —with-generator [David Heinemeier Hansson]
  • Removed app/apis as a default empty dir since its automatically created when using script/generate web_service [David Heinemeier Hansson]
  • Added script/plugin to manage plugins (install, remove, list, etc) [Ryan Tomayko]
  • Added test_plugins task: Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name) [David Heinemeier Hansson]
  • Added plugin generator to create a stub structure for a new plugin in vendor/plugins (see "script/generate plugin" for help) [David Heinemeier Hansson]
  • Fixed scaffold generator when started with only 1 parameter 2609 [self@mattmower.com]
  • rake should run functional tests even if the unit tests have failures [Jim Weirich]
  • Back off cleanpath to be symlink friendly. Closes 2533 [Nicholas Seckar]
  • Load rake task files in alphabetical order so you can build dependencies and count on them 2554 [Blair Zajac]

*0.14.2 (RC3)* (October 26th, 2005)

  • Constants set in the development/test/production environment file are set in Object
  • Scaffold generator pays attention to the controller name. 2562 [self@mattmower.com]
  • Include tasks from vendor/plugins/*/tasks in the Rakefile 2545 [Rick Olson]

*0.14.1 (RC2)* (October 19th, 2005)

  • Don‘t clean RAILS_ROOT on windows
  • Remove trailing ’/’ from RAILS_ROOT [Nicholas Seckar]
  • Upgraded to Active Record 1.12.1 and Action Pack 1.10.1

*0.14.0 (RC1)* (October 16th, 2005)

  • Moved generator folder from RAILS_ROOT/generators to RAILS_ROOT/lib/generators [Tobias Lütke]
  • Fix rake dev and related commands [Nicholas Seckar]
  • The rails command tries to deduce your MySQL socket by running `mysql_config


Class: BlankSlate

Class | BlankSlate
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb
Parent: | Object

BlankSlate provides an abstract base class with no predefined methods (except for __send__ and __id__). BlankSlate is useful as a base class when writing classes that depend upon method_missing (e.g. dynamic proxies).

Methods

find_hidden_method hide reveal

Public Class methods

find_hidden_method(name)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 31
31:     def find_hidden_method(name)
32:       @hidden_methods ||= {}
33:       @hidden_methods[name] || superclass.find_hidden_method(name)
34:     end
hide(name)

Hide the method named name in the BlankSlate class. Don‘t hide instance_eval or any method beginning with "__".

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 22
22:     def hide(name)
23:       if instance_methods.include?(name.to_s) and
24:         name !~ /^(__|instance_eval)/
25:         @hidden_methods ||= {}
26:         @hidden_methods[name.to_sym] = instance_method(name)
27:         undef_method name
28:       end
29:     end
reveal(name)

Redefine a previously hidden method so that it may be called on a blank slate object.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 38
38:     def reveal(name)
39:       bound_method = nil
40:       unbound_method = find_hidden_method(name)
41:       fail "Don't know how to reveal method '#{name}'" unless unbound_method
42:       define_method(name) do |*args|
43:         bound_method ||= unbound_method.bind(self)
44:         bound_method.call(*args)
45:       end
46:     end


Module: Builder

Module | Builder
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb

Methods

check_for_name_collision

Classes and Modules

Class Builder::CSS
Class Builder::IllegalBlockError
Class Builder::XmlBase
Class Builder::XmlEvents
Class Builder::XmlMarkup

Constants

BlankSlate = ::BlankSlate

Public Class methods

check_for_name_collision(klass, method_name, defined_constant=nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb, line 12
12:   def self.check_for_name_collision(klass, method_name, defined_constant=nil)
13:     if klass.instance_methods.include?(method_name.to_s)
14:       fail RuntimeError,
15:         "Name Collision: Method '#{method_name}' is already defined in #{klass}"
16:     end
17:   end


Class: Builder::CSS

Class | Builder::CSS
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb
Parent: | BlankSlate

Create a Cascading Style Sheet (CSS) using Ruby.

Example usage:

  css = Builder::CSS.new

  text_color      = '#7F7F7F'
  preferred_fonts = 'Helvetica, Arial, sans_serif'

  css.comment! 'This is our stylesheet'
  css.body {
    background_color '#FAFAFA'
    font_size        'small'
    font_family      preferred_fonts
    color            text_color
  }

  css.id!('navbar') {
    width            '500px'
  }

  css.class!('navitem') {
    color            'red'
  }

  css.a :hover {
    text_decoration  'underline'
  }

  css.div(:id => 'menu') {
    background       'green'
  }

  css.div(:class => 'foo') {
    background       'red'
  }

This will yield the following stylesheet:

  /* This is our stylesheet */
  body {
    background_color: #FAFAFA;
    font_size:        small;
    font_family:      Helvetica, Arial, sans_serif;
    color:            #7F7F7F;
  }

  #navbar {
    width:            500px;
  }

  .navitem {
    color:            red;
  }

  a:hover {
    text_decoration:  underline;
  }

  div#menu {
    background:       green;
  }

  div.foo {
    background:       red;
  }

Methods

+ > >> class! comment! group! id! method_missing new nil? store! target! |

Public Class methods

new(indent=2)

Create a CSS builder.

out: | Object receiving the markup.1 out must respond to <<.
indent: | Number of spaces used for indentation (0 implies no indentation and no line breaks).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 101
101:     def initialize(indent=2)
102:       @indent      = indent
103:       @target      = []
104:       @parts       = []
105:       @library     = {}
106:     end

Public Instance methods

+(part)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 108
108:     def +(part)
109:       _join_with_op! '+'
110:       self
111:     end
>(part)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 118
118:     def >(part)
119:       _join_with_op! '>'
120:       self
121:     end
>>(part)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 113
113:     def >>(part)
114:       _join_with_op! ''
115:       self
116:     end
class!(arg, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 145
145:     def class!(arg, &block)
146:       _start_container('.'+arg.to_s, nil, block_given?)
147:       _css_block(block) if block
148:       _unify_block
149:       self
150:     end
comment!(comment_text)

Create a comment string in the output.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 134
134:     def comment!(comment_text)
135:       @target << "/* #{comment_text} */\n"
136:     end
group!(*args, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 156
156:     def group!(*args, &block)
157:       args.each do |arg|
158:         if arg.is_a?(Symbol)
159:           instance_eval(&@library[arg])
160:         else
161:           instance_eval(&arg)
162:         end
163:         _text ', ' unless arg == args.last
164:       end
165:       if block
166:         _css_block(block)
167:         _unify_block
168:       end
169:     end
id!(arg, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 138
138:     def id!(arg, &block)
139:       _start_container('#'+arg.to_s, nil, block_given?)
140:       _css_block(block) if block
141:       _unify_block
142:       self
143:     end
method_missing(sym, *args, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 171
171:     def method_missing(sym, *args, &block)
172:       sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
173:       if block
174:         _start_container(sym, args.first)
175:         _css_block(block)
176:         _unify_block
177:       elsif @in_block
178:         _indent
179:         _css_line(sym, *args)
180:         _newline
181:         return self
182:       else
183:         _start_container(sym, args.first, false)
184:         _unify_block
185:       end
186:       self
187:     end
nil?()

"Cargo culted" from Jim who also "cargo culted" it. See xmlbase.rb.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 190
190:     def nil?
191:       false
192:     end
store!(sym, &block)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 152
152:     def store!(sym, &block)
153:       @library[sym] = block.to_proc
154:     end
target!()

Return the target of the builder

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 129
129:     def target!
130:       @target * ''
131:     end
|(part)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 123
123:     def |(part)
124:       _join_with_op! ','
125:       self
126:     end


Class: Builder::IllegalBlockError

Class | Builder::IllegalBlockError
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb
Parent: | RuntimeError

Generic error for builder


Class: Builder::XmlBase

Class | Builder::XmlBase
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb
Parent: | BlankSlate

XmlBase is a base class for building XML builders. See Builder::XmlMarkup and Builder::XmlEvents for examples.

Methods

<< method_missing new nil? tag! text!

Public Class methods

new(indent=0, initial=0)

Create an XML markup builder.

out: | Object receiving the markup. out must respond to <<.
indent: | Number of spaces used for indentation (0 implies no indentation and no line breaks).
initial: | Level of initial indentation.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 22
22:     def initialize(indent=0, initial=0)
23:       @indent = indent
24:       @level  = initial
25:     end

Public Instance methods

<<(text)

Append text to the output target without escaping any markup. May be used within the markup brackets as:

  builder.p { |x| x << "<br/>HI" }   #=>  <p><br/>HI</p>

This is useful when using non-builder enabled software that generates strings. Just insert the string directly into the builder without changing the inserted markup.

It is also useful for stacking builder objects. Builders only use << to append to the target, so by supporting this method/operation builders can use other builders as their targets.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 97
97:     def <<(text)
98:       _text(text)
99:     end
method_missing(sym, *args, &block)

Create XML markup based on the name of the method. This method is never invoked directly, but is called for each markup method in the markup block.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 37
37:     def method_missing(sym, *args, &block)
38:       text = nil
39:       attrs = nil
40:       sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
41:       args.each do |arg|
42:         case arg
43:         when Hash
44:           attrs ||= {}
45:           attrs.merge!(arg)
46:         else
47:           text ||= ''
48:           text << arg.to_s
49:         end
50:       end
51:       if block
52:         unless text.nil?
53:           raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
54:         end
55:         _indent
56:         _start_tag(sym, attrs)
57:         _newline
58:         _nested_structures(block)
59:         _indent
60:         _end_tag(sym)
61:         _newline
62:       elsif text.nil?
63:         _indent
64:         _start_tag(sym, attrs, true)
65:         _newline
66:       else
67:         _indent
68:         _start_tag(sym, attrs)
69:         text! text
70:         _end_tag(sym)
71:         _newline
72:       end
73:       @target
74:     end
nil?()

For some reason, nil? is sent to the XmlMarkup object. If nil? is not defined and method_missing is invoked, some strange kind of recursion happens. Since nil? won‘t ever be an XML tag, it is pretty safe to define it here. (Note: this is an example of cargo cult programming, cf. fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 107
107:     def nil?
108:       false
109:     end
tag!(sym, *args, &block)

Create a tag named sym. Other than the first argument which is the tag name, the arguments are the same as the tags implemented via method_missing.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 30
30:     def tag!(sym, *args, &block)
31:       method_missing(sym.to_sym, *args, &block)
32:     end
text!(text)

Append text to the output target. Escape any markup. May be used within the markup brackets as:

  builder.p { |b| b.br; b.text! "HI" }   #=>  <p><br/>HI</p>

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb, line 80
80:     def text!(text)
81:       _text(_escape(text))
82:     end


Class: Builder::XmlEvents

Class | Builder::XmlEvents
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb
Parent: | XmlMarkup

Create a series of SAX-like XML events (e.g. start_tag, end_tag) from the markup code. XmlEvent objects are used in a way similar to XmlMarkup objects, except that a series of events are generated and passed to a handler rather than generating character-based markup.

Usage:

  xe = Builder::XmlEvents.new(handler)
  xe.title("HI")    # Sends start_tag/end_tag/text messages to the handler.

Indentation may also be selected by providing value for the indentation size and initial indentation level.

  xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)

XML Event Handler

The handler object must expect the following events.

start_tag(tag, attrs)
Announces that a new tag has been found. tag is the name of the tag and attrs is a hash of attributes for the tag.
end_tag(tag)
Announces that an end tag for tag has been found.
text(text)
Announces that a string of characters (text) has been found. A series of characters may be broken up into more than one text call, so the client cannot assume that a single callback contains all the text data.

Methods

_end_tag _start_tag text!

Public Instance methods

_end_tag(sym)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb, line 58
58:     def _end_tag(sym)
59:       @target.end_tag(sym)
60:     end
_start_tag(sym, attrs, end_too=false)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb, line 53
53:     def _start_tag(sym, attrs, end_too=false)
54:       @target.start_tag(sym, attrs)
55:       _end_tag(sym) if end_too
56:     end
text!(text)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb, line 49
49:     def text!(text)
50:       @target.text(text)
51:     end


Class: Builder::XmlMarkup

Class | Builder::XmlMarkup
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb
Parent: | XmlBase

Create XML markup easily. All (well, almost all) methods sent to an XmlMarkup object will be translated to the equivalent XML markup. Any method with a block will be treated as an XML markup tag with nested markup in the block.

Examples will demonstrate this easier than words. In the following, xm is an XmlMarkup object.

  xm.em("emphasized")             # => <em>emphasized</em>
  xm.em { xmm.b("emp & bold") }   # => <em><b>emph &amp; bold</b></em>
  xm.a("A Link", "href"=>"http://onestepback.org")
                                  # => <a href="http://onestepback.org">A Link</a>
  xm.div { br }                    # => <div><br/></div>
  xm.target("name"=>"compile", "option"=>"fast")
                                  # => <target option="fast" name="compile"\>
                                  # NOTE: order of attributes is not specified.

  xm.instruct!                   # <?xml version="1.0" encoding="UTF-8"?>
  xm.html {                      # <html>
    xm.head {                    #   <head>
      xm.title("History")        #     <title>History</title>
    }                            #   </head>
    xm.body {                    #   <body>
      xm.comment! "HI"           #     <! -- HI -->
      xm.h1("Header")            #     <h1>Header</h1>
      xm.p("paragraph")          #     <p>paragraph</p>
    }                            #   </body>
  }                              # </html>

Notes:

  • The order that attributes are inserted in markup tags is undefined.
  • Sometimes you wish to insert text without enclosing tags. Use the text! method to accomplish this.

    Example:

      xm.div {                          # <div>
    xm.text! "line"; xm.br          #   line<br/>
    xm.text! "another line"; xmbr   #    another line<br/>
  }                                 # </div>
  • The special XML characters <, >, and & are converted to &lt;, &gt; and &amp; automatically. Use the << operation to insert text without modification.
  • Sometimes tags use special characters not allowed in ruby identifiers. Use the tag! method to handle these cases.

    Example:

      xml.tag!("SOAP:Envelope") { ... }

    will produce …

      <SOAP:Envelope> ... </SOAP:Envelope>"

    tag! will also take text and attribute arguments (after the tag name) like normal markup methods. (But see the next bullet item for a better way to handle XML namespaces).

  • Direct support for XML namespaces is now available. If the first argument to a tag call is a symbol, it will be joined to the tag to produce a namespace:tag combination. It is easier to show this than describe it.
      xml.SOAP :Envelope do ... end

    Just put a space before the colon in a namespace to produce the right form for builder (e.g. "SOAP:Envelope" => "xml.SOAP :Envelope")

  • XmlMarkup builds the markup in any object (called a target) that accepts the << method. If no target is given, then XmlMarkup defaults to a string target.

    Examples:

      xm = Builder::XmlMarkup.new
  result = xm.title("yada")
  # result is a string containing the markup.

  buffer = ""
  xm = Builder::XmlMarkup.new(buffer)
  # The markup is appended to buffer (using <<)

  xm = Builder::XmlMarkup.new(STDOUT)
  # The markup is written to STDOUT (using <<)

  xm = Builder::XmlMarkup.new
  x2 = Builder::XmlMarkup.new(:target=>xm)
  # Markup written to +x2+ will be send to +xm+.
  • Indentation is enabled by providing the number of spaces to indent for each level as a second argument to XmlBuilder.new. Initial indentation may be specified using a third parameter.

    Example:

      xm = Builder.new(:indent=>2)
  # xm will produce nicely formatted and indented XML.

  xm = Builder.new(:indent=>2, :margin=>4)
  # xm will produce nicely formatted and indented XML with 2
  # spaces per indent and an over all indentation level of 4.

  builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
  builder.name { |b| b.first("Jim"); b.last("Weirich) }
  # prints:
  #     <name>
  #       <first>Jim</first>
  #       <last>Weirich</last>
  #     </name>
  • The instance_eval implementation which forces self to refer to the message receiver as self is now obsolete. We now use normal block calls to execute the markup block. This means that all markup methods must now be explicitly send to the xml builder. For instance, instead of
       xml.div { strong("text") }

    you need to write:

       xml.div { xml.strong("text") }

    Although more verbose, the subtle change in semantics within the block was found to be prone to error. To make this change a little less cumbersome, the markup block now gets the markup object sent as an argument, allowing you to use a shorter alias within the block.

    For example:

      xml_builder = Builder::XmlMarkup.new
  xml_builder.div { |xml|
    xml.stong("text")
  }

Methods

cdata! comment! declare! instruct! new target!

Public Class methods

new(options={})

Create an XML markup builder. Parameters are specified by an option hash.

:target=>target_object: | Object receiving the markup. out must respond to the << operator. The default is a plain string target.
:indent=>indentation: | Number of spaces used for indentation. The default is no indentation and no line breaks.
:margin=>initial_indentation_level: | Amount of initial indentation (specified in levels, not spaces).
:escape_attrs=><b>OBSOLETE</em>: | The :escape_attrs option is no longer supported by builder (and will be quietly ignored). String attribute values are now automatically escaped. If you need unescaped attribute values (perhaps you are using entities in the attribute values), then give the value as a Symbol. This allows much finer control over escaping attribute values.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 185
185:     def initialize(options={})
186:       indent = options[:indent] || 0
187:       margin = options[:margin] || 0
188:       super(indent, margin)
189:       @target = options[:target] || ""
190:     end

Public Instance methods

cdata!(text)

Insert a CDATA section into the XML markup.

For example:

   xml.cdata!("text to be included in cdata")
       #=> <![CDATA[text to be included in cdata]]>

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 259
259:     def cdata!(text)
260:       _ensure_no_block block_given?
261:       _special("<![CDATA[", "]]>", text, nil)
262:     end
comment!(comment_text)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 197
197:     def comment!(comment_text)
198:       _ensure_no_block block_given?
199:       _special("<!-- ", " -->", comment_text, nil)
200:     end
declare!(inst, *args, &block)

Insert an XML declaration into the XML markup.

For example:

  xml.declare! :ELEMENT, :blah, "yada"
      # => <!ELEMENT blah "yada">

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 208
208:     def declare!(inst, *args, &block)
209:       _indent
210:       @target << "<!#{inst}"
211:       args.each do |arg|
212:         case arg
213:         when String
214:           @target << %{ "#{arg}"} # " WART
215:         when Symbol
216:           @target << " #{arg}"
217:         end
218:       end
219:       if block_given?
220:         @target << " ["
221:         _newline
222:         _nested_structures(block)
223:         @target << "]"
224:       end
225:       @target << ">"
226:       _newline
227:     end
instruct!(directive_tag=:xml, attrs={})

Insert a processing instruction into the XML markup. E.g.

For example:

   xml.instruct!
       #=> <?xml version="1.0" encoding="UTF-8"?>
   xml.instruct! :aaa, :bbb=>"ccc"
       #=> <?aaa bbb="ccc"?>

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 238
238:     def instruct!(directive_tag=:xml, attrs={})
239:       _ensure_no_block block_given?
240:       if directive_tag == :xml
241:         a = { :version=>"1.0", :encoding=>"UTF-8" }
242:         attrs = a.merge attrs
243:       end
244:       _special(
245:       "<?#{directive_tag}",
246:       "?>",
247:       nil,
248:       attrs,
249:       [:version, :encoding, :standalone])
250:     end
target!()

Return the target of the builder.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb, line 193
193:     def target!
194:       @target
195:     end


Class: CGI::Cookie

Class | CGI::Cookie
In: | vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb
Parent: | DelegateClass(Array)

Methods

http_only= new parse respond_to? secure= to_s

Attributes

domain | [RW]
expires | [RW]
http_only | [R]
name | [RW]
path | [RW]
secure | [R]
value | [RW]

Public Class methods

new(name = '', *value)

Creates a new CGI::Cookie object.

The contents of the cookie can be specified as a name and one or more value arguments. Alternatively, the contents can be specified as a single hash argument. The possible keywords of this hash are as follows:

  • :name - The name of the cookie. Required.
  • :value - The cookie‘s value or list of values.
  • :path - The path for which this cookie applies. Defaults to the base directory of the CGI script.
  • :domain - The domain for which this cookie applies.
  • :expires - The time at which this cookie expires, as a Time object.
  • :secure - Whether this cookie is a secure cookie or not (defaults to false). Secure cookies are only transmitted to HTTPS servers.
  • :http_only - Whether this cookie can be accessed by client side scripts (e.g. document.cookie) or only over HTTP. More details in msdn2.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx. Defaults to false.

These keywords correspond to attributes of the cookie object.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 30
30:     def initialize(name = '', *value)
31:       if name.kind_of?(String)
32:         @name = name
33:         @value = Array(value)
34:         @domain = nil
35:         @expires = nil
36:         @secure = false
37:         @http_only = false
38:         @path = nil
39:       else
40:         @name = name['name']
41:         @value = (name['value'].kind_of?(String) ? [name['value']] : Array(name['value'])).delete_if(&:blank?)
42:         @domain = name['domain']
43:         @expires = name['expires']
44:         @secure = name['secure'] || false
45:         @http_only = name['http_only'] || false
46:         @path = name['path']
47:       end
48:
49:       raise ArgumentError, "`name' required" unless @name
50:
51:       # simple support for IE
52:       unless @path
53:         %r|^(.*/)|.match(ENV['SCRIPT_NAME'])
54:         @path = ($1 or '')
55:       end
56:
57:       super(@value)
58:     end
parse(raw_cookie)

Parses a raw cookie string into a hash of cookie-name => cookie-object pairs.

  cookies = CGI::Cookie::parse("raw_cookie_string")
    # => { "name1" => cookie1, "name2" => cookie2, ... }

[Source]

     # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 95
 95:     def self.parse(raw_cookie)
 96:       cookies = Hash.new([])
 97:
 98:       if raw_cookie
 99:         raw_cookie.split(/;\s?/).each do |pairs|
100:           name, value = pairs.split('=',2)
101:           next unless name and value
102:           name = CGI::unescape(name)
103:           unless cookies.has_key?(name)
104:             cookies[name] = new(name, CGI::unescape(value))
105:           end
106:         end
107:       end
108:
109:       cookies
110:     end

Public Instance methods

http_only=(val)

Sets whether the Cookie is an HTTP only cookie or not.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 66
66:     def http_only=(val)
67:       @http_only = val == true
68:     end
respond_to?(method, include_private = false)

FIXME: work around broken 1.8.7 DelegateClass#respond_to?

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 84
84:     def respond_to?(method, include_private = false)
85:       return true if super(method)
86:       return __getobj__.respond_to?(method, include_private)
87:     end
secure=(val)

Sets whether the Cookie is a secure cookie or not.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 61
61:     def secure=(val)
62:       @secure = val == true
63:     end
to_s()

Converts the Cookie to its string representation.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie.rb, line 71
71:     def to_s
72:       buf = ''
73:       buf << @name << '='
74:       buf << (@value.kind_of?(String) ? CGI::escape(@value) : @value.collect{|v| CGI::escape(v) }.join("&"))
75:       buf << '; domain=' << @domain if @domain
76:       buf << '; path=' << @path if @path
77:       buf << '; expires=' << CGI::rfc1123_date(@expires) if @expires
78:       buf << '; secure' if @secure
79:       buf << '; HttpOnly' if @http_only
80:       buf
81:     end


Module: CGI::QueryExtension

Module | CGI::QueryExtension
In: | vendor/rails/actionpack/lib/action_controller/cgi_ext/query_extension.rb

Methods

initialize_query

Public Instance methods

initialize_query()

Neuter CGI parameter parsing.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/cgi_ext/query_extension.rb, line 9
 9:     def initialize_query
10:       # Fix some strange request environments.
11:       env_table['REQUEST_METHOD'] ||= 'GET'
12:
13:       # POST assumes missing Content-Type is application/x-www-form-urlencoded.
14:       if env_table['CONTENT_TYPE'].blank? && env_table['REQUEST_METHOD'] == 'POST'
15:         env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
16:       end
17:
18:       @cookies = CGI::Cookie::parse(env_table['HTTP_COOKIE'] || env_table['COOKIE'])
19:       @params = {}
20:     end


Module: Commands

Module | Commands
In: | vendor/rails/railties/lib/commands/plugin.rb

Classes and Modules

Class Commands::Discover
Class Commands::Info
Class Commands::Install
Class Commands::List
Class Commands::Plugin
Class Commands::Remove
Class Commands::Source
Class Commands::Sources
Class Commands::Unsource
Class Commands::Update


Class: Commands::Discover

Class | Commands::Discover
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

extract_repository_uri new options parse! scrape

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 679
679:     def initialize(base_command)
680:       @base_command = base_command
681:       @list = false
682:       @prompt = true
683:     end

Public Instance methods

extract_repository_uri(uri)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 746
746:     def extract_repository_uri(uri)
747:       uri.match(/(svn|https?):.*\/plugins\//i)[0]
748:     end
options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 685
685:     def options
686:       OptionParser.new do |o|
687:         o.set_summary_indent('  ')
688:         o.banner =    "Usage: #{@base_command.script_name} discover URI [URI [URI]...]"
689:         o.define_head "Discover repositories referenced on a page."
690:         o.separator   ""
691:         o.separator   "Options:"
692:         o.separator   ""
693:         o.on(         "-l", "--list",
694:                       "List but don't prompt or add discovered repositories.") { |list| @list, @prompt = list, !@list }
695:         o.on(         "-n", "--no-prompt",
696:                       "Add all new repositories without prompting.") { |v| @prompt = !v }
697:       end
698:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 700
700:     def parse!(args)
701:       options.parse!(args)
702:       args = ['http://wiki.rubyonrails.org/rails/pages/Plugins'] if args.empty?
703:       args.each do |uri|
704:         scrape(uri) do |repo_uri|
705:           catch(:next_uri) do
706:             if @prompt
707:               begin
708:                 $stdout.print "Add #{repo_uri}? [Y/n] "
709:                 throw :next_uri if $stdin.gets !~ /^y?$/i
710:               rescue Interrupt
711:                 $stdout.puts
712:                 exit 1
713:               end
714:             elsif @list
715:               puts repo_uri
716:               throw :next_uri
717:             end
718:             Repositories.instance.add(repo_uri)
719:             puts "discovered: #{repo_uri}" if $verbose or !@prompt
720:           end
721:         end
722:       end
723:       Repositories.instance.save
724:     end
scrape(uri) {|uri unless dupes.include?(uri) || Repositories.instance.exist?(uri)| ...}

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 726
726:     def scrape(uri)
727:       require 'open-uri'
728:       puts "Scraping #{uri}" if $verbose
729:       dupes = []
730:       content = open(uri).each do |line|
731:         begin
732:           if line =~ /<a[^>]*href=['"]([^'"]*)['"]/ || line =~ /(svn:\/\/[^<|\n]*)/
733:             uri = $1
734:             if uri =~ /^\w+:\/\// && uri =~ /\/plugins\// && uri !~ /\/browser\// && uri !~ /^http:\/\/wiki\.rubyonrails/ && uri !~ /http:\/\/instiki/
735:               uri = extract_repository_uri(uri)
736:               yield uri unless dupes.include?(uri) || Repositories.instance.exist?(uri)
737:               dupes << uri
738:             end
739:           end
740:         rescue
741:           puts "Problems scraping '#{uri}': #{$!.to_s}"
742:         end
743:       end
744:     end


Class: Commands::Info

Class | Commands::Info
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 879
879:     def initialize(base_command)
880:       @base_command = base_command
881:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 883
883:     def options
884:       OptionParser.new do |o|
885:         o.set_summary_indent('  ')
886:         o.banner =    "Usage: #{@base_command.script_name} info name [name]..."
887:         o.define_head "Shows plugin info at {url}/about.yml."
888:       end
889:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 891
891:     def parse!(args)
892:       options.parse!(args)
893:       args.each do |name|
894:         puts ::Plugin.find(name).info
895:         puts
896:       end
897:     end


Class: Commands::Install

Class | Commands::Install
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

determine_install_method new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 752
752:     def initialize(base_command)
753:       @base_command = base_command
754:       @method = :http
755:       @options = { :quiet => false, :revision => nil, :force => false }
756:     end

Public Instance methods

determine_install_method()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 788
788:     def determine_install_method
789:       best = @base_command.environment.best_install_method
790:       @method = :http if best == :http and @method == :export
791:       case
792:       when (best == :http and @method != :http)
793:         msg = "Cannot install using subversion because `svn' cannot be found in your PATH"
794:       when (best == :export and (@method != :export and @method != :http))
795:         msg = "Cannot install using #{@method} because this project is not under subversion."
796:       when (best != :externals and @method == :externals)
797:         msg = "Cannot install using externals because vendor/plugins is not under subversion."
798:       end
799:       if msg
800:         puts msg
801:         exit 1
802:       end
803:       @method
804:     end
options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 758
758:     def options
759:       OptionParser.new do |o|
760:         o.set_summary_indent('  ')
761:         o.banner =    "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]"
762:         o.define_head "Install one or more plugins."
763:         o.separator   ""
764:         o.separator   "Options:"
765:         o.on(         "-x", "--externals",
766:                       "Use svn:externals to grab the plugin.",
767:                       "Enables plugin updates and plugin versioning.") { |v| @method = :externals }
768:         o.on(         "-o", "--checkout",
769:                       "Use svn checkout to grab the plugin.",
770:                       "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout }
771:         o.on(         "-e", "--export",
772:                       "Use svn export to grab the plugin.",
773:                       "Exports the plugin, allowing you to check it into your local repository. Does not enable updates, or add an svn:externals entry.") { |v| @method = :export }
774:         o.on(         "-q", "--quiet",
775:                       "Suppresses the output from installation.",
776:                       "Ignored if -v is passed (./script/plugin -v install ...)") { |v| @options[:quiet] = true }
777:         o.on(         "-r REVISION", "--revision REVISION",
778:                       "Checks out the given revision from subversion or git.",
779:                       "Ignored if subversion/git is not used.") { |v| @options[:revision] = v }
780:         o.on(         "-f", "--force",
781:                       "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true }
782:         o.separator   ""
783:         o.separator   "You can specify plugin names as given in 'plugin list' output or absolute URLs to "
784:         o.separator   "a plugin repository."
785:       end
786:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 806
806:     def parse!(args)
807:       options.parse!(args)
808:       environment = @base_command.environment
809:       install_method = determine_install_method
810:       puts "Plugins will be installed using #{install_method}" if $verbose
811:       args.each do |name|
812:         ::Plugin.find(name).install(install_method, @options)
813:       end
814:     rescue StandardError => e
815:       puts "Plugin not found: #{args.inspect}"
816:       puts e.inspect if $verbose
817:       exit 1
818:     end


Class: Commands::List

Class | Commands::List
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 541
541:     def initialize(base_command)
542:       @base_command = base_command
543:       @sources = []
544:       @local = false
545:       @remote = true
546:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 548
548:     def options
549:       OptionParser.new do |o|
550:         o.set_summary_indent('  ')
551:         o.banner =    "Usage: #{@base_command.script_name} list [OPTIONS] [PATTERN]"
552:         o.define_head "List available plugins."
553:         o.separator   ""
554:         o.separator   "Options:"
555:         o.separator   ""
556:         o.on(         "-s", "--source=URL1,URL2", Array,
557:                       "Use the specified plugin repositories.") {|sources| @sources = sources}
558:         o.on(         "--local",
559:                       "List locally installed plugins.") {|local| @local, @remote = local, false}
560:         o.on(         "--remote",
561:                       "List remotely available plugins. This is the default behavior",
562:                       "unless --local is provided.") {|remote| @remote = remote}
563:       end
564:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 566
566:     def parse!(args)
567:       options.order!(args)
568:       unless @sources.empty?
569:         @sources.map!{ |uri| Repository.new(uri) }
570:       else
571:         @sources = Repositories.instance.all
572:       end
573:       if @remote
574:         @sources.map{|r| r.plugins}.flatten.each do |plugin|
575:           if @local or !plugin.installed?
576:             puts plugin.to_s
577:           end
578:         end
579:       else
580:         cd "#{@base_command.environment.root}/vendor/plugins"
581:         Dir["*"].select{|p| File.directory?(p)}.each do |name|
582:           puts name
583:         end
584:       end
585:     end


Class: Commands::Plugin

Class | Commands::Plugin
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

environment= new options parse! parse! split_args

Attributes

environment | [R]
script_name | [R]
sources | [R]

Public Class methods

new()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 443
443:     def initialize
444:       @environment = RailsEnvironment.default
445:       @rails_root = RailsEnvironment.default.root
446:       @script_name = File.basename($0)
447:       @sources = []
448:     end
parse!(args=ARGV)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 534
534:     def self.parse!(args=ARGV)
535:       Plugin.new.parse!(args)
536:     end

Public Instance methods

environment=(value)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 450
450:     def environment=(value)
451:       @environment = value
452:       RailsEnvironment.default = value
453:     end
options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 455
455:     def options
456:       OptionParser.new do |o|
457:         o.set_summary_indent('  ')
458:         o.banner =    "Usage: #{@script_name} [OPTIONS] command"
459:         o.define_head "Rails plugin manager."
460:
461:         o.separator ""
462:         o.separator "GENERAL OPTIONS"
463:
464:         o.on("-r", "--root=DIR", String,
465:              "Set an explicit rails app directory.",
466:              "Default: #{@rails_root}") { |rails_root| @rails_root = rails_root; self.environment = RailsEnvironment.new(@rails_root) }
467:         o.on("-s", "--source=URL1,URL2", Array,
468:              "Use the specified plugin repositories instead of the defaults.") { |sources| @sources = sources}
469:
470:         o.on("-v", "--verbose", "Turn on verbose output.") { |verbose| $verbose = verbose }
471:         o.on("-h", "--help", "Show this help message.") { puts o; exit }
472:
473:         o.separator ""
474:         o.separator "COMMANDS"
475:
476:         o.separator "  discover   Discover plugin repositories."
477:         o.separator "  list       List available plugins."
478:         o.separator "  install    Install plugin(s) from known repositories or URLs."
479:         o.separator "  update     Update installed plugins."
480:         o.separator "  remove     Uninstall plugins."
481:         o.separator "  source     Add a plugin source repository."
482:         o.separator "  unsource   Remove a plugin repository."
483:         o.separator "  sources    List currently configured plugin repositories."
484:
485:         o.separator ""
486:         o.separator "EXAMPLES"
487:         o.separator "  Install a plugin:"
488:         o.separator "    #{@script_name} install continuous_builder\n"
489:         o.separator "  Install a plugin from a subversion URL:"
490:         o.separator "    #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
491:         o.separator "  Install a plugin from a git URL:"
492:         o.separator "    #{@script_name} install git://github.com/SomeGuy/my_awesome_plugin.git\n"
493:         o.separator "  Install a plugin and add a svn:externals entry to vendor/plugins"
494:         o.separator "    #{@script_name} install -x continuous_builder\n"
495:         o.separator "  List all available plugins:"
496:         o.separator "    #{@script_name} list\n"
497:         o.separator "  List plugins in the specified repository:"
498:         o.separator "    #{@script_name} list --source=http://dev.rubyonrails.com/svn/rails/plugins/\n"
499:         o.separator "  Discover and prompt to add new repositories:"
500:         o.separator "    #{@script_name} discover\n"
501:         o.separator "  Discover new repositories but just list them, don't add anything:"
502:         o.separator "    #{@script_name} discover -l\n"
503:         o.separator "  Add a new repository to the source list:"
504:         o.separator "    #{@script_name} source http://dev.rubyonrails.com/svn/rails/plugins/\n"
505:         o.separator "  Remove a repository from the source list:"
506:         o.separator "    #{@script_name} unsource http://dev.rubyonrails.com/svn/rails/plugins/\n"
507:         o.separator "  Show currently configured repositories:"
508:         o.separator "    #{@script_name} sources\n"
509:       end
510:     end
parse!(args=ARGV)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 512
512:     def parse!(args=ARGV)
513:       general, sub = split_args(args)
514:       options.parse!(general)
515:
516:       command = general.shift
517:       if command =~ /^(list|discover|install|source|unsource|sources|remove|update|info)$/
518:         command = Commands.const_get(command.capitalize).new(self)
519:         command.parse!(sub)
520:       else
521:         puts "Unknown command: #{command}"
522:         puts options
523:         exit 1
524:       end
525:     end
split_args(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 527
527:     def split_args(args)
528:       left = []
529:       left << args.shift while args[0] and args[0] =~ /^-/
530:       left << args.shift if args[0]
531:       return [left, args]
532:     end


Class: Commands::Remove

Class | Commands::Remove
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 857
857:     def initialize(base_command)
858:       @base_command = base_command
859:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 861
861:     def options
862:       OptionParser.new do |o|
863:         o.set_summary_indent('  ')
864:         o.banner =    "Usage: #{@base_command.script_name} remove name [name]..."
865:         o.define_head "Remove plugins."
866:       end
867:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 869
869:     def parse!(args)
870:       options.parse!(args)
871:       root = @base_command.environment.root
872:       args.each do |name|
873:         ::Plugin.new(name).uninstall
874:       end
875:     end


Class: Commands::Source

Class | Commands::Source
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 617
617:     def initialize(base_command)
618:       @base_command = base_command
619:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 621
621:     def options
622:       OptionParser.new do |o|
623:         o.set_summary_indent('  ')
624:         o.banner =    "Usage: #{@base_command.script_name} source REPOSITORY [REPOSITORY [REPOSITORY]...]"
625:         o.define_head "Add new repositories to the default search list."
626:       end
627:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 629
629:     def parse!(args)
630:       options.parse!(args)
631:       count = 0
632:       args.each do |uri|
633:         if Repositories.instance.add(uri)
634:           puts "added: #{uri.ljust(50)}" if $verbose
635:           count += 1
636:         else
637:           puts "failed: #{uri.ljust(50)}"
638:         end
639:       end
640:       Repositories.instance.save
641:       puts "Added #{count} repositories."
642:     end


Class: Commands::Sources

Class | Commands::Sources
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 590
590:     def initialize(base_command)
591:       @base_command = base_command
592:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 594
594:     def options
595:       OptionParser.new do |o|
596:         o.set_summary_indent('  ')
597:         o.banner =    "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]"
598:         o.define_head "List configured plugin repositories."
599:         o.separator   ""
600:         o.separator   "Options:"
601:         o.separator   ""
602:         o.on(         "-c", "--check",
603:                       "Report status of repository.") { |sources| @sources = sources}
604:       end
605:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 607
607:     def parse!(args)
608:       options.parse!(args)
609:       Repositories.each do |repo|
610:         puts repo.uri
611:       end
612:     end


Class: Commands::Unsource

Class | Commands::Unsource
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 647
647:     def initialize(base_command)
648:       @base_command = base_command
649:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 651
651:     def options
652:       OptionParser.new do |o|
653:         o.set_summary_indent('  ')
654:         o.banner =    "Usage: #{@base_command.script_name} unsource URI [URI [URI]...]"
655:         o.define_head "Remove repositories from the default search list."
656:         o.separator ""
657:         o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
658:       end
659:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 661
661:     def parse!(args)
662:       options.parse!(args)
663:       count = 0
664:       args.each do |uri|
665:         if Repositories.instance.remove(uri)
666:           count += 1
667:           puts "removed: #{uri.ljust(50)}"
668:         else
669:           puts "failed: #{uri.ljust(50)}"
670:         end
671:       end
672:       Repositories.instance.save
673:       puts "Removed #{count} repositories."
674:     end


Class: Commands::Update

Class | Commands::Update
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

new options parse!

Public Class methods

new(base_command)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 822
822:     def initialize(base_command)
823:       @base_command = base_command
824:     end

Public Instance methods

options()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 826
826:     def options
827:       OptionParser.new do |o|
828:         o.set_summary_indent('  ')
829:         o.banner =    "Usage: #{@base_command.script_name} update [name [name]...]"
830:         o.on(         "-r REVISION", "--revision REVISION",
831:                       "Checks out the given revision from subversion.",
832:                       "Ignored if subversion is not used.") { |v| @revision = v }
833:         o.define_head "Update plugins."
834:       end
835:     end
parse!(args)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 837
837:     def parse!(args)
838:       options.parse!(args)
839:       root = @base_command.environment.root
840:       cd root
841:       args = Dir["vendor/plugins/*"].map do |f|
842:         File.directory?("#{f}/.svn") ? File.basename(f) : nil
843:       end.compact if args.empty?
844:       cd "vendor/plugins"
845:       args.each do |name|
846:         if File.directory?(name)
847:           puts "Updating plugin: #{name}"
848:           system("svn #{$verbose ? '' : '-q'} up \"#{name}\" #{@revision ? "-r #{@revision}" : ''}")
849:         else
850:           puts "Plugin doesn't exist: #{name}"
851:         end
852:       end
853:     end


Module: Continuum

Module | Continuum
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb

Methods

binary_search

Classes and Modules

Class Continuum::Entry

Constants

POINTS_PER_SERVER = 160

Public Class methods

binary_search(ary, value, &block)

Find the closest index in Continuum with value <= the given value

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 903
903:   def self.binary_search(ary, value, &block)
904:     upper = ary.size - 1
905:     lower = 0
906:     idx = 0
907:
908:     while(lower <= upper) do
909:       idx = (lower + upper) / 2
910:       comp = ary[idx].value <=> value
911:
912:       if comp == 0
913:         return idx
914:       elsif comp > 0
915:         upper = idx - 1
916:       else
917:         lower = idx + 1
918:       end
919:     end
920:     return upper
921:   end


Class: Continuum::Entry

Class | Continuum::Entry
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Parent: | Object

Methods

inspect new

Attributes

server | [R]
value | [R]

Public Class methods

new(val, srv)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 927
927:     def initialize(val, srv)
928:       @value = val
929:       @server = srv
930:     end

Public Instance methods

inspect()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 932
932:     def inspect
933:       "<#{value}, #{server.host}:#{server.port}>"
934:     end


Class: DateTime

Class | DateTime
In: | vendor/rails/activesupport/lib/active_support/core_ext/date_time.rb vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb
Parent: | Object

Methods

to_json

Included Modules

ActiveSupport::CoreExtensions::Time::Behavior
ActiveSupport::CoreExtensions::Time::Zones
ActiveSupport::CoreExtensions::DateTime::Calculations
ActiveSupport::CoreExtensions::DateTime::Conversions

Public Instance methods

to_json(options = nil)

Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the ISO 8601 format is used.

Examples

  # With ActiveSupport.use_standard_json_time_format = true
  DateTime.civil(2005,2,1,15,15,10).to_json
  # => "2005-02-01T15:15:10+00:00"

  # With ActiveSupport.use_standard_json_time_format = false
  DateTime.civil(2005,2,1,15,15,10).to_json
  # => "2005/02/01 15:15:10 +0000"

[Source]

    # File vendor/rails/activesupport/lib/active_support/json/encoders/date_time.rb, line 14
14:   def to_json(options = nil)
15:     if ActiveSupport.use_standard_json_time_format
16:       xmlschema.inspect
17:     else
18:       strftime('"%Y/%m/%d %H:%M:%S %z"')
19:     end
20:   end


Class: Dir

Class | Dir
In: |
Parent: | Object

Methods

user_home

Public Class methods

user_home()

User home directory lookup adapted from RubyGems.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 27
27: def Dir.user_home
28:   if ENV['HOME']
29:     ENV['HOME']
30:   elsif ENV['USERPROFILE']
31:     ENV['USERPROFILE']
32:   elsif ENV['HOMEDRIVE'] and ENV['HOMEPATH']
33:     "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
34:   else
35:     File.expand_path '~'
36:   end
37: end


Class: DispatchServlet

Class | DispatchServlet
In: | vendor/rails/railties/lib/webrick_server.rb
Parent: | WEBrick::HTTPServlet::AbstractServlet

A custom dispatch servlet for use with WEBrick. It dispatches requests (using the Rails Dispatcher) to the appropriate controller/action. By default, it restricts WEBrick to a managing a single Rails request at a time, but you can change this behavior by setting ActionController::Base.allow_concurrency to true.

Methods

dispatch

Public Class methods

dispatch(options = {})

Start the WEBrick server with the given options, mounting the DispatchServlet at /.

[Source]

    # File vendor/rails/railties/lib/webrick_server.rb, line 48
48:   def self.dispatch(options = {})
49:     Socket.do_not_reverse_lookup = true # patch for OS X
50:
51:     params = { :Port        => options[:port].to_i,
52:                :ServerType  => options[:server_type],
53:                :BindAddress => options[:ip] }
54:     params[:MimeTypes] = options[:mime_types] if options[:mime_types]
55:
56:     server = WEBrick::HTTPServer.new(params)
57:     server.mount('/', DispatchServlet, options)
58:
59:     trap("INT") { server.shutdown }
60:     server.start
61:   end


Class: ERB

Class | ERB
In: | vendor/rails/actionpack/lib/action_view/erb/util.rb
Parent: | Object

Classes and Modules

Module ERB::Util


Module: ERB::Util

Module | ERB::Util
In: | vendor/rails/actionpack/lib/action_view/erb/util.rb

Methods

html_escape j json_escape

Constants

HTML_ESCAPE | = | { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
JSON_ESCAPE | = | { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }

Public Instance methods

html_escape(s)

A utility method for escaping HTML tag characters. This method is also aliased as h.

In your ERb templates, use this method to escape any unsafe content. For example:

  <%=h @person.name %>

Example:

  puts html_escape("is a > 0 & a < 10?")
  # => is a &gt; 0 &amp; a &lt; 10?

[Source]

    # File vendor/rails/actionpack/lib/action_view/erb/util.rb, line 17
17:     def html_escape(s)
18:       s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
19:     end
j(s)

Alias for json_escape

json_escape(s)

A utility method for escaping HTML entities in JSON strings. This method is also aliased as j.

In your ERb templates, use this method to escape any HTML entities:

  <%=j @person.to_json %>

Example:

  puts json_escape("is a > 0 & a < 10?")
  # => is a \u003E 0 \u0026 a \u003C 10?

[Source]

    # File vendor/rails/actionpack/lib/action_view/erb/util.rb, line 30
30:     def json_escape(s)
31:       s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
32:     end


Module: Enumerable

Module | Enumerable
In: | vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb vendor/rails/activesupport/lib/active_support/json/encoders/enumerable.rb

Methods

each_with_object group_by index_by many? none? sum

Public Instance methods

each_with_object(memo, &block)

Iterates over a collection, passing the current element and the memo to the block. Handy for building up hashes or reducing collections down to one object. Examples:

  %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}

Note that you can‘t use immutable objects like numbers, true or false as the memo. You would think the following returns 120, but since the memo is never changed, it does not.

  (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 79
79:   def each_with_object(memo, &block)
80:     returning memo do |m|
81:       each do |element|
82:         block.call(element, m)
83:       end
84:     end
85:   end
group_by() {|element| ...}

Collect an enumerable into sets, grouped by the result of a block. Useful, for example, for grouping records by date.

Example:

  latest_transcripts.group_by(&:day).each do |day, transcripts|
    p "#{day} -> #{transcripts.map(&:class).join(', ')}"
  end
  "2006-03-01 -> Transcript"
  "2006-02-28 -> Transcript"
  "2006-02-27 -> Transcript, Transcript"
  "2006-02-26 -> Transcript, Transcript"
  "2006-02-25 -> Transcript"
  "2006-02-24 -> Transcript, Transcript"
  "2006-02-23 -> Transcript"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 22
22:   def group_by
23:     assoc = ActiveSupport::OrderedHash.new
24:
25:     each do |element|
26:       key = yield(element)
27:
28:       if assoc.has_key?(key)
29:         assoc[key] << element
30:       else
31:         assoc[key] = [element]
32:       end
33:     end
34:
35:     assoc
36:   end
index_by() {|elem| ...}

Convert an enumerable to a hash. Examples:

  people.index_by(&:login)
    => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
  people.index_by { |person| "#{person.first_name} #{person.last_name}" }
    => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 94
94:   def index_by
95:     inject({}) do |accum, elem|
96:       accum[yield(elem)] = elem
97:       accum
98:     end
99:   end
many?(&block)

Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1. Works with a block too ala any?, so people.many? { |p| p.age > 26 } # => returns true if more than 1 person is over 26.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 103
103:   def many?(&block)
104:     size = block_given? ? select(&block).size : self.size
105:     size > 1
106:   end
none?(&block)

Returns true if none of the elements match the given block.

  success = responses.none? {|r| r.status / 100 == 5 }

This is a builtin method in Ruby 1.8.7 and later.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 113
113:   def none?(&block)
114:     !any?(&block)
115:   end
sum(identity = 0, &block)

Calculates a sum from the elements. Examples:

 payments.sum { |p| p.price * p.tax_rate }
 payments.sum(&:price)

The latter is a shortcut for:

 payments.inject { |sum, p| sum + p.price }

It can also calculate the sum without the use of a block.

 [5, 15, 10].sum # => 30
 ["foo", "bar"].sum # => "foobar"
 [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]

The default sum of an empty list is zero. You can override this default:

 [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb, line 57
57:   def sum(identity = 0, &block)
58:     return identity unless size > 0
59:
60:     if block_given?
61:       map(&block).sum
62:     else
63:       inject { |sum, element| sum + element }
64:     end
65:   end


Class: Fixnum

Class | Fixnum
In: | vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb
Parent: | Object

Enhance the Fixnum class with a XML escaped character conversion.

Methods

xchr

Constants

XChar = Builder::XChar if ! defined?(XChar)

Public Instance methods

xchr()

XML escaped version of chr

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb, line 93
 93:   def xchr
 94:     n = XChar::CP1252[self] || self
 95:     case n when *XChar::VALID
 96:       XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
 97:     else
 98:       '*'
 99:     end
100:   end


Class: Fixtures

Class | Fixtures
In: | vendor/rails/activerecord/lib/active_record/fixtures.rb
Parent: | (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)

Fixtures are a way of organizing data that you want to test against; in short, sample data.

Fixture formats

Fixtures come in 3 flavors:

  1.  YAML fixtures
  2.  CSV fixtures
  3.  Single-file fixtures

YAML fixtures

This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures in a non-verbose, human-readable format. It ships with Ruby 1.8.1+.

Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed in the directory appointed by ActiveSupport::TestCase.fixture_path=(path) (this is automatically configured for Rails, so you can just put your files in <your-rails-app>/test/fixtures/). The fixture file ends with the .yml file extension (Rails example: <your-rails-app>/test/fixtures/web_sites.yml). The format of a YAML fixture file looks like this:

  rubyonrails:
    id: 1
    name: Ruby on Rails
    url: http://www.rubyonrails.org

  google:
    id: 2
    name: Google
    url: http://www.google.com

This YAML fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing pleasure.

Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See yaml.org/type/omap.html for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table. This is commonly needed for tree structures. Example:

   --- !omap
   - parent:
       id:         1
       parent_id:  NULL
       title:      Parent
   - child:
       id:         2
       parent_id:  1
       title:      Child

CSV fixtures

Fixtures can also be kept in the Comma Separated Value (CSV) format. Akin to YAML fixtures, CSV fixtures are stored in a single file, but instead end with the .csv file extension (Rails example: <your-rails-app>/test/fixtures/web_sites.csv).

The format of this type of fixture file is much more compact than the others, but also a little harder to read by us humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised of the actual data (1 per line). Here‘s an example:

  id, name, url
  1, Ruby On Rails, http://www.rubyonrails.org
  2, Google, http://www.google.com

Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you need to use a double quote character, you must escape it with another double quote.

Another unique attribute of the CSV fixture is that it has no fixture name like the other two formats. Instead, the fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called "web_site_2".

Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you have existing data somewhere already.

Single-file fixtures

This type of fixture was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats. Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory appointed by ActiveSupport::TestCase.fixture_path=(path) (this is automatically configured for Rails, so you can just put your files in <your-rails-app>/test/fixtures/<your-model-name>/ — like <your-rails-app>/test/fixtures/web_sites/ for the WebSite model).

Each text file placed in this directory represents a "record". Usually these types of fixtures are named without extensions, but if you are on a Windows machine, you might consider adding .txt as the extension. Here‘s what the above example might look like:

  web_sites/google
  web_sites/yahoo.txt
  web_sites/ruby-on-rails

The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax of "name => value". Here‘s an example of the ruby-on-rails fixture above:

  id => 1
  name => Ruby on Rails
  url => http://www.rubyonrails.org

Using fixtures in testcases

Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the fixtures, but first let‘s take a look at a sample unit test:

  require 'test_helper'

  class WebSiteTest < ActiveSupport::TestCase
    test "web_site_count" do
      assert_equal 2, WebSite.count
    end
  end

By default, the test_helper module will load all of your fixtures into your test database, so this test will succeed. The testing environment will automatically load the all fixtures into the database before each test. To ensure consistent data, the environment deletes the fixtures before running the load.

In addition to being available in the database, the fixture‘s data may also be accessed by using a special dynamic method, which has the same name as the model, and accepts the name of the fixture to instantiate:

  test "find" do
    assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
  end

Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the following tests:

  test "find_alt_method_1" do
    assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name']
  end

  test "find_alt_method_2" do
    assert_equal "Ruby on Rails", @rubyonrails.news
  end

In order to use these methods to access fixtured data within your testcases, you must specify one of the following in your ActiveSupport::TestCase-derived class:

  • to fully enable instantiated fixtures (enable alternate methods 1 and 2 above)
      self.use_instantiated_fixtures = true
  • create only the hash for the fixtures, do not ‘find’ each instance (enable alternate method 1 only)
      self.use_instantiated_fixtures = :no_instances

Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully traversed in the database to create the fixture hash and/or instance variables. This is expensive for large sets of fixtured data.

Dynamic fixtures with ERb

Some times you don‘t care about the content of the fixtures as much as you care about the volume. In these cases, you can mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:

  <% for i in 1..1000 %>
  fix_<%= i %>:
    id: <%= i %>
    name: guy_<%= 1 %>
  <% end %>

This will create 1000 very simple YAML fixtures.

Using ERb, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>. This is however a feature to be used with some caution. The point of fixtures are that they‘re stable units of predictable sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.

Transactional fixtures

TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case.

  class FooTest < ActiveSupport::TestCase
    self.use_transactional_fixtures = true

    test "godzilla" do
      assert !Foo.find(:all).empty?
      Foo.destroy_all
      assert Foo.find(:all).empty?
    end

    test "godzilla aftermath" do
      assert !Foo.find(:all).empty?
    end
  end

If you preload your test database with all fixture data (probably in the Rakefile task) and use transactional fixtures, then you may omit all fixtures declarations in your test cases since all the data‘s already there and every case rolls back its changes.

In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to true. This will provide access to fixture data for every table that has been loaded through fixtures (depending on the value of use_instantiated_fixtures)

When not to use transactional fixtures:

  1. You‘re testing whether a transaction works correctly. Nested transactions don‘t commit until all parent transactions commit, particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won‘t be able to verify the results of your transaction until Active Record supports nested transactions or savepoints (in progress).
  2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. Use InnoDB, MaxDB, or NDB instead.

Advanced YAML Fixtures

YAML fixtures that don‘t specify an ID get some extra features:

  • Stable, autogenerated IDs
  • Label references for associations (belongs_to, has_one, has_many)
  • HABTM associations as inline lists
  • Autofilled timestamp columns
  • Fixture label interpolation
  • Support for YAML defaults

Stable, autogenerated IDs

Here, have a monkey fixture:

  george:
    id: 1
    name: George the Monkey

  reginald:
    id: 2
    name: Reginald the Pirate

Each of these fixtures has two unique identifiers: one for the database and one for the humans. Why don‘t we generate the primary key instead? Hashing each fixture‘s label yields a consistent ID:

  george: # generated id: 503576764
    name: George the Monkey

  reginald: # generated id: 324201669
    name: Reginald the Pirate

Active Record looks at the fixture‘s model class, discovers the correct primary key, and generates it right before inserting the fixture into the database.

The generated ID for a given label is constant, so we can discover any fixture‘s ID without loading anything, as long as we know the label.

Label references for associations (belongs_to, has_one, has_many)

Specifying foreign keys in fixtures can be very fragile, not to mention difficult to read. Since Active Record can figure out the ID of any fixture from its label, you can specify FK‘s by label instead of ID.

belongs_to

Let‘s break out some more monkeys and pirates.

  ### in pirates.yml

  reginald:
    id: 1
    name: Reginald the Pirate
    monkey_id: 1

  ### in monkeys.yml

  george:
    id: 1
    name: George the Monkey
    pirate_id: 1

Add a few more monkeys and pirates and break this into multiple files, and it gets pretty hard to keep track of what‘s going on. Let‘s use labels instead of IDs:

  ### in pirates.yml

  reginald:
    name: Reginald the Pirate
    monkey: george

  ### in monkeys.yml

  george:
    name: George the Monkey
    pirate: reginald

Pow! All is made clear. Active Record reflects on the fixture‘s model class, finds all the belongs_to associations, and allows you to specify a target label for the association (monkey: george) rather than a target id for the FK (monkey_id: 1).

Polymorphic belongs_to

Supporting polymorphic relationships is a little bit more complicated, since Active Record needs to know what type your association is pointing at. Something like this should look familiar:

  ### in fruit.rb

  belongs_to :eater, :polymorphic => true

  ### in fruits.yml

  apple:
    id: 1
    name: apple
    eater_id: 1
    eater_type: Monkey

Can we do better? You bet!

  apple:
    eater: george (Monkey)

Just provide the polymorphic target type and Active Record will take care of the rest.

has_and_belongs_to_many

Time to give our monkey some fruit.

  ### in monkeys.yml

  george:
    id: 1
    name: George the Monkey
    pirate_id: 1

  ### in fruits.yml

  apple:
    id: 1
    name: apple

  orange:
    id: 2
    name: orange

  grape:
    id: 3
    name: grape

  ### in fruits_monkeys.yml

  apple_george:
    fruit_id: 1
    monkey_id: 1

  orange_george:
    fruit_id: 2
    monkey_id: 1

  grape_george:
    fruit_id: 3
    monkey_id: 1

Let‘s make the HABTM fixture go away.

  ### in monkeys.yml

  george:
    name: George the Monkey
    pirate: reginald
    fruits: apple, orange, grape

  ### in fruits.yml

  apple:
    name: apple

  orange:
    name: orange

  grape:
    name: grape

Zap! No more fruits_monkeys.yml file. We‘ve specified the list of fruits on George‘s fixture, but we could‘ve just as easily specified a list of monkeys on each fruit. As with belongs_to, Active Record reflects on the fixture‘s model class and discovers the has_and_belongs_to_many associations.

Autofilled timestamp columns

If your table/model specifies any of Active Record‘s standard timestamp columns (created_at, created_on, updated_at, updated_on), they will automatically be set to Time.now.

If you‘ve set specific values, they‘ll be left alone.

Fixture label interpolation

The label of the current fixture is always available as a column value:

  geeksomnia:
    name: Geeksomnia's Account
    subdomain: $LABEL

Also, sometimes (like when porting older join table fixtures) you‘ll need to be able to get ahold of the identifier for a given label. ERB to the rescue:

  george_reginald:
    monkey_id: <%= Fixtures.identify(:reginald) %>
    pirate_id: <%= Fixtures.identify(:george) %>

Support for YAML defaults

You probably already know how to use YAML to set and reuse defaults in your database.yml file. You can use the same technique in your fixtures:

  DEFAULTS: &DEFAULTS
    created_on: <%= 3.weeks.ago.to_s(:db) %>

  first:
    name: Smurf
    <<: *DEFAULTS

  second:
    name: Fraggle
    <<: *DEFAULTS

Any fixture labeled "DEFAULTS" is safely ignored.

Methods

cache_fixtures cache_for_connection cached_fixtures create_fixtures delete_existing_fixtures fixture_is_cached? identify insert_fixtures instantiate_all_loaded_fixtures instantiate_fixtures new reset_cache

Constants

DEFAULT_FILTER_RE = /\.ya?ml$/

Attributes

name | [R]
table_name | [R]

Public Class methods

cache_fixtures(connection, fixtures_map)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 463
463:   def self.cache_fixtures(connection, fixtures_map)
464:     cache_for_connection(connection).update(fixtures_map)
465:   end
cache_for_connection(connection)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 445
445:   def self.cache_for_connection(connection)
446:     @@all_cached_fixtures[connection.object_id] ||= {}
447:     @@all_cached_fixtures[connection.object_id]
448:   end
cached_fixtures(connection, keys_to_fetch = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 454
454:   def self.cached_fixtures(connection, keys_to_fetch = nil)
455:     if keys_to_fetch
456:       fixtures = cache_for_connection(connection).values_at(*keys_to_fetch)
457:     else
458:       fixtures = cache_for_connection(connection).values
459:     end
460:     fixtures.size > 1 ? fixtures : fixtures.first
461:   end
create_fixtures(fixtures_directory, table_names, class_names = {}) {|: ActiveRecord::Base.connection| ...}

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 491
491:   def self.create_fixtures(fixtures_directory, table_names, class_names = {})
492:     table_names = [table_names].flatten.map { |n| n.to_s }
493:     connection  = block_given? ? yield : ActiveRecord::Base.connection
494:
495:     table_names_to_fetch = table_names.reject { |table_name| fixture_is_cached?(connection, table_name) }
496:
497:     unless table_names_to_fetch.empty?
498:       ActiveRecord::Base.silence do
499:         connection.disable_referential_integrity do
500:           fixtures_map = {}
501:
502:           fixtures = table_names_to_fetch.map do |table_name|
503:             fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, class_names[table_name.to_sym], File.join(fixtures_directory, table_name.to_s))
504:           end
505:
506:           all_loaded_fixtures.update(fixtures_map)
507:
508:           connection.transaction(:requires_new => true) do
509:             fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
510:             fixtures.each { |fixture| fixture.insert_fixtures }
511:
512:             # Cap primary key sequences to max(pk).
513:             if connection.respond_to?(:reset_pk_sequence!)
514:               table_names.each do |table_name|
515:                 connection.reset_pk_sequence!(table_name)
516:               end
517:             end
518:           end
519:
520:           cache_fixtures(connection, fixtures_map)
521:         end
522:       end
523:     end
524:     cached_fixtures(connection, table_names)
525:   end
fixture_is_cached?(connection, table_name)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 450
450:   def self.fixture_is_cached?(connection, table_name)
451:     cache_for_connection(connection)[table_name]
452:   end
identify(label)

Returns a consistent identifier for label. This will always be a positive integer, and will always be the same for a given label, assuming the same OS, platform, and version of Ruby.

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 530
530:   def self.identify(label)
531:     label.to_s.hash.abs
532:   end
instantiate_all_loaded_fixtures(object, load_instances = true)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 482
482:   def self.instantiate_all_loaded_fixtures(object, load_instances = true)
483:     all_loaded_fixtures.each do |table_name, fixtures|
484:       Fixtures.instantiate_fixtures(object, table_name, fixtures, load_instances)
485:     end
486:   end
instantiate_fixtures(object, table_name, fixtures, load_instances = true)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 467
467:   def self.instantiate_fixtures(object, table_name, fixtures, load_instances = true)
468:     object.instance_variable_set "@#{table_name.to_s.gsub('.','_')}", fixtures
469:     if load_instances
470:       ActiveRecord::Base.silence do
471:         fixtures.each do |name, fixture|
472:           begin
473:             object.instance_variable_set "@#{name}", fixture.find
474:           rescue FixtureClassNotFound
475:             nil
476:           end
477:         end
478:       end
479:     end
480:   end
new(connection, table_name, class_name, fixture_path, file_filter = DEFAULT_FILTER_RE)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 536
536:   def initialize(connection, table_name, class_name, fixture_path, file_filter = DEFAULT_FILTER_RE)
537:     @connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
538:     @name = table_name # preserve fixture base name
539:     @class_name = class_name ||
540:                   (ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
541:     @table_name = "#{ActiveRecord::Base.table_name_prefix}#{@table_name}#{ActiveRecord::Base.table_name_suffix}"
542:     @table_name = class_name.table_name if class_name.respond_to?(:table_name)
543:     @connection = class_name.connection if class_name.respond_to?(:connection)
544:     read_fixture_files
545:   end
reset_cache(connection = nil)

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 440
440:   def self.reset_cache(connection = nil)
441:     connection ||= ActiveRecord::Base.connection
442:     @@all_cached_fixtures[connection.object_id] = {}
443:   end

Public Instance methods

delete_existing_fixtures()

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 547
547:   def delete_existing_fixtures
548:     @connection.delete "DELETE FROM #{@connection.quote_table_name(table_name)}", 'Fixture Delete'
549:   end
insert_fixtures()

[Source]

     # File vendor/rails/activerecord/lib/active_record/fixtures.rb, line 551
551:   def insert_fixtures
552:     now = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
553:     now = now.to_s(:db)
554:
555:     # allow a standard key to be used for doing defaults in YAML
556:     if is_a?(Hash)
557:       delete('DEFAULTS')
558:     else
559:       delete(assoc('DEFAULTS'))
560:     end
561:
562:     # track any join tables we need to insert later
563:     habtm_fixtures = Hash.new do |h, habtm|
564:       h[habtm] = HabtmFixtures.new(@connection, habtm.options[:join_table], nil, nil)
565:     end
566:
567:     each do |label, fixture|
568:       row = fixture.to_hash
569:
570:       if model_class && model_class < ActiveRecord::Base
571:         # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
572:         if model_class.record_timestamps
573:           timestamp_column_names.each do |name|
574:             row[name] = now unless row.key?(name)
575:           end
576:         end
577:
578:         # interpolate the fixture label
579:         row.each do |key, value|
580:           row[key] = label if value == "$LABEL"
581:         end
582:
583:         # generate a primary key if necessary
584:         if has_primary_key_column? && !row.include?(primary_key_name)
585:           row[primary_key_name] = Fixtures.identify(label)
586:         end
587:
588:         # If STI is used, find the correct subclass for association reflection
589:         reflection_class =
590:           if row.include?(inheritance_column_name)
591:             row[inheritance_column_name].constantize rescue model_class
592:           else
593:             model_class
594:           end
595:
596:         reflection_class.reflect_on_all_associations.each do |association|
597:           case association.macro
598:           when :belongs_to
599:             # Do not replace association name with association foreign key if they are named the same
600:             fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
601:
602:             if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
603:               if association.options[:polymorphic]
604:                 if value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
605:                   target_type = $1
606:                   target_type_name = (association.options[:foreign_type] || "#{association.name}_type").to_s
607:
608:                   # support polymorphic belongs_to as "label (Type)"
609:                   row[target_type_name] = target_type
610:                 end
611:               end
612:
613:               row[fk_name] = Fixtures.identify(value)
614:             end
615:           when :has_and_belongs_to_many
616:             if (targets = row.delete(association.name.to_s))
617:               targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
618:               join_fixtures = habtm_fixtures[association]
619:
620:               targets.each do |target|
621:                 join_fixtures["#{label}_#{target}"] = Fixture.new(
622:                   { association.primary_key_name => row[primary_key_name],
623:                     association.association_foreign_key => Fixtures.identify(target) }, nil)
624:               end
625:             end
626:           end
627:         end
628:       end
629:
630:       @connection.insert_fixture(fixture, @table_name)
631:     end
632:
633:     # insert any HABTM join tables we discovered
634:     habtm_fixtures.values.each do |fixture|
635:       fixture.delete_existing_fixtures
636:       fixture.insert_fixtures
637:     end
638:   end


Class: HTML::FullSanitizer

Class | HTML::FullSanitizer
In: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
Parent: | Sanitizer

Methods

process_node sanitize

Public Instance methods

process_node(node, result, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 38
38:     def process_node(node, result, options)
39:       result << node.to_s if node.class == HTML::Text
40:     end
sanitize(text, options = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 29
29:     def sanitize(text, options = {})
30:       result = super
31:       # strip any comments, and if they have a newline at the end (ie. line with
32:       # only a comment) strip that too
33:       result.gsub!(/<!--(.*?)-->[\n]?/m, "") if result
34:       # Recurse - handle all dirty nested tags
35:       result == text ? result : sanitize(result, options)
36:     end


Class: HTML::LinkSanitizer

Class | HTML::LinkSanitizer
In: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
Parent: | FullSanitizer

Methods

process_node sanitizeable?

Public Instance methods

sanitizeable?(text)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 47
47:     def sanitizeable?(text)
48:       !(text.nil? || text.empty? || !((text.index("<a") || text.index("<href")) && text.index(">")))
49:     end

Protected Instance methods

process_node(node, result, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 52
52:     def process_node(node, result, options)
53:       result << node.to_s unless node.is_a?(HTML::Tag) && included_tags.include?(node.name)
54:     end


Class: HTML::Sanitizer

Class | HTML::Sanitizer
In: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
Parent: | Object

Methods

process_node sanitize sanitizeable? tokenize

Public Instance methods

sanitize(text, options = {})

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 3
3:     def sanitize(text, options = {})
4:       return text unless sanitizeable?(text)
5:       tokenize(text, options).join
6:     end
sanitizeable?(text)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 8
 8:     def sanitizeable?(text)
 9:       !(text.nil? || text.empty? || !text.index("<"))
10:     end

Protected Instance methods

process_node(node, result, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 23
23:     def process_node(node, result, options)
24:       result << node.to_s
25:     end
tokenize(text, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 13
13:     def tokenize(text, options)
14:       tokenizer = HTML::Tokenizer.new(text)
15:       result = []
16:       while token = tokenizer.next
17:         node = Node.parse(nil, 0, 0, token, false)
18:         process_node node, result, options
19:       end
20:       result
21:     end


Class: HTML::Selector

Class | HTML::Selector
In: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
Parent: | Object

Selects HTML elements using CSS 2 selectors.

The Selector class uses CSS selector expressions to match and select HTML elements.

For example:

  selector = HTML::Selector.new "form.login[action=/login]"

creates a new selector that matches any form element with the class login and an attribute action with the value /login.

Matching Elements

Use the match method to determine if an element matches the selector.

For simple selectors, the method returns an array with that element, or nil if the element does not match. For complex selectors (see below) the method returns an array with all matched elements, of nil if no match found.

For example:

  if selector.match(element)
    puts "Element is a login form"
  end

Selecting Elements

Use the select method to select all matching elements starting with one element and going through all children in depth-first order.

This method returns an array of all matching elements, an empty array if no match is found

For example:

  selector = HTML::Selector.new "input[type=text]"
  matches = selector.select(element)
  matches.each do |match|
    puts "Found text field with name #{match.attributes['name']}"
  end

Expressions

Selectors can match elements using any of the following criteria:

  • name — Match an element based on its name (tag name). For example, p to match a paragraph. You can use * to match any element.
  • #id — Match an element based on its identifier (the id attribute). For example, #page.
  • .class — Match an element based on its class name, all class names if more than one specified.
  • [attr] — Match an element that has the specified attribute.
  • [attr=value] — Match an element that has the specified attribute and value. (More operators are supported see below)
  • :pseudo-class — Match an element based on a pseudo class, such as :nth-child and :empty.
  • :not(expr) — Match an element that does not match the negation expression.

When using a combination of the above, the element name comes first followed by identifier, class names, attributes, pseudo classes and negation in any order. Do not separate these parts with spaces! Space separation is used for descendant selectors.

For example:

  selector = HTML::Selector.new "form.login[action=/login]"

The matched element must be of type form and have the class login. It may have other classes, but the class login is required to match. It must also have an attribute called action with the value /login.

This selector will match the following element:

  <form class="login form" method="post" action="/login">

but will not match the element:

  <form method="post" action="/logout">

Attribute Values

Several operators are supported for matching attributes:

  • name — The element must have an attribute with that name.
  • name=value — The element must have an attribute with that name and value.
  • name^=value — The attribute value must start with the specified value.
  • name$=value — The attribute value must end with the specified value.
  • name*=value — The attribute value must contain the specified value.
  • name~=word — The attribute value must contain the specified word (space separated).
  • name|=word — The attribute value must start with specified word.

For example, the following two selectors match the same element:

  #my_id
  [id=my_id]

and so do the following two selectors:

  .my_class
  [class~=my_class]

Alternatives, siblings, children

Complex selectors use a combination of expressions to match elements:

  • expr1 expr2 — Match any element against the second expression if it has some parent element that matches the first expression.
  • expr1 > expr2 — Match any element against the second expression if it is the child of an element that matches the first expression.
  • expr1 + expr2 — Match any element against the second expression if it immediately follows an element that matches the first expression.
  • expr1 ~ expr2 — Match any element against the second expression that comes after an element that matches the first expression.
  • expr1, expr2 — Match any element against the first expression, or against the second expression.

Since children and sibling selectors may match more than one element given the first element, the match method may return more than one match.

Pseudo classes

Pseudo classes were introduced in CSS 3. They are most often used to select elements in a given position:

  • :root — Match the element only if it is the root element (no parent element).
  • :empty — Match the element only if it has no child elements, and no text content.
  • :only-child — Match the element if it is the only child (element) of its parent element.
  • :only-of-type — Match the element if it is the only child (element) of its parent element and its type.
  • :first-child — Match the element if it is the first child (element) of its parent element.
  • :first-of-type — Match the element if it is the first child (element) of its parent element of its type.
  • :last-child — Match the element if it is the last child (element) of its parent element.
  • :last-of-type — Match the element if it is the last child (element) of its parent element of its type.
  • :nth-child(b) — Match the element if it is the b-th child (element) of its parent element. The value b specifies its index, starting with 1.
  • :nth-child(an+b) — Match the element if it is the b-th child (element) in each group of a child elements of its parent element.
  • :nth-child(-an+b) — Match the element if it is the first child (element) in each group of a child elements, up to the first b child elements of its parent element.
  • :nth-child(odd) — Match element in the odd position (i.e. first, third). Same as :nth-child(2n+1).
  • :nth-child(even) — Match element in the even position (i.e. second, fourth). Same as :nth-child(2n+2).
  • :nth-of-type(..) — As above, but only counts elements of its type.
  • :nth-last-child(..) — As above, but counts from the last child.
  • :nth-last-of-type(..) — As above, but counts from the last child and only elements of its type.
  • :not(selector) — Match the element only if the element does not match the simple selector.

As you can see, <tt>:nth-child<tt> pseudo class and its variant can get quite tricky and the CSS specification doesn‘t do a much better job explaining it. But after reading the examples and trying a few combinations, it‘s easy to figure out.

For example:

  table tr:nth-child(odd)

Selects every second row in the table starting with the first one.

  div p:nth-child(4)

Selects the fourth paragraph in the div, but not if the div contains other elements, since those are also counted.

  div p:nth-of-type(4)

Selects the fourth paragraph in the div, counting only paragraphs, and ignoring all other elements.

  div p:nth-of-type(-n+4)

Selects the first four paragraphs, ignoring all others.

And you can always select an element that matches one set of rules but not another using :not. For example:

  p:not(.post)

Matches all paragraphs that do not have the class .post.

Substitution Values

You can use substitution with identifiers, class names and element values. A substitution takes the form of a question mark (?) and uses the next value in the argument list following the CSS expression.

The substitution value may be a string or a regular expression. All other values are converted to strings.

For example:

  selector = HTML::Selector.new "#?", /^\d+$/

matches any element whose identifier consists of one or more digits.

See www.w3.org/TR/css3-selectors/

Methods

attribute_match for_class for_id match new next_element next_selector nth_child only_child select select_first simple_selector

Public Class methods

Selector.for_class(cls) => selector

Creates a new selector for the given class name.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 214
214:       def for_class(cls)
215:         self.new([".?", cls])
216:       end
Selector.for_id(id) => selector

Creates a new selector for the given id.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 223
223:       def for_id(id)
224:         self.new(["#?", id])
225:       end
Selector.new(string, [values ...]) => selector

Creates a new selector from a CSS 2 selector expression.

The first argument is the selector expression. All other arguments are used for value substitution.

Throws InvalidSelectorError is the selector expression is invalid.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 239
239:     def initialize(selector, *values)
240:       raise ArgumentError, "CSS expression cannot be empty" if selector.empty?
241:       @source = ""
242:       values = values[0] if values.size == 1 && values[0].is_a?(Array)
243:
244:       # We need a copy to determine if we failed to parse, and also
245:       # preserve the original pass by-ref statement.
246:       statement = selector.strip.dup
247:
248:       # Create a simple selector, along with negation.
249:       simple_selector(statement, values).each { |name, value| instance_variable_set("@#{name}", value) }
250:
251:       @alternates = []
252:       @depends = nil
253:
254:       # Alternative selector.
255:       if statement.sub!(/^\s*,\s*/, "")
256:         second = Selector.new(statement, values)
257:         @alternates << second
258:         # If there are alternate selectors, we group them in the top selector.
259:         if alternates = second.instance_variable_get(:@alternates)
260:           second.instance_variable_set(:@alternates, [])
261:           @alternates.concat alternates
262:         end
263:         @source << " , " << second.to_s
264:       # Sibling selector: create a dependency into second selector that will
265:       # match element immediately following this one.
266:       elsif statement.sub!(/^\s*\+\s*/, "")
267:         second = next_selector(statement, values)
268:         @depends = lambda do |element, first|
269:           if element = next_element(element)
270:             second.match(element, first)
271:           end
272:         end
273:         @source << " + " << second.to_s
274:       # Adjacent selector: create a dependency into second selector that will
275:       # match all elements following this one.
276:       elsif statement.sub!(/^\s*~\s*/, "")
277:         second = next_selector(statement, values)
278:         @depends = lambda do |element, first|
279:           matches = []
280:           while element = next_element(element)
281:             if subset = second.match(element, first)
282:               if first && !subset.empty?
283:                 matches << subset.first
284:                 break
285:               else
286:                 matches.concat subset
287:               end
288:             end
289:           end
290:           matches.empty? ? nil : matches
291:         end
292:         @source << " ~ " << second.to_s
293:       # Child selector: create a dependency into second selector that will
294:       # match a child element of this one.
295:       elsif statement.sub!(/^\s*>\s*/, "")
296:         second = next_selector(statement, values)
297:         @depends = lambda do |element, first|
298:           matches = []
299:           element.children.each do |child|
300:             if child.tag? && subset = second.match(child, first)
301:               if first && !subset.empty?
302:                 matches << subset.first
303:                 break
304:               else
305:                 matches.concat subset
306:               end
307:             end
308:           end
309:           matches.empty? ? nil : matches
310:         end
311:         @source << " > " << second.to_s
312:       # Descendant selector: create a dependency into second selector that
313:       # will match all descendant elements of this one. Note,
314:       elsif statement =~ /^\s+\S+/ && statement != selector
315:         second = next_selector(statement, values)
316:         @depends = lambda do |element, first|
317:           matches = []
318:           stack = element.children.reverse
319:           while node = stack.pop
320:             next unless node.tag?
321:             if subset = second.match(node, first)
322:               if first && !subset.empty?
323:                 matches << subset.first
324:                 break
325:               else
326:                 matches.concat subset
327:               end
328:             elsif children = node.children
329:               stack.concat children.reverse
330:             end
331:           end
332:           matches.empty? ? nil : matches
333:         end
334:         @source << " " << second.to_s
335:       else
336:         # The last selector is where we check that we parsed
337:         # all the parts.
338:         unless statement.empty? || statement.strip.empty?
339:           raise ArgumentError, "Invalid selector: #{statement}"
340:         end
341:       end
342:     end

Public Instance methods

match(element, first?) => array or nil

Matches an element against the selector.

For a simple selector this method returns an array with the element if the element matches, nil otherwise.

For a complex selector (sibling and descendant) this method returns an array with all matching elements, nil if no match is found.

Use +first_only=true+ if you are only interested in the first element.

For example:

  if selector.match(element)
    puts "Element is a login form"
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 363
363:     def match(element, first_only = false)
364:       # Match element if no element name or element name same as element name
365:       if matched = (!@tag_name || @tag_name == element.name)
366:         # No match if one of the attribute matches failed
367:         for attr in @attributes
368:           if element.attributes[attr[0]] !~ attr[1]
369:             matched = false
370:             break
371:           end
372:         end
373:       end
374:
375:       # Pseudo class matches (nth-child, empty, etc).
376:       if matched
377:         for pseudo in @pseudo
378:           unless pseudo.call(element)
379:             matched = false
380:             break
381:           end
382:         end
383:       end
384:
385:       # Negation. Same rules as above, but we fail if a match is made.
386:       if matched && @negation
387:         for negation in @negation
388:           if negation[:tag_name] == element.name
389:             matched = false
390:           else
391:             for attr in negation[:attributes]
392:               if element.attributes[attr[0]] =~ attr[1]
393:                 matched = false
394:                 break
395:               end
396:             end
397:           end
398:           if matched
399:             for pseudo in negation[:pseudo]
400:               if pseudo.call(element)
401:                 matched = false
402:                 break
403:               end
404:             end
405:           end
406:           break unless matched
407:         end
408:       end
409:
410:       # If element matched but depends on another element (child,
411:       # sibling, etc), apply the dependent matches instead.
412:       if matched && @depends
413:         matches = @depends.call(element, first_only)
414:       else
415:         matches = matched ? [element] : nil
416:       end
417:
418:       # If this selector is part of the group, try all the alternative
419:       # selectors (unless first_only).
420:       if !first_only || !matches
421:         @alternates.each do |alternate|
422:           break if matches && first_only
423:           if subset = alternate.match(element, first_only)
424:             if matches
425:               matches.concat subset
426:             else
427:               matches = subset
428:             end
429:           end
430:         end
431:       end
432:
433:       matches
434:     end
next_element(element, name = nil)

Return the next element after this one. Skips sibling text nodes.

With the name argument, returns the next element with that name, skipping other sibling elements.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 493
493:     def next_element(element, name = nil)
494:       if siblings = element.parent.children
495:         found = false
496:         siblings.each do |node|
497:           if node.equal?(element)
498:             found = true
499:           elsif found && node.tag?
500:             return node if (name.nil? || node.name == name)
501:           end
502:         end
503:       end
504:       nil
505:     end
select(root) => array

Selects and returns an array with all matching elements, beginning with one node and traversing through all children depth-first. Returns an empty array if no match is found.

The root node may be any element in the document, or the document itself.

For example:

  selector = HTML::Selector.new "input[type=text]"
  matches = selector.select(element)
  matches.each do |match|
    puts "Found text field with name #{match.attributes['name']}"
  end

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 453
453:     def select(root)
454:       matches = []
455:       stack = [root]
456:       while node = stack.pop
457:         if node.tag? && subset = match(node, false)
458:           subset.each do |match|
459:             matches << match unless matches.any? { |item| item.equal?(match) }
460:           end
461:         elsif children = node.children
462:           stack.concat children.reverse
463:         end
464:       end
465:       matches
466:     end
select_first(root)

Similar to select but returns the first matching element. Returns nil if no element matches the selector.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 471
471:     def select_first(root)
472:       stack = [root]
473:       while node = stack.pop
474:         if node.tag? && subset = match(node, true)
475:           return subset.first if !subset.empty?
476:         elsif children = node.children
477:           stack.concat children.reverse
478:         end
479:       end
480:       nil
481:     end

Protected Instance methods

attribute_match(equality, value)

Create a regular expression to match an attribute value based on the equality operator (=, ^=, |=, etc).

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 687
687:     def attribute_match(equality, value)
688:       regexp = value.is_a?(Regexp) ? value : Regexp.escape(value.to_s)
689:       case equality
690:         when "=" then
691:           # Match the attribute value in full
692:           Regexp.new("^#{regexp}$")
693:         when "~=" then
694:           # Match a space-separated word within the attribute value
695:           Regexp.new("(^|\s)#{regexp}($|\s)")
696:         when "^="
697:           # Match the beginning of the attribute value
698:           Regexp.new("^#{regexp}")
699:         when "$="
700:           # Match the end of the attribute value
701:           Regexp.new("#{regexp}$")
702:         when "*="
703:           # Match substring of the attribute value
704:           regexp.is_a?(Regexp) ? regexp : Regexp.new(regexp)
705:         when "|=" then
706:           # Match the first space-separated item of the attribute value
707:           Regexp.new("^#{regexp}($|\s)")
708:         else
709:           raise InvalidSelectorError, "Invalid operation/value" unless value.empty?
710:           # Match all attributes values (existence check)
711:           //
712:       end
713:     end
next_selector(statement, values)

Called to create a dependent selector (sibling, descendant, etc). Passes the remainder of the statement that will be reduced to zero eventually, and array of substitution values.

This method is called from four places, so it helps to put it here for reuse. The only logic deals with the need to detect comma separators (alternate) and apply them to the selector group of the top selector.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 800
800:     def next_selector(statement, values)
801:       second = Selector.new(statement, values)
802:       # If there are alternate selectors, we group them in the top selector.
803:       if alternates = second.instance_variable_get(:@alternates)
804:         second.instance_variable_set(:@alternates, [])
805:         @alternates.concat alternates
806:       end
807:       second
808:     end
nth_child(a, b, of_type, reverse)

Returns a lambda that can match an element against the nth-child pseudo class, given the following arguments:

  • a — Value of a part.
  • b — Value of b part.
  • of_type — True to test only elements of this type (of-type).
  • reverse — True to count in reverse order (last-).

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 722
722:     def nth_child(a, b, of_type, reverse)
723:       # a = 0 means select at index b, if b = 0 nothing selected
724:       return lambda { |element| false } if a == 0 && b == 0
725:       # a < 0 and b < 0 will never match against an index
726:       return lambda { |element| false } if a < 0 && b < 0
727:       b = a + b + 1 if b < 0   # b < 0 just picks last element from each group
728:       b -= 1 unless b == 0  # b == 0 is same as b == 1, otherwise zero based
729:       lambda do |element|
730:         # Element must be inside parent element.
731:         return false unless element.parent && element.parent.tag?
732:         index = 0
733:         # Get siblings, reverse if counting from last.
734:         siblings = element.parent.children
735:         siblings = siblings.reverse if reverse
736:         # Match element name if of-type, otherwise ignore name.
737:         name = of_type ? element.name : nil
738:         found = false
739:         for child in siblings
740:           # Skip text nodes/comments.
741:           if child.tag? && (name == nil || child.name == name)
742:             if a == 0
743:               # Shortcut when a == 0 no need to go past count
744:               if index == b
745:                 found = child.equal?(element)
746:                 break
747:               end
748:             elsif a < 0
749:               # Only look for first b elements
750:               break if index > b
751:               if child.equal?(element)
752:                 found = (index % a) == 0
753:                 break
754:               end
755:             else
756:               # Otherwise, break if child found and count ==  an+b
757:               if child.equal?(element)
758:                 found = (index % a) == b
759:                 break
760:               end
761:             end
762:             index += 1
763:           end
764:         end
765:         found
766:       end
767:     end
only_child(of_type)

Creates a only child lambda. Pass +of-type+ to only look at elements of its type.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 772
772:     def only_child(of_type)
773:       lambda do |element|
774:         # Element must be inside parent element.
775:         return false unless element.parent && element.parent.tag?
776:         name = of_type ? element.name : nil
777:         other = false
778:         for child in element.parent.children
779:           # Skip text nodes/comments.
780:           if child.tag? && (name == nil || child.name == name)
781:             unless child.equal?(element)
782:               other = true
783:               break
784:             end
785:           end
786:         end
787:         !other
788:       end
789:     end
simple_selector(statement, values, can_negate = true)

Creates a simple selector given the statement and array of substitution values.

Returns a hash with the values tag_name, attributes, pseudo (classes) and negation.

Called the first time with can_negate true to allow negation. Called a second time with false since negation cannot be negated.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb, line 520
520:     def simple_selector(statement, values, can_negate = true)
521:       tag_name = nil
522:       attributes = []
523:       pseudo = []
524:       negation = []
525:
526:       # Element name. (Note that in negation, this can come at
527:       # any order, but for simplicity we allow if only first).
528:       statement.sub!(/^(\*|[[:alpha:]][\w\-]*)/) do |match|
529:         match.strip!
530:         tag_name = match.downcase unless match == "*"
531:         @source << match
532:         "" # Remove
533:       end
534:
535:       # Get identifier, class, attribute name, pseudo or negation.
536:       while true
537:         # Element identifier.
538:         next if statement.sub!(/^#(\?|[\w\-]+)/) do |match|
539:           id = $1
540:           if id == "?"
541:             id = values.shift
542:           end
543:           @source << "##{id}"
544:           id = Regexp.new("^#{Regexp.escape(id.to_s)}$") unless id.is_a?(Regexp)
545:           attributes << ["id", id]
546:           "" # Remove
547:         end
548:
549:         # Class name.
550:         next if statement.sub!(/^\.([\w\-]+)/) do |match|
551:           class_name = $1
552:           @source << ".#{class_name}"
553:           class_name = Regexp.new("(^|\s)#{Regexp.escape(class_name)}($|\s)") unless class_name.is_a?(Regexp)
554:           attributes << ["class", class_name]
555:           "" # Remove
556:         end
557:
558:         # Attribute value.
559:         next if statement.sub!(/^\[\s*([[:alpha:]][\w\-:]*)\s*((?:[~|^$*])?=)?\s*('[^']*'|"[^*]"|[^\]]*)\s*\]/) do |match|
560:           name, equality, value = $1, $2, $3
561:           if value == "?"
562:             value = values.shift
563:           else
564:             # Handle single and double quotes.
565:             value.strip!
566:             if (value[0] == ?" || value[0] == ?') && value[0] == value[-1]
567:               value = value[1..-2]
568:             end
569:           end
570:           @source << "[#{name}#{equality}'#{value}']"
571:           attributes << [name.downcase.strip, attribute_match(equality, value)]
572:           "" # Remove
573:         end
574:
575:         # Root element only.
576:         next if statement.sub!(/^:root/) do |match|
577:           pseudo << lambda do |element|
578:             element.parent.nil? || !element.parent.tag?
579:           end
580:           @source << ":root"
581:           "" # Remove
582:         end
583:
584:         # Nth-child including last and of-type.
585:         next if statement.sub!(/^:nth-(last-)?(child|of-type)\((odd|even|(\d+|\?)|(-?\d*|\?)?n([+\-]\d+|\?)?)\)/) do |match|
586:           reverse = $1 == "last-"
587:           of_type = $2 == "of-type"
588:           @source << ":nth-#{$1}#{$2}("
589:           case $3
590:             when "odd"
591:               pseudo << nth_child(2, 1, of_type, reverse)
592:               @source << "odd)"
593:             when "even"
594:               pseudo << nth_child(2, 2, of_type, reverse)
595:               @source << "even)"
596:             when /^(\d+|\?)$/  # b only
597:               b = ($1 == "?" ? values.shift : $1).to_i
598:               pseudo << nth_child(0, b, of_type, reverse)
599:               @source << "#{b})"
600:             when /^(-?\d*|\?)?n([+\-]\d+|\?)?$/
601:               a = ($1 == "?" ? values.shift :
602:                    $1 == "" ? 1 : $1 == "-" ? -1 : $1).to_i
603:               b = ($2 == "?" ? values.shift : $2).to_i
604:               pseudo << nth_child(a, b, of_type, reverse)
605:               @source << (b >= 0 ? "#{a}n+#{b})" : "#{a}n#{b})")
606:             else
607:               raise ArgumentError, "Invalid nth-child #{match}"
608:           end
609:           "" # Remove
610:         end
611:         # First/last child (of type).
612:         next if statement.sub!(/^:(first|last)-(child|of-type)/) do |match|
613:           reverse = $1 == "last"
614:           of_type = $2 == "of-type"
615:           pseudo << nth_child(0, 1, of_type, reverse)
616:           @source << ":#{$1}-#{$2}"
617:           "" # Remove
618:         end
619:         # Only child (of type).
620:         next if statement.sub!(/^:only-(child|of-type)/) do |match|
621:           of_type = $1 == "of-type"
622:           pseudo << only_child(of_type)
623:           @source << ":only-#{$1}"
624:           "" # Remove
625:         end
626:
627:         # Empty: no child elements or meaningful content (whitespaces
628:         # are ignored).
629:         next if statement.sub!(/^:empty/) do |match|
630:           pseudo << lambda do |element|
631:             empty = true
632:             for child in element.children
633:               if child.tag? || !child.content.strip.empty?
634:                 empty = false
635:                 break
636:               end
637:             end
638:             empty
639:           end
640:           @source << ":empty"
641:           "" # Remove
642:         end
643:         # Content: match the text content of the element, stripping
644:         # leading and trailing spaces.
645:         next if statement.sub!(/^:content\(\s*(\?|'[^']*'|"[^"]*"|[^)]*)\s*\)/) do |match|
646:           content = $1
647:           if content == "?"
648:             content = values.shift
649:           elsif (content[0] == ?" || content[0] == ?') && content[0] == content[-1]
650:             content = content[1..-2]
651:           end
652:           @source << ":content('#{content}')"
653:           content = Regexp.new("^#{Regexp.escape(content.to_s)}$") unless content.is_a?(Regexp)
654:           pseudo << lambda do |element|
655:             text = ""
656:             for child in element.children
657:               unless child.tag?
658:                 text << child.content
659:               end
660:             end
661:             text.strip =~ content
662:           end
663:           "" # Remove
664:         end
665:
666:         # Negation. Create another simple selector to handle it.
667:         if statement.sub!(/^:not\(\s*/, "")
668:           raise ArgumentError, "Double negatives are not missing feature" unless can_negate
669:           @source << ":not("
670:           negation << simple_selector(statement, values, false)
671:           raise ArgumentError, "Negation not closed" unless statement.sub!(/^\s*\)/, "")
672:           @source << ")"
673:           next
674:         end
675:
676:         # No match: moving on.
677:         break
678:       end
679:
680:       # Return hash. The keys are mapped to instance variables.
681:       {:tag_name=>tag_name, :attributes=>attributes, :pseudo=>pseudo, :negation=>negation}
682:     end


Class: HTML::WhiteListSanitizer

Class | HTML::WhiteListSanitizer
In: | vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
Parent: | Sanitizer

Methods

contains_bad_protocols? process_attributes_for process_node sanitize_css tokenize

Public Instance methods

sanitize_css(style)

Sanitizes a block of css code. Used by sanitize when it comes across a style attribute

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 104
104:     def sanitize_css(style)
105:       # disallow urls
106:       style = style.to_s.gsub(/url\s*\(\s*[^\s)]+?\s*\)\s*/, ' ')
107:
108:       # gauntlet
109:       if style !~ /^([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*$/ ||
110:           style !~ /^(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*$/
111:         return ''
112:       end
113:
114:       clean = []
115:       style.scan(/([-\w]+)\s*:\s*([^:;]*)/) do |prop,val|
116:         if allowed_css_properties.include?(prop.downcase)
117:           clean <<  prop + ': ' + val + ';'
118:         elsif shorthand_css_properties.include?(prop.split('-')[0].downcase)
119:           unless val.split().any? do |keyword|
120:             !allowed_css_keywords.include?(keyword) &&
121:               keyword !~ /^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$/
122:           end
123:             clean << prop + ': ' + val + ';'
124:           end
125:         end
126:       end
127:       clean.join(' ')
128:     end

Protected Instance methods

contains_bad_protocols?(attr_name, value)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 168
168:     def contains_bad_protocols?(attr_name, value)
169:       uri_attributes.include?(attr_name) &&
170:       (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(%|&#37;)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first))
171:     end
process_attributes_for(node, options)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 155
155:     def process_attributes_for(node, options)
156:       return unless node.attributes
157:       node.attributes.keys.each do |attr_name|
158:         value = node.attributes[attr_name].to_s
159:
160:         if !options[:attributes].include?(attr_name) || contains_bad_protocols?(attr_name, value)
161:           node.attributes.delete(attr_name)
162:         else
163:           node.attributes[attr_name] = attr_name == 'style' ? sanitize_css(value) : CGI::escapeHTML(CGI::unescapeHTML(value))
164:         end
165:       end
166:     end
process_node(node, result, options)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 138
138:     def process_node(node, result, options)
139:       result << case node
140:         when HTML::Tag
141:           if node.closing == :close
142:             options[:parent].shift
143:           else
144:             options[:parent].unshift node.name
145:           end
146:
147:           process_attributes_for node, options
148:
149:           options[:tags].include?(node.name) ? node : nil
150:         else
151:           bad_tags.include?(options[:parent].first) ? nil : node.to_s.gsub(/</, "&lt;")
152:       end
153:     end
tokenize(text, options)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb, line 131
131:     def tokenize(text, options)
132:       options[:parent] = []
133:       options[:attributes] ||= allowed_attributes
134:       options[:tags]       ||= allowed_tags
135:       super
136:     end


Class: HashWithIndifferentAccess

Class | HashWithIndifferentAccess
In: | vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
Parent: | Hash

This class has dubious semantics and we only have it so that people can write params[:key] instead of params[‘key’] and they get the same value for both keys.

Methods

[]= convert_key convert_value default delete dup fetch key? merge new reverse_merge stringify_keys! symbolize_keys! to_hash to_options! update values_at

External Aliases

[]= -> regular_writer

Public Class methods

new(constructor = {})

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 6
 6:   def initialize(constructor = {})
 7:     if constructor.is_a?(Hash)
 8:       super()
 9:       update(constructor)
10:     else
11:       super(constructor)
12:     end
13:   end

Public Instance methods

[]=(key, value)

Assigns a new value to the hash:

  hash = HashWithIndifferentAccess.new
  hash[:key] = "value"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 31
31:   def []=(key, value)
32:     regular_writer(convert_key(key), convert_value(value))
33:   end
convert_key(key)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 115
115:     def convert_key(key)
116:       key.kind_of?(Symbol) ? key.to_s : key
117:     end
convert_value(value)

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 119
119:     def convert_value(value)
120:       case value
121:       when Hash
122:         value.with_indifferent_access
123:       when Array
124:         value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
125:       else
126:         value
127:       end
128:     end
default(key = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 15
15:   def default(key = nil)
16:     if key.is_a?(Symbol) && include?(key = key.to_s)
17:       self[key]
18:     else
19:       super
20:     end
21:   end
delete(key)

Removes a specified key from the hash.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 101
101:   def delete(key)
102:     super(convert_key(key))
103:   end
dup()

Returns an exact copy of the hash.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 84
84:   def dup
85:     HashWithIndifferentAccess.new(self)
86:   end
fetch(key, *extras)

Fetches the value for the specified key, same as doing hash[key]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 68
68:   def fetch(key, *extras)
69:     super(convert_key(key), *extras)
70:   end
key?(key)

Checks the hash for a key matching the argument passed in:

  hash = HashWithIndifferentAccess.new
  hash["key"] = "value"
  hash.key? :key  # => true
  hash.key? "key" # => true

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 59
59:   def key?(key)
60:     super(convert_key(key))
61:   end
merge(hash)

Merges the instantized and the specified hashes together, giving precedence to the values from the second hash Does not overwrite the existing hash.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 90
90:   def merge(hash)
91:     self.dup.update(hash)
92:   end
reverse_merge(other_hash)

Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second. This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 96
96:   def reverse_merge(other_hash)
97:     super other_hash.with_indifferent_access
98:   end
stringify_keys!()

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 105
105:   def stringify_keys!; self end
symbolize_keys!()

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 106
106:   def symbolize_keys!; self end
to_hash()

Convert to a Hash with String keys.

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 110
110:   def to_hash
111:     Hash.new(default).merge(self)
112:   end
to_options!()

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 107
107:   def to_options!; self end
update(other_hash)

Updates the instantized hash with values from the second:

  hash_1 = HashWithIndifferentAccess.new
  hash_1[:key] = "value"

  hash_2 = HashWithIndifferentAccess.new
  hash_2[:key] = "New Value!"

  hash_1.update(hash_2) # => {"key"=>"New Value!"}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 45
45:   def update(other_hash)
46:     other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
47:     self
48:   end
values_at(*indices)

Returns an array of the values at the specified indices:

  hash = HashWithIndifferentAccess.new
  hash[:a] = "x"
  hash[:b] = "y"
  hash.values_at("a", "b") # => ["x", "y"]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 79
79:   def values_at(*indices)
80:     indices.collect {|key| self[convert_key(key)]}
81:   end


Module: I18n

Module | I18n
In: | vendor/rails/activerecord/lib/active_record/i18n_interpolation_deprecation.rb vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb

Methods

available_locales backend backend= default_exception_handler default_locale default_locale= exception_handler= load_path load_path= locale locale= localize normalize_translation_keys reload! translate

Classes and Modules

Module I18n::Backend
Class I18n::ArgumentError
Class I18n::InvalidLocale
Class I18n::InvalidPluralizationData
Class I18n::MissingInterpolationArgument
Class I18n::MissingTranslationData
Class I18n::ReservedInterpolationKey
Class I18n::UnknownFileType

External Aliases

translate | -> | t
localize | -> | l

Public Class methods

available_locales()

Returns an array of locales for which translations are available

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 49
49:     def available_locales
50:       backend.available_locales
51:     end
backend()

Returns the current backend. Defaults to +Backend::Simple+.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 19
19:     def backend
20:       @@backend ||= Backend::Simple.new
21:     end
backend=(backend)

Sets the current backend. Used to set a custom backend.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 24
24:     def backend=(backend)
25:       @@backend = backend
26:     end
default_locale()

Returns the current default locale. Defaults to :’en‘

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 29
29:     def default_locale
30:       @@default_locale
31:     end
default_locale=(locale)

Sets the current default locale. Used to set a custom default locale.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 34
34:     def default_locale=(locale)
35:       @@default_locale = locale
36:     end
exception_handler=(exception_handler)

Sets the exception handler.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 54
54:     def exception_handler=(exception_handler)
55:       @@exception_handler = exception_handler
56:     end
load_path()

Allow clients to register paths providing translation data sources. The backend defines acceptable sources.

E.g. the provided SimpleBackend accepts a list of paths to translation files which are either named *.rb and contain plain Ruby Hashes or are named *.yml and contain YAML data. So for the SimpleBackend clients may register translation files like this:

  I18n.load_path << 'path/to/locale/en.yml'

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 66
66:     def load_path
67:       @@load_path ||= []
68:     end
load_path=(load_path)

Sets the load path instance. Custom implementations are expected to behave like a Ruby Array.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 72
72:     def load_path=(load_path)
73:       @@load_path = load_path
74:     end
locale()

Returns the current locale. Defaults to I18n.default_locale.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 39
39:     def locale
40:       Thread.current[:locale] ||= default_locale
41:     end
locale=(locale)

Sets the current locale pseudo-globally, i.e. in the Thread.current hash.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 44
44:     def locale=(locale)
45:       Thread.current[:locale] = locale
46:     end
localize(object, options = {})

Localizes certain objects, such as dates and numbers to local formatting.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 173
173:     def localize(object, options = {})
174:       locale = options[:locale] || I18n.locale
175:       format = options[:format] || :default
176:       backend.localize(locale, object, format)
177:     end
reload!()

Tells the backend to reload translations. Used in situations like the Rails development environment. Backends can implement whatever strategy is useful.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 79
79:     def reload!
80:       backend.reload!
81:     end
translate(key, options = {})

Translates, pluralizes and interpolates a given key using a given locale, scope, and default, as well as interpolation values.

LOOKUP

Translation data is organized as a nested hash using the upper-level keys as namespaces. E.g., ActionView ships with the translation: :date => {:formats => {:short => "%b %d"}}.

Translations can be looked up at any level of this hash using the key argument and the scope option. E.g., in this example I18n.t :date returns the whole translations hash {:formats => {:short => "%b %d"}}.

Key can be either a single key or a dot-separated key (both Strings and Symbols work). E.g., the short format can be looked up using both:

  I18n.t 'date.formats.short'
  I18n.t :'date.formats.short'

Scope can be either a single key, a dot-separated key or an array of keys or dot-separated keys. Keys and scopes can be combined freely. So these examples will all look up the same short date format:

  I18n.t 'date.formats.short'
  I18n.t 'formats.short', :scope => 'date'
  I18n.t 'short', :scope => 'date.formats'
  I18n.t 'short', :scope => %w(date formats)

INTERPOLATION

Translations can contain interpolation variables which will be replaced by values passed to translate as part of the options hash, with the keys matching the interpolation variable names.

E.g., with a translation :foo => "foo {{bar}}" the option value for the key bar will be interpolated into the translation:

  I18n.t :foo, :bar => 'baz' # => 'foo baz'

PLURALIZATION

Translation data can contain pluralized translations. Pluralized translations are arrays of singluar/plural versions of translations like [‘Foo’, ‘Foos’].

Note that I18n::Backend::Simple only supports an algorithm for English pluralization rules. Other algorithms can be supported by custom backends.

This returns the singular version of a pluralized translation:

  I18n.t :foo, :count => 1 # => 'Foo'

These both return the plural version of a pluralized translation:

  I18n.t :foo, :count => 0 # => 'Foos'
  I18n.t :foo, :count => 2 # => 'Foos'

The :count option can be used both for pluralization and interpolation. E.g., with the translation :foo => [’{{count}} foo’, ’{{count}} foos’], count will be interpolated to the pluralized translation:

  I18n.t :foo, :count => 1 # => '1 foo'

DEFAULTS

This returns the translation for :foo or default if no translation was found:

  I18n.t :foo, :default => 'default'

This returns the translation for :foo or the translation for :bar if no translation for :foo was found:

  I18n.t :foo, :default => :bar

Returns the translation for :foo or the translation for :bar or default if no translations for :foo and :bar were found.

  I18n.t :foo, :default => [:bar, 'default']

BULK LOOKUP

This returns an array with the translations for :foo and :bar.

  I18n.t [:foo, :bar]

Can be used with dot-separated nested keys:

  I18n.t [:'baz.foo', :'baz.bar']

Which is the same as using a scope option:

  I18n.t [:foo, :bar], :scope => :baz

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 163
163:     def translate(key, options = {})
164:       locale = options.delete(:locale) || I18n.locale
165:       backend.translate(locale, key, options)
166:     rescue I18n::ArgumentError => e
167:       raise e if options[:raise]
168:       send(@@exception_handler, e, locale, key, options)
169:     end

Protected Class methods

default_exception_handler(exception, locale, key, options)

Handles exceptions raised in the backend. All exceptions except for MissingTranslationData exceptions are re-raised. When a MissingTranslationData was caught and the option :raise is not set the handler returns an error message string containing the key/scope.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 185
185:     def default_exception_handler(exception, locale, key, options)
186:       return exception.message if MissingTranslationData === exception
187:       raise exception
188:     end
normalize_translation_keys(locale, key, scope)

Merges the given locale, key and scope into a single array of keys. Splits keys that contain dots into multiple keys. Makes sure all keys are Symbols.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb, line 193
193:     def normalize_translation_keys(locale, key, scope)
194:       keys = [locale] + Array(scope) + [key]
195:       keys = keys.map { |k| k.to_s.split(/\./) }
196:       keys.flatten.map { |k| k.to_sym }
197:     end


Class: I18n::ArgumentError

Class | I18n::ArgumentError
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ::ArgumentError


Module: I18n::Backend

Module | I18n::Backend
In: | vendor/rails/activerecord/lib/active_record/i18n_interpolation_deprecation.rb vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb

Classes and Modules

Class I18n::Backend::Simple


Class: I18n::Backend::Simple

Class | I18n::Backend::Simple
In: | vendor/rails/activerecord/lib/active_record/i18n_interpolation_deprecation.rb vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
Parent: | Object

Methods

available_locales deep_symbolize_keys default init_translations initialized? interpolate interpolate_with_deprecated_syntax load_file load_rb load_translations load_yml localize lookup merge_translations pluralize reload! store_translations translate translations

Constants

DEPRECATED_INTERPOLATORS | = | { '%d' => '{{count}}', '%s' => '{{value}}' }
INTERPOLATION_RESERVED_KEYS | = | %w(scope default)
MATCH | = | /(\\\\)?\{\{([^\}]+)\}\}/

Public Instance methods

available_locales()

Returns an array of locales for which translations are available

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 73
73:       def available_locales
74:         init_translations unless initialized?
75:         translations.keys
76:       end
initialized?()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 68
68:       def initialized?
69:         @initialized ||= false
70:       end
load_translations(*filenames)

Accepts a list of paths to translation files. Loads translations from plain Ruby (*.rb) or YAML files (*.yml). See load_rb and load_yml for details.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 12
12:       def load_translations(*filenames)
13:         filenames.each { |filename| load_file(filename) }
14:       end
localize(locale, object, format = :default)

Acts the same as strftime, but returns a localized version of the formatted date string. Takes a key from the date/time formats translations as a format argument (e.g., :short in :’date.formats‘).

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 48
48:       def localize(locale, object, format = :default)
49:         raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
50:
51:         type = object.respond_to?(:sec) ? 'time' : 'date'
52:         # TODO only translate these if format is a String?
53:         formats = translate(locale, "#{type}.formats""#{type}.formats")
54:         format = formats[format.to_sym] if formats && formats[format.to_sym]
55:         # TODO raise exception unless format found?
56:         format = format.to_s.dup
57:
58:         # TODO only translate these if the format string is actually present
59:         # TODO check which format strings are present, then bulk translate then, then replace them
60:         format.gsub!(/%a/, translate(locale, "date.abbr_day_names""date.abbr_day_names")[object.wday])
61:         format.gsub!(/%A/, translate(locale, "date.day_names""date.day_names")[object.wday])
62:         format.gsub!(/%b/, translate(locale, "date.abbr_month_names""date.abbr_month_names")[object.mon])
63:         format.gsub!(/%B/, translate(locale, "date.month_names""date.month_names")[object.mon])
64:         format.gsub!(/%p/, translate(locale, "time.#{object.hour < 12 ? :am : :pm}""time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
65:         object.strftime(format)
66:       end
reload!()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 78
78:       def reload!
79:         @initialized = false
80:         @translations = nil
81:       end
store_translations(locale, data)

Stores translations for the given locale in memory. This uses a deep merge for the translations hash, so existing translations will be overwritten by new ones only at the deepest level of the hash.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 20
20:       def store_translations(locale, data)
21:         merge_translations(locale, data)
22:       end
translate(locale, key, options = {})

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 24
24:       def translate(locale, key, options = {})
25:         raise InvalidLocale.new(locale) if locale.nil?
26:         return key.map { |k| translate(locale, k, options) } if key.is_a? Array
27:
28:         reserved = :scope, :default
29:         count, scope, default = options.values_at(:count, *reserved)
30:         options.delete(:default)
31:         values = options.reject { |name, value| reserved.include?(name) }
32:
33:         entry = lookup(locale, key, scope)
34:         if entry.nil?
35:           entry = default(locale, default, options)
36:           if entry.nil?
37:             raise(I18n::MissingTranslationData.new(locale, key, options))
38:           end
39:         end
40:         entry = pluralize(locale, entry, count)
41:         entry = interpolate(locale, entry, values)
42:         entry
43:       end

Protected Instance methods

deep_symbolize_keys(hash)

Return a new hash with all keys and nested keys converted to symbols.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 205
205:         def deep_symbolize_keys(hash)
206:           hash.inject({}) { |result, (key, value)|
207:             value = deep_symbolize_keys(value) if value.is_a? Hash
208:             result[(key.to_sym rescue key) || key] = value
209:             result
210:           }
211:         end
default(locale, default, options = {})

Evaluates a default translation. If the given default is a String it is used literally. If it is a Symbol it will be translated with the given options. If it is an Array the first translation yielded will be returned.

I.e., default(locale, [:foo, ‘default’]) will return default if translate(locale, :foo) does not yield a result.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 118
118:         def default(locale, default, options = {})
119:           case default
120:             when String then default
121:             when Symbol then translate locale, default, options
122:             when Array  then default.each do |obj|
123:               result = default(locale, obj, options.dup) and return result
124:             end and nil
125:           end
126:         rescue MissingTranslationData
127:           nil
128:         end
init_translations()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 84
84:         def init_translations
85:           load_translations(*I18n.load_path.flatten)
86:           @initialized = true
87:         end
interpolate(locale, string, values = {})

Interpolates values into a given string.

  interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
  # => "file test.txt opened by {{user}}"

Note that you have to double escape the \ when you want to escape the {{…}} key in a string (once for the string and once for the interpolation).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 151
151:         def interpolate(locale, string, values = {})
152:           return string unless string.is_a?(String)
153:
154:           string.gsub(MATCH) do
155:             escaped, pattern, key = $1, $2, $2.to_sym
156:
157:             if escaped
158:               pattern
159:             elsif INTERPOLATION_RESERVED_KEYS.include?(pattern)
160:               raise ReservedInterpolationKey.new(pattern, string)
161:             elsif !values.include?(key)
162:               raise MissingInterpolationArgument.new(pattern, string)
163:             else
164:               values[key].to_s
165:             end
166:           end
167:         end
interpolate_with_deprecated_syntax(locale, string, values = {})

[Source]

    # File vendor/rails/activerecord/lib/active_record/i18n_interpolation_deprecation.rb, line 12
12:         def interpolate_with_deprecated_syntax(locale, string, values = {})
13:           return string unless string.is_a?(String)
14:
15:           string = string.gsub(/%d|%s/) do |s|
16:             instead = DEPRECATED_INTERPOLATORS[s]
17:             ActiveSupport::Deprecation.warn "using #{s} in messages is deprecated; use #{instead} instead."
18:             instead
19:           end
20:
21:           interpolate_without_deprecated_syntax(locale, string, values)
22:         end
load_file(filename)

Loads a single translations file by delegating to load_rb or load_yml depending on the file extension and directly merges the data to the existing translations. Raises I18n::UnknownFileType for all other file extensions.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 173
173:         def load_file(filename)
174:           type = File.extname(filename).tr('.', '').downcase
175:           raise UnknownFileType.new(type, filename) unless respond_to?("load_#{type}""load_#{type}")
176:           data = send "load_#{type}""load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
177:           data.each { |locale, d| merge_translations(locale, d) }
178:         end
load_rb(filename)

Loads a plain Ruby translations file. eval‘ing the file must yield a Hash containing translation data with locales as toplevel keys.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 182
182:         def load_rb(filename)
183:           eval(IO.read(filename), binding, filename)
184:         end
load_yml(filename)

Loads a YAML translations file. The data must have locales as toplevel keys.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 188
188:         def load_yml(filename)
189:           YAML::load(IO.read(filename))
190:         end
lookup(locale, key, scope = [])

Looks up a translation from the translations hash. Returns nil if eiher key is nil, or locale, scope or key do not exist as a key in the nested translations hash. Splits keys or scopes containing dots into multiple keys, i.e. currency.format is regarded the same as %w(currency format).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 98
 98:         def lookup(locale, key, scope = [])
 99:           return unless key
100:           init_translations unless initialized?
101:           keys = I18n.send(:normalize_translation_keys, locale, key, scope)
102:           keys.inject(translations) do |result, k|
103:             if (x = result[k.to_sym]).nil?
104:               return nil
105:             else
106:               x
107:             end
108:           end
109:         end
merge_translations(locale, data)

Deep merges the given translations hash with the existing translations for the given locale

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 194
194:         def merge_translations(locale, data)
195:           locale = locale.to_sym
196:           translations[locale] ||= {}
197:           data = deep_symbolize_keys(data)
198:
199:           # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
200:           merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
201:           translations[locale].merge!(data, &merger)
202:         end
pluralize(locale, entry, count)

Picks a translation from an array according to English pluralization rules. It will pick the first translation if count is not equal to 1 and the second translation if it is equal to 1. Other backends can implement more flexible or complex pluralization rules.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 134
134:         def pluralize(locale, entry, count)
135:           return entry unless entry.is_a?(Hash) and count
136:           # raise InvalidPluralizationData.new(entry, count) unless entry.is_a?(Hash)
137:           key = :zero if count == 0 && entry.has_key?(:zero)
138:           key ||= count == 1 ? :one : :other
139:           raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
140:           entry[key]
141:         end
translations()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb, line 89
89:         def translations
90:           @translations ||= {}
91:         end


Class: I18n::InvalidLocale

Class | I18n::InvalidLocale
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

locale [R]

Public Class methods

new(locale)

[Source]

   # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 6
6:     def initialize(locale)
7:       @locale = locale
8:       super "#{locale.inspect} is not a valid locale"
9:     end


Class: I18n::InvalidPluralizationData

Class | I18n::InvalidPluralizationData
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

count | [R]
entry | [R]

Public Class methods

new(entry, count)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 24
24:     def initialize(entry, count)
25:       @entry, @count = entry, count
26:       super "translation data #{entry.inspect} can not be used with :count => #{count}"
27:     end


Class: I18n::MissingInterpolationArgument

Class | I18n::MissingInterpolationArgument
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

key | [R]
string | [R]

Public Class methods

new(key, string)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 32
32:     def initialize(key, string)
33:       @key, @string = key, string
34:       super "interpolation argument #{key} missing in #{string.inspect}"
35:     end


Class: I18n::MissingTranslationData

Class | I18n::MissingTranslationData
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

key | [R]
locale | [R]
options | [R]

Public Class methods

new(locale, key, options)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 14
14:     def initialize(locale, key, options)
15:       @key, @locale, @options = key, locale, options
16:       keys = I18n.send(:normalize_translation_keys, locale, key, options[:scope])
17:       keys << 'no key' if keys.size < 2
18:       super "translation missing: #{keys.join(', ')}"
19:     end


Class: I18n::ReservedInterpolationKey

Class | I18n::ReservedInterpolationKey
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

key | [R]
string | [R]

Public Class methods

new(key, string)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 40
40:     def initialize(key, string)
41:       @key, @string = key, string
42:       super "reserved key #{key.inspect} used in #{string.inspect}"
43:     end


Class: I18n::UnknownFileType

Class | I18n::UnknownFileType
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
Parent: | ArgumentError

Methods

new

Attributes

filename | [R]
type | [R]

Public Class methods

new(type, filename)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb, line 48
48:     def initialize(type, filename)
49:       @type, @filename = type, filename
50:       super "can not load translations from #{filename}, the file type #{type} is not known"
51:     end


Class: I18nExceptionsTest

Class | I18nExceptionsTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
Parent: | Test::Unit::TestCase

Methods

test_invalid_locale_message test_invalid_locale_stores_locale test_invalid_pluralization_data_message test_invalid_pluralization_data_stores_entry_and_count test_missing_interpolation_argument_message test_missing_interpolation_argument_stores_key_and_string test_missing_translation_data_message test_missing_translation_data_stores_locale_key_and_options test_reserved_interpolation_key_message test_reserved_interpolation_key_stores_key_and_string

Public Instance methods

test_invalid_locale_message()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 16
16:   def test_invalid_locale_message
17:     force_invalid_locale
18:   rescue I18n::ArgumentError => e
19:     assert_equal 'nil is not a valid locale', e.message
20:   end
test_invalid_locale_stores_locale()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 10
10:   def test_invalid_locale_stores_locale
11:     force_invalid_locale
12:   rescue I18n::ArgumentError => e
13:     assert_nil e.locale
14:   end
test_invalid_pluralization_data_message()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 44
44:   def test_invalid_pluralization_data_message
45:     force_invalid_pluralization_data
46:   rescue I18n::ArgumentError => e
47:     assert_equal 'translation data [:bar] can not be used with :count => 1', e.message
48:   end
test_invalid_pluralization_data_stores_entry_and_count()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 37
37:   def test_invalid_pluralization_data_stores_entry_and_count
38:     force_invalid_pluralization_data
39:   rescue I18n::ArgumentError => e
40:     assert_equal [:bar], e.entry
41:     assert_equal 1, e.count
42:   end
test_missing_interpolation_argument_message()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 57
57:   def test_missing_interpolation_argument_message
58:     force_missing_interpolation_argument
59:   rescue I18n::ArgumentError => e
60:     assert_equal 'interpolation argument bar missing in "{{bar}}"', e.message
61:   end
test_missing_interpolation_argument_stores_key_and_string()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 50
50:   def test_missing_interpolation_argument_stores_key_and_string
51:     force_missing_interpolation_argument
52:   rescue I18n::ArgumentError => e
53:     assert_equal 'bar', e.key
54:     assert_equal "{{bar}}", e.string
55:   end
test_missing_translation_data_message()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 31
31:   def test_missing_translation_data_message
32:     force_missing_translation_data
33:   rescue I18n::ArgumentError => e
34:     assert_equal 'translation missing: de, bar, foo', e.message
35:   end
test_missing_translation_data_stores_locale_key_and_options()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 22
22:   def test_missing_translation_data_stores_locale_key_and_options
23:     force_missing_translation_data
24:   rescue I18n::ArgumentError => e
25:     options = {:scope => :bar}
26:     assert_equal 'de', e.locale
27:     assert_equal :foo, e.key
28:     assert_equal options, e.options
29:   end
test_reserved_interpolation_key_message()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 70
70:   def test_reserved_interpolation_key_message
71:     force_reserved_interpolation_key
72:   rescue I18n::ArgumentError => e
73:     assert_equal 'reserved key "scope" used in "{{scope}}"', e.message
74:   end
test_reserved_interpolation_key_stores_key_and_string()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb, line 63
63:   def test_reserved_interpolation_key_stores_key_and_string
64:     force_reserved_interpolation_key
65:   rescue I18n::ArgumentError => e
66:     assert_equal 'scope', e.key
67:     assert_equal "{{scope}}", e.string
68:   end


Class: I18nSimpleBackendAvailableLocalesTest

Class | I18nSimpleBackendAvailableLocalesTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_available_locales

Public Instance methods

test_available_locales()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 128
128:   def test_available_locales
129:     @backend = I18n::Backend::Simple.new
130:     @backend.store_translations 'de', :foo => 'bar'
131:     @backend.store_translations 'en', :foo => 'foo'
132:
133:     assert_equal ['de', 'en'], @backend.available_locales.map{|locale| locale.to_s }.sort
134:   end


Class: I18nSimpleBackendHelperMethodsTest

Class | I18nSimpleBackendHelperMethodsTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

setup test_deep_symbolize_keys_works

Public Instance methods

setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 474
474:   def setup
475:     @backend = I18n::Backend::Simple.new
476:   end
test_deep_symbolize_keys_works()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 478
478:   def test_deep_symbolize_keys_works
479:     result = @backend.send :deep_symbolize_keys, 'foo' => {'bar' => {'baz' => 'bar'}}
480:     expected = {:foo => {:bar => {:baz => 'bar'}}}
481:     assert_equal expected, result
482:   end


Class: I18nSimpleBackendInterpolateTest

Class | I18nSimpleBackendInterpolateTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key test_interpolate_given_a_value_hash_interpolates_into_unicode_string test_interpolate_given_a_value_hash_interpolates_the_values_to_the_string test_interpolate_given_a_values_hash_with_nil_values_interpolates_the_string test_interpolate_given_an_empty_values_hash_raises_missing_interpolation_argument test_interpolate_given_an_non_string_as_a_string_returns_nil test_interpolate_given_an_unicode_value_hash_interpolates_into_unicode_string test_interpolate_given_an_unicode_value_hash_interpolates_to_the_string test_interpolate_given_an_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error test_interpolate_given_nil_as_a_string_returns_nil

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 265
265:     def test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding
266:       assert_equal euc_jp('Hi ゆきひろ!'), @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
267:     end
test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 275
275:     def test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error
276:       assert_raise(Encoding::CompatibilityError) do
277:         @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
278:       end
279:     end
test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 298
298:   def test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key
299:     assert_raise(I18n::ReservedInterpolationKey) { @backend.send(:interpolate, nil, '{{default}}', {:default => nil}) }
300:   end
test_interpolate_given_a_value_hash_interpolates_into_unicode_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 252
252:   def test_interpolate_given_a_value_hash_interpolates_into_unicode_string
253:     assert_equal 'Häi David!', @backend.send(:interpolate, nil, 'Häi {{name}}!', :name => 'David')
254:   end
test_interpolate_given_a_value_hash_interpolates_the_values_to_the_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 248
248:   def test_interpolate_given_a_value_hash_interpolates_the_values_to_the_string
249:     assert_equal 'Hi David!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'David')
250:   end
test_interpolate_given_a_values_hash_with_nil_values_interpolates_the_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 290
290:   def test_interpolate_given_a_values_hash_with_nil_values_interpolates_the_string
291:     assert_equal 'Hi !', @backend.send(:interpolate, nil, 'Hi {{name}}!', {:name => nil})
292:   end
test_interpolate_given_an_empty_values_hash_raises_missing_interpolation_argument()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 294
294:   def test_interpolate_given_an_empty_values_hash_raises_missing_interpolation_argument
295:     assert_raise(I18n::MissingInterpolationArgument) { @backend.send(:interpolate, nil, 'Hi {{name}}!', {}) }
296:   end
test_interpolate_given_an_non_string_as_a_string_returns_nil()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 286
286:   def test_interpolate_given_an_non_string_as_a_string_returns_nil
287:     assert_equal [], @backend.send(:interpolate, nil, [], :name => 'David')
288:   end
test_interpolate_given_an_unicode_value_hash_interpolates_into_unicode_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 260
260:   def test_interpolate_given_an_unicode_value_hash_interpolates_into_unicode_string
261:     assert_equal 'こんにちは、ゆきひろさん!', @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
262:   end
test_interpolate_given_an_unicode_value_hash_interpolates_to_the_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 256
256:   def test_interpolate_given_an_unicode_value_hash_interpolates_to_the_string
257:     assert_equal 'Hi ゆきひろ!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'ゆきひろ')
258:   end
test_interpolate_given_an_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 269
269:     def test_interpolate_given_an_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error
270:       assert_raise(Encoding::CompatibilityError) do
271:         @backend.send(:interpolate, nil, euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
272:       end
273:     end
test_interpolate_given_nil_as_a_string_returns_nil()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 282
282:   def test_interpolate_given_nil_as_a_string_returns_nil
283:     assert_nil @backend.send(:interpolate, nil, nil, :name => 'David')
284:   end


Class: I18nSimpleBackendLoadPathTest

Class | I18nSimpleBackendLoadPathTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

teardown test_adding_arrays_of_filenames_to_load_path_do_not_break_locale_loading test_nested_load_paths_do_not_break_locale_loading

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

teardown()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 520
520:   def teardown
521:     I18n.load_path = []
522:   end
test_adding_arrays_of_filenames_to_load_path_do_not_break_locale_loading()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 532
532:   def test_adding_arrays_of_filenames_to_load_path_do_not_break_locale_loading
533:     @backend = I18n::Backend::Simple.new
534:     I18n.load_path << Dir[File.dirname(__FILE__) + '/locale/*.{rb,yml}']
535:     assert_nil backend_get_translations
536:     assert_nothing_raised { @backend.send :init_translations }
537:     assert_not_nil backend_get_translations
538:   end
test_nested_load_paths_do_not_break_locale_loading()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 524
524:   def test_nested_load_paths_do_not_break_locale_loading
525:     @backend = I18n::Backend::Simple.new
526:     I18n.load_path = [[File.dirname(__FILE__) + '/locale/en.yml']]
527:     assert_nil backend_get_translations
528:     assert_nothing_raised { @backend.send :init_translations }
529:     assert_not_nil backend_get_translations
530:   end


Class: I18nSimpleBackendLoadTranslationsTest

Class | I18nSimpleBackendLoadTranslationsTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_load_rb_loads_data_from_ruby_file test_load_rb_loads_data_from_yaml_file test_load_translations_loads_from_different_file_formats test_load_translations_with_ruby_file_type_does_not_raise_exception test_load_translations_with_unknown_file_type_raises_exception

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_load_rb_loads_data_from_ruby_file()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 496
496:   def test_load_rb_loads_data_from_ruby_file
497:     data = @backend.send :load_rb, "#{@locale_dir}/en.rb"
498:     assert_equal({'en-Ruby''en-Ruby' => {:foo => {:bar => "baz"}}}, data)
499:   end
test_load_rb_loads_data_from_yaml_file()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 501
501:   def test_load_rb_loads_data_from_yaml_file
502:     data = @backend.send :load_yml, "#{@locale_dir}/en.yml"
503:     assert_equal({'en-Yaml' => {'foo' => {'bar' => 'baz'}}}, data)
504:   end
test_load_translations_loads_from_different_file_formats()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 506
506:   def test_load_translations_loads_from_different_file_formats
507:     @backend = I18n::Backend::Simple.new
508:     @backend.load_translations "#{@locale_dir}/en.rb", "#{@locale_dir}/en.yml"
509:     expected = {
510:       'en-Ruby''en-Ruby' => {:foo => {:bar => "baz"}},
511:       'en-Yaml''en-Yaml' => {:foo => {:bar => "baz"}}
512:     }
513:     assert_equal expected, backend_get_translations
514:   end
test_load_translations_with_ruby_file_type_does_not_raise_exception()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 492
492:   def test_load_translations_with_ruby_file_type_does_not_raise_exception
493:     assert_nothing_raised { @backend.load_translations "#{@locale_dir}/en.rb" }
494:   end
test_load_translations_with_unknown_file_type_raises_exception()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 488
488:   def test_load_translations_with_unknown_file_type_raises_exception
489:     assert_raise(I18n::UnknownFileType) { @backend.load_translations "#{@locale_dir}/en.xml" }
490:   end


Class: I18nSimpleBackendLocalizeDateTest

Class | I18nSimpleBackendLocalizeDateTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

setup test_localize_nil_raises_argument_error test_localize_object_raises_argument_error test_translate_given_a_day_name_format_it_returns_a_day_name test_translate_given_a_month_name_format_it_returns_a_month_name test_translate_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name test_translate_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name test_translate_given_an_unknown_format_it_does_not_fail test_translate_given_no_format_it_does_not_fail test_translate_given_the_default_format_it_uses_it test_translate_given_the_long_format_it_uses_it test_translate_given_the_short_format_it_uses_it

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 312
312:   def setup
313:     @backend = I18n::Backend::Simple.new
314:     add_datetime_translations
315:     @date = Date.new 2008, 1, 1
316:   end
test_localize_nil_raises_argument_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 354
354:   def test_localize_nil_raises_argument_error
355:     assert_raise(I18n::ArgumentError) { @backend.localize 'de', nil }
356:   end
test_localize_object_raises_argument_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 358
358:   def test_localize_object_raises_argument_error
359:     assert_raise(I18n::ArgumentError) { @backend.localize 'de', Object.new }
360:   end
test_translate_given_a_day_name_format_it_returns_a_day_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 330
330:   def test_translate_given_a_day_name_format_it_returns_a_day_name
331:     assert_equal 'Dienstag', @backend.localize('de', @date, '%A')
332:   end
test_translate_given_a_month_name_format_it_returns_a_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 338
338:   def test_translate_given_a_month_name_format_it_returns_a_month_name
339:     assert_equal 'Januar', @backend.localize('de', @date, '%B')
340:   end
test_translate_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 334
334:   def test_translate_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name
335:     assert_equal 'Di', @backend.localize('de', @date, '%a')
336:   end
test_translate_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 342
342:   def test_translate_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name
343:     assert_equal 'Jan', @backend.localize('de', @date, '%b')
344:   end
test_translate_given_an_unknown_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 350
350:   def test_translate_given_an_unknown_format_it_does_not_fail
351:     assert_nothing_raised{ @backend.localize 'de', @date, '%x' }
352:   end
test_translate_given_no_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 346
346:   def test_translate_given_no_format_it_does_not_fail
347:     assert_nothing_raised{ @backend.localize 'de', @date }
348:   end
test_translate_given_the_default_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 326
326:   def test_translate_given_the_default_format_it_uses_it
327:     assert_equal '01.01.2008', @backend.localize('de', @date, :default)
328:   end
test_translate_given_the_long_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 322
322:   def test_translate_given_the_long_format_it_uses_it
323:     assert_equal '01. Januar 2008', @backend.localize('de', @date, :long)
324:   end
test_translate_given_the_short_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 318
318:   def test_translate_given_the_short_format_it_uses_it
319:     assert_equal '01. Jan', @backend.localize('de', @date, :short)
320:   end


Class: I18nSimpleBackendLocalizeDateTimeTest

Class | I18nSimpleBackendLocalizeDateTimeTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

setup test_translate_given_a_day_name_format_it_returns_the_correct_day_name test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator test_translate_given_a_month_name_format_it_returns_the_correct_month_name test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name test_translate_given_an_unknown_format_it_does_not_fail test_translate_given_no_format_it_does_not_fail test_translate_given_the_default_format_it_uses_it test_translate_given_the_long_format_it_uses_it test_translate_given_the_short_format_it_uses_it

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 366
366:   def setup
367:     @backend = I18n::Backend::Simple.new
368:     add_datetime_translations
369:     @morning = DateTime.new 2008, 1, 1, 6
370:     @evening = DateTime.new 2008, 1, 1, 18
371:   end
test_translate_given_a_day_name_format_it_returns_the_correct_day_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 385
385:   def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
386:     assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
387:   end
test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 401
401:   def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
402:     assert_equal 'am', @backend.localize('de', @morning, '%p')
403:     assert_equal 'pm', @backend.localize('de', @evening, '%p')
404:   end
test_translate_given_a_month_name_format_it_returns_the_correct_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 393
393:   def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
394:     assert_equal 'Januar', @backend.localize('de', @morning, '%B')
395:   end
test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 389
389:   def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
390:     assert_equal 'Di', @backend.localize('de', @morning, '%a')
391:   end
test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 397
397:   def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
398:     assert_equal 'Jan', @backend.localize('de', @morning, '%b')
399:   end
test_translate_given_an_unknown_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 410
410:   def test_translate_given_an_unknown_format_it_does_not_fail
411:     assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
412:   end
test_translate_given_no_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 406
406:   def test_translate_given_no_format_it_does_not_fail
407:     assert_nothing_raised{ @backend.localize 'de', @morning }
408:   end
test_translate_given_the_default_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 381
381:   def test_translate_given_the_default_format_it_uses_it
382:     assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)
383:   end
test_translate_given_the_long_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 377
377:   def test_translate_given_the_long_format_it_uses_it
378:     assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
379:   end
test_translate_given_the_short_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 373
373:   def test_translate_given_the_short_format_it_uses_it
374:     assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
375:   end


Class: I18nSimpleBackendLocalizeTimeTest

Class | I18nSimpleBackendLocalizeTimeTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

setup teardown test_translate_given_a_day_name_format_it_returns_the_correct_day_name test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator test_translate_given_a_month_name_format_it_returns_the_correct_month_name test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name test_translate_given_an_unknown_format_it_does_not_fail test_translate_given_no_format_it_does_not_fail test_translate_given_the_long_format_it_uses_it test_translate_given_the_short_format_it_uses_it

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 418
418:   def setup
419:     @old_timezone, ENV['TZ'] = ENV['TZ'], 'UTC'
420:     @backend = I18n::Backend::Simple.new
421:     add_datetime_translations
422:     @morning = Time.parse '2008-01-01 6:00 UTC'
423:     @evening = Time.parse '2008-01-01 18:00 UTC'
424:   end
teardown()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 426
426:   def teardown
427:     @old_timezone ? ENV['TZ'] = @old_timezone : ENV.delete('TZ')
428:   end
test_translate_given_a_day_name_format_it_returns_the_correct_day_name()

TODO Seems to break on Windows because ENV[‘TZ’] is ignored. What‘s a better way to do this? def test_translate_given_the_default_format_it_uses_it

  assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)

end

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 443
443:   def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
444:     assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
445:   end
test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 459
459:   def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
460:     assert_equal 'am', @backend.localize('de', @morning, '%p')
461:     assert_equal 'pm', @backend.localize('de', @evening, '%p')
462:   end
test_translate_given_a_month_name_format_it_returns_the_correct_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 451
451:   def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
452:     assert_equal 'Januar', @backend.localize('de', @morning, '%B')
453:   end
test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 447
447:   def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
448:     assert_equal 'Di', @backend.localize('de', @morning, '%a')
449:   end
test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 455
455:   def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
456:     assert_equal 'Jan', @backend.localize('de', @morning, '%b')
457:   end
test_translate_given_an_unknown_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 468
468:   def test_translate_given_an_unknown_format_it_does_not_fail
469:     assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
470:   end
test_translate_given_no_format_it_does_not_fail()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 464
464:   def test_translate_given_no_format_it_does_not_fail
465:     assert_nothing_raised{ @backend.localize 'de', @morning }
466:   end
test_translate_given_the_long_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 434
434:   def test_translate_given_the_long_format_it_uses_it
435:     assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
436:   end
test_translate_given_the_short_format_it_uses_it()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 430
430:   def test_translate_given_the_short_format_it_uses_it
431:     assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
432:   end


Class: I18nSimpleBackendLookupTest

Class | I18nSimpleBackendLookupTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_lookup_given_nested_keys_looks_up_a_nested_hash_value test_lookup_given_nil_as_a_key_returns_nil

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_lookup_given_nested_keys_looks_up_a_nested_hash_value()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 199
199:   def test_lookup_given_nested_keys_looks_up_a_nested_hash_value
200:     assert_equal 'bar', @backend.send(:lookup, 'en', :bar, [:foo])
201:   end
test_lookup_given_nil_as_a_key_returns_nil()

useful because this way we can use the backend with no key for interpolation/pluralization

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 195
195:   def test_lookup_given_nil_as_a_key_returns_nil
196:     assert_nil @backend.send(:lookup, 'en', nil)
197:   end


Class: I18nSimpleBackendPluralizeTest

Class | I18nSimpleBackendPluralizeTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluralization_data test_pluralize_given_0_returns_plural_string_if_no_zero_key_given test_pluralize_given_0_returns_zero_string_if_zero_key_given test_pluralize_given_1_returns_singular_string test_pluralize_given_2_returns_plural_string test_pluralize_given_3_returns_plural_string test_pluralize_given_nil_returns_the_given_entry

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluralization_data()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 232
232:   def test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluralization_data
233:     assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, {:one => 'bar'}, 2) }
234:   end
test_pluralize_given_0_returns_plural_string_if_no_zero_key_given()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 216
216:   def test_pluralize_given_0_returns_plural_string_if_no_zero_key_given
217:     assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 0)
218:   end
test_pluralize_given_0_returns_zero_string_if_zero_key_given()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 212
212:   def test_pluralize_given_0_returns_zero_string_if_zero_key_given
213:     assert_equal 'zero', @backend.send(:pluralize, nil, {:zero => 'zero', :one => 'bar', :other => 'bars'}, 0)
214:   end
test_pluralize_given_1_returns_singular_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 220
220:   def test_pluralize_given_1_returns_singular_string
221:     assert_equal 'bar', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 1)
222:   end
test_pluralize_given_2_returns_plural_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 224
224:   def test_pluralize_given_2_returns_plural_string
225:     assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 2)
226:   end
test_pluralize_given_3_returns_plural_string()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 228
228:   def test_pluralize_given_3_returns_plural_string
229:     assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 3)
230:   end
test_pluralize_given_nil_returns_the_given_entry()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 207
207:   def test_pluralize_given_nil_returns_the_given_entry
208:     entry = {:one => 'bar', :other => 'bars'}
209:     assert_equal entry, @backend.send(:pluralize, nil, entry, nil)
210:   end


Class: I18nSimpleBackendReloadTranslationsTest

Class | I18nSimpleBackendReloadTranslationsTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

setup teardown test_reload_translations_uninitializes_translations test_reload_translations_unloads_translations test_setup

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 544
544:   def setup
545:     @backend = I18n::Backend::Simple.new
546:     I18n.load_path = [File.dirname(__FILE__) + '/locale/en.yml']
547:     assert_nil backend_get_translations
548:     @backend.send :init_translations
549:   end
teardown()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 551
551:   def teardown
552:     I18n.load_path = []
553:   end
test_reload_translations_uninitializes_translations()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 564
564:   def test_reload_translations_uninitializes_translations
565:     @backend.reload!
566:     assert_equal @backend.initialized?, false
567:   end
test_reload_translations_unloads_translations()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 559
559:   def test_reload_translations_unloads_translations
560:     @backend.reload!
561:     assert_nil backend_get_translations
562:   end
test_setup()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 555
555:   def test_setup
556:     assert_not_nil backend_get_translations
557:   end


Module: I18nSimpleBackendTestSetup

Module | I18nSimpleBackendTestSetup
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb

Methods

add_datetime_translations backend_get_translations setup setup_backend

Public Instance methods

add_datetime_translations()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 29
29:   def add_datetime_translations
30:     @backend.store_translations 'de''de', {
31:       :date => {
32:         :formats => {
33:           :default => "%d.%m.%Y",
34:           :short => "%d. %b",
35:           :long => "%d. %B %Y",
36:         },
37:         :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
38:         :abbr_day_names => %w(So Mo Di Mi Do Fr  Sa),
39:         :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
40:         :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil),
41:         :order => [:day, :month, :year]
42:       },
43:       :time => {
44:         :formats => {
45:           :default => "%a, %d. %b %Y %H:%M:%S %z",
46:           :short => "%d. %b %H:%M",
47:           :long => "%d. %B %Y %H:%M",
48:         },
49:         :am => 'am',
50:         :pm => 'pm'
51:       },
52:       :datetime => {
53:         :distance_in_words => {
54:           :half_a_minute => 'half a minute',
55:           :less_than_x_seconds => {
56:             :one => 'less than 1 second',
57:             :other => 'less than {{count}} seconds'
58:           },
59:           :x_seconds => {
60:             :one => '1 second',
61:             :other => '{{count}} seconds'
62:           },
63:           :less_than_x_minutes => {
64:             :one => 'less than a minute',
65:             :other => 'less than {{count}} minutes'
66:           },
67:           :x_minutes => {
68:             :one => '1 minute',
69:             :other => '{{count}} minutes'
70:           },
71:           :about_x_hours => {
72:             :one => 'about 1 hour',
73:             :other => 'about {{count}} hours'
74:           },
75:           :x_days => {
76:             :one => '1 day',
77:             :other => '{{count}} days'
78:           },
79:           :about_x_months => {
80:             :one => 'about 1 month',
81:             :other => 'about {{count}} months'
82:           },
83:           :x_months => {
84:             :one => '1 month',
85:             :other => '{{count}} months'
86:           },
87:           :about_x_years => {
88:             :one => 'about 1 year',
89:             :other => 'about {{count}} year'
90:           },
91:           :over_x_years => {
92:             :one => 'over 1 year',
93:             :other => 'over {{count}} years'
94:           }
95:         }
96:       }
97:     }
98:   end
backend_get_translations()

def backend_reset_translations!

  I18n::Backend::Simple::ClassMethods.send :class_variable_set, :@@translations, {}

end

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 24
24:   def backend_get_translations
25:     # I18n::Backend::Simple::ClassMethods.send :class_variable_get, :@@translations
26:     @backend.instance_variable_get :@translations
27:   end
setup()

Alias for setup_backend

setup_backend()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 12
12:   def setup_backend
13:     # backend_reset_translations!
14:     @backend = I18n::Backend::Simple.new
15:     @backend.store_translations 'en', :foo => {:bar => 'bar', :baz => 'baz'}
16:     @locale_dir = File.dirname(__FILE__) + '/locale'
17:   end


Class: I18nSimpleBackendTranslateTest

Class | I18nSimpleBackendTranslateTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_given_no_keys_it_returns_the_default test_translate_an_array_of_keys_translates_all_of_them test_translate_calls_interpolate test_translate_calls_interpolate_including_count_as_a_value test_translate_calls_lookup_with_locale_given test_translate_calls_pluralize test_translate_given_a_symbol_as_a_default_translates_the_symbol test_translate_given_an_array_as_default_uses_the_first_match test_translate_given_an_array_of_inexistent_keys_it_raises_missing_translation_data test_translate_given_nil_as_a_locale_raises_an_argument_error test_translate_with_a_bogus_key_and_no_default_raises_missing_translation_data

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_given_no_keys_it_returns_the_default()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 145
145:   def test_given_no_keys_it_returns_the_default
146:     assert_equal 'default', @backend.translate('en', nil, :default => 'default')
147:   end
test_translate_an_array_of_keys_translates_all_of_them()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 163
163:   def test_translate_an_array_of_keys_translates_all_of_them
164:     assert_equal %w(bar baz), @backend.translate('en', [:bar, :baz], :scope => [:foo])
165:   end
test_translate_calls_interpolate()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 172
172:   def test_translate_calls_interpolate
173:     @backend.expects(:interpolate).with 'en', 'bar', {}
174:     @backend.translate 'en', :bar, :scope => [:foo]
175:   end
test_translate_calls_interpolate_including_count_as_a_value()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 177
177:   def test_translate_calls_interpolate_including_count_as_a_value
178:     @backend.expects(:interpolate).with 'en', 'bar', {:count => 1}
179:     @backend.translate 'en', :bar, :scope => [:foo], :count => 1
180:   end
test_translate_calls_lookup_with_locale_given()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 140
140:   def test_translate_calls_lookup_with_locale_given
141:     @backend.expects(:lookup).with('de', :bar, [:foo]).returns 'bar'
142:     @backend.translate 'de', :bar, :scope => [:foo]
143:   end
test_translate_calls_pluralize()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 167
167:   def test_translate_calls_pluralize
168:     @backend.expects(:pluralize).with 'en', 'bar', 1
169:     @backend.translate 'en', :bar, :scope => [:foo], :count => 1
170:   end
test_translate_given_a_symbol_as_a_default_translates_the_symbol()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 149
149:   def test_translate_given_a_symbol_as_a_default_translates_the_symbol
150:     assert_equal 'bar', @backend.translate('en', nil, :scope => [:foo], :default => :bar)
151:   end
test_translate_given_an_array_as_default_uses_the_first_match()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 153
153:   def test_translate_given_an_array_as_default_uses_the_first_match
154:     assert_equal 'bar', @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :bar])
155:   end
test_translate_given_an_array_of_inexistent_keys_it_raises_missing_translation_data()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 157
157:   def test_translate_given_an_array_of_inexistent_keys_it_raises_missing_translation_data
158:     assert_raise I18n::MissingTranslationData do
159:       @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :does_not_exist_3])
160:     end
161:   end
test_translate_given_nil_as_a_locale_raises_an_argument_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 182
182:   def test_translate_given_nil_as_a_locale_raises_an_argument_error
183:     assert_raise(I18n::InvalidLocale){ @backend.translate nil, :bar }
184:   end
test_translate_with_a_bogus_key_and_no_default_raises_missing_translation_data()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 186
186:   def test_translate_with_a_bogus_key_and_no_default_raises_missing_translation_data
187:     assert_raise(I18n::MissingTranslationData){ @backend.translate 'de', :bogus }
188:   end


Class: I18nSimpleBackendTranslationsTest

Class | I18nSimpleBackendTranslationsTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
Parent: | Test::Unit::TestCase

Methods

test_store_translations_adds_translations test_store_translations_converts_keys_to_symbols test_store_translations_deep_merges_translations test_store_translations_forces_locale_to_sym

Included Modules

I18nSimpleBackendTestSetup

Public Instance methods

test_store_translations_adds_translations(

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 104
104:   def test_store_translations_adds_translations # no, really :-)
105:     @backend.store_translations 'en''en', :foo => 'bar'
106:     assert_equal Hash['en''en', {:foo => 'bar'}], backend_get_translations
107:   end
test_store_translations_converts_keys_to_symbols()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 120
120:   def test_store_translations_converts_keys_to_symbols
121:     # backend_reset_translations!
122:     @backend.store_translations 'en', 'foo' => {'bar' => 'bar', 'baz' => 'baz'}
123:     assert_equal Hash['en''en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
124:   end
test_store_translations_deep_merges_translations()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 109
109:   def test_store_translations_deep_merges_translations
110:     @backend.store_translations 'en''en', :foo => {:bar => 'bar'}
111:     @backend.store_translations 'en''en', :foo => {:baz => 'baz'}
112:     assert_equal Hash['en''en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
113:   end
test_store_translations_forces_locale_to_sym()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb, line 115
115:   def test_store_translations_forces_locale_to_sym
116:     @backend.store_translations 'en', :foo => 'bar'
117:     assert_equal Hash['en''en', {:foo => 'bar'}], backend_get_translations
118:   end


Class: I18nTest

Class | I18nTest
In: | vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
Parent: | Test::Unit::TestCase

Methods

setup test_can_set_backend test_can_set_default_locale test_can_set_exception_handler test_can_set_locale_to_thread_current test_delegates_localize_to_backend test_delegates_translate_to_backend test_localize_nil_raises_argument_error test_localize_object_raises_argument_error test_translate_given_a_bogus_key_raises_missing_translation_data test_translate_given_no_locale_uses_i18n_locale test_translate_on_nested_symbol_keys_works test_translate_with_array_as_scope_works test_translate_with_array_containing_dot_separated_strings_as_scope_works test_translate_with_dot_separated_key_array_and_scope_works test_translate_with_key_array_and_dot_separated_scope_works test_translate_with_nested_string_keys_works test_translate_with_options_using_scope_works test_uses_custom_exception_handler test_uses_default_locale_as_locale_by_default test_uses_en_us_as_default_locale_by_default test_uses_simple_backend_set_by_default

Public Instance methods

setup()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 10
10:   def setup
11:     I18n.backend.store_translations 'en''en', {
12:       :currency => {
13:         :format => {
14:           :separator => '.',
15:           :delimiter => ',',
16:         }
17:       }
18:     }
19:   end
test_can_set_backend()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 25
25:   def test_can_set_backend
26:     assert_nothing_raised{ I18n.backend = self }
27:     assert_equal self, I18n.backend
28:     I18n.backend = I18n::Backend::Simple.new
29:   end
test_can_set_default_locale()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 35
35:   def test_can_set_default_locale
36:     assert_nothing_raised{ I18n.default_locale = 'de' }
37:     assert_equal 'de', I18n.default_locale
38:     I18n.default_locale = 'en'
39:   end
test_can_set_exception_handler()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 52
52:   def test_can_set_exception_handler
53:     assert_nothing_raised{ I18n.exception_handler = :custom_exception_handler }
54:     I18n.exception_handler = :default_exception_handler # revert it
55:   end
test_can_set_locale_to_thread_current()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 45
45:   def test_can_set_locale_to_thread_current
46:     assert_nothing_raised{ I18n.locale = 'de' }
47:     assert_equal 'de', I18n.locale
48:     assert_equal 'de', Thread.current[:locale]
49:     I18n.locale = 'en'
50:   end
test_delegates_localize_to_backend()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 69
69:   def test_delegates_localize_to_backend
70:     I18n.backend.expects(:localize).with 'de', :whatever, :default
71:     I18n.localize :whatever, :locale => 'de'
72:   end
test_delegates_translate_to_backend()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 64
64:   def test_delegates_translate_to_backend
65:     I18n.backend.expects(:translate).with 'de', :foo, {}
66:     I18n.translate :foo, :locale => 'de'
67:   end
test_localize_nil_raises_argument_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 118
118:   def test_localize_nil_raises_argument_error
119:     assert_raise(I18n::ArgumentError) { I18n.l nil }
120:   end
test_localize_object_raises_argument_error()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 122
122:   def test_localize_object_raises_argument_error
123:     assert_raise(I18n::ArgumentError) { I18n.l Object.new }
124:   end
test_translate_given_a_bogus_key_raises_missing_translation_data()

def test_translate_given_no_args_raises_missing_translation_data

  assert_equal "translation missing: en, no key", I18n.t

end

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 114
114:   def test_translate_given_a_bogus_key_raises_missing_translation_data
115:     assert_equal "translation missing: en, bogus", I18n.t(:bogus)
116:   end
test_translate_given_no_locale_uses_i18n_locale()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 74
74:   def test_translate_given_no_locale_uses_i18n_locale
75:     I18n.backend.expects(:translate).with 'en', :foo, {}
76:     I18n.translate :foo
77:   end
test_translate_on_nested_symbol_keys_works()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 79
79:   def test_translate_on_nested_symbol_keys_works
80:     assert_equal ".", I18n.t('currency.format.separator''currency.format.separator')
81:   end
test_translate_with_array_as_scope_works()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 87
87:   def test_translate_with_array_as_scope_works
88:     assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
89:   end
test_translate_with_array_containing_dot_separated_strings_as_scope_works()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 91
91:   def test_translate_with_array_containing_dot_separated_strings_as_scope_works
92:     assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
93:   end
test_translate_with_dot_separated_key_array_and_scope_works()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 99
 99:   def test_translate_with_dot_separated_key_array_and_scope_works
100:     assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency')
101:   end
test_translate_with_key_array_and_dot_separated_scope_works()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 95
95:   def test_translate_with_key_array_and_dot_separated_scope_works
96:     assert_equal [".", ","], I18n.t(%w(separator delimiter), :scope => 'currency.format')
97:   end
test_translate_with_nested_string_keys_works()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 83
83:   def test_translate_with_nested_string_keys_works
84:     assert_equal ".", I18n.t('currency.format.separator')
85:   end
test_translate_with_options_using_scope_works()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 103
103:   def test_translate_with_options_using_scope_works
104:     I18n.backend.expects(:translate).with('de', :precision, :scope => "currency.format""currency.format")
105:     I18n.with_options :locale => 'de', :scope => 'currency.format''currency.format' do |locale|
106:       locale.t :precision
107:     end
108:   end
test_uses_custom_exception_handler()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 57
57:   def test_uses_custom_exception_handler
58:     I18n.exception_handler = :custom_exception_handler
59:     I18n.expects(:custom_exception_handler)
60:     I18n.translate :bogus
61:     I18n.exception_handler = :default_exception_handler # revert it
62:   end
test_uses_default_locale_as_locale_by_default()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 41
41:   def test_uses_default_locale_as_locale_by_default
42:     assert_equal I18n.default_locale, I18n.locale
43:   end
test_uses_en_us_as_default_locale_by_default()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 31
31:   def test_uses_en_us_as_default_locale_by_default
32:     assert_equal 'en', I18n.default_locale
33:   end
test_uses_simple_backend_set_by_default()

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb, line 21
21:   def test_uses_simple_backend_set_by_default
22:     assert I18n.backend.is_a?(I18n::Backend::Simple)
23:   end


Module: Kernel

Module | Kernel
In: | vendor/rails/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb vendor/rails/activesupport/lib/active_support/core_ext/kernel/requires.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb

Since Ruby is very dynamic, methods added to the ancestors of BlankSlate after BlankSlate is defined will show up in the list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any method defined after BlankSlate has been loaded.

Methods

breakpoint daemonize debugger enable_warnings method_added require_library_or_gem silence_stream silence_warnings suppress

External Aliases

method_added -> blank_slate_method_added

Public Class methods

method_added(name)

Detect method additions to Kernel and remove them in the BlankSlate class.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 65
65:     def method_added(name)
66:       result = blank_slate_method_added(name)
67:       return result if self != Kernel
68:       BlankSlate.hide(name)
69:       result
70:     end

Public Instance methods

breakpoint()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb, line 9
 9:   def breakpoint
10:     Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
11:     debugger
12:   end
daemonize()

Turns the current script into a daemon process that detaches from the console. It can be shut down with a TERM signal.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb, line 4
4:   def daemonize
5:     Process.daemon
6:   end
debugger()

Starts a debugging session if ruby-debug has been loaded (call script/server —debugger to do load it).

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/debugger.rb, line 4
4:     def debugger
5:       Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
6:     end
enable_warnings() {|| ...}

Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 17
17:   def enable_warnings
18:     old_verbose, $VERBOSE = $VERBOSE, true
19:     yield
20:   ensure
21:     $VERBOSE = old_verbose
22:   end
require_library_or_gem(library_name)

Require a library with fallback to RubyGems. Warnings during library loading are silenced to increase signal/noise for application warnings.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/requires.rb, line 4
 4:   def require_library_or_gem(library_name)
 5:     silence_warnings do
 6:       begin
 7:         require library_name
 8:       rescue LoadError => cannot_require
 9:         # 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
10:         begin
11:           require 'rubygems'
12:         rescue LoadError => rubygems_not_installed
13:           raise cannot_require
14:         end
15:         # 2. Rubygems is installed and loaded. Try to load the library again
16:         begin
17:           require library_name
18:         rescue LoadError => gem_not_installed
19:           raise cannot_require
20:         end
21:       end
22:     end
23:   end
silence_stream(stream) {|| ...}

Silences any stream for the duration of the block.

  silence_stream(STDOUT) do
    puts 'This will never be seen'
  end

  puts 'But this will'

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 36
36:   def silence_stream(stream)
37:     old_stream = stream.dup
38:     stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
39:     stream.sync = true
40:     yield
41:   ensure
42:     stream.reopen(old_stream)
43:   end
silence_warnings() {|| ...}

Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.

  silence_warnings do
    value = noisy_call # no warning voiced
  end

  noisy_call # warning voiced

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 9
 9:   def silence_warnings
10:     old_verbose, $VERBOSE = $VERBOSE, nil
11:     yield
12:   ensure
13:     $VERBOSE = old_verbose
14:   end
suppress(*exception_classes) {|| ...}

Blocks and ignores any exception passed as argument if raised within the block.

  suppress(ZeroDivisionError) do
    1/0
    puts "This code is NOT reached"
  end

  puts "This code gets executed and nothing related to ZeroDivisionError was seen"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 53
53:   def suppress(*exception_classes)
54:     begin yield
55:     rescue Exception => e
56:       raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
57:     end
58:   end


Module: LibXML

Module | LibXML
In: | vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb

Classes and Modules

Module LibXML::Conversions


Module: LibXML::Conversions

Module | LibXML::Conversions
In: | vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb

Classes and Modules

Module LibXML::Conversions::Document
Module LibXML::Conversions::Node


Module: LibXML::Conversions::Document

Module | LibXML::Conversions::Document
In: | vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb

Methods

to_hash

Public Instance methods

to_hash()

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 27
27:       def to_hash
28:         root.to_hash
29:       end


Module: LibXML::Conversions::Node

Module | LibXML::Conversions::Node
In: | vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb

Methods

array? attributes_to_hash children_array_to_hash children_to_hash children_yaml_to_hash insert_name_into_hash to_hash yaml?

Constants

CONTENT_ROOT | = | '__content__'
LIB_XML_LIMIT | = | 30000000

Public Instance methods

to_hash(hash={})

Convert XML document to hash

hash: Hash to merge the converted element into.

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 40
40:       def to_hash(hash={})
41:         if text?
42:           raise LibXML::XML::Error if content.length >= LIB_XML_LIMIT
43:           hash[CONTENT_ROOT] = content
44:         else
45:           sub_hash = insert_name_into_hash(hash, name)
46:           attributes_to_hash(sub_hash)
47:           if array?
48:             children_array_to_hash(sub_hash)
49:           elsif yaml?
50:             children_yaml_to_hash(sub_hash)
51:           else
52:             children_to_hash(sub_hash)
53:           end
54:         end
55:         hash
56:       end

Protected Instance methods

array?()

Check if child is of type array

[Source]

     # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 119
119:         def array?
120:           child? && child.next? && child.name == child.next.name
121:         end
attributes_to_hash(hash={})

Convert xml attributes to hash

hash: Hash to merge the attributes into

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 93
93:         def attributes_to_hash(hash={})
94:           each_attr { |attr| hash[attr.name] = attr.value }
95:           hash
96:         end
children_array_to_hash(hash={})

Convert array into hash

hash: Hash to merge the array into

[Source]

     # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 102
102:         def children_array_to_hash(hash={})
103:           hash[child.name] = map do |child|
104:             returning({}) { |sub_hash| child.children_to_hash(sub_hash) }
105:           end
106:           hash
107:         end
children_to_hash(hash={})

Insert children into hash

hash: Hash to merge the children into.

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 83
83:         def children_to_hash(hash={})
84:           each { |child| child.to_hash(hash) }
85:           attributes_to_hash(hash)
86:           hash
87:         end
children_yaml_to_hash(hash = {})

Convert yaml into hash

hash: Hash to merge the yaml into

[Source]

     # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 113
113:         def children_yaml_to_hash(hash = {})
114:           hash[CONTENT_ROOT] = content unless content.blank?
115:           hash
116:         end
insert_name_into_hash(hash, name)

Insert name into hash

hash: | Hash to merge the converted element into.
name: | name to to merge into hash

[Source]

    # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 66
66:         def insert_name_into_hash(hash, name)
67:           sub_hash = {}
68:           if hash[name]
69:             if !hash[name].kind_of? Array
70:               hash[name] = [hash[name]]
71:             end
72:             hash[name] << sub_hash
73:           else
74:             hash[name] = sub_hash
75:           end
76:           sub_hash
77:         end
yaml?()

Check if child is of type yaml

[Source]

     # File vendor/rails/activesupport/lib/active_support/xml_mini/libxml.rb, line 124
124:         def yaml?
125:           attributes.collect{|x| x.value}.include?('yaml')
126:         end


Class: Logger

Class | Logger
In: | vendor/rails/activesupport/lib/active_support/core_ext/logger.rb
Parent: | Object

Extensions to the built in Ruby logger.

If you want to use the default log formatter as defined in the Ruby core, then you will need to set the formatter for the logger as in:

  logger.formatter = Formatter.new

You can then specify the datetime format, for example:

  logger.datetime_format = "%Y-%m-%d"

Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger

Methods

datetime_format datetime_format= define_around_helper formatter silence

Classes and Modules

Class Logger::Formatter
Class Logger::SimpleFormatter

External Aliases

datetime_format= | -> | old_datetime_format=
datetime_format | -> | old_datetime_format
formatter | -> | old_formatter
format_message | -> | old_format_message
format_datetime | -> | old_format_datetime
msg2str | -> | old_msg2str

Public Class methods

define_around_helper(level)

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 4
4:   def self.define_around_helper(level)
5:     module_eval "def around_\#{level}(before_message, after_message, &block)  # def around_debug(before_message, after_message, &block)\nself.\#{level}(before_message)                             #   self.debug(before_message)\nreturn_value = block.call(self)                           #   return_value = block.call(self)\nself.\#{level}(after_message)                              #   self.debug(after_message)\nreturn return_value                                       #   return return_value\nend                                                         # end\n"
6:   end

Public Instance methods

datetime_format()

Get the logging datetime format. Returns nil if the formatter does not support datetime formatting.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 64
64:   def datetime_format
65:     formatter.datetime_format if formatter.respond_to?(:datetime_format)
66:   end
datetime_format=(datetime_format)

Logging date-time format (string passed to strftime). Ignored if the formatter does not respond to datetime_format=.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 57
57:   def datetime_format=(datetime_format)
58:     formatter.datetime_format = datetime_format if formatter.respond_to?(:datetime_format=)
59:   end
formatter()

Get the current formatter. The default formatter is a SimpleFormatter which only displays the log message

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 71
71:   def formatter
72:     @formatter ||= SimpleFormatter.new
73:   end
silence(temporary_level = Logger::ERROR) {|self| ...}

Silences the logger for the duration of the block.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 41
41:   def silence(temporary_level = Logger::ERROR)
42:     if silencer
43:       begin
44:         old_logger_level, self.level = level, temporary_level
45:         yield self
46:       ensure
47:         self.level = old_logger_level
48:       end
49:     else
50:       yield self
51:     end
52:   end


Class: Logger::Formatter

Class | Logger::Formatter
In: | vendor/rails/activesupport/lib/active_support/core_ext/logger.rb
Parent: | Object

Methods

call new

Constants

Format = "%s, [%s#%d] %5s -- %s: %s\n"

Attributes

datetime_format [RW]

Public Class methods

new()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 81
81:       def initialize
82:         @datetime_format = nil
83:       end

Public Instance methods

call(severity, time, progname, msg)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 85
85:       def call(severity, time, progname, msg)
86:         Format % [severity[0..0], format_datetime(time), $$, severity, progname,
87:         msg2str(msg)]
88:       end


Class: Logger::SimpleFormatter

Class | Logger::SimpleFormatter
In: | vendor/rails/activesupport/lib/active_support/core_ext/logger.rb
Parent: | Logger::Formatter

Simple formatter which only displays the message.

Methods

call

Public Instance methods

call(severity, timestamp, progname, msg)

This method is invoked when a log event occurs

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/logger.rb, line 116
116:     def call(severity, timestamp, progname, msg)
117:       "#{String === msg ? msg : msg.inspect}\n"
118:     end


Class: MemCache

Class | MemCache
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Parent: | Object

A Ruby client library for memcached.

Methods

[] []= active? add cache_decr cache_get cache_get_multi cache_incr check_multithread_status! create_continuum_for decr delete entry_count_for flush_all get get_multi get_server_for_key handle_error hash_for incr inspect make_cache_key new raise_on_error_response! readonly? request_setup reset servers= set stats with_server with_socket_management

Classes and Modules

Class MemCache::MemCacheError
Class MemCache::Server

Constants

VERSION | = | '1.6.4.99' | The version of MemCache you are using.
DEFAULT_OPTIONS | = | { :namespace => nil, :readonly => false, :multithread => true, :failover => true, :timeout => 0.5, :logger => nil, } | Default options for the cache object.
DEFAULT_PORT | = | 11211 | Default memcached port.
DEFAULT_WEIGHT | = | 1 | Default memcached server weight.
ONE_MB | = | 1024 * 1024 | Add key to the cache with value value that expires in expiry seconds. If raw is true, value will not be Marshalled. Warning: Readers should not call this method in the event of a cache miss; see MemCache#add.

Attributes

failover | [R] | Should the client try to failover to another server if the first server is down? Defaults to true.
logger | [R] | Log debug/info/warn/error to the given Logger, defaults to nil.
multithread | [R] | The multithread setting for this instance
namespace | [R] | The namespace for this instance
servers | [R] | The servers this client talks to. Play at your own peril.
timeout | [R] | Socket timeout limit with this client, defaults to 0.5 sec. Set to nil to disable timeouts.

Public Class methods

new(*args)

Accepts a list of servers and a list of opts. servers may be omitted. See +servers=+ for acceptable server list arguments.

Valid options for opts are:

  [:namespace]   Prepends this value to all keys added or retrieved.
  [:readonly]    Raises an exception on cache writes when true.
  [:multithread] Wraps cache access in a Mutex for thread safety.
  [:failover]    Should the client try to failover to another server if the
                 first server is down?  Defaults to true.
  [:timeout]     Time to use as the socket read timeout.  Defaults to 0.5 sec,
                 set to nil to disable timeouts (this is a major performance penalty in Ruby 1.8).
  [:logger]      Logger to use for info/debug output, defaults to nil

Other options are ignored.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 90
 90:   def initialize(*args)
 91:     servers = []
 92:     opts = {}
 93:
 94:     case args.length
 95:     when 0 then # NOP
 96:     when 1 then
 97:       arg = args.shift
 98:       case arg
 99:       when Hash   then opts = arg
100:       when Array  then servers = arg
101:       when String then servers = [arg]
102:       else raise ArgumentError, 'first argument must be Array, Hash or String'
103:       end
104:     when 2 then
105:       servers, opts = args
106:     else
107:       raise ArgumentError, "wrong number of arguments (#{args.length} for 2)"
108:     end
109:
110:     opts = DEFAULT_OPTIONS.merge opts
111:     @namespace   = opts[:namespace]
112:     @readonly    = opts[:readonly]
113:     @multithread = opts[:multithread]
114:     @timeout     = opts[:timeout]
115:     @failover    = opts[:failover]
116:     @logger      = opts[:logger]
117:     @mutex       = Mutex.new if @multithread
118:
119:     logger.info { "memcache-client #{VERSION} #{Array(servers).inspect}" } if logger
120:
121:     Thread.current[:memcache_client] = self.object_id if !@multithread
122:
123:     self.servers = servers
124:   end

Public Instance methods

[](key, raw = false)

Alias for get

[]=(key, value)

Shortcut to save a value in the cache. This method does not set an expiration on the entry. Use set to specify an explicit expiry.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 458
458:   def []=(key, value)
459:     set key, value
460:   end
active?()

Returns whether there is at least one active server for the object.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 137
137:   def active?
138:     not @servers.empty?
139:   end
add(key, value, expiry = 0, raw = false)

Add key to the cache with value value that expires in expiry seconds, but only if key does not already exist in the cache. If raw is true, value will not be Marshalled.

Readers should call this method in the event of a cache miss, not MemCache#set or MemCache#[]=.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 316
316:   def add(key, value, expiry = 0, raw = false)
317:     raise MemCacheError, "Update of readonly cache" if @readonly
318:     with_server(key) do |server, cache_key|
319:       value = Marshal.dump value unless raw
320:       logger.debug { "ADD #{key} to #{server}: #{value ? value.to_s.size : 'nil'}" } if logger
321:       command = "add #{cache_key} 0 #{expiry} #{value.to_s.size}\r\n#{value}\r\n"
322:
323:       with_socket_management(server) do |socket|
324:         socket.write command
325:         result = socket.gets
326:         raise_on_error_response! result
327:         result
328:       end
329:     end
330:   end
decr(key, amount = 1)

Decrements the value for key by amount and returns the new value. key must already exist. If key is not an integer, it is assumed to be

  1. key can not be decremented below 0.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 180
180:   def decr(key, amount = 1)
181:     raise MemCacheError, "Update of readonly cache" if @readonly
182:     with_server(key) do |server, cache_key|
183:       cache_decr server, cache_key, amount
184:     end
185:   rescue TypeError => err
186:     handle_error nil, err
187:   end
delete(key, expiry = 0)

Removes key from the cache in expiry seconds.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 335
335:   def delete(key, expiry = 0)
336:     raise MemCacheError, "Update of readonly cache" if @readonly
337:     with_server(key) do |server, cache_key|
338:       with_socket_management(server) do |socket|
339:         socket.write "delete #{cache_key} #{expiry}\r\n"
340:         result = socket.gets
341:         raise_on_error_response! result
342:         result
343:       end
344:     end
345:   end
flush_all()

Flush the cache from all memcache servers.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 350
350:   def flush_all
351:     raise MemCacheError, 'No active servers' unless active?
352:     raise MemCacheError, "Update of readonly cache" if @readonly
353:
354:     begin
355:       @servers.each do |server|
356:         with_socket_management(server) do |socket|
357:           socket.write "flush_all\r\n"
358:           result = socket.gets
359:           raise_on_error_response! result
360:           result
361:         end
362:       end
363:     rescue IndexError => err
364:       handle_error nil, err
365:     end
366:   end
get(key, raw = false)

Retrieves key from memcache. If raw is false, the value will be unmarshalled.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 193
193:   def get(key, raw = false)
194:     with_server(key) do |server, cache_key|
195:       value = cache_get server, cache_key
196:       logger.debug { "GET #{key} from #{server.inspect}: #{value ? value.to_s.size : 'nil'}" } if logger
197:       return nil if value.nil?
198:       value = Marshal.load value unless raw
199:       return value
200:     end
201:   rescue TypeError => err
202:     handle_error nil, err
203:   end
get_multi(*keys)

Retrieves multiple values from memcached in parallel, if possible.

The memcached protocol supports the ability to retrieve multiple keys in a single request. Pass in an array of keys to this method and it will:

  1. map the key to the appropriate memcached server
  2. send a single request to each server that has one or more key values

Returns a hash of values.

  cache["a"] = 1
  cache["b"] = 2
  cache.get_multi "a", "b" # => { "a" => 1, "b" => 2 }

Note that get_multi assumes the values are marshalled.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 223
223:   def get_multi(*keys)
224:     raise MemCacheError, 'No active servers' unless active?
225:
226:     keys.flatten!
227:     key_count = keys.length
228:     cache_keys = {}
229:     server_keys = Hash.new { |h,k| h[k] = [] }
230:
231:     # map keys to servers
232:     keys.each do |key|
233:       server, cache_key = request_setup key
234:       cache_keys[cache_key] = key
235:       server_keys[server] << cache_key
236:     end
237:
238:     results = {}
239:
240:     server_keys.each do |server, keys_for_server|
241:       keys_for_server_str = keys_for_server.join ' '
242:       begin
243:         values = cache_get_multi server, keys_for_server_str
244:         values.each do |key, value|
245:           results[cache_keys[key]] = Marshal.load value
246:         end
247:       rescue IndexError => e
248:         # Ignore this server and try the others
249:         logger.warn { "Unable to retrieve #{keys_for_server.size} elements from #{server.inspect}: #{e.message}"} if logger
250:       end
251:     end
252:
253:     return results
254:   rescue TypeError => err
255:     handle_error nil, err
256:   end
incr(key, amount = 1)

Increments the value for key by amount and returns the new value. key must already exist. If key is not an integer, it is assumed to be 0.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 263
263:   def incr(key, amount = 1)
264:     raise MemCacheError, "Update of readonly cache" if @readonly
265:     with_server(key) do |server, cache_key|
266:       cache_incr server, cache_key, amount
267:     end
268:   rescue TypeError => err
269:     handle_error nil, err
270:   end
inspect()

Returns a string representation of the cache object.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 129
129:   def inspect
130:     "<MemCache: %d servers, ns: %p, ro: %p>" %
131:       [@servers.length, @namespace, @readonly]
132:   end
readonly?()

Returns whether or not the cache object was created read only.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 144
144:   def readonly?
145:     @readonly
146:   end
reset()

Reset the connection to all memcache servers. This should be called if there is a problem with a cache lookup that might have left the connection in a corrupted state.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 373
373:   def reset
374:     @servers.each { |server| server.close }
375:   end
servers=(servers)

Set the servers that the requests will be distributed between. Entries can be either strings of the form "hostname:port" or "hostname:port:weight" or MemCache::Server objects.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 153
153:   def servers=(servers)
154:     # Create the server objects.
155:     @servers = Array(servers).collect do |server|
156:       case server
157:       when String
158:         host, port, weight = server.split ':', 3
159:         port ||= DEFAULT_PORT
160:         weight ||= DEFAULT_WEIGHT
161:         Server.new self, host, port, weight
162:       else
163:         server
164:       end
165:     end
166:
167:     logger.debug { "Servers now: #{@servers.inspect}" } if logger
168:
169:     # There's no point in doing this if there's only one server
170:     @continuum = create_continuum_for(@servers) if @servers.size > 1
171:
172:     @servers
173:   end
set(key, value, expiry = 0, raw = false)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 281
281:   def set(key, value, expiry = 0, raw = false)
282:     raise MemCacheError, "Update of readonly cache" if @readonly
283:     with_server(key) do |server, cache_key|
284:
285:       value = Marshal.dump value unless raw
286:       logger.debug { "SET #{key} to #{server.inspect}: #{value ? value.to_s.size : 'nil'}" } if logger
287:
288:       data = value.to_s
289:       raise MemCacheError, "Value too large, memcached can only store 1MB of data per key" if data.size > ONE_MB
290:
291:       command = "set #{cache_key} 0 #{expiry} #{data.size}\r\n#{data}\r\n"
292:
293:       with_socket_management(server) do |socket|
294:         socket.write command
295:         result = socket.gets
296:         raise_on_error_response! result
297:
298:         if result.nil?
299:           server.close
300:           raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
301:         end
302:
303:         result
304:       end
305:     end
306:   end
stats()

Returns statistics for each memcached server. An explanation of the statistics can be found in the memcached docs:

code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt

Example:

  >> pp CACHE.stats
  {"localhost:11211"=>
    {"bytes"=>4718,
     "pid"=>20188,
     "connection_structures"=>4,
     "time"=>1162278121,
     "pointer_size"=>32,
     "limit_maxbytes"=>67108864,
     "cmd_get"=>14532,
     "version"=>"1.2.0",
     "bytes_written"=>432583,
     "cmd_set"=>32,
     "get_misses"=>0,
     "total_connections"=>19,
     "curr_connections"=>3,
     "curr_items"=>4,
     "uptime"=>1557,
     "get_hits"=>14532,
     "total_items"=>32,
     "rusage_system"=>0.313952,
     "rusage_user"=>0.119981,
     "bytes_read"=>190619}}
  => nil

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 409
409:   def stats
410:     raise MemCacheError, "No active servers" unless active?
411:     server_stats = {}
412:
413:     @servers.each do |server|
414:       next unless server.alive?
415:
416:       with_socket_management(server) do |socket|
417:         value = nil
418:         socket.write "stats\r\n"
419:         stats = {}
420:         while line = socket.gets do
421:           raise_on_error_response! line
422:           break if line == "END\r\n"
423:           if line =~ /\ASTAT ([\S]+) ([\w\.\:]+)/ then
424:             name, value = $1, $2
425:             stats[name] = case name
426:                           when 'version'
427:                             value
428:                           when 'rusage_user', 'rusage_system' then
429:                             seconds, microseconds = value.split(/:/, 2)
430:                             microseconds ||= 0
431:                             Float(seconds) + (Float(microseconds) / 1_000_000)
432:                           else
433:                             if value =~ /\A\d+\Z/ then
434:                               value.to_i
435:                             else
436:                               value
437:                             end
438:                           end
439:           end
440:         end
441:         server_stats["#{server.host}:#{server.port}"] = stats
442:       end
443:     end
444:
445:     raise MemCacheError, "No active servers" if server_stats.empty?
446:     server_stats
447:   end

Protected Instance methods

cache_decr(server, cache_key, amount)

Performs a raw decr for cache_key from server. Returns nil if not found.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 511
511:   def cache_decr(server, cache_key, amount)
512:     with_socket_management(server) do |socket|
513:       socket.write "decr #{cache_key} #{amount}\r\n"
514:       text = socket.gets
515:       raise_on_error_response! text
516:       return nil if text == "NOT_FOUND\r\n"
517:       return text.to_i
518:     end
519:   end
cache_get(server, cache_key)

Fetches the raw data for cache_key from server. Returns nil on cache miss.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 525
525:   def cache_get(server, cache_key)
526:     with_socket_management(server) do |socket|
527:       socket.write "get #{cache_key}\r\n"
528:       keyline = socket.gets # "VALUE <key> <flags> <bytes>\r\n"
529:
530:       if keyline.nil? then
531:         server.close
532:         raise MemCacheError, "lost connection to #{server.host}:#{server.port}"
533:       end
534:
535:       raise_on_error_response! keyline
536:       return nil if keyline == "END\r\n"
537:
538:       unless keyline =~ /(\d+)\r/ then
539:         server.close
540:         raise MemCacheError, "unexpected response #{keyline.inspect}"
541:       end
542:       value = socket.read $1.to_i
543:       socket.read 2 # "\r\n"
544:       socket.gets   # "END\r\n"
545:       return value
546:     end
547:   end
cache_get_multi(server, cache_keys)

Fetches cache_keys from server using a multi-get.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 552
552:   def cache_get_multi(server, cache_keys)
553:     with_socket_management(server) do |socket|
554:       values = {}
555:       socket.write "get #{cache_keys}\r\n"
556:
557:       while keyline = socket.gets do
558:         return values if keyline == "END\r\n"
559:         raise_on_error_response! keyline
560:
561:         unless keyline =~ /\AVALUE (.+) (.+) (.+)/ then
562:           server.close
563:           raise MemCacheError, "unexpected response #{keyline.inspect}"
564:         end
565:
566:         key, data_length = $1, $3
567:         values[$1] = socket.read data_length.to_i
568:         socket.read(2) # "\r\n"
569:       end
570:
571:       server.close
572:       raise MemCacheError, "lost connection to #{server.host}:#{server.port}" # TODO: retry here too
573:     end
574:   end
cache_incr(server, cache_key, amount)

Performs a raw incr for cache_key from server. Returns nil if not found.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 580
580:   def cache_incr(server, cache_key, amount)
581:     with_socket_management(server) do |socket|
582:       socket.write "incr #{cache_key} #{amount}\r\n"
583:       text = socket.gets
584:       raise_on_error_response! text
585:       return nil if text == "NOT_FOUND\r\n"
586:       return text.to_i
587:     end
588:   end
check_multithread_status!()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 698
698:   def check_multithread_status!
699:     return if @multithread
700:
701:     if Thread.current[:memcache_client] != self.object_id
702:       raise MemCacheError, "You are accessing this memcache-client instance from multiple threads but have not enabled multithread support.\nNormally:  MemCache.new(['localhost:11211'], :multithread => true)\nIn Rails:  config.cache_store = [:mem_cache_store, 'localhost:11211', { :multithread => true }]\n"
703:     end
704:   end
create_continuum_for(servers)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 679
679:   def create_continuum_for(servers)
680:     total_weight = servers.inject(0) { |memo, srv| memo + srv.weight }
681:     continuum = []
682:
683:     servers.each do |server|
684:       entry_count_for(server, servers.size, total_weight).times do |idx|
685:         hash = Digest::SHA1.hexdigest("#{server.host}:#{server.port}:#{idx}")
686:         value = Integer("0x#{hash[0..7]}")
687:         continuum << Continuum::Entry.new(value, server)
688:       end
689:     end
690:
691:     continuum.sort { |a, b| a.value <=> b.value }
692:   end
entry_count_for(server, total_servers, total_weight)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 694
694:   def entry_count_for(server, total_servers, total_weight)
695:     ((total_servers * Continuum::POINTS_PER_SERVER * server.weight) / Float(total_weight)).floor
696:   end
get_server_for_key(key, options = {})

Pick a server to handle the request based on a hash of the key.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 487
487:   def get_server_for_key(key, options = {})
488:     raise ArgumentError, "illegal character in key #{key.inspect}" if
489:       key =~ /\s/
490:     raise ArgumentError, "key too long #{key.inspect}" if key.length > 250
491:     raise MemCacheError, "No servers available" if @servers.empty?
492:     return @servers.first if @servers.length == 1
493:
494:     hkey = hash_for(key)
495:
496:     20.times do |try|
497:       entryidx = Continuum.binary_search(@continuum, hkey)
498:       server = @continuum[entryidx].server
499:       return server if server.alive?
500:       break unless failover
501:       hkey = hash_for "#{try}#{key}"
502:     end
503:
504:     raise MemCacheError, "No servers available"
505:   end
handle_error(server, error)

Handles error from server.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 654
654:   def handle_error(server, error)
655:     raise error if error.is_a?(MemCacheError)
656:     server.close if server
657:     new_error = MemCacheError.new error.message
658:     new_error.set_backtrace error.backtrace
659:     raise new_error
660:   end
hash_for(key)

Returns an interoperable hash value for key. (I think, docs are sketchy for down servers).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 480
480:   def hash_for(key)
481:     Zlib.crc32(key)
482:   end
make_cache_key(key)

Create a key for the cache, incorporating the namespace qualifier if requested.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 468
468:   def make_cache_key(key)
469:     if namespace.nil? then
470:       key
471:     else
472:       "#{@namespace}:#{key}"
473:     end
474:   end
raise_on_error_response!(response)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 673
673:   def raise_on_error_response!(response)
674:     if response =~ /\A(?:CLIENT_|SERVER_)?ERROR(.*)/
675:       raise MemCacheError, $1.strip
676:     end
677:   end
request_setup(key)

Performs setup for making a request with key from memcached. Returns the server to fetch the key from and the complete key to use.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 666
666:   def request_setup(key)
667:     raise MemCacheError, 'No active servers' unless active?
668:     cache_key = make_cache_key key
669:     server = get_server_for_key cache_key
670:     return server, cache_key
671:   end
with_server(key) {|server, cache_key| ...}

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 635
635:   def with_server(key)
636:     retried = false
637:     begin
638:       server, cache_key = request_setup(key)
639:       yield server, cache_key
640:     rescue IndexError => e
641:       logger.warn { "Server failed: #{e.class.name}: #{e.message}" } if logger
642:       if !retried && @servers.size > 1
643:         logger.info { "Connection to server #{server.inspect} DIED! Retrying operation..." } if logger
644:         retried = true
645:         retry
646:       end
647:       handle_error(nil, e)
648:     end
649:   end
with_socket_management(server, &block)

Gets or creates a socket connected to the given server, and yields it to the block, wrapped in a mutex synchronization if @multithread is true.

If a socket error (SocketError, SystemCallError, IOError) or protocol error (MemCacheError) is raised by the block, closes the socket, attempts to connect again, and retries the block (once). If an error is again raised, reraises it as MemCacheError.

If unable to connect to the server (or if in the reconnect wait period), raises MemCacheError. Note that the socket connect code marks a server dead for a timeout period, so retrying does not apply to connection attempt failures (but does still apply to unexpectedly lost connections etc.).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 604
604:   def with_socket_management(server, &block)
605:     check_multithread_status!
606:
607:     @mutex.lock if @multithread
608:     retried = false
609:
610:     begin
611:       socket = server.socket
612:
613:       # Raise an IndexError to show this server is out of whack. If were inside
614:       # a with_server block, we'll catch it and attempt to restart the operation.
615:
616:       raise IndexError, "No connection to server (#{server.status})" if socket.nil?
617:
618:       block.call(socket)
619:
620:     rescue SocketError => err
621:       logger.warn { "Socket failure: #{err.message}" } if logger
622:       server.mark_dead(err)
623:       handle_error(server, err)
624:
625:     rescue MemCacheError, SystemCallError, IOError => err
626:       logger.warn { "Generic failure: #{err.class.name}: #{err.message}" } if logger
627:       handle_error(server, err) if retried || socket.nil?
628:       retried = true
629:       retry
630:     end
631:   ensure
632:     @mutex.unlock if @multithread
633:   end


Class: MemCache::MemCacheError

Class | MemCache::MemCacheError
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Parent: | RuntimeError

Base MemCache exception class.


Class: MemCache::Server

Class | MemCache::Server
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Parent: | Object

This class represents a memcached server instance.

Methods

alive? close inspect mark_dead new socket

Constants

CONNECT_TIMEOUT | = | 0.25 | The amount of time to wait to establish a connection with a memcached server. If a connection cannot be established within this time limit, the server will be marked as down.
RETRY_DELAY | = | 30.0 | The amount of time to wait before attempting to re-establish a connection with a server that is marked dead.

Attributes

host | [R] | The host the memcached server is running on.
logger | [R] |
port | [R] | The port the memcached server is listening on.
retry | [R] | The time of next retry if the connection is dead.
status | [R] | A text status string describing the state of the server.
weight | [R] | The weight given to the server.

Public Class methods

new(memcache, host, port = DEFAULT_PORT, weight = DEFAULT_WEIGHT)

Create a new MemCache::Server object for the memcached instance listening on the given host and port, weighted by the given weight.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 760
760:     def initialize(memcache, host, port = DEFAULT_PORT, weight = DEFAULT_WEIGHT)
761:       raise ArgumentError, "No host specified" if host.nil? or host.empty?
762:       raise ArgumentError, "No port specified" if port.nil? or port.to_i.zero?
763:
764:       @host   = host
765:       @port   = port.to_i
766:       @weight = weight.to_i
767:
768:       @sock   = nil
769:       @retry  = nil
770:       @status = 'NOT CONNECTED'
771:       @timeout = memcache.timeout
772:       @logger = memcache.logger
773:     end

Public Instance methods

alive?()

Check whether the server connection is alive. This will cause the socket to attempt to connect if it isn‘t already connected and or if the server was previously marked as down and the retry time has been exceeded.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 788
788:     def alive?
789:       !!socket
790:     end
close()

Close the connection to the memcached server targeted by this object. The server is not considered dead.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 825
825:     def close
826:       @sock.close if @sock && !@sock.closed?
827:       @sock   = nil
828:       @retry  = nil
829:       @status = "NOT CONNECTED"
830:     end
inspect()

Return a string representation of the server object.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 778
778:     def inspect
779:       "<MemCache::Server: %s:%d [%d] (%s)>" % [@host, @port, @weight, @status]
780:     end
mark_dead(error)

Mark the server as dead and close its socket.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 835
835:     def mark_dead(error)
836:       @sock.close if @sock && !@sock.closed?
837:       @sock   = nil
838:       @retry  = Time.now + RETRY_DELAY
839:
840:       reason = "#{error.class.name}: #{error.message}"
841:       @status = sprintf "%s:%s DEAD (%s), will retry at %s", @host, @port, reason, @retry
842:       @logger.info { @status } if @logger
843:     end
socket()

Try to connect to the memcached server targeted by this object. Returns the connected socket object on success or nil on failure.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 796
796:     def socket
797:       return @sock if @sock and not @sock.closed?
798:
799:       @sock = nil
800:
801:       # If the host was dead, don't retry for a while.
802:       return if @retry and @retry > Time.now
803:
804:       # Attempt to connect if not already connected.
805:       begin
806:         @sock = @timeout ? TCPTimeoutSocket.new(@host, @port, @timeout) : TCPSocket.new(@host, @port)
807:
808:         if Socket.constants.include? 'TCP_NODELAY' then
809:           @sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
810:         end
811:         @retry  = nil
812:         @status = 'CONNECTED'
813:       rescue SocketError, SystemCallError, IOError, Timeout::Error => err
814:         logger.warn { "Unable to open socket: #{err.class.name}, #{err.message}" } if logger
815:         mark_dead err
816:       end
817:
818:       return @sock
819:     end


Module: Mime

Module | Mime
In: | vendor/rails/actionpack/lib/action_controller/mime_type.rb

Classes and Modules

Class Mime::Type

Constants

SET | = | []
EXTENSION_LOOKUP | = | Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
LOOKUP | = | Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }


Class: Mime::Type

Class | Mime::Type
In: | vendor/rails/actionpack/lib/action_controller/mime_type.rb
Parent: | Object

Encapsulates the notion of a mime type. Can be used at render time, for example, with:

  class PostsController < ActionController::Base
    def show
      @post = Post.find(params[:id])

      respond_to do |format|
        format.html
        format.ics { render :text => post.to_ics, :mime_type => Mime::Type["text/calendar"]  }
        format.xml { render :xml => @people.to_xml }
      end
    end
  end

Methods

== === =~ browser_generated? html? lookup lookup_by_extension new parse register register_alias to_s to_str to_sym unverifiable_types verify_request?

Public Class methods

lookup(string)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 65
65:       def lookup(string)
66:         LOOKUP[string]
67:       end
lookup_by_extension(extension)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 69
69:       def lookup_by_extension(extension)
70:         EXTENSION_LOOKUP[extension]
71:       end
new(string, symbol = nil, synonyms = [])

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 147
147:     def initialize(string, symbol = nil, synonyms = [])
148:       @symbol, @synonyms = symbol, synonyms
149:       @string = string
150:     end
parse(accept_header)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 88
 88:       def parse(accept_header)
 89:         if accept_header !~ /,/
 90:           [Mime::Type.lookup(accept_header)]
 91:         else
 92:           # keep track of creation order to keep the subsequent sort stable
 93:           list = []
 94:           accept_header.split(/,/).each_with_index do |header, index|
 95:             params, q = header.split(/;\s*q=/)
 96:             if params
 97:               params.strip!
 98:               list << AcceptItem.new(index, params, q) unless params.empty?
 99:             end
100:           end
101:           list.sort!
102:
103:           # Take care of the broken text/xml entry by renaming or deleting it
104:           text_xml = list.index("text/xml")
105:           app_xml = list.index(Mime::XML.to_s)
106:
107:           if text_xml && app_xml
108:             # set the q value to the max of the two
109:             list[app_xml].q = [list[text_xml].q, list[app_xml].q].max
110:
111:             # make sure app_xml is ahead of text_xml in the list
112:             if app_xml > text_xml
113:               list[app_xml], list[text_xml] = list[text_xml], list[app_xml]
114:               app_xml, text_xml = text_xml, app_xml
115:             end
116:
117:             # delete text_xml from the list
118:             list.delete_at(text_xml)
119:
120:           elsif text_xml
121:             list[text_xml].name = Mime::XML.to_s
122:           end
123:
124:           # Look for more specific XML-based types and sort them ahead of app/xml
125:
126:           if app_xml
127:             idx = app_xml
128:             app_xml_type = list[app_xml]
129:
130:             while(idx < list.length)
131:               type = list[idx]
132:               break if type.q < app_xml_type.q
133:               if type.name =~ /\+xml$/
134:                 list[app_xml], list[idx] = list[idx], list[app_xml]
135:                 app_xml = idx
136:               end
137:               idx += 1
138:             end
139:           end
140:
141:           list.map! { |i| Mime::Type.lookup(i.name) }.uniq!
142:           list
143:         end
144:       end
register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 79
79:       def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
80:         Mime.instance_eval { const_set symbol.to_s.upcase, Type.new(string, symbol, mime_type_synonyms) }
81:
82:         SET << Mime.const_get(symbol.to_s.upcase)
83:
84:         ([string] + mime_type_synonyms).each { |string| LOOKUP[string] = SET.last } unless skip_lookup
85:         ([symbol.to_s] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext] = SET.last }
86:       end
register_alias(string, symbol, extension_synonyms = [])

Registers an alias that‘s not used on mime type lookup, but can be referenced directly. Especially useful for rendering different HTML versions depending on the user agent, like an iPhone.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 75
75:       def register_alias(string, symbol, extension_synonyms = [])
76:         register(string, symbol, [], extension_synonyms, true)
77:       end
unverifiable_types()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 33
33:     def self.unverifiable_types
34:       ActiveSupport::Deprecation.warn("unverifiable_types is deprecated and has no effect", caller)
35:       @@unverifiable_types
36:     end

Public Instance methods

==(mime_type)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 172
172:     def ==(mime_type)
173:       return false if mime_type.blank?
174:       (@synonyms + [ self ]).any? do |synonym|
175:         synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
176:       end
177:     end
===(list)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 164
164:     def ===(list)
165:       if list.is_a?(Array)
166:         (@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
167:       else
168:         super
169:       end
170:     end
=~(mime_type)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 179
179:     def =~(mime_type)
180:       return false if mime_type.blank?
181:       regexp = Regexp.new(Regexp.quote(mime_type.to_s))
182:       (@synonyms + [ self ]).any? do |synonym|
183:         synonym.to_s =~ regexp
184:       end
185:     end
browser_generated?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 197
197:     def browser_generated?
198:       @@browser_generated_types.include?(to_sym)
199:     end
html?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 193
193:     def html?
194:       @@html_types.include?(to_sym) || @string =~ /html/
195:     end
to_s()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 152
152:     def to_s
153:       @string
154:     end
to_str()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 156
156:     def to_str
157:       to_s
158:     end
to_sym()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 160
160:     def to_sym
161:       @symbol || @string.to_sym
162:     end
verify_request?()

Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See ActionController::RequestForgeryProtection.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/mime_type.rb, line 189
189:     def verify_request?
190:       browser_generated?
191:     end


Class: Module

Class | Module
In: | vendor/rails/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb vendor/rails/activesupport/lib/active_support/core_ext/module/attr_internal.rb vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb vendor/rails/activesupport/lib/active_support/core_ext/module/inclusion.rb vendor/rails/activesupport/lib/active_support/core_ext/module/loading.rb vendor/rails/activesupport/lib/active_support/core_ext/module/synchronization.rb vendor/rails/activesupport/lib/active_support/core_ext/module.rb vendor/rails/activesupport/lib/active_support/deprecation.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb
Parent: | Object

Also, modules included into Object need to be scanned and have their instance methods removed from blank slate. In theory, modules included into Kernel would have to be removed as well, but a "feature" of Ruby prevents late includes into modules from being exposed in the first place.

Methods

append_features as_load_path attr_accessor_with_default attr_internal attr_internal_accessor attr_internal_reader attr_internal_writer delegate included_in_classes mattr_accessor mattr_reader mattr_writer synchronize

Included Modules

ActiveSupport::CoreExtensions::Module ActiveSupport::Deprecation::ClassMethods

External Aliases

append_features -> blankslate_original_append_features

Public Instance methods

append_features(mod)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 105
105:   def append_features(mod)
106:     result = blankslate_original_append_features(mod)
107:     return result if mod != Object
108:     instance_methods.each do |name|
109:       BlankSlate.hide(name)
110:     end
111:     result
112:   end
as_load_path()

Returns String#underscore applied to the module name minus trailing classes.

  ActiveRecord.as_load_path               # => "active_record"
  ActiveRecord::Associations.as_load_path # => "active_record/associations"
  ActiveRecord::Base.as_load_path         # => "active_record" (Base is a class)

The Kernel module gives an empty string by definition.

  Kernel.as_load_path # => ""
  Math.as_load_path   # => "math"

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/loading.rb, line 12
12:   def as_load_path
13:     if self == Object || self == Kernel
14:       ''
15:     elsif is_a? Class
16:       parent == self ? '' : parent.as_load_path
17:     else
18:       name.split('::').collect do |word|
19:         word.underscore
20:       end * '/'
21:     end
22:   end
attr_accessor_with_default(sym, default = nil, &block)

Declare an attribute accessor with an initial default return value.

To give attribute :age the initial value 25:

  class Person
    attr_accessor_with_default :age, 25
  end

  some_person.age
  => 25
  some_person.age = 26
  some_person.age
  => 26

To give attribute :element_name a dynamic default value, evaluated in scope of self:

  attr_accessor_with_default(:element_name) { name.underscore }

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb, line 21
21:   def attr_accessor_with_default(sym, default = nil, &block)
22:     raise 'Default value or block required' unless !default.nil? || block
23:     define_method(sym, block_given? ? block : Proc.new { default })
24:     module_eval("def \#{sym}=(value)                        # def age=(value)\nclass << self; attr_reader :\#{sym} end  #   class << self; attr_reader :age end\n@\#{sym} = value                         #   @age = value\nend                                       # end\n", __FILE__, __LINE__)
25:   end
attr_internal(*attrs)

Alias for attr_internal_accessor

attr_internal_accessor(*attrs)

Declares an attribute reader and writer backed by an internally-named instance variable.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 18
18:   def attr_internal_accessor(*attrs)
19:     attr_internal_reader(*attrs)
20:     attr_internal_writer(*attrs)
21:   end
attr_internal_reader(*attrs)

Declares an attribute reader backed by an internally-named instance variable.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 3
3:   def attr_internal_reader(*attrs)
4:     attrs.each do |attr|
5:       module_eval "def #{attr}() #{attr_internal_ivar_name(attr)} end"
6:     end
7:   end
attr_internal_writer(*attrs)

Declares an attribute writer backed by an internally-named instance variable.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 10
10:   def attr_internal_writer(*attrs)
11:     attrs.each do |attr|
12:       module_eval "def #{attr}=(v) #{attr_internal_ivar_name(attr)} = v end"
13:     end
14:   end
delegate(*methods)

Provides a delegate class method to easily expose contained objects’ methods as your own. Pass one or more methods (specified as symbols or strings) and the name of the target object as the final :to option (also a symbol or string). At least one method and the :to option are required.

Delegation is particularly useful with Active Record associations:

  class Greeter < ActiveRecord::Base
    def hello()   "hello"   end
    def goodbye() "goodbye" end
  end

  class Foo < ActiveRecord::Base
    belongs_to :greeter
    delegate :hello, :to => :greeter
  end

  Foo.new.hello   # => "hello"
  Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>

Multiple delegates to the same target are allowed:

  class Foo < ActiveRecord::Base
    belongs_to :greeter
    delegate :hello, :goodbye, :to => :greeter
  end

  Foo.new.goodbye # => "goodbye"

Methods can be delegated to instance variables, class variables, or constants by providing them as a symbols:

  class Foo
    CONSTANT_ARRAY = [0,1,2,3]
    @@class_array  = [4,5,6,7]

    def initialize
      @instance_array = [8,9,10,11]
    end
    delegate :sum, :to => :CONSTANT_ARRAY
    delegate :min, :to => :@@class_array
    delegate :max, :to => :@instance_array
  end

  Foo.new.sum # => 6
  Foo.new.min # => 4
  Foo.new.max # => 11

Delegates can optionally be prefixed using the :prefix option. If the value is true, the delegate methods are prefixed with the name of the object being delegated to.

  Person = Struct.new(:name, :address)

  class Invoice < Struct.new(:client)
    delegate :name, :address, :to => :client, :prefix => true
  end

  john_doe = Person.new("John Doe", "Vimmersvej 13")
  invoice = Invoice.new(john_doe)
  invoice.client_name    # => "John Doe"
  invoice.client_address # => "Vimmersvej 13"

It is also possible to supply a custom prefix.

  class Invoice < Struct.new(:client)
    delegate :name, :address, :to => :client, :prefix => :customer
  end

  invoice = Invoice.new(john_doe)
  invoice.customer_name    # => "John Doe"
  invoice.customer_address # => "Vimmersvej 13"

If the object to which you delegate can be nil, you may want to use the :allow_nil option. In that case, it returns nil instead of raising a NoMethodError exception:

 class Foo
   attr_accessor :bar
   def initialize(bar = nil)
     @bar = bar
   end
   delegate :zoo, :to => :bar
 end

 Foo.new.zoo   # raises NoMethodError exception (you called nil.zoo)

 class Foo
   attr_accessor :bar
   def initialize(bar = nil)
     @bar = bar
   end
   delegate :zoo, :to => :bar, :allow_nil => true
 end

 Foo.new.zoo   # returns nil

[Source]

     # File vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb, line 99
 99:   def delegate(*methods)
100:     options = methods.pop
101:     unless options.is_a?(Hash) && to = options[:to]
102:       raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
103:     end
104:
105:     if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/
106:       raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
107:     end
108:
109:     prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
110:
111:     allow_nil = options[:allow_nil] && "#{to} && "
112:
113:     methods.each do |method|
114:       module_eval("def \#{prefix}\#{method}(*args, &block)                           # def customer_name(*args, &block)\n\#{allow_nil}\#{to}.__send__(\#{method.inspect}, *args, &block)  #   client && client.__send__(:name, *args, &block)\nend                                                             # end\n", "(__DELEGATION__)", 1)
115:     end
116:   end
included_in_classes()

Returns the classes in the current ObjectSpace where this module has been mixed in according to Module#included_modules.

  module M
  end

  module N
    include M
  end

  class C
    include M
  end

  class D < C
  end

  p M.included_in_classes # => [C, D]

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/inclusion.rb, line 21
21:   def included_in_classes
22:     classes = []
23:     ObjectSpace.each_object(Class) { |k| classes << k if k.included_modules.include?(self) }
24:
25:     classes.reverse.inject([]) do |unique_classes, klass|
26:       unique_classes << klass unless unique_classes.collect { |k| k.to_s }.include?(klass.to_s)
27:       unique_classes
28:     end
29:   end
mattr_accessor(*syms)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 56
56:   def mattr_accessor(*syms)
57:     mattr_reader(*syms)
58:     mattr_writer(*syms)
59:   end
mattr_reader(*syms)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 14
14:   def mattr_reader(*syms)
15:     syms.each do |sym|
16:       next if sym.is_a?(Hash)
17:       class_eval("unless defined? @@\#{sym}  # unless defined? @@pagination_options\n@@\#{sym} = nil          #   @@pagination_options = nil\nend                       # end\n#\ndef self.\#{sym}           # def self.pagination_options\n@@\#{sym}                #   @@pagination_options\nend                       # end\n#\ndef \#{sym}                # def pagination_options\n@@\#{sym}                #   @@pagination_options\nend                       # end\n", __FILE__, __LINE__)
18:     end
19:   end
mattr_writer(*syms)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 34
34:   def mattr_writer(*syms)
35:     options = syms.extract_options!
36:     syms.each do |sym|
37:       class_eval("unless defined? @@\#{sym}                       # unless defined? @@pagination_options\n@@\#{sym} = nil                               #   @@pagination_options = nil\nend                                            # end\n#\ndef self.\#{sym}=(obj)                          # def self.pagination_options=(obj)\n@@\#{sym} = obj                               #   @@pagination_options = obj\nend                                            # end\n#\n\#{\"                                            #\ndef \#{sym}=(obj)                               # def pagination_options=(obj)\n@@\#{sym} = obj                               #   @@pagination_options = obj\nend                                            # end\n\" unless options[:instance_writer] == false }  # # instance writer above is generated unless options[:instance_writer] == false\n", __FILE__, __LINE__)
38:     end
39:   end
synchronize(*methods)

Synchronize access around a method, delegating synchronization to a particular mutex. A mutex (either a Mutex, or any object that responds to synchronize and yields to a block) must be provided as a final :with option. The :with option should be a symbol or string, and can represent a method, constant, or instance or class variable. Example:

  class SharedCache
    @@lock = Mutex.new
    def expire
      ...
    end
    synchronize :expire, :with => :@@lock
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/module/synchronization.rb, line 15
15:   def synchronize(*methods)
16:     options = methods.extract_options!
17:     unless options.is_a?(Hash) && with = options[:with]
18:       raise ArgumentError, "Synchronization needs a mutex. Supply an options hash with a :with key as the last argument (e.g. synchronize :hello, :with => :@mutex)."
19:     end
20:
21:     methods.each do |method|
22:       aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
23:
24:       if method_defined?("#{aliased_method}_without_synchronization#{punctuation}")
25:         raise ArgumentError, "#{method} is already synchronized. Double synchronization is not currently supported."
26:       end
27:
28:       module_eval("def \#{aliased_method}_with_synchronization\#{punctuation}(*args, &block)     # def expire_with_synchronization(*args, &block)\n\#{with}.synchronize do                                                    #   @@lock.synchronize do\n\#{aliased_method}_without_synchronization\#{punctuation}(*args, &block)  #     expire_without_synchronization(*args, &block)\nend                                                                       #   end\nend                                                                         # end\n", __FILE__, __LINE__)
29:
30:       alias_method_chain method, :synchronization
31:     end
32:   end


Class: Object

Class | Object
In: | vendor/rails/railties/lib/rails_generator/lookup.rb vendor/rails/actionpack/lib/action_controller/routing/routing_ext.rb vendor/rails/activesupport/lib/active_support/core_ext/blank.rb vendor/rails/activesupport/lib/active_support/core_ext/duplicable.rb vendor/rails/activesupport/lib/active_support/core_ext/kernel/agnostics.rb vendor/rails/activesupport/lib/active_support/core_ext/object/conversions.rb vendor/rails/activesupport/lib/active_support/core_ext/object/extending.rb vendor/rails/activesupport/lib/active_support/core_ext/object/instance_variables.rb vendor/rails/activesupport/lib/active_support/core_ext/object/metaclass.rb vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb vendor/rails/activesupport/lib/active_support/core_ext/try.rb vendor/rails/activesupport/lib/active_support/json/encoders/object.rb vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb
Parent: | Object

Same as above, except in Object.

Methods

acts_like? blank? class_eval duplicable? find_hidden_method instance_exec instance_variable_defined? instance_variable_names lookup_missing_generator metaclass method_added present? returning tap to_json to_param to_param to_query try with_options

Included Modules

InstanceExecMethods

External Aliases

__send__ | -> | try
method_added | -> | blank_slate_method_added

Public Class methods

find_hidden_method(name)

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 90
90:     def find_hidden_method(name)
91:       nil
92:     end
lookup_missing_generator(class_id)

Lookup missing generators using const_missing. This allows any generator to reference another without having to know its location: RubyGems, ~/.rails/generators, and RAILS_ROOT/generators.

[Source]

    # File vendor/rails/railties/lib/rails_generator/lookup.rb, line 10
10:     def lookup_missing_generator(class_id)
11:       if md = /(.+)Generator$/.match(class_id.to_s)
12:         name = md.captures.first.demodulize.underscore
13:         Rails::Generator::Base.lookup(name).klass
14:       else
15:         const_missing_before_generators(class_id)
16:       end
17:     end
method_added(name)

Detect method additions to Object and remove them in the BlankSlate class.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/blankslate.rb, line 83
83:     def method_added(name)
84:       result = blank_slate_method_added(name)
85:       return result if self != Object
86:       BlankSlate.hide(name)
87:       result
88:     end

Public Instance methods

acts_like?(duck)

A duck-type assistant method. For example, Active Support extends Date to define an acts_like_date? method, and extends Time to define acts_like_time?. As a result, we can do "x.acts_like?(:time)" and "x.acts_like?(:date)" to do duck-type-safe comparisons, since classes that we want to act like Time simply need to define an acts_like_time? method.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb, line 86
86:   def acts_like?(duck)
87:     respond_to? "acts_like_#{duck}?"
88:   end
blank?()

An object is blank if it‘s false, empty, or a whitespace string. For example, "", " ", nil, [], and {} are blank.

This simplifies

  if !address.nil? && !address.empty?

to

  if !address.blank?

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/blank.rb, line 12
12:   def blank?
13:     respond_to?(:empty?) ? empty? : !self
14:   end
class_eval(*args, &block)

If class_eval is called on an object, add those methods to its metaclass

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/metaclass.rb, line 10
10:   def class_eval(*args, &block)
11:     metaclass.class_eval(*args, &block)
12:   end
duplicable?()

Can you safely .dup this object? False for nil, false, true, symbols, and numbers; true otherwise.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/duplicable.rb, line 4
4:   def duplicable?
5:     true
6:   end
instance_exec(*args, &block)

Evaluate the block with the given arguments within the context of this object, so self is set to the method receiver.

From Mauricio‘s eigenclass.org/hiki/bounded+space+instance_exec

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/extending.rb, line 63
63:     def instance_exec(*args, &block)
64:       begin
65:         old_critical, Thread.critical = Thread.critical, true
66:         n = 0
67:         n += 1 while respond_to?(method_name = "__instance_exec#{n}")
68:         InstanceExecMethods.module_eval { define_method(method_name, &block) }
69:       ensure
70:         Thread.critical = old_critical
71:       end
72:
73:       begin
74:         send(method_name, *args)
75:       ensure
76:         InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
77:       end
78:     end
instance_variable_defined?(variable)

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 4
4:     def instance_variable_defined?(variable)
5:       instance_variables.include?(variable.to_s)
6:     end
instance_variable_names()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 37
37:     def instance_variable_names
38:       instance_variables.map { |var| var.to_s }
39:     end
metaclass()

Get object‘s meta (ghost, eigenclass, singleton) class

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/object/metaclass.rb, line 3
3:   def metaclass
4:     class << self
5:       self
6:     end
7:   end
present?()

An object is present if it‘s not blank.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/blank.rb, line 17
17:   def present?
18:     !blank?
19:   end
returning(value) {|value| ...}

Returns value after yielding value to the block. This simplifies the process of constructing an object, performing work on the object, and then returning the object from a method. It is a Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.

Examples

 # Without returning
 def foo
   values = []
   values << "bar"
   values << "baz"
   return values
 end

 foo # => ['bar', 'baz']

 # returning with a local variable
 def foo
   returning values = [] do
     values << 'bar'
     values << 'baz'
   end
 end

 foo # => ['bar', 'baz']

 # returning with a block argument
 def foo
   returning [] do |values|
     values << 'bar'
     values << 'baz'
   end
 end

 foo # => ['bar', 'baz']

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb, line 38
38:   def returning(value)
39:     yield(value)
40:     value
41:   end
tap() {|self| ...}

Yields x to the block, and then returns x. The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.

  (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
    tap    { |x| puts "array: #{x.inspect}" }.
    select { |x| x%2 == 0 }.
    tap    { |x| puts "evens: #{x.inspect}" }.
    map    { |x| x*x }.
    tap    { |x| puts "squares: #{x.inspect}" }

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb, line 53
53:   def tap
54:     yield self
55:     self
56:   end
to_json(options = {})

Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.

[Source]

   # File vendor/rails/activesupport/lib/active_support/json/encoders/object.rb, line 3
3:   def to_json(options = {})
4:     ActiveSupport::JSON.encode(instance_values, options)
5:   end
to_param()

[Source]

   # File vendor/rails/actionpack/lib/action_controller/routing/routing_ext.rb, line 2
2:   def to_param
3:     to_s
4:   end
to_param()

Alias of to_s.

[Source]

   # File vendor/rails/activesupport/lib/active_support/core_ext/object/conversions.rb, line 3
3:   def to_param
4:     to_s
5:   end
to_query(key)

Converts an object into a string suitable for use as a URL query string, using the given key as the param name.

Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/conversions.rb, line 11
11:   def to_query(key)
12:     require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
13:     "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
14:   end
try(method, *args, &block)

Invokes the method identified by the symbol method, passing it any arguments and/or the block specified, just like the regular Ruby Object#send does.

Unlike that method however, a NoMethodError exception will not be raised and nil will be returned instead, if the receiving object is a nil object or NilClass.

Examples

Without try

  @person && @person.name

or

  @person ? @person.name : nil

With try

  @person.try(:name)

try also accepts arguments and/or a block, for the method it is trying

  Person.try(:find, 1)
  @people.try(:collect) {|p| p.name}

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/try.rb, line 25
25:   def try(method, *args, &block)
26:     send(method, *args, &block)
27:   end
with_options(options) {|ActiveSupport::OptionMerger.new(self, options)| ...}

An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. Each method called on the block variable must take an options hash as its final argument.

  with_options :order => 'created_at', :class_name => 'Comment' do |post|
    post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
    post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
    post.has_many :all_comments
  end

Can also be used with an explicit receiver:

  map.with_options :controller => "people" do |people|
    people.connect "/people",     :action => "index"
    people.connect "/people/:id", :action => "show"
  end

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb, line 77
77:   def with_options(options)
78:     yield ActiveSupport::OptionMerger.new(self, options)
79:   end


Class: PGresult

Class | PGresult
In: | vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
Parent: | Object

External Aliases

num_fields | -> | nfields
num_tuples | -> | ntuples
type | -> | ftype
cmdtuples | -> | cmd_tuples


Class: Plugin

Class | Plugin
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

find git_url? info install installed? new svn_url? to_s uninstall

Attributes

name | [R]
uri | [R]

Public Class methods

find(name)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 164
164:   def self.find(name)
165:     name =~ /\// ? new(name) : Repositories.instance.find_plugin(name)
166:   end
new(uri, name=nil)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 159
159:   def initialize(uri, name=nil)
160:     @uri = uri
161:     guess_name(uri)
162:   end

Public Instance methods

git_url?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 176
176:   def git_url?
177:     @uri =~ /^git:\/\// || @uri =~ /\.git$/
178:   end
info()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 217
217:   def info
218:     tmp = "#{rails_env.root}/_tmp_about.yml"
219:     if svn_url?
220:       cmd = "svn export #{@uri} \"#{rails_env.root}/#{tmp}\""
221:       puts cmd if $verbose
222:       system(cmd)
223:     end
224:     open(svn_url? ? tmp : File.join(@uri, 'about.yml')) do |stream|
225:       stream.read
226:     end rescue "No about.yml found in #{uri}"
227:   ensure
228:     FileUtils.rm_rf tmp if svn_url?
229:   end
install(method=nil, options = {})

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 185
185:   def install(method=nil, options = {})
186:     method ||= rails_env.best_install_method?
187:     if :http == method
188:       method = :export if svn_url?
189:       method = :git    if git_url?
190:     end
191:
192:     uninstall if installed? and options[:force]
193:
194:     unless installed?
195:       send("install_using_#{method}", options)
196:       run_install_hook
197:     else
198:       puts "already installed: #{name} (#{uri}).  pass --force to reinstall"
199:     end
200:   end
installed?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 180
180:   def installed?
181:     File.directory?("#{rails_env.root}/vendor/plugins/#{name}") \
182:       or rails_env.externals.detect{ |name, repo| self.uri == repo }
183:   end
svn_url?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 172
172:   def svn_url?
173:     @uri =~ /svn(?:\+ssh)?:\/\/*/
174:   end
to_s()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 168
168:   def to_s
169:     "#{@name.ljust(30)}#{@uri}"
170:   end
uninstall()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 202
202:   def uninstall
203:     path = "#{rails_env.root}/vendor/plugins/#{name}"
204:     if File.directory?(path)
205:       puts "Removing 'vendor/plugins/#{name}'" if $verbose
206:       run_uninstall_hook
207:       rm_r path
208:     else
209:       puts "Plugin doesn't exist: #{path}"
210:     end
211:     # clean up svn:externals
212:     externals = rails_env.externals
213:     externals.reject!{|n,u| name == n or name == u}
214:     rails_env.externals = externals
215:   end


Module: Process

Module | Process
In: | vendor/rails/activesupport/lib/active_support/core_ext/process/daemon.rb

Methods

daemon

Public Class methods

daemon(nochdir = nil, noclose = nil)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/process/daemon.rb, line 3
 3:     def self.daemon(nochdir = nil, noclose = nil)
 4:       exit if fork                     # Parent exits, child continues.
 5:       Process.setsid                   # Become session leader.
 6:       exit if fork                     # Zap session leader. See [1].
 7:
 8:       unless nochdir
 9:         Dir.chdir "/"                  # Release old working directory.
10:       end
11:
12:       File.umask 0000                  # Ensure sensible umask. Adjust as needed.
13:
14:       unless noclose
15:         STDIN.reopen "/dev/null"       # Free file descriptors and
16:         STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
17:         STDERR.reopen '/dev/null', 'a'
18:       end
19:
20:       trap("TERM") { exit }
21:
22:       return 0
23:     end


Module: REXML

Module | REXML
In: | vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb

Classes and Modules

Class REXML::Document
Class REXML::Entity


Class: REXML::Document

Class | REXML::Document
In: | vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb
Parent: | Element

Methods

entity_expansion_limit= record_entity_expansion!

Public Class methods

entity_expansion_limit=(val)

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb, line 27
27:         def self.entity_expansion_limit= val
28:           @@entity_expansion_limit = val
29:         end

Public Instance methods

record_entity_expansion!()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb, line 31
31:         def record_entity_expansion!
32:           @number_of_expansions ||= 0
33:           @number_of_expansions += 1
34:           if @number_of_expansions > @@entity_expansion_limit
35:             raise "Number of entity expansions exceeded, processing aborted."
36:           end
37:         end


Class: REXML::Entity

Class | REXML::Entity
In: | vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb
Parent: | Child

Methods

unnormalized

Public Instance methods

unnormalized()

[Source]

    # File vendor/rails/activesupport/lib/active_support/core_ext/rexml.rb, line 17
17:         def unnormalized
18:           document.record_entity_expansion! if document
19:           v = value()
20:           return nil if v.nil?
21:           @unnormalized = Text::unnormalize(v, parent)
22:           @unnormalized
23:         end


Module: Rack
In: vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb

The Rack main module, serving as a namespace for all core Rack modules and classes.

All modules meant for use in your application are autoloaded here, so it should be enough just to require rack.rb in your code.

Methods

call release version

Classes and Modules

Module Rack::Adapter
Module Rack::Auth
Module Rack::Handler
Module Rack::Mime
Module Rack::Session
Module Rack::Utils
Class Rack::Builder
Class Rack::Cascade
Class Rack::Chunked
Class Rack::CommonLogger
Class Rack::ConditionalGet
Class Rack::ContentLength
Class Rack::ContentType
Class Rack::Deflater
Class Rack::Directory
Class Rack::File
Class Rack::ForwardRequest
Class Rack::Head
Class Rack::Lint
Class Rack::Lobster
Class Rack::Lock
Class Rack::MethodOverride
Class Rack::MockRequest
Class Rack::MockResponse
Class Rack::Recursive
Class Rack::Reloader
Class Rack::Request
Class Rack::Response
Class Rack::ShowExceptions
Class Rack::ShowStatus
Class Rack::Static
Class Rack::URLMap

Constants

VERSION = [0,1] The Rack protocol version number implemented.

Public Class methods

release()

Return the Rack release as a dotted string.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb, line 25
25:   def self.release
26:     "1.0 bundled"
27:   end
version()

Return the Rack protocol version as a dotted string.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb, line 20
20:   def self.version
21:     VERSION.join(".")
22:   end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb, line 32
32:     def call(env)
33:       req = Request.new(env)
34:       if req.GET["flip"] == "left"
35:         lobster = LobsterString.split("\n").
36:           map { |line| line.ljust(42).reverse }.
37:           join("\n")
38:         href = "?flip=right"
39:       elsif req.GET["flip"] == "crash"
40:         raise "Lobster crashed"
41:       else
42:         lobster = LobsterString
43:         href = "?flip=left"
44:       end
45:
46:       res = Response.new
47:       res.write "<title>Lobstericious!</title>"
48:       res.write "<pre>"
49:       res.write lobster
50:       res.write "</pre>"
51:       res.write "<p><a href='#{href}'>flip!</a></p>"
52:       res.write "<p><a href='?flip=crash'>crash!</a></p>"
53:       res.finish
54:     end


Module: Rack::Adapter

Module | Rack::Adapter
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb

Adapters connect Rack with third party web frameworks.

Rack includes an adapter for Camping, see README for other frameworks supporting Rack in their code bases.

Refer to the submodules for framework-specific calling details.

Classes and Modules

Class Rack::Adapter::Camping


Class: Rack::Adapter::Camping

Class | Rack::Adapter::Camping
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb, line 4
4:       def initialize(app)
5:         @app = app
6:       end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb, line 8
 8:       def call(env)
 9:         env["PATH_INFO"] ||= ""
10:         env["SCRIPT_NAME"] ||= ""
11:         controller = @app.run(env['rack.input'], env)
12:         h = controller.headers
13:         h.each_pair do |k,v|
14:           if v.kind_of? URI
15:             h[k] = v.to_s
16:           end
17:         end
18:         [controller.status, controller.headers, [controller.body.to_s]]
19:       end


Module: Rack::Auth

Module | Rack::Auth
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb

Classes and Modules

Module Rack::Auth::Digest
Class Rack::Auth::AbstractHandler
Class Rack::Auth::AbstractRequest
Class Rack::Auth::Basic
Class Rack::Auth::OpenID
Class Rack::Auth::OpenIDAuth


Class: Rack::Auth::AbstractHandler

Class | Rack::Auth::AbstractHandler
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
Parent: | Object

Rack::Auth::AbstractHandler implements common authentication functionality.

realm should be set for all handlers.

Methods

new

Attributes

realm [RW]

Public Class methods

new(app, realm=nil, &authenticator)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb, line 11
11:       def initialize(app, realm=nil, &authenticator)
12:         @app, @realm, @authenticator = app, realm, authenticator
13:       end


Class: Rack::Auth::AbstractRequest

Class | Rack::Auth::AbstractRequest
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb
Parent: | Object

Methods

new params parts provided? scheme

Constants

AUTHORIZATION_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION']

Public Class methods

new(env)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb, line 5
5:       def initialize(env)
6:         @env = env
7:       end

Public Instance methods

params()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb, line 21
21:       def params
22:         @params ||= parts.last
23:       end
parts()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb, line 13
13:       def parts
14:         @parts ||= @env[authorization_key].split(' ', 2)
15:       end
provided?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb, line 9
 9:       def provided?
10:         !authorization_key.nil?
11:       end
scheme()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb, line 17
17:       def scheme
18:         @scheme ||= parts.first.downcase.to_sym
19:       end


Class: Rack::Auth::Basic

Class | Rack::Auth::Basic
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb
Parent: | AbstractHandler

Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617.

Initialize with the Rack application that you want protecting, and a block that checks if a username and password pair are valid.

See also: example/protectedlobster.rb

Methods

call

Classes and Modules

Class Rack::Auth::Basic::Request

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb, line 15
15:       def call(env)
16:         auth = Basic::Request.new(env)
17:
18:         return unauthorized unless auth.provided?
19:
20:         return bad_request unless auth.basic?
21:
22:         if valid?(auth)
23:           env['REMOTE_USER'] = auth.username
24:
25:           return @app.call(env)
26:         end
27:
28:         unauthorized
29:       end


Class: Rack::Auth::Basic::Request

Class | Rack::Auth::Basic::Request
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb
Parent: | Auth::AbstractRequest

Methods

basic? credentials username

Public Instance methods

basic?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb, line 43
43:         def basic?
44:           :basic == scheme
45:         end
credentials()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb, line 47
47:         def credentials
48:           @credentials ||= params.unpack("m*").first.split(/:/, 2)
49:         end
username()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb, line 51
51:         def username
52:           credentials.first
53:         end


Module: Rack::Auth::Digest

Module | Rack::Auth::Digest
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb

Classes and Modules

Class Rack::Auth::Digest::MD5
Class Rack::Auth::Digest::Nonce
Class Rack::Auth::Digest::Params
Class Rack::Auth::Digest::Request


Class: Rack::Auth::Digest::MD5

Class | Rack::Auth::Digest::MD5
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
Parent: | AbstractHandler

Rack::Auth::Digest::MD5 implements the MD5 algorithm version of HTTP Digest Authentication, as per RFC 2617.

Initialize with the [Rack] application that you want protecting, and a block that looks up a plaintext password for a given username.

opaque needs to be set to a constant base64/hexadecimal string.

Methods

call new passwords_hashed?

Constants

QOP = 'auth'.freeze

Attributes

opaque | [RW]
passwords_hashed | [W]

Public Class methods

new(*args)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb, line 24
24:         def initialize(*args)
25:           super
26:           @passwords_hashed = nil
27:         end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb, line 33
33:         def call(env)
34:           auth = Request.new(env)
35:
36:           unless auth.provided?
37:             return unauthorized
38:           end
39:
40:           if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth)
41:             return bad_request
42:           end
43:
44:           if valid?(auth)
45:             if auth.nonce.stale?
46:               return unauthorized(challenge(:stale => true))
47:             else
48:               env['REMOTE_USER'] = auth.username
49:
50:               return @app.call(env)
51:             end
52:           end
53:
54:           unauthorized
55:         end
passwords_hashed?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb, line 29
29:         def passwords_hashed?
30:           !!@passwords_hashed
31:         end


Class: Rack::Auth::Digest::Nonce

Class | Rack::Auth::Digest::Nonce
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb
Parent: | Object

Rack::Auth::Digest::Nonce is the default nonce generator for the Rack::Auth::Digest::MD5 authentication handler.

private_key needs to set to a constant string.

time_limit can be optionally set to an integer (number of seconds), to limit the validity of the generated nonces.

Methods

digest fresh? new parse stale? to_s valid?

Attributes

private_key | [RW]
time_limit | [RW]

Public Class methods

new(timestamp = Time.now, given_digest = nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 24
24:         def initialize(timestamp = Time.now, given_digest = nil)
25:           @timestamp, @given_digest = timestamp.to_i, given_digest
26:         end
parse(string)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 20
20:         def self.parse(string)
21:           new(*string.unpack("m*").first.split(' ', 2))
22:         end

Public Instance methods

digest()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 32
32:         def digest
33:           ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
34:         end
fresh?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 44
44:         def fresh?
45:           !stale?
46:         end
stale?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 40
40:         def stale?
41:           !self.class.time_limit.nil? && (@timestamp - Time.now.to_i) < self.class.time_limit
42:         end
to_s()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 28
28:         def to_s
29:           [([ @timestamp, digest ] * ' ')].pack("m*").strip
30:         end
valid?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb, line 36
36:         def valid?
37:           digest == @given_digest
38:         end


Class: Rack::Auth::Digest::Params

Class | Rack::Auth::Digest::Params
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb
Parent: | Hash

Methods

[] []= dequote new parse quote split_header_value to_s

Constants

UNQUOTED = ['qop', 'nc', 'stale']

Public Class methods

dequote(str)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 14
14:         def self.dequote(str) # From WEBrick::HTTPUtils
15:           ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
16:           ret.gsub!(/\\(.)/, "\\1")
17:           ret
18:         end
new() {|self if block_given?| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 24
24:         def initialize
25:           super
26:
27:           yield self if block_given?
28:         end
parse(str)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 6
 6:         def self.parse(str)
 7:           split_header_value(str).inject(new) do |header, param|
 8:             k, v = param.split('=', 2)
 9:             header[k] = dequote(v)
10:             header
11:           end
12:         end
split_header_value(str)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 20
20:         def self.split_header_value(str)
21:           str.scan( /(\w+\=(?:"[^\"]+"|[^,]+))/n ).collect{ |v| v[0] }
22:         end

Public Instance methods

[](k)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 30
30:         def [](k)
31:           super k.to_s
32:         end
[]=(k, v)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 34
34:         def []=(k, v)
35:           super k.to_s, v.to_s
36:         end
quote(str)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 47
47:         def quote(str) # From WEBrick::HTTPUtils
48:           '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
49:         end
to_s()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb, line 40
40:         def to_s
41:           inject([]) do |parts, (k, v)|
42:             parts << "#{k}=" + (UNQUOTED.include?(k) ? v.to_s : quote(v))
43:             parts
44:           end.join(', ')
45:         end


Class: Rack::Auth::Digest::Request

Class | Rack::Auth::Digest::Request
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
Parent: | Auth::AbstractRequest

Methods

correct_uri? digest? method method_missing nonce params

Public Instance methods

correct_uri?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 18
18:         def correct_uri?
19:           (@env['SCRIPT_NAME'].to_s + @env['PATH_INFO'].to_s) == uri
20:         end
digest?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 14
14:         def digest?
15:           :digest == scheme
16:         end
method()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 10
10:         def method
11:           @env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD']
12:         end
method_missing(sym)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 30
30:         def method_missing(sym)
31:           if params.has_key? key = sym.to_s
32:             return params[key]
33:           end
34:           super
35:         end
nonce()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 22
22:         def nonce
23:           @nonce ||= Nonce.parse(params['nonce'])
24:         end
params()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb, line 26
26:         def params
27:           @params ||= Params.parse(parts.last)
28:         end


Class: Rack::Auth::OpenID

Class | Rack::Auth::OpenID
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
Parent: | Object

Rack::Auth::OpenID provides a simple method for setting up an OpenID Consumer. It requires the ruby-openid library from janrain to operate, as well as a rack method of session management.

The ruby-openid home page is at openidenabled.com/ruby-openid/.

The OpenID specifications can be found at openid.net/specs/openid-authentication-1_1.html and openid.net/specs/openid-authentication-2_0.html. Documentation for published OpenID extensions and related topics can be found at openid.net/developers/specs/.

It is recommended to read through the OpenID spec, as well as ruby-openid‘s documentation, to understand what exactly goes on. However a setup as simple as the presented examples is enough to provide Consumer functionality.

This library strongly intends to utilize the OpenID 2.0 features of the ruby-openid library, which provides OpenID 1.0 compatiblity.

NOTE: Due to the amount of data that this library stores in the session, Rack::Session::Cookie may fault.

Methods

access_denied add_extension bad_request call check confirm_post_params finish foreign_server_failure include? new redirect unauthorized valid_extension? within_realm?

Classes and Modules

Class Rack::Auth::OpenID::BadExtension
Class Rack::Auth::OpenID::NoSession

Constants

ValidStatus = [:success, :setup_needed, :cancel, :failure] Required for ruby-openid

Attributes

extensions | [R]
immediate | [R]
openid_param | [R]
realm | [R]
return_to | [R]
session_key | [R]
store | [R]

Public Class methods

new(realm, options={})

Arguments

The first argument is the realm, identifying the site they are trusting with their identity. This is required, also treated as the trust_root in OpenID 1.x exchanges.

The optional second argument is a hash of options.

Options

:return_to defines the url to return to after the client authenticates with the openid service provider. This url should point to where Rack::Auth::OpenID is mounted. If :return_to is not provided, return_to will be the current url which allows flexibility with caveats.

:session_key defines the key to the session hash in the env. It defaults to ‘rack.session’.

:openid_param defines at what key in the request parameters to find the identifier to resolve. As per the 2.0 spec, the default is ‘openid_identifier’.

:store defined what OpenID Store to use for persistant information. By default a Store::Memory will be used.

:immediate as true will make initial requests to be of an immediate type. This is false by default. See OpenID specification documentation.

:extensions should be a hash of openid extension implementations. The key should be the extension main module, the value should be an array of arguments for extension::Request.new. The hash is iterated over and passed to add_extension for processing. Please see add_extension for further documentation.

Examples

  simple_oid = OpenID.new('http://mysite.com/')

  return_oid = OpenID.new('http://mysite.com/', {
    :return_to => 'http://mysite.com/openid'
  })

  complex_oid = OpenID.new('http://mysite.com/',
    :immediate => true,
    :extensions => {
      ::OpenID::SReg => [['email'],['nickname']]
    }
  )

Advanced

Most of the functionality of this library is encapsulated such that expansion and overriding functions isn‘t difficult nor tricky. Alternately, to avoid opening up singleton objects or subclassing, a wrapper rack middleware can be composed to act upon Auth::OpenID‘s responses. See check and finish for locations of pertinent data.

Responses

To change the responses that Auth::OpenID returns, override the methods redirect, bad_request, unauthorized, access_denied, and foreign_server_failure.

Additionally confirm_post_params is used when the URI would exceed length limits on a GET request when doing the initial verification request.

Processing

To change methods of processing completed transactions, override the methods success, setup_needed, cancel, and failure. Please ensure the returned object is a rack compatible response.

The first argument is an OpenID::Response, the second is a Rack::Request of the current request, the last is the hash used in ruby-openid handling, which can be found manually at env[:openid].

This is useful if you wanted to expand the processing done, such as setting up user accounts.

  oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
  def oid_app.success oid, request, session
    user = Models::User[oid.identity_url]
    user ||= Models::User.create_from_openid oid
    request['rack.session'][:user] = user.id
    redirect MyApp.site_home
  end

  site_map['/openid'] = oid_app
  map = Rack::URLMap.new site_map
  ...

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 151
151:       def initialize(realm, options={})
152:         realm = URI(realm)
153:         raise ArgumentError, "Invalid realm: #{realm}" \
154:           unless realm.absolute? \
155:           and realm.fragment.nil? \
156:           and realm.scheme =~ /^https?$/ \
157:           and realm.host =~ /^(\*\.)?#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+/
158:         realm.path = '/' if realm.path.empty?
159:         @realm = realm.to_s
160:
161:         if ruri = options[:return_to]
162:           ruri = URI(ruri)
163:           raise ArgumentError, "Invalid return_to: #{ruri}" \
164:             unless ruri.absolute? \
165:             and ruri.scheme  =~ /^https?$/ \
166:             and ruri.fragment.nil?
167:           raise ArgumentError, "return_to #{ruri} not within realm #{realm}" \
168:             unless self.within_realm?(ruri)
169:           @return_to = ruri.to_s
170:         end
171:
172:         @session_key  = options[:session_key]   || 'rack.session'
173:         @openid_param = options[:openid_param]  || 'openid_identifier'
174:         @store        = options[:store]         || ::OpenID::Store::Memory.new
175:         @immediate    = !!options[:immediate]
176:
177:         @extensions = {}
178:         if extensions = options.delete(:extensions)
179:           extensions.each do |ext, args|
180:             add_extension ext, *args
181:           end
182:         end
183:
184:         # Undocumented, semi-experimental
185:         @anonymous    = !!options[:anonymous]
186:       end

Public Instance methods

add_extension(ext, *args)

The first argument should be the main extension module. The extension module should contain the constants:

  * class Request, should have OpenID::Extension as an ancestor
  * class Response, should have OpenID::Extension as an ancestor
  * string NS_URI, which defining the namespace of the extension

All trailing arguments will be passed to extension::Request.new in check. The openid response will be passed to extension::Response#from_success_response, get_extension_args will be called on the result to attain the gathered data.

This method returns the key at which the response data will be found in the session, which is the namespace uri by default.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 312
312:       def add_extension(ext, *args)
313:         raise BadExtension unless valid_extension?(ext)
314:         extensions[ext] = args
315:         return ext::NS_URI
316:       end
call(env)

Sets up and uses session data at :openid within the session. Errors in this setup will raise a NoSession exception.

If the parameter ‘openid.mode’ is set, which implies a followup from the openid server, processing is passed to finish and the result is returned. However, if there is no appropriate openid information in the session, a 400 error is returned.

If the parameter specified by options[:openid_param] is present, processing is passed to check and the result is returned.

If neither of these conditions are met, unauthorized is called.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 204
204:       def call(env)
205:         env['rack.auth.openid'] = self
206:         env_session = env[@session_key]
207:         unless env_session and env_session.is_a?(Hash)
208:           raise NoSession, 'No compatible session'
209:         end
210:         # let us work in our own namespace...
211:         session = (env_session[:openid] ||= {})
212:         unless session and session.is_a?(Hash)
213:           raise NoSession, 'Incompatible openid session'
214:         end
215:
216:         request = Rack::Request.new(env)
217:         consumer = ::OpenID::Consumer.new(session, @store)
218:
219:         if mode = request.GET['openid.mode']
220:           if session.key?(:openid_param)
221:             finish(consumer, session, request)
222:           else
223:             bad_request
224:           end
225:         elsif request.GET[@openid_param]
226:           check(consumer, session, request)
227:         else
228:           unauthorized
229:         end
230:       end
check(consumer, session, req)

As the first part of OpenID consumer action, check retrieves the data required for completion.

If all parameters fit within the max length of a URI, a 303 redirect will be returned. Otherwise confirm_post_params will be called.

Any messages from OpenID‘s request are logged to env

env is the openid checkid request instance.

session[:openid_param] is set to the openid identifier provided by the user.

session[:return_to] is set to the return_to uri given to the identity provider.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 249
249:       def check(consumer, session, req)
250:         oid = consumer.begin(req.GET[@openid_param], @anonymous)
251:         req.env['rack.auth.openid.request'] = oid
252:         req.env['rack.errors'].puts(oid.message)
253:         p oid if $DEBUG
254:
255:         ## Extension support
256:         extensions.each do |ext,args|
257:           oid.add_extension(ext::Request.new(*args))
258:         end
259:
260:         session[:openid_param] = req.GET[openid_param]
261:         return_to_uri = return_to ? return_to : req.url
262:         session[:return_to] = return_to_uri
263:         immediate = session.key?(:setup_needed) ? false : immediate
264:
265:         if oid.send_redirect?(realm, return_to_uri, immediate)
266:           uri = oid.redirect_url(realm, return_to_uri, immediate)
267:           redirect(uri)
268:         else
269:           confirm_post_params(oid, realm, return_to_uri, immediate)
270:         end
271:       rescue ::OpenID::DiscoveryFailure => e
272:         # thrown from inside OpenID::Consumer#begin by yadis stuff
273:         req.env['rack.errors'].puts([e.message, *e.backtrace]*"\n")
274:         return foreign_server_failure
275:       end
finish(consumer, session, req)

This is the final portion of authentication. If successful, a redirect to the realm is be returned. Data gathered from extensions are stored in session[:openid] with the extension‘s namespace uri as the key.

Any messages from OpenID‘s response are logged to env

env will contain the openid response.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 287
287:       def finish(consumer, session, req)
288:         oid = consumer.complete(req.GET, req.url)
289:         req.env['rack.auth.openid.response'] = oid
290:         req.env['rack.errors'].puts(oid.message)
291:         p oid if $DEBUG
292:
293:         raise unless ValidStatus.include?(oid.status)
294:         __send__(oid.status, oid, req, session)
295:       end
include?(uri)

Alias for within_realm?

valid_extension?(ext)

Checks the validitity, in the context of usage, of a submitted extension.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 321
321:       def valid_extension?(ext)
322:         if not %w[NS_URI Request Response].all?{|c| ext.const_defined?(c) }
323:           raise ArgumentError, 'Extension is missing constants.'
324:         elsif not ext::Response.respond_to?(:from_success_response)
325:           raise ArgumentError, 'Response is missing required method.'
326:         end
327:         return true
328:       rescue
329:         return false
330:       end
within_realm?(uri)

Checks the provided uri to ensure it‘d be considered within the realm. is currently not compatible with wildcard realms.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 335
335:       def within_realm? uri
336:         uri = URI.parse(uri.to_s)
337:         realm = URI.parse(self.realm)
338:         return false unless uri.absolute?
339:         return false unless uri.path[0, realm.path.size] == realm.path
340:         return false unless uri.host == realm.host or realm.host[/^\*\./]
341:         # for wildcard support, is awkward with URI limitations
342:         realm_match = Regexp.escape(realm.host).
343:           sub(/^\*\./,"^#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+.")+'$'
344:         return false unless uri.host.match(realm_match)
345:         return true
346:       end

Protected Instance methods

access_denied()

Returns a basic access denied 403 response.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 389
389:       def access_denied
390:         [ 403, {'Content-Type' => 'text/plain', 'Content-Length' => '14'},
391:           ['Access denied.'] ]
392:       end
bad_request()

Returns an empty 400 response.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 375
375:       def bad_request
376:         [ 400, {'Content-Type'=>'text/plain', 'Content-Length'=>'0'},
377:           [''] ]
378:       end
confirm_post_params(oid, realm, return_to, immediate)

Returns an html form page for posting to an Identity Provider if the GET request would exceed the upper URI length limit.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 356
356:       def confirm_post_params(oid, realm, return_to, immediate)
357:         Rack::Response.new.finish do |r|
358:           r.write '<html><head><title>Confirm...</title></head><body>'
359:           r.write oid.form_markup(realm, return_to, immediate)
360:           r.write '</body></html>'
361:         end
362:       end
foreign_server_failure()

Returns a 503 response to be used if communication with the remote OpenID server fails.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 397
397:       def foreign_server_failure
398:         [ 503, {'Content-Type'=>'text/plain', 'Content-Length' => '23'},
399:           ['Foreign server failure.'] ]
400:       end
redirect(uri)

Returns a 303 redirect with the destination of that provided by the argument.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 367
367:       def redirect(uri)
368:         [ 303, {'Content-Length'=>'0', 'Content-Type'=>'text/plain',
369:           'Location' => uri},
370:           [] ]
371:       end
unauthorized()

Returns a basic unauthorized 401 response.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 382
382:       def unauthorized
383:         [ 401, {'Content-Type' => 'text/plain', 'Content-Length' => '13'},
384:           ['Unauthorized.'] ]
385:       end


Class: Rack::Auth::OpenID::BadExtension

Class | Rack::Auth::OpenID::BadExtension
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
Parent: | RuntimeError


Class: Rack::Auth::OpenID::NoSession

Class | Rack::Auth::OpenID::NoSession
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
Parent: | RuntimeError


Class: Rack::Auth::OpenIDAuth

Class | Rack::Auth::OpenIDAuth
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb
Parent: | Rack::Auth::AbstractHandler

A class developed out of the request to use OpenID as an authentication middleware. The request will be sent to the OpenID instance unless the block evaluates to true. For example in rackup, you can use it as such:

  use Rack::Session::Pool
  use Rack::Auth::OpenIDAuth, realm, openid_options do |env|
    env['rack.session'][:authkey] == a_string
  end
  run RackApp

Or simply:

  app = Rack::Auth::OpenIDAuth.new app, realm, openid_options, &auth

Methods

call new

Attributes

oid [R]

Public Class methods

new(app, realm, options={}, &auth)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 469
469:       def initialize(app, realm, options={}, &auth)
470:         @oid = OpenID.new(realm, options)
471:         super(app, &auth)
472:       end

Public Instance methods

call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 474
474:       def call(env)
475:         to = auth.call(env) ? @app : @oid
476:         to.call env
477:       end


Class: Rack::Builder

Class | Rack::Builder
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
Parent: | Object

Rack::Builder implements a small DSL to iteratively construct Rack applications.

Example:

 app = Rack::Builder.new {
   use Rack::CommonLogger
   use Rack::ShowExceptions
   map "/lobster" do
     use Rack::Lint
     run Rack::Lobster.new
   end
 }

Or

 app = Rack::Builder.app do
   use Rack::CommonLogger
   lambda { |env| [200, {'Content-Type' => 'text/plain'}, 'OK'] }
 end

use adds a middleware to the stack, run dispatches to an application. You can use map to construct a Rack::URLMap in a convenient way.

Methods

app call map new run to_app use

Public Class methods

app(&block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 32
32:     def self.app(&block)
33:       self.new(&block).to_app
34:     end
new(&block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 27
27:     def initialize(&block)
28:       @ins = []
29:       instance_eval(&block) if block_given?
30:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 59
59:     def call(env)
60:       to_app.call(env)
61:     end
map(path, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 44
44:     def map(path, &block)
45:       if @ins.last.kind_of? Hash
46:         @ins.last[path] = self.class.new(&block).to_app
47:       else
48:         @ins << {}
49:         map(path, &block)
50:       end
51:     end
run(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 40
40:     def run(app)
41:       @ins << app #lambda { |nothing| app }
42:     end
to_app()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 53
53:     def to_app
54:       @ins[-1] = Rack::URLMap.new(@ins.last)  if Hash === @ins.last
55:       inner_app = @ins.last
56:       @ins[0...-1].reverse.inject(inner_app) { |a, e| e.call(a) }
57:     end
use(middleware, *args, &block)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb, line 36
36:     def use(middleware, *args, &block)
37:       @ins << lambda { |app| middleware.new(app, *args, &block) }
38:     end


Class: Rack::Cascade

Class | Rack::Cascade
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb
Parent: | Object

Rack::Cascade tries an request on several apps, and returns the first response that is not 404 (or in a list of configurable status codes).

Methods

<< add call include? new

Attributes

apps [R]

Public Class methods

new(apps, catch=404)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb, line 9
 9:     def initialize(apps, catch=404)
10:       @apps = apps
11:       @catch = [*catch]
12:     end

Public Instance methods

<<(app)

Alias for add

add(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb, line 26
26:     def add app
27:       @apps << app
28:     end
call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb, line 14
14:     def call(env)
15:       status = headers = body = nil
16:       raise ArgumentError, "empty cascade"  if @apps.empty?
17:       @apps.each { |app|
18:         begin
19:           status, headers, body = app.call(env)
20:           break  unless @catch.include?(status.to_i)
21:         end
22:       }
23:       [status, headers, body]
24:     end
include?(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/cascade.rb, line 30
30:     def include? app
31:       @apps.include? app
32:     end


Class: Rack::Chunked

Class | Rack::Chunked
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
Parent: | Object

Middleware that applies chunked transfer encoding to response bodies when the response does not include a Content-Length header.

Methods

call chunk close each new

Included Modules

Rack::Utils

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb, line 10
10:     def initialize(app)
11:       @app = app
12:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb, line 14
14:     def call(env)
15:       status, headers, body = @app.call(env)
16:       headers = HeaderHash.new(headers)
17:
18:       if env['HTTP_VERSION'] == 'HTTP/1.0' ||
19:          STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
20:          headers['Content-Length'] ||
21:          headers['Transfer-Encoding']
22:         [status, headers.to_hash, body]
23:       else
24:         dup.chunk(status, headers, body)
25:       end
26:     end
chunk(status, headers, body)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb, line 28
28:     def chunk(status, headers, body)
29:       @body = body
30:       headers.delete('Content-Length')
31:       headers['Transfer-Encoding'] = 'chunked'
32:       [status, headers.to_hash, self]
33:     end
close()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb, line 45
45:     def close
46:       @body.close if @body.respond_to?(:close)
47:     end
each() {|[size.to_s(16), term, chunk, term].join| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb, line 35
35:     def each
36:       term = "\r\n"
37:       @body.each do |chunk|
38:         size = bytesize(chunk)
39:         next if size == 0
40:         yield [size.to_s(16), term, chunk, term].join
41:       end
42:       yield ["0", term, "", term].join
43:     end


Class: Rack::CommonLogger

Class | Rack::CommonLogger
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb
Parent: | Object

Rack::CommonLogger forwards every request to an app given, and logs a line in the Apache common log format to the logger, or rack.errors by default.

Methods

<< _call call close each new

Public Class methods

new(app, logger=nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 7
 7:     def initialize(app, logger=nil)
 8:       @app = app
 9:       @logger = logger
10:     end

Public Instance methods

<<(str)

By default, log to rack.errors.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 29
29:     def <<(str)
30:       @env["rack.errors"].write(str)
31:       @env["rack.errors"].flush
32:     end
_call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 16
16:     def _call(env)
17:       @env = env
18:       @logger ||= self
19:       @time = Time.now
20:       @status, @header, @body = @app.call(env)
21:       [@status, @header, self]
22:     end
call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 12
12:     def call(env)
13:       dup._call(env)
14:     end
close()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 24
24:     def close
25:       @body.close if @body.respond_to? :close
26:     end
each() {|part| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb, line 34
34:     def each
35:       length = 0
36:       @body.each { |part|
37:         length += part.size
38:         yield part
39:       }
40:
41:       @now = Time.now
42:
43:       # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
44:       # lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
45:       #             %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
46:       @logger << %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n} %
47:         [
48:          @env['HTTP_X_FORWARDED_FOR'] || @env["REMOTE_ADDR"] || "-",
49:          @env["REMOTE_USER"] || "-",
50:          @now.strftime("%d/%b/%Y %H:%M:%S"),
51:          @env["REQUEST_METHOD"],
52:          @env["PATH_INFO"],
53:          @env["QUERY_STRING"].empty? ? "" : "?"+@env["QUERY_STRING"],
54:          @env["HTTP_VERSION"],
55:          @status.to_s[0..3],
56:          (length.zero? ? "-" : length.to_s),
57:          @now - @time
58:         ]
59:     end


Class: Rack::ConditionalGet

Class | Rack::ConditionalGet
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb
Parent: | Object

Middleware that enables conditional GET using If-None-Match and If-Modified-Since. The application should set either or both of the Last-Modified or Etag response headers according to RFC 2616. When either of the conditions is met, the response body is set to be zero length and the response status is set to 304 Not Modified.

Applications that defer response body generation until the body‘s each message is received will avoid response body generation completely when a conditional GET matches.

Adapted from Michael Klishin‘s Merb implementation: github.com/wycats/merb-core/tree/master/lib/merb-core/rack/middleware/conditional_get.rb

Methods

call new

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb, line 18
18:     def initialize(app)
19:       @app = app
20:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb, line 22
22:     def call(env)
23:       return @app.call(env) unless %w[GET HEAD].include?(env['REQUEST_METHOD'])
24:
25:       status, headers, body = @app.call(env)
26:       headers = Utils::HeaderHash.new(headers)
27:       if etag_matches?(env, headers) || modified_since?(env, headers)
28:         status = 304
29:         body = []
30:       end
31:       [status, headers, body]
32:     end


Class: Rack::ContentLength

Class | Rack::ContentLength
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
Parent: | Object

Sets the Content-Length header on responses with fixed-length bodies.

Methods

call new

Included Modules

Rack::Utils

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb, line 8
 8:     def initialize(app)
 9:       @app = app
10:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb, line 12
12:     def call(env)
13:       status, headers, body = @app.call(env)
14:       headers = HeaderHash.new(headers)
15:
16:       if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
17:          !headers['Content-Length'] &&
18:          !headers['Transfer-Encoding'] &&
19:          (body.respond_to?(:to_ary) || body.respond_to?(:to_str))
20:
21:         body = [body] if body.respond_to?(:to_str) # rack 0.4 compat
22:         length = body.to_ary.inject(0) { |len, part| len + bytesize(part) }
23:         headers['Content-Length'] = length.to_s
24:       end
25:
26:       [status, headers, body]
27:     end


Class: Rack::ContentType

Class | Rack::ContentType
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
Parent: | Object

Sets the Content-Type header on responses which don‘t have one.

Builder Usage:

  use Rack::ContentType, "text/plain"

When no content type argument is provided, "text/html" is assumed.

Methods

call new

Public Class methods

new(app, content_type = "text/html")

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb, line 12
12:     def initialize(app, content_type = "text/html")
13:       @app, @content_type = app, content_type
14:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb, line 16
16:     def call(env)
17:       status, headers, body = @app.call(env)
18:       headers = Utils::HeaderHash.new(headers)
19:       headers['Content-Type'] ||= @content_type
20:       [status, headers.to_hash, body]
21:     end


Class: Rack::Deflater

Class | Rack::Deflater
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
Parent: | Object

Methods

call deflate gzip new

Constants

DEFLATE_ARGS = [ Zlib::DEFAULT_COMPRESSION, # drop the zlib header which causes both Safari and IE to choke -Zlib::MAX_WBITS, Zlib::DEF_MEM_LEVEL, Zlib::DEFAULT_STRATEGY

Public Class methods

deflate(body)

Loosely based on Mongrel‘s Deflate handler

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb, line 76
76:     def self.deflate(body)
77:       deflater = Zlib::Deflate.new(*DEFLATE_ARGS)
78:
79:       # TODO: Add streaming
80:       body.each { |part| deflater << part }
81:
82:       return deflater.finish
83:     end
gzip(body, mtime)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb, line 55
55:     def self.gzip(body, mtime)
56:       io = StringIO.new
57:       gzip = Zlib::GzipWriter.new(io)
58:       gzip.mtime = mtime
59:
60:       # TODO: Add streaming
61:       body.each { |part| gzip << part }
62:
63:       gzip.close
64:       return io.string
65:     end
new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb, line 8
 8:     def initialize(app)
 9:       @app = app
10:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb, line 12
12:     def call(env)
13:       status, headers, body = @app.call(env)
14:       headers = Utils::HeaderHash.new(headers)
15:
16:       # Skip compressing empty entity body responses and responses with
17:       # no-transform set.
18:       if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
19:           headers['Cache-Control'].to_s =~ /\bno-transform\b/
20:         return [status, headers, body]
21:       end
22:
23:       request = Request.new(env)
24:
25:       encoding = Utils.select_best_encoding(%w(gzip deflate identity),
26:                                             request.accept_encoding)
27:
28:       # Set the Vary HTTP header.
29:       vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
30:       unless vary.include?("*") || vary.include?("Accept-Encoding")
31:         headers["Vary"] = vary.push("Accept-Encoding").join(",")
32:       end
33:
34:       case encoding
35:       when "gzip"
36:         mtime = headers.key?("Last-Modified") ?
37:           Time.httpdate(headers["Last-Modified"]) : Time.now
38:         body = self.class.gzip(body, mtime)
39:         size = Rack::Utils.bytesize(body)
40:         headers = headers.merge("Content-Encoding" => "gzip", "Content-Length" => size.to_s)
41:         [status, headers, [body]]
42:       when "deflate"
43:         body = self.class.deflate(body)
44:         size = Rack::Utils.bytesize(body)
45:         headers = headers.merge("Content-Encoding" => "deflate", "Content-Length" => size.to_s)
46:         [status, headers, [body]]
47:       when "identity"
48:         [status, headers, body]
49:       when nil
50:         message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found."
51:         [406, {"Content-Type" => "text/plain", "Content-Length" => message.length.to_s}, [message]]
52:       end
53:     end


Class: Rack::Directory

Class | Rack::Directory
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
Parent: | Object

Rack::Directory serves entries below the root given, according to the path info of the Rack request. If a directory is found, the file‘s contents will be presented in an html based index. If a file is found, the env will be passed to the specified app.

If app is not specified, a Rack::File of the same root will be used.

Methods

_call call check_forbidden each entity_not_found filesize_format list_directory list_path new stat

Constants

DIR_FILE | = | "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>"
DIR_PAGE | = | <<-PAGE <html><head> <title>%s</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <style type='text/css'> table { width:100%%; } .name { text-align:left; } .size, .mtime { text-align:right; } .type { width:11em; } .mtime { width:15em; } </style> </head><body> <h1>%s</h1> <hr /> <table> <tr> <th class='name'>Name</th> <th class='size'>Size</th> <th class='type'>Type</th> <th class='mtime'>Last Modified</th> </tr> %s </table> <hr /> </body></html> PAGE
F | = | ::File
FILESIZE_FORMAT | = | [ ['%.1fT', 1 << 40], ['%.1fG', 1 << 30], ['%.1fM', 1 << 20], ['%.1fK', 1 << 10], ] | Stolen from Ramaze

Attributes

files | [R]
path | [RW]
root | [RW]

Public Class methods

new(root, app=nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 46
46:     def initialize(root, app=nil)
47:       @root = F.expand_path(root)
48:       @app = app || Rack::File.new(@root)
49:     end

Public Instance methods

_call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 57
57:     def _call(env)
58:       @env = env
59:       @script_name = env['SCRIPT_NAME']
60:       @path_info = Utils.unescape(env['PATH_INFO'])
61:
62:       if forbidden = check_forbidden
63:         forbidden
64:       else
65:         @path = F.join(@root, @path_info)
66:         list_path
67:       end
68:     end
call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 51
51:     def call(env)
52:       dup._call(env)
53:     end
check_forbidden()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 70
70:     def check_forbidden
71:       return unless @path_info.include? ".."
72:
73:       body = "Forbidden\n"
74:       size = Rack::Utils.bytesize(body)
75:       return [403, {"Content-Type" => "text/plain","Content-Length" => size.to_s}, [body]]
76:     end
each() {|l| ...}

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 130
130:     def each
131:       show_path = @path.sub(/^#{@root}/,'')
132:       files = @files.map{|f| DIR_FILE % f }*"\n"
133:       page  = DIR_PAGE % [ show_path, show_path , files ]
134:       page.each_line{|l| yield l }
135:     end
entity_not_found()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 124
124:     def entity_not_found
125:       body = "Entity not found: #{@path_info}\n"
126:       size = Rack::Utils.bytesize(body)
127:       return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
128:     end
filesize_format(int)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 146
146:     def filesize_format(int)
147:       FILESIZE_FORMAT.each do |format, size|
148:         return format % (int.to_f / size) if int >= size
149:       end
150:
151:       int.to_s + 'B'
152:     end
list_directory()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 78
 78:     def list_directory
 79:       @files = [['../','Parent Directory','','','']]
 80:       glob = F.join(@path, '*')
 81:
 82:       Dir[glob].sort.each do |node|
 83:         stat = stat(node)
 84:         next  unless stat
 85:         basename = F.basename(node)
 86:         ext = F.extname(node)
 87:
 88:         url = F.join(@script_name, @path_info, basename)
 89:         size = stat.size
 90:         type = stat.directory? ? 'directory' : Mime.mime_type(ext)
 91:         size = stat.directory? ? '-' : filesize_format(size)
 92:         mtime = stat.mtime.httpdate
 93:         url << '/'  if stat.directory?
 94:         basename << '/'  if stat.directory?
 95:
 96:         @files << [ url, basename, size, type, mtime ]
 97:       end
 98:
 99:       return [ 200, {'Content-Type'=>'text/html; charset=utf-8'}, self ]
100:     end
list_path()

TODO: add correct response if not readable, not sure if 404 is the best

      option

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 110
110:     def list_path
111:       @stat = F.stat(@path)
112:
113:       if @stat.readable?
114:         return @app.call(@env) if @stat.file?
115:         return list_directory if @stat.directory?
116:       else
117:         raise Errno::ENOENT, 'No such file or directory'
118:       end
119:
120:     rescue Errno::ENOENT, Errno::ELOOP
121:       return entity_not_found
122:     end
stat(node, max = 10)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb, line 102
102:     def stat(node, max = 10)
103:       F.stat(node)
104:     rescue Errno::ENOENT, Errno::ELOOP
105:       return nil
106:     end


Class: Rack::File

Class | Rack::File
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
Parent: | Object

Rack::File serves files below the root given, according to the path info of the Rack request.

Handlers can detect if bodies are a Rack::File, and use mechanisms like sendfile on the path.

Methods

_call call each forbidden new not_found serving

Constants

F = ::File

External Aliases

path -> to_path

Attributes

path | [RW]
root | [RW]

Public Class methods

new(root)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 18
18:     def initialize(root)
19:       @root = root
20:     end

Public Instance methods

_call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 28
28:     def _call(env)
29:       @path_info = Utils.unescape(env["PATH_INFO"])
30:       return forbidden  if @path_info.include? ".."
31:
32:       @path = F.join(@root, @path_info)
33:
34:       begin
35:         if F.file?(@path) && F.readable?(@path)
36:           serving
37:         else
38:           raise Errno::EPERM
39:         end
40:       rescue SystemCallError
41:         not_found
42:       end
43:     end
call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 22
22:     def call(env)
23:       dup._call(env)
24:     end
each() {|part| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 80
80:     def each
81:       F.open(@path, "rb") { |file|
82:         while part = file.read(8192)
83:           yield part
84:         end
85:       }
86:     end
forbidden()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 45
45:     def forbidden
46:       body = "Forbidden\n"
47:       [403, {"Content-Type" => "text/plain",
48:              "Content-Length" => body.size.to_s},
49:        [body]]
50:     end
not_found()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 73
73:     def not_found
74:       body = "File not found: #{@path_info}\n"
75:       [404, {"Content-Type" => "text/plain",
76:          "Content-Length" => body.size.to_s},
77:        [body]]
78:     end
serving()

NOTE:

  We check via File::size? whether this file provides size info
  via stat (e.g. /proc files often don't), otherwise we have to
  figure it out by reading the whole file into memory. And while
  we're at it we also use this as body then.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb, line 58
58:     def serving
59:       if size = F.size?(@path)
60:         body = self
61:       else
62:         body = [F.read(@path)]
63:         size = Utils.bytesize(body.first)
64:       end
65:
66:       [200, {
67:         "Last-Modified"  => F.mtime(@path).httpdate,
68:         "Content-Type"   => Mime.mime_type(F.extname(@path), 'text/plain'),
69:         "Content-Length" => size.to_s
70:       }, body]
71:     end


Class: Rack::ForwardRequest

Class | Rack::ForwardRequest
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb
Parent: | Exception

Rack::ForwardRequest gets caught by Rack::Recursive and redirects the current request to the app at url.

  raise ForwardRequest.new("/not-found")

Methods

new

Attributes

env | [R]
url | [R]

Public Class methods

new(url, env={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb, line 13
13:     def initialize(url, env={})
14:       @url = URI(url)
15:       @env = env
16:
17:       @env["PATH_INFO"] =       @url.path
18:       @env["QUERY_STRING"] =    @url.query  if @url.query
19:       @env["HTTP_HOST"] =       @url.host   if @url.host
20:       @env["HTTP_PORT"] =       @url.port   if @url.port
21:       @env["rack.url_scheme"] = @url.scheme if @url.scheme
22:
23:       super "forwarding to #{url}"
24:     end


Module: Rack::Handler

Module | Rack::Handler
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb

Handlers connect web servers with Rack.

Rack includes Handlers for Mongrel, WEBrick, FastCGI, CGI, SCGI and LiteSpeed.

Handlers usually are activated by calling MyHandler.run(myapp). A second optional hash can be passed to include server-specific configuration.

Methods

get register

Classes and Modules

Class Rack::Handler::CGI
Class Rack::Handler::EventedMongrel
Class Rack::Handler::FastCGI
Class Rack::Handler::LSWS
Class Rack::Handler::Mongrel
Class Rack::Handler::SCGI
Class Rack::Handler::SwiftipliedMongrel
Class Rack::Handler::Thin
Class Rack::Handler::WEBrick

Public Class methods

get(server)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb, line 11
11:     def self.get(server)
12:       return unless server
13:
14:       if klass = @handlers[server]
15:         obj = Object
16:         klass.split("::").each { |x| obj = obj.const_get(x) }
17:         obj
18:       else
19:         Rack::Handler.const_get(server.capitalize)
20:       end
21:     end
register(server, klass)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler.rb, line 23
23:     def self.register(server, klass)
24:       @handlers ||= {}
25:       @handlers[server] = klass
26:     end


Class: Rack::Handler::CGI

Class | Rack::Handler::CGI
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
Parent: | Object

Methods

run send_body send_headers serve

Public Class methods

run(app, options=nil)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb, line 6
6:       def self.run(app, options=nil)
7:         serve app
8:       end
send_body(body)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb, line 53
53:       def self.send_body(body)
54:         body.each { |part|
55:           STDOUT.print part
56:           STDOUT.flush
57:         }
58:       end
send_headers(status, headers)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb, line 42
42:       def self.send_headers(status, headers)
43:         STDOUT.print "Status: #{status}\r\n"
44:         headers.each { |k, vs|
45:           vs.split("\n").each { |v|
46:             STDOUT.print "#{k}: #{v}\r\n"
47:           }
48:         }
49:         STDOUT.print "\r\n"
50:         STDOUT.flush
51:       end
serve(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb, line 10
10:       def self.serve(app)
11:         app = ContentLength.new(app)
12:
13:         env = ENV.to_hash
14:         env.delete "HTTP_CONTENT_LENGTH"
15:
16:         env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
17:
18:         env.update({"rack.version" => [0,1],
19:                      "rack.input" => $stdin,
20:                      "rack.errors" => $stderr,
21:
22:                      "rack.multithread" => false,
23:                      "rack.multiprocess" => true,
24:                      "rack.run_once" => true,
25:
26:                      "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
27:                    })
28:
29:         env["QUERY_STRING"] ||= ""
30:         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
31:         env["REQUEST_PATH"] ||= "/"
32:
33:         status, headers, body = app.call(env)
34:         begin
35:           send_headers status, headers
36:           send_body body
37:         ensure
38:           body.close  if body.respond_to? :close
39:         end
40:       end


Class: Rack::Handler::EventedMongrel

Class | Rack::Handler::EventedMongrel
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb
Parent: | Handler::Mongrel


Class: Rack::Handler::FastCGI

Class | Rack::Handler::FastCGI
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
Parent: | Object

Methods

run send_body send_headers serve

Public Class methods

run(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb, line 8
 8:       def self.run(app, options={})
 9:         file = options[:File] and STDIN.reopen(UNIXServer.new(file))
10:         port = options[:Port] and STDIN.reopen(TCPServer.new(port))
11:         FCGI.each { |request|
12:           serve request, app
13:         }
14:       end
send_body(out, body)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb, line 81
81:       def self.send_body(out, body)
82:         body.each { |part|
83:           out.print part
84:           out.flush
85:         }
86:       end
send_headers(out, status, headers)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb, line 70
70:       def self.send_headers(out, status, headers)
71:         out.print "Status: #{status}\r\n"
72:         headers.each { |k, vs|
73:           vs.split("\n").each { |v|
74:             out.print "#{k}: #{v}\r\n"
75:           }
76:         }
77:         out.print "\r\n"
78:         out.flush
79:       end
serve(request, app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb, line 32
32:       def self.serve(request, app)
33:         app = Rack::ContentLength.new(app)
34:
35:         env = request.env
36:         env.delete "HTTP_CONTENT_LENGTH"
37:
38:         request.in.extend ProperStream
39:
40:         env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
41:
42:         env.update({"rack.version" => [0,1],
43:                      "rack.input" => request.in,
44:                      "rack.errors" => request.err,
45:
46:                      "rack.multithread" => false,
47:                      "rack.multiprocess" => true,
48:                      "rack.run_once" => false,
49:
50:                      "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
51:                    })
52:
53:         env["QUERY_STRING"] ||= ""
54:         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
55:         env["REQUEST_PATH"] ||= "/"
56:         env.delete "PATH_INFO"  if env["PATH_INFO"] == ""
57:         env.delete "CONTENT_TYPE"  if env["CONTENT_TYPE"] == ""
58:         env.delete "CONTENT_LENGTH"  if env["CONTENT_LENGTH"] == ""
59:
60:         status, headers, body = app.call(env)
61:         begin
62:           send_headers request.out, status, headers
63:           send_body request.out, body
64:         ensure
65:           body.close  if body.respond_to? :close
66:           request.finish
67:         end
68:       end


Class: Rack::Handler::LSWS

Class | Rack::Handler::LSWS
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
Parent: | Object

Methods

run send_body send_headers serve

Public Class methods

run(app, options=nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb, line 7
 7:       def self.run(app, options=nil)
 8:         while LSAPI.accept != nil
 9:           serve app
10:         end
11:       end
send_body(body)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb, line 47
47:       def self.send_body(body)
48:         body.each { |part|
49:           print part
50:           STDOUT.flush
51:         }
52:       end
send_headers(status, headers)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb, line 37
37:       def self.send_headers(status, headers)
38:         print "Status: #{status}\r\n"
39:         headers.each { |k, vs|
40:           vs.split("\n").each { |v|
41:             print "#{k}: #{v}\r\n"
42:           }
43:         }
44:         print "\r\n"
45:         STDOUT.flush
46:       end
serve(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb, line 12
12:       def self.serve(app)
13:         app = Rack::ContentLength.new(app)
14:
15:         env = ENV.to_hash
16:         env.delete "HTTP_CONTENT_LENGTH"
17:         env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
18:         env.update({"rack.version" => [0,1],
19:                      "rack.input" => StringIO.new($stdin.read.to_s),
20:                      "rack.errors" => $stderr,
21:                      "rack.multithread" => false,
22:                      "rack.multiprocess" => true,
23:                      "rack.run_once" => false,
24:                      "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
25:                    })
26:         env["QUERY_STRING"] ||= ""
27:         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
28:         env["REQUEST_PATH"] ||= "/"
29:         status, headers, body = app.call(env)
30:         begin
31:           send_headers status, headers
32:           send_body body
33:         ensure
34:           body.close if body.respond_to? :close
35:         end
36:       end


Class: Rack::Handler::Mongrel

Class | Rack::Handler::Mongrel
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
Parent: | ::Mongrel::HttpHandler

Methods

new process run

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb, line 37
37:       def initialize(app)
38:         @app = Rack::Chunked.new(Rack::ContentLength.new(app))
39:       end
run(app, options={}) {|server if block_given?| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb, line 9
 9:       def self.run(app, options={})
10:         server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
11:                                            options[:Port] || 8080)
12:         # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
13:         # Use is similar to #run, replacing the app argument with a hash of
14:         # { path=>app, ... } or an instance of Rack::URLMap.
15:         if options[:map]
16:           if app.is_a? Hash
17:             app.each do |path, appl|
18:               path = '/'+path unless path[0] == ?/
19:               server.register(path, Rack::Handler::Mongrel.new(appl))
20:             end
21:           elsif app.is_a? URLMap
22:             app.instance_variable_get(:@mapping).each do |(host, path, appl)|
23:              next if !host.nil? && !options[:Host].nil? && options[:Host] != host
24:              path = '/'+path unless path[0] == ?/
25:              server.register(path, Rack::Handler::Mongrel.new(appl))
26:             end
27:           else
28:             raise ArgumentError, "first argument should be a Hash or URLMap"
29:           end
30:         else
31:           server.register('/', Rack::Handler::Mongrel.new(app))
32:         end
33:         yield server  if block_given?
34:         server.run.join
35:       end

Public Instance methods

process(request, response)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb, line 41
41:       def process(request, response)
42:         env = {}.replace(request.params)
43:         env.delete "HTTP_CONTENT_TYPE"
44:         env.delete "HTTP_CONTENT_LENGTH"
45:
46:         env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
47:
48:         env.update({"rack.version" => [0,1],
49:                      "rack.input" => request.body || StringIO.new(""),
50:                      "rack.errors" => $stderr,
51:
52:                      "rack.multithread" => true,
53:                      "rack.multiprocess" => false, # ???
54:                      "rack.run_once" => false,
55:
56:                      "rack.url_scheme" => "http",
57:                    })
58:         env["QUERY_STRING"] ||= ""
59:         env.delete "PATH_INFO"  if env["PATH_INFO"] == ""
60:
61:         status, headers, body = @app.call(env)
62:
63:         begin
64:           response.status = status.to_i
65:           response.send_status(nil)
66:
67:           headers.each { |k, vs|
68:             vs.split("\n").each { |v|
69:               response.header[k] = v
70:             }
71:           }
72:           response.send_header
73:
74:           body.each { |part|
75:             response.write part
76:             response.socket.flush
77:           }
78:         ensure
79:           body.close  if body.respond_to? :close
80:         end
81:       end


Class: Rack::Handler::SCGI

Class | Rack::Handler::SCGI
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
Parent: | ::SCGI::Processor

Methods

new process_request run

Attributes

app [RW]

Public Class methods

new(settings = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb, line 18
18:       def initialize(settings = {})
19:         @app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
20:         @log = Object.new
21:         def @log.info(*args); end
22:         def @log.error(*args); end
23:         super(settings)
24:       end
run(app, options=nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb, line 11
11:       def self.run(app, options=nil)
12:         new(options.merge(:app=>app,
13:                           :host=>options[:Host],
14:                           :port=>options[:Port],
15:                           :socket=>options[:Socket])).listen
16:       end

Public Instance methods

process_request(request, input_body, socket)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb, line 26
26:       def   process_requestprocess_requestprocess_request(request, input_body, socket)
27:         env = {}.replace(request)
28:         env.delete "HTTP_CONTENT_TYPE"
29:         env.delete "HTTP_CONTENT_LENGTH"
30:         env["REQUEST_PATH"], env["QUERY_STRING"] = env["REQUEST_URI"].split('?', 2)
31:         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
32:         env["PATH_INFO"] = env["REQUEST_PATH"]
33:         env["QUERY_STRING"] ||= ""
34:         env["SCRIPT_NAME"] = ""
35:         env.update({"rack.version" => [0,1],
36:                      "rack.input" => StringIO.new(input_body),
37:                      "rack.errors" => $stderr,
38:
39:                      "rack.multithread" => true,
40:                      "rack.multiprocess" => true,
41:                      "rack.run_once" => false,
42:
43:                      "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
44:                    })
45:         status, headers, body = app.call(env)
46:         begin
47:           socket.write("Status: #{status}\r\n")
48:           headers.each do |k, vs|
49:             vs.split("\n").each { |v| socket.write("#{k}: #{v}\r\n")}
50:           end
51:           socket.write("\r\n")
52:           body.each {|s| socket.write(s)}
53:         ensure
54:           body.close if body.respond_to? :close
55:         end
56:       end


Class: Rack::Handler::SwiftipliedMongrel

Class | Rack::Handler::SwiftipliedMongrel
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb
Parent: | Handler::Mongrel


Class: Rack::Handler::Thin

Class | Rack::Handler::Thin
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
Parent: | Object

Methods

run

Public Class methods

run(app, options={}) {|server if block_given?| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb, line 8
 8:       def self.run(app, options={})
 9:         app = Rack::Chunked.new(Rack::ContentLength.new(app))
10:         server = ::Thin::Server.new(options[:Host] || '0.0.0.0',
11:                                     options[:Port] || 8080,
12:                                     app)
13:         yield server if block_given?
14:         server.start
15:       end


Class: Rack::Handler::WEBrick

Class | Rack::Handler::WEBrick
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
Parent: | ::WEBrick::HTTPServlet::AbstractServlet

Methods

new run service

Public Class methods

new(server, app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb, line 16
16:       def initialize(server, app)
17:         super server
18:         @app = Rack::ContentLength.new(app)
19:       end
run(app, options={}) {|server if block_given?| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb, line 8
 8:       def self.run(app, options={})
 9:         server = ::WEBrick::HTTPServer.new(options)
10:         server.mount "/", Rack::Handler::WEBrick, app
11:         trap(:INT) { server.shutdown }
12:         yield server  if block_given?
13:         server.start
14:       end

Public Instance methods

service(req, res)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb, line 21
21:       def service(req, res)
22:         env = req.meta_vars
23:         env.delete_if { |k, v| v.nil? }
24:
25:         env.update({"rack.version" => [0,1],
26:                      "rack.input" => StringIO.new(req.body.to_s),
27:                      "rack.errors" => $stderr,
28:
29:                      "rack.multithread" => true,
30:                      "rack.multiprocess" => false,
31:                      "rack.run_once" => false,
32:
33:                      "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
34:                    })
35:
36:         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
37:         env["QUERY_STRING"] ||= ""
38:         env["REQUEST_PATH"] ||= "/"
39:         if env["PATH_INFO"] == ""
40:           env.delete "PATH_INFO"
41:         else
42:           path, n = req.request_uri.path, env["SCRIPT_NAME"].length
43:           env["PATH_INFO"] = path[n, path.length-n]
44:         end
45:
46:         status, headers, body = @app.call(env)
47:         begin
48:           res.status = status.to_i
49:           headers.each { |k, vs|
50:             if k.downcase == "set-cookie"
51:               res.cookies.concat vs.split("\n")
52:             else
53:               vs.split("\n").each { |v|
54:                 res[k] = v
55:               }
56:             end
57:           }
58:           body.each { |part|
59:             res.body << part
60:           }
61:         ensure
62:           body.close  if body.respond_to? :close
63:         end
64:       end


Class: Rack::Head

Class | Rack::Head
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb
Parent: | Object

Methods

call new

Public Class methods

new(app)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb, line 4
4:   def initialize(app)
5:     @app = app
6:   end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/head.rb, line 8
 8:   def call(env)
 9:     status, headers, body = @app.call(env)
10:
11:     if env["REQUEST_METHOD"] == "HEAD"
12:       [status, headers, []]
13:     else
14:       [status, headers, body]
15:     end
16:   end


Class: Rack::Lint

Class | Rack::Lint
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
Parent: | Object

Rack::Lint validates your application and the requests and responses according to the Rack spec.

Methods

new

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb, line 8
 8:     def initialize(app)
 9:       @app = app
10:     end


Class: Rack::Lobster

Class | Rack::Lobster
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lobster.rb
Parent: | Object

Paste has a Pony, Rack has a Lobster!

Constants

LobsterString | = | Zlib::Inflate.inflate("eJx9kEEOwyAMBO99xd7MAcytUhPlJyj2 P6jy9i4k9EQyGAnBarEXeCBqSkntNXsi/ZCvC48zGQoZKikGrFMZvgS5ZHd+aGWVuWwhVF0 t1drVmiR42HcWNz5w3QanT+2gIvTVCiE1lm1Y0eU4JGmIIbaKwextKn8rvW+p5PIwFl8ZWJ I8jyiTlhTcYXkekJAzTyYN6E08A+dk8voBkAVTJQ==".delete("\n ").unpack("m*")[0])
LambdaLobster | = | lambda { |env| if env["QUERY_STRING"].include?("flip")


Class: Rack::Lock

Class | Rack::Lock
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb
Parent: | Object

Methods

call new

Constants

FLAG = 'rack.multithread'.freeze

Public Class methods

new(app, lock = Mutex.new)

[Source]

   # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb, line 5
5:     def initialize(app, lock = Mutex.new)
6:       @app, @lock = app, lock
7:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/lock.rb, line 9
 9:     def call(env)
10:       old, env[FLAG] = env[FLAG], false
11:       @lock.synchronize { @app.call(env) }
12:     ensure
13:       env[FLAG] = old
14:     end


Class: Rack::MethodOverride

Class | Rack::MethodOverride
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb
Parent: | Object

Methods

call new

Constants

HTTP_METHODS | = | %w(GET HEAD PUT POST DELETE OPTIONS)
METHOD_OVERRIDE_PARAM_KEY | = | "_method".freeze
HTTP_METHOD_OVERRIDE_HEADER | = | "HTTP_X_HTTP_METHOD_OVERRIDE".freeze

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb, line 8
 8:     def initialize(app)
 9:       @app = app
10:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb, line 12
12:     def call(env)
13:       if env["REQUEST_METHOD"] == "POST"
14:         req = Request.new(env)
15:         method = req.POST[METHOD_OVERRIDE_PARAM_KEY] ||
16:           env[HTTP_METHOD_OVERRIDE_HEADER]
17:         method = method.to_s.upcase
18:         if HTTP_METHODS.include?(method)
19:           env["rack.methodoverride.original_method"] = env["REQUEST_METHOD"]
20:           env["REQUEST_METHOD"] = method
21:         end
22:       end
23:
24:       @app.call(env)
25:     end


Module: Rack::Mime

Module | Rack::Mime
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb

Methods

mime_type

Constants

MIME_TYPES = { ".3gp" => "video/3gpp", ".a" => "application/octet-stream", ".ai" => "application/postscript", ".aif" => "audio/x-aiff", ".aiff" => "audio/x-aiff", ".asc" => "application/pgp-signature", ".asf" => "video/x-ms-asf", ".asm" => "text/x-asm", ".asx" => "video/x-ms-asf", ".atom" => "application/atom+xml", ".au" => "audio/basic", ".avi" => "video/x-msvideo", ".bat" => "application/x-msdownload", ".bin" => "application/octet-stream", ".bmp" => "image/bmp", ".bz2" => "application/x-bzip2", ".c" => "text/x-c", ".cab" => "application/vnd.ms-cab-compressed", ".cc" => "text/x-c", ".chm" => "application/vnd.ms-htmlhelp", ".class" => "application/octet-stream", ".com" => "application/x-msdownload", ".conf" => "text/plain", ".cpp" => "text/x-c", ".crt" => "application/x-x509-ca-cert", ".css" => "text/css", ".csv" => "text/csv", ".cxx" => "text/x-c", ".deb" => "application/x-debian-package", ".der" => "application/x-x509-ca-cert", ".diff" => "text/x-diff", ".djv" => "image/vnd.djvu", ".djvu" => "image/vnd.djvu", ".dll" => "application/x-msdownload", ".dmg" => "application/octet-stream", ".doc" => "application/msword", ".dot" => "application/msword", ".dtd" => "application/xml-dtd", ".dvi" => "application/x-dvi", ".ear" => "application/java-archive", ".eml" => "message/rfc822", ".eps" => "application/postscript", ".exe" => "application/x-msdownload", ".f" => "text/x-fortran", ".f77" => "text/x-fortran", ".f90" => "text/x-fortran", ".flv" => "video/x-flv", ".for" => "text/x-fortran", ".gem" => "application/octet-stream", ".gemspec" => "text/x-script.ruby", ".gif" => "image/gif", ".gz" => "application/x-gzip", ".h" => "text/x-c", ".hh" => "text/x-c", ".htm" => "text/html", ".html" => "text/html", ".ico" => "image/vnd.microsoft.icon", ".ics" => "text/calendar", ".ifb" => "text/calendar", ".iso" => "application/octet-stream", ".jar" => "application/java-archive", ".java" => "text/x-java-source", ".jnlp" => "application/x-java-jnlp-file", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".js" => "application/javascript", ".json" => "application/json", ".log" => "text/plain", ".m3u" => "audio/x-mpegurl", ".m4v" => "video/mp4", ".man" => "text/troff", ".mathml" => "application/mathml+xml", ".mbox" => "application/mbox", ".mdoc" => "text/troff", ".me" => "text/troff", ".mid" => "audio/midi", ".midi" => "audio/midi", ".mime" => "message/rfc822", ".mml" => "application/mathml+xml", ".mng" => "video/x-mng", ".mov" => "video/quicktime", ".mp3" => "audio/mpeg", ".mp4" => "video/mp4", ".mp4v" => "video/mp4", ".mpeg" => "video/mpeg", ".mpg" => "video/mpeg", ".ms" => "text/troff", ".msi" => "application/x-msdownload", ".odp" => "application/vnd.oasis.opendocument.presentation", ".ods" => "application/vnd.oasis.opendocument.spreadsheet", ".odt" => "application/vnd.oasis.opendocument.text", ".ogg" => "application/ogg", ".p" => "text/x-pascal", ".pas" => "text/x-pascal", ".pbm" => "image/x-portable-bitmap", ".pdf" => "application/pdf", ".pem" => "application/x-x509-ca-cert", ".pgm" => "image/x-portable-graymap", ".pgp" => "application/pgp-encrypted", ".pkg" => "application/octet-stream", ".pl" => "text/x-script.perl", ".pm" => "text/x-script.perl-module", ".png" => "image/png", ".pnm" => "image/x-portable-anymap", ".ppm" => "image/x-portable-pixmap", ".pps" => "application/vnd.ms-powerpoint", ".ppt" => "application/vnd.ms-powerpoint", ".ps" => "application/postscript", ".psd" => "image/vnd.adobe.photoshop", ".py" => "text/x-script.python", ".qt" => "video/quicktime", ".ra" => "audio/x-pn-realaudio", ".rake" => "text/x-script.ruby", ".ram" => "audio/x-pn-realaudio", ".rar" => "application/x-rar-compressed", ".rb" => "text/x-script.ruby", ".rdf" => "application/rdf+xml", ".roff" => "text/troff", ".rpm" => "application/x-redhat-package-manager", ".rss" => "application/rss+xml", ".rtf" => "application/rtf", ".ru" => "text/x-script.ruby", ".s" => "text/x-asm", ".sgm" => "text/sgml", ".sgml" => "text/sgml", ".sh" => "application/x-sh", ".sig" => "application/pgp-signature", ".snd" => "audio/basic", ".so" => "application/octet-stream", ".svg" => "image/svg+xml", ".svgz" => "image/svg+xml", ".swf" => "application/x-shockwave-flash", ".t" => "text/troff", ".tar" => "application/x-tar", ".tbz" => "application/x-bzip-compressed-tar", ".tcl" => "application/x-tcl", ".tex" => "application/x-tex", ".texi" => "application/x-texinfo", ".texinfo" => "application/x-texinfo", ".text" => "text/plain", ".tif" => "image/tiff", ".tiff" => "image/tiff", ".torrent" => "application/x-bittorrent", ".tr" => "text/troff", ".txt" => "text/plain", ".vcf" => "text/x-vcard", ".vcs" => "text/x-vcalendar", ".vrml" => "model/vrml", ".war" => "application/java-archive", ".wav" => "audio/x-wav", ".wma" => "audio/x-ms-wma", ".wmv" => "video/x-ms-wmv", ".wmx" => "video/x-ms-wmx", ".wrl" => "model/vrml", ".wsdl" => "application/wsdl+xml", ".xbm" => "image/x-xbitmap", ".xhtml" => "application/xhtml+xml", ".xls" => "application/vnd.ms-excel", ".xml" => "application/xml", ".xpm" => "image/x-xpixmap", ".xsl" => "application/xml", ".xslt" => "application/xslt+xml", ".yaml" => "text/yaml", ".yml" => "text/yaml", ".zip" => "application/zip", } List of most common mime-types, selected various sources according to their usefulness in a webserving scope for Ruby users.

To amend this list with your local mime.types list you can use:

    require 'webrick/httputils'
    list = WEBrick::HTTPUtils.load_mime_types('/etc/mime.types')
    Rack::Mime::MIME_TYPES.merge!(list)

To add the list mongrel provides, use:

    require 'mongrel/handlers'
    Rack::Mime::MIME_TYPES.merge!(Mongrel::DirHandler::MIME_TYPES)

Public Instance methods

mime_type(ext, fallback='application/octet-stream')

Returns String with mime type if found, otherwise use fallback. ext should be filename extension in the ’.ext’ format that

      File.extname(file) returns.

fallback may be any object

Also see the documentation for MIME_TYPES

Usage:

    Rack::Mime.mime_type('.foo')

This is a shortcut for:

    Rack::Mime::MIME_TYPES.fetch('.foo', 'application/octet-stream')

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mime.rb, line 16
16:     def mime_type(ext, fallback='application/octet-stream')
17:       MIME_TYPES.fetch(ext, fallback)
18:     end


Class: Rack::MockRequest

Class | Rack::MockRequest
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
Parent: | Object

Rack::MockRequest helps testing your Rack application without actually using HTTP.

After performing a request on a URL with get/post/put/delete, it returns a MockResponse with useful helper methods for effective testing.

You can pass a hash with additional configuration to the get/post/put/delete.

:input: | A String or IO-like to be used as rack.input.
:fatal: | Raise a FatalWarning if the app writes to rack.errors.
:lint: | If true, wrap the application in a Rack::Lint.

Methods

delete env_for get new post put request

Classes and Modules

Class Rack::MockRequest::FatalWarner
Class Rack::MockRequest::FatalWarning

Constants

DEFAULT_ENV = { "rack.version" => [0,1], "rack.input" => StringIO.new, "rack.errors" => StringIO.new, "rack.multithread" => true, "rack.multiprocess" => true, "rack.run_once" => false, }

Public Class methods

env_for(uri="", opts={})

Return the Rack environment used for a request to uri.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 74
 74:     def self.env_for(uri="", opts={})
 75:       uri = URI(uri)
 76:       env = DEFAULT_ENV.dup
 77:
 78:       env["REQUEST_METHOD"] = opts[:method] || "GET"
 79:       env["SERVER_NAME"] = uri.host || "example.org"
 80:       env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
 81:       env["QUERY_STRING"] = uri.query.to_s
 82:       env["PATH_INFO"] = (!uri.path || uri.path.empty?) ? "/" : uri.path
 83:       env["rack.url_scheme"] = uri.scheme || "http"
 84:
 85:       env["SCRIPT_NAME"] = opts[:script_name] || ""
 86:
 87:       if opts[:fatal]
 88:         env["rack.errors"] = FatalWarner.new
 89:       else
 90:         env["rack.errors"] = StringIO.new
 91:       end
 92:
 93:       opts[:input] ||= ""
 94:       if String === opts[:input]
 95:         env["rack.input"] = StringIO.new(opts[:input])
 96:       else
 97:         env["rack.input"] = opts[:input]
 98:       end
 99:
100:       env["CONTENT_LENGTH"] ||= env["rack.input"].length.to_s
101:
102:       opts.each { |field, value|
103:         env[field] = value  if String === field
104:       }
105:
106:       env
107:     end
new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 51
51:     def initialize(app)
52:       @app = app
53:     end

Public Instance methods

delete(uri, opts={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 58
58:     def delete(uri, opts={}) request("DELETE", uri, opts) end
get(uri, opts={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 55
55:     def get(uri, opts={})    request("GET", uri, opts)    end
post(uri, opts={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 56
56:     def post(uri, opts={})   request("POST", uri, opts)   end
put(uri, opts={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 57
57:     def put(uri, opts={})    request("PUT", uri, opts)    end
request(method="GET", uri="", opts={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 60
60:     def request(method="GET", uri="", opts={})
61:       env = self.class.env_for(uri, opts.merge(:method => method))
62:
63:       if opts[:lint]
64:         app = Rack::Lint.new(@app)
65:       else
66:         app = @app
67:       end
68:
69:       errors = env["rack.errors"]
70:       MockResponse.new(*(app.call(env) + [errors]))
71:     end


Class: Rack::MockRequest::FatalWarner

Class | Rack::MockRequest::FatalWarner
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
Parent: | Object

Methods

flush puts string write

Public Instance methods

flush()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 34
34:       def flush
35:       end
puts(warning)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 26
26:       def puts(warning)
27:         raise FatalWarning, warning
28:       end
string()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 37
37:       def string
38:         ""
39:       end
write(warning)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 30
30:       def write(warning)
31:         raise FatalWarning, warning
32:       end


Class: Rack::MockRequest::FatalWarning

Class | Rack::MockRequest::FatalWarning
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
Parent: | RuntimeError


Class: Rack::MockResponse

Class | Rack::MockResponse
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb
Parent: | Object

Rack::MockResponse provides useful helpers for testing your apps. Usually, you don‘t create the MockResponse on your own, but use MockRequest.

Methods

=~ [] match new

Included Modules

Response::Helpers

Attributes

body | [R] | Body
errors | [RW] | Errors
headers | [R] | Headers
original_headers | [R] | Headers
status | [R] | Status

Public Class methods

new(status, headers, body, errors=StringIO.new(""))

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 115
115:     def initialize(status, headers, body, errors=StringIO.new(""))
116:       @status = status.to_i
117:
118:       @original_headers = headers
119:       @headers = Rack::Utils::HeaderHash.new
120:       headers.each { |field, values|
121:         @headers[field] = values
122:         @headers[field] = ""  if values.empty?
123:       }
124:
125:       @body = ""
126:       body.each { |part| @body << part }
127:
128:       @errors = errors.string
129:     end

Public Instance methods

=~(other)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 145
145:     def =~(other)
146:       @body =~ other
147:     end
[](field)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 137
137:     def [](field)
138:       headers[field]
139:     end
match(other)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/mock.rb, line 149
149:     def match(other)
150:       @body.match other
151:     end


Class: Rack::Recursive

Class | Rack::Recursive
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb
Parent: | Object

Rack::Recursive allows applications called down the chain to include data from other applications (by using rack[…] or raise a ForwardRequest to redirect internally.

Methods

call include new

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb, line 33
33:     def initialize(app)
34:       @app = app
35:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb, line 37
37:     def call(env)
38:       @script_name = env["SCRIPT_NAME"]
39:       @app.call(env.merge('rack.recursive.include' => method(:include)))
40:     rescue ForwardRequest => req
41:       call(env.merge(req.env))
42:     end
include(env, path)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/recursive.rb, line 44
44:     def include(env, path)
45:       unless path.index(@script_name) == 0 && (path[@script_name.size] == ?/ ||
46:                                                path[@script_name.size].nil?)
47:         raise ArgumentError, "can only include below #{@script_name}, not #{path}"
48:       end
49:
50:       env = env.merge("PATH_INFO" => path, "SCRIPT_NAME" => @script_name,
51:                       "REQUEST_METHOD" => "GET",
52:                       "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "",
53:                       "rack.input" => StringIO.new(""))
54:       @app.call(env)
55:     end


Class: Rack::Reloader

Class | Rack::Reloader
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb
Parent: | Object

Rack::Reloader checks on every request, but at most every secs seconds, if a file loaded changed, and reloads it, logging to rack.errors.

It is recommended you use ShowExceptions to catch SyntaxErrors etc.

Methods

call new reload!

Public Class methods

new(app, secs=10)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb, line 11
11:     def initialize(app, secs=10)
12:       @app = app
13:       @secs = secs              # reload every @secs seconds max
14:       @last = Time.now
15:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb, line 17
17:     def call(env)
18:       if Time.now > @last + @secs
19:         Thread.exclusive {
20:           reload!(env['rack.errors'])
21:           @last = Time.now
22:         }
23:       end
24:
25:       @app.call(env)
26:     end
reload!(stderr=$stderr)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/reloader.rb, line 28
28:     def reload!(stderr=$stderr)
29:       need_reload = $LOADED_FEATURES.find_all { |loaded|
30:         begin
31:           if loaded =~ /\A[.\/]/  # absolute filename or 1.9
32:             abs = loaded
33:           else
34:             abs = $LOAD_PATH.map { |path| ::File.join(path, loaded) }.
35:                              find { |file| ::File.exist? file }
36:           end
37:
38:           if abs
39:             ::File.mtime(abs) > @last - @secs  rescue false
40:           else
41:             false
42:           end
43:         end
44:       }
45:
46:       need_reload.each { |l|
47:         $LOADED_FEATURES.delete l
48:       }
49:
50:       need_reload.each { |to_load|
51:         begin
52:           if require to_load
53:             stderr.puts "#{self.class}: reloaded `#{to_load}'"
54:           end
55:         rescue LoadError, SyntaxError => e
56:           raise e                 # Possibly ShowExceptions
57:         end
58:       }
59:
60:       stderr.flush
61:       need_reload
62:     end


Class: Rack::Request

Class | Rack::Request
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb
Parent: | Object

Rack::Request provides a convenient interface to a Rack environment. It is stateless, the environment env passed to the constructor will be directly modified.

  req = Rack::Request.new(env)
  req.post?
  req.params["data"]

The environment hash passed will store a reference to the Request object instantiated so that it will only instantiate if an instance of the Request object doesn‘t already exist.

Methods

GET POST [] []= accept_encoding body content_charset content_length content_type cookies delete? form_data? fullpath get? head? host ip media_type media_type_params new new openid_request openid_response params path_info path_info= port post? put? query_string referer referrer request_method scheme script_name script_name= url values_at xhr?

Constants

FORM_DATA_MEDIA_TYPES = [ nil, 'application/x-www-form-urlencoded', 'multipart/form-data' The set of form-data media-types. Requests that do not indicate one of the media types presents in this list will not be eligible for form-data / param parsing.

Attributes

env [R] The environment of the request.

Public Class methods

new(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 20
20:     def self.new(env)
21:       if self == Rack::Request
22:         env["rack.request"] ||= super
23:       else
24:         super
25:       end
26:     end
new(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 28
28:     def initialize(env)
29:       @env = env
30:     end

Public Instance methods

GET()

Returns the data recieved in the query string.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 105
105:     def GET
106:       if @env["rack.request.query_string"] == query_string
107:         @env["rack.request.query_hash"]
108:       else
109:         @env["rack.request.query_string"] = query_string
110:         @env["rack.request.query_hash"]   =
111:           Utils.parse_nested_query(query_string)
112:       end
113:     end
POST()

Returns the data recieved in the request body.

This method support both application/x-www-form-urlencoded and multipart/form-data.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 119
119:     def POST
120:       if @env["rack.request.form_input"].eql? @env["rack.input"]
121:         @env["rack.request.form_hash"]
122:       elsif form_data?
123:         @env["rack.request.form_input"] = @env["rack.input"]
124:         unless @env["rack.request.form_hash"] =
125:             Utils::Multipart.parse_multipart(env)
126:           form_vars = @env["rack.input"].read
127:
128:           # Fix for Safari Ajax postings that always append \0
129:           form_vars.sub!(/\0\z/, '')
130:
131:           @env["rack.request.form_vars"] = form_vars
132:           @env["rack.request.form_hash"] = Utils.parse_nested_query(form_vars)
133:
134:           begin
135:             @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
136:           rescue Errno::ESPIPE
137:             # Handles exceptions raised by input streams that cannot be rewound
138:             # such as when using plain CGI under Apache
139:           end
140:         end
141:         @env["rack.request.form_hash"]
142:       else
143:         {}
144:       end
145:     end
[](key)

shortcut for request.params[key]

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 155
155:     def [](key)
156:       params[key.to_s]
157:     end
[]=(key, value)

shortcut for request.params[key] = value

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 160
160:     def []=(key, value)
161:       params[key.to_s] = value
162:     end
accept_encoding()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 221
221:     def accept_encoding
222:       @env["HTTP_ACCEPT_ENCODING"].to_s.split(/,\s*/).map do |part|
223:         m = /^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$/.match(part) # From WEBrick
224:
225:         if m
226:           [m[1], (m[2] || 1.0).to_f]
227:         else
228:           raise "Invalid value for Accept-Encoding: #{part.inspect}"
229:         end
230:       end
231:     end
body()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 32
32:     def body;            @env["rack.input"]                       end
content_charset()

The character set of the request body if a "charset" media type parameter was given, or nil if no "charset" was specified. Note that, per RFC2616, text/* media types that specify no explicit charset are to be considered ISO-8859-1.

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 68
68:     def content_charset
69:       media_type_params['charset']
70:     end
content_length()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 39
39:     def content_length;  @env['CONTENT_LENGTH']                   end
content_type()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 40
40:     def content_type;    @env['CONTENT_TYPE']                     end
cookies()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 176
176:     def cookies
177:       return {}  unless @env["HTTP_COOKIE"]
178:
179:       if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
180:         @env["rack.request.cookie_hash"]
181:       else
182:         @env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
183:         # According to RFC 2109:
184:         #   If multiple cookies satisfy the criteria above, they are ordered in
185:         #   the Cookie header such that those with more specific Path attributes
186:         #   precede those with less specific.  Ordering with respect to other
187:         #   attributes (e.g., Domain) is unspecified.
188:         @env["rack.request.cookie_hash"] =
189:           Utils.parse_query(@env["rack.request.cookie_string"], ';,').inject({}) {|h,(k,v)|
190:             h[k] = Array === v ? v.first : v
191:             h
192:           }
193:       end
194:     end
delete?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 83
83:     def delete?;         request_method == "DELETE"               end
form_data?()

Determine whether the request body contains form-data by checking the request media_type against registered form-data media-types: "application/x-www-form-urlencoded" and "multipart/form-data". The list of form-data media types can be modified through the FORM_DATA_MEDIA_TYPES array.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 100
100:     def form_data?
101:       FORM_DATA_MEDIA_TYPES.include?(media_type)
102:     end
fullpath()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 215
215:     def fullpath
216:       path = script_name + path_info
217:       path << "?" << query_string  unless query_string.empty?
218:       path
219:     end
get?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 80
80:     def get?;            request_method == "GET"                  end
head?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 84
84:     def head?;           request_method == "HEAD"                 end
host()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 72
72:     def host
73:       # Remove port number.
74:       (@env["HTTP_HOST"] || @env["SERVER_NAME"]).gsub(/:\d+\z/, '')
75:     end
ip()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 233
233:     def ip
234:       if addr = @env['HTTP_X_FORWARDED_FOR']
235:         addr.split(',').last.strip
236:       else
237:         @env['REMOTE_ADDR']
238:       end
239:     end
media_type()

The media type (type/subtype) portion of the CONTENT_TYPE header without any media type parameters. e.g., when CONTENT_TYPE is "text/plain;charset=utf-8", the media-type is "text/plain".

For more information on the use of media types in HTTP, see: www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 48
48:     def media_type
49:       content_type && content_type.split(/\s*[;,]\s*/, 2)[0].downcase
50:     end
media_type_params()

The media type parameters provided in CONTENT_TYPE as a Hash, or an empty Hash if no CONTENT_TYPE or media-type parameters were provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8", this method responds with the following Hash:

  { 'charset' => 'utf-8' }

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 57
57:     def media_type_params
58:       return {} if content_type.nil?
59:       content_type.split(/\s*[;,]\s*/)[1..-1].
60:         collect { |s| s.split('=', 2) }.
61:         inject({}) { |hash,(k,v)| hash[k.downcase] = v ; hash }
62:     end
openid_request()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 14
14:     def openid_request
15:       @env['rack.auth.openid.request']
16:     end
openid_response()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb, line 18
18:     def openid_response
19:       @env['rack.auth.openid.response']
20:     end
params()

The union of GET and POST data.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 148
148:     def params
149:       self.put? ? self.GET : self.GET.update(self.POST)
150:     rescue EOFError => e
151:       self.GET
152:     end
path_info()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 35
35:     def path_info;       @env["PATH_INFO"].to_s                   end
path_info=(s)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 78
78:     def path_info=(s);   @env["PATH_INFO"] = s.to_s               end
port()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 36
36:     def port;            @env["SERVER_PORT"].to_i                 end
post?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 81
81:     def post?;           request_method == "POST"                 end
put?()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 82
82:     def put?;            request_method == "PUT"                  end
query_string()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 38
38:     def query_string;    @env["QUERY_STRING"].to_s                end
referer()

the referer of the client or ’/’

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 170
170:     def referer
171:       @env['HTTP_REFERER'] || '/'
172:     end
referrer()

Alias for referer

request_method()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 37
37:     def request_method;  @env["REQUEST_METHOD"]                   end
scheme()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 33
33:     def scheme;          @env["rack.url_scheme"]                  end
script_name()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 34
34:     def script_name;     @env["SCRIPT_NAME"].to_s                 end
script_name=(s)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 77
77:     def script_name=(s); @env["SCRIPT_NAME"] = s.to_s             end
url()

Tries to return a remake of the original request URL as a string.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 201
201:     def url
202:       url = scheme + "://"
203:       url << host
204:
205:       if scheme == "https" && port != 443 ||
206:           scheme == "http" && port != 80
207:         url << ":#{port}"
208:       end
209:
210:       url << fullpath
211:
212:       url
213:     end
values_at(*keys)

like Hash#values_at

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 165
165:     def values_at(*keys)
166:       keys.map{|key| params[key] }
167:     end
xhr?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/request.rb, line 196
196:     def xhr?
197:       @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
198:     end


Class: Rack::Response

Class | Rack::Response
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
Parent: | Object

Rack::Response provides a convenient interface to create a Rack response.

It allows setting of headers and cookies, and provides useful defaults (a OK response containing HTML).

You can use Response#write to iteratively generate your response, but note that this is buffered by Rack::Response until you call finish. finish however can take a block inside which calls to write are syncronous with the Rack response.

Your application‘s call should end returning Response#finish.

Methods

[] []= close delete_cookie each empty? finish new set_cookie to_a write

Included Modules

Helpers

Classes and Modules

Module Rack::Response::Helpers

External Aliases

header -> headers

Attributes

body | [RW]
header | [R]
length | [RW]
status | [RW]

Public Class methods

new(body=[], status=200, header={}) {|self if block_given?| ...}

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 21
21:     def initialize(body=[], status=200, header={}, &block)
22:       @status = status
23:       @header = Utils::HeaderHash.new({"Content-Type" => "text/html"}.
24:                                       merge(header))
25:
26:       @writer = lambda { |x| @body << x }
27:       @block = nil
28:       @length = 0
29:
30:       @body = []
31:
32:       if body.respond_to? :to_str
33:         write body.to_str
34:       elsif body.respond_to?(:each)
35:         body.each { |part|
36:           write part.to_s
37:         }
38:       else
39:         raise TypeError, "stringable or iterable required"
40:       end
41:
42:       yield self  if block_given?
43:     end

Public Instance methods

[](key)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 48
48:     def [](key)
49:       header[key]
50:     end
[]=(key, value)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 52
52:     def []=(key, value)
53:       header[key] = value
54:     end
close()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 130
130:     def close
131:       body.close if body.respond_to?(:close)
132:     end
delete_cookie(key, value={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 84
84:     def delete_cookie(key, value={})
85:       unless Array === self["Set-Cookie"]
86:         self["Set-Cookie"] = [self["Set-Cookie"]].compact
87:       end
88:
89:       self["Set-Cookie"].reject! { |cookie|
90:         cookie =~ /\A#{Utils.escape(key)}=/
91:       }
92:
93:       set_cookie(key,
94:                  {:value => '', :path => nil, :domain => nil,
95:                    :expires => Time.at(0) }.merge(value))
96:     end
each(&callback)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 111
111:     def each(&callback)
112:       @body.each(&callback)
113:       @writer = callback
114:       @block.call(self)  if @block
115:     end
empty?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 134
134:     def empty?
135:       @block == nil && @body.empty?
136:     end
finish(&block)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 99
 99:     def finish(&block)
100:       @block = block
101:
102:       if [204, 304].include?(status.to_i)
103:         header.delete "Content-Type"
104:         [status.to_i, header.to_hash, []]
105:       else
106:         [status.to_i, header.to_hash, self]
107:       end
108:     end
set_cookie(key, value)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 56
56:     def set_cookie(key, value)
57:       case value
58:       when Hash
59:         domain  = "; domain="  + value[:domain]    if value[:domain]
60:         path    = "; path="    + value[:path]      if value[:path]
61:         # According to RFC 2109, we need dashes here.
62:         # N.B.: cgi.rb uses spaces...
63:         expires = "; expires=" + value[:expires].clone.gmtime.
64:           strftime("%a, %d-%b-%Y %H:%M:%S GMT")    if value[:expires]
65:         secure = "; secure"  if value[:secure]
66:         httponly = "; HttpOnly" if value[:httponly]
67:         value = value[:value]
68:       end
69:       value = [value]  unless Array === value
70:       cookie = Utils.escape(key) + "=" +
71:         value.map { |v| Utils.escape v }.join("&") +
72:         "#{domain}#{path}#{expires}#{secure}#{httponly}"
73:
74:       case self["Set-Cookie"]
75:       when Array
76:         self["Set-Cookie"] << cookie
77:       when String
78:         self["Set-Cookie"] = [self["Set-Cookie"], cookie]
79:       when nil
80:         self["Set-Cookie"] = cookie
81:       end
82:     end
to_a(&block)

Alias for finish

write(str)

Append to body and update Content-Length.

NOTE: Do not mix write and direct body access!

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 121
121:     def write(str)
122:       s = str.to_s
123:       @length += s.size
124:       @writer.call s
125:
126:       header["Content-Length"] = @length.to_s
127:       str
128:     end


Module: Rack::Response::Helpers

Module | Rack::Response::Helpers
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb

Methods

client_error? content_length content_type empty? forbidden? include? informational? invalid? location not_found? ok? redirect? redirection? server_error? successful?

Attributes

headers | [R] | Headers
original_headers | [R] | Headers

Public Instance methods

client_error?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 146
146:       def client_error?;  @status >= 400 && @status < 500;       end
content_length()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 167
167:       def content_length
168:         cl = headers["Content-Length"]
169:         cl ? cl.to_i : cl
170:       end
content_type()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 163
163:       def content_type
164:         headers["Content-Type"]
165:       end
empty?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 154
154:       def empty?;         [201, 204, 304].include?      @status; end
forbidden?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 150
150:       def forbidden?;     @status == 403;                        end
include?(header)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 159
159:       def include?(header)
160:         !!headers[header]
161:       end
informational?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 143
143:       def informational?; @status >= 100 && @status < 200;       end
invalid?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 141
141:       def invalid?;       @status < 100 || @status >= 600;       end
location()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 172
172:       def location
173:         headers["Location"]
174:       end
not_found?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 151
151:       def not_found?;     @status == 404;                        end
ok?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 149
149:       def ok?;            @status == 200;                        end
redirect?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 153
153:       def redirect?;      [301, 302, 303, 307].include? @status; end
redirection?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 145
145:       def redirection?;   @status >= 300 && @status < 400;       end
server_error?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 147
147:       def server_error?;  @status >= 500 && @status < 600;       end
successful?()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb, line 144
144:       def successful?;    @status >= 200 && @status < 300;       end


Module: Rack::Session

Module | Rack::Session
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb

Classes and Modules

Module Rack::Session::Abstract
Class Rack::Session::Cookie
Class Rack::Session::Memcache
Class Rack::Session::Pool


Module: Rack::Session::Abstract

Module | Rack::Session::Abstract
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb

Classes and Modules

Class Rack::Session::Abstract::ID


Class: Rack::Session::Abstract::ID

Class | Rack::Session::Abstract::ID
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb
Parent: | Object

ID sets up a basic framework for implementing an id based sessioning service. Cookies sent to the client for maintaining sessions will only contain an id reference. Only get_session and set_session are required to be overwritten.

All parameters are optional.

  • :key determines the name of the cookie, by default it is ‘rack.session‘
  • :path, :domain, :expire_after, :secure, and :httponly set the related cookie options as by Rack::Response#add_cookie
  • :defer will not set a cookie in the response.
  • :renew (implementation dependent) will prompt the generation of a new session id, and migration of data to be referenced at the new id. If :defer is set, it will be overridden and the cookie will be set.
  • :sidbits sets the number of bits in length that a generated session id will be.

These options can be set on a per request basis, at the location of env. Additionally the id of the session can be found within the options hash at the key :id. It is highly not recommended to change its value.

Is Rack::Utils::Context compatible.

Methods

call context new

Constants

DEFAULT_OPTIONS = { :path => '/', :domain => nil, :expire_after => nil, :secure => false, :httponly => true, :defer => false, :renew => false, :sidbits => 128

Attributes

default_options | [R]
key | [R]

Public Class methods

new(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb, line 51
51:         def initialize(app, options={})
52:           @app = app
53:           @key = options[:key] || "rack.session"
54:           @default_options = self.class::DEFAULT_OPTIONS.merge(options)
55:         end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb, line 57
57:         def call(env)
58:           context(env)
59:         end
context(env, app=@app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb, line 61
61:         def context(env, app=@app)
62:           load_session(env)
63:           status, headers, body = app.call(env)
64:           commit_session(env, status, headers, body)
65:         end


Class: Rack::Session::Cookie

Class | Rack::Session::Cookie
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb
Parent: | Object

Rack::Session::Cookie provides simple cookie based session management. The session is a Ruby Hash stored as base64 encoded marshalled data set to :key (default: rack.session). When the secret key is set, cookie data is checked for data integrity.

Example:

    use Rack::Session::Cookie, :key => 'rack.session',
                               :domain => 'foo.com',
                               :path => '/',
                               :expire_after => 2592000,
                               :secret => 'change_me'

    All parameters are optional.

Methods

call new

Public Class methods

new(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb, line 26
26:       def initialize(app, options={})
27:         @app = app
28:         @key = options[:key] || "rack.session"
29:         @secret = options[:secret]
30:         @default_options = {:domain => nil,
31:           :path => "/",
32:           :expire_after => nil}.merge(options)
33:       end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb, line 35
35:       def call(env)
36:         load_session(env)
37:         status, headers, body = @app.call(env)
38:         commit_session(env, status, headers, body)
39:       end


Class: Rack::Session::Memcache

Class | Rack::Session::Memcache
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb
Parent: | Abstract::ID

Rack::Session::Memcache provides simple cookie based session management. Session data is stored in memcached. The corresponding session key is maintained in the cookie. You may treat Session::Memcache as you would Session::Pool with the following caveats.

  • Setting :expire_after to 0 would note to the Memcache server to hang onto the session data until it would drop it according to it‘s own specifications. However, the cookie sent to the client would expire immediately.

Note that memcache does drop data before it may be listed to expire. For a full description of behaviour, please see memcache‘s documentation.

Methods

generate_sid get_session new set_session

Constants

DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \ :namespace => 'rack:session', :memcache_server => 'localhost:11211'

Attributes

mutex | [R]
pool | [R]

Public Class methods

new(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb, line 28
28:       def initialize(app, options={})
29:         super
30:
31:         @mutex = Mutex.new
32:         @pool = MemCache.
33:           new @default_options[:memcache_server], @default_options
34:         raise 'No memcache servers' unless @pool.servers.any?{|s|s.alive?}
35:       end

Public Instance methods

generate_sid()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb, line 37
37:       def generate_sid
38:         loop do
39:           sid = super
40:           break sid unless @pool.get(sid, true)
41:         end
42:       end
get_session(env, sid)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb, line 44
44:       def get_session(env, sid)
45:         session = @pool.get(sid) if sid
46:         @mutex.lock if env['rack.multithread']
47:         unless sid and session
48:           env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
49:           session = {}
50:           sid = generate_sid
51:           ret = @pool.add sid, session
52:           raise "Session collision on '#{sid.inspect}'" unless /^STORED/ =~ ret
53:         end
54:         session.instance_variable_set('@old', {}.merge(session))
55:         return [sid, session]
56:       rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
57:         warn "#{self} is unable to find server."
58:         warn $!.inspect
59:         return [ nil, {} ]
60:       ensure
61:         @mutex.unlock if env['rack.multithread']
62:       end
set_session(env, session_id, new_session, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb, line 64
64:       def set_session(env, session_id, new_session, options)
65:         expiry = options[:expire_after]
66:         expiry = expiry.nil? ? 0 : expiry + 1
67:
68:         @mutex.lock if env['rack.multithread']
69:         session = @pool.get(session_id) || {}
70:         if options[:renew] or options[:drop]
71:           @pool.delete session_id
72:           return false if options[:drop]
73:           session_id = generate_sid
74:           @pool.add session_id, 0 # so we don't worry about cache miss on #set
75:         end
76:         old_session = new_session.instance_variable_get('@old') || {}
77:         session = merge_sessions session_id, old_session, new_session, session
78:         @pool.set session_id, session, expiry
79:         return session_id
80:       rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
81:         warn "#{self} is unable to find server."
82:         warn $!.inspect
83:         return false
84:       ensure
85:         @mutex.unlock if env['rack.multithread']
86:       end


Class: Rack::Session::Pool

Class | Rack::Session::Pool
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb
Parent: | Abstract::ID

Rack::Session::Pool provides simple cookie based session management. Session data is stored in a hash held by @pool. In the context of a multithreaded environment, sessions being committed to the pool is done in a merging manner.

The :drop option is available in rack.session.options if you with to explicitly remove the session from the session cache.

Example:

  myapp = MyRackApp.new
  sessioned = Rack::Session::Pool.new(myapp,
    :domain => 'foo.com',
    :expire_after => 2592000
  )
  Rack::Handler::WEBrick.run sessioned

Methods

generate_sid get_session new set_session

Constants

DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :drop => false

Attributes

mutex | [R]
pool | [R]

Public Class methods

new(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb, line 31
31:       def initialize(app, options={})
32:         super
33:         @pool = Hash.new
34:         @mutex = Mutex.new
35:       end

Public Instance methods

generate_sid()

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb, line 37
37:       def generate_sid
38:         loop do
39:           sid = super
40:           break sid unless @pool.key? sid
41:         end
42:       end
get_session(env, sid)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb, line 44
44:       def get_session(env, sid)
45:         session = @pool[sid] if sid
46:         @mutex.lock if env['rack.multithread']
47:         unless sid and session
48:           env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
49:           session = {}
50:           sid = generate_sid
51:           @pool.store sid, session
52:         end
53:         session.instance_variable_set('@old', {}.merge(session))
54:         return [sid, session]
55:       ensure
56:         @mutex.unlock if env['rack.multithread']
57:       end
set_session(env, session_id, new_session, options)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb, line 59
59:       def set_session(env, session_id, new_session, options)
60:         @mutex.lock if env['rack.multithread']
61:         session = @pool[session_id]
62:         if options[:renew] or options[:drop]
63:           @pool.delete session_id
64:           return false if options[:drop]
65:           session_id = generate_sid
66:           @pool.store session_id, 0
67:         end
68:         old_session = new_session.instance_variable_get('@old') || {}
69:         session = merge_sessions session_id, old_session, new_session, session
70:         @pool.store session_id, session
71:         return session_id
72:       rescue
73:         warn "#{new_session.inspect} has been lost."
74:         warn $!.inspect
75:       ensure
76:         @mutex.unlock if env['rack.multithread']
77:       end


Class: Rack::ShowExceptions

Class | Rack::ShowExceptions
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb
Parent: | Object

Rack::ShowExceptions catches all exceptions raised from the app it wraps. It shows a useful backtrace with the sourcefile and clickable context, the whole Rack environment and the request data.

Be careful when you use this on public-facing sites as it could reveal information helpful to attackers.

Methods

call new pretty

Constants

CONTEXT = 7

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb, line 18
18:     def initialize(app)
19:       @app = app
20:       @template = ERB.new(TEMPLATE)
21:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb, line 23
23:     def call(env)
24:       @app.call(env)
25:     rescue StandardError, LoadError, SyntaxError => e
26:       backtrace = pretty(env, e)
27:       [500,
28:        {"Content-Type" => "text/html",
29:         "Content-Length" => backtrace.join.size.to_s},
30:        backtrace]
31:     end
pretty(env, exception)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb, line 33
33:     def pretty(env, exception)
34:       req = Rack::Request.new(env)
35:       path = (req.script_name + req.path_info).squeeze("/")
36:
37:       frames = exception.backtrace.map { |line|
38:         frame = OpenStruct.new
39:         if line =~ /(.*?):(\d+)(:in `(.*)')?/
40:           frame.filename = $1
41:           frame.lineno = $2.to_i
42:           frame.function = $4
43:
44:           begin
45:             lineno = frame.lineno-1
46:             lines = ::File.readlines(frame.filename)
47:             frame.pre_context_lineno = [lineno-CONTEXT, 0].max
48:             frame.pre_context = lines[frame.pre_context_lineno...lineno]
49:             frame.context_line = lines[lineno].chomp
50:             frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
51:             frame.post_context = lines[lineno+1..frame.post_context_lineno]
52:           rescue
53:           end
54:
55:           frame
56:         else
57:           nil
58:         end
59:       }.compact
60:
61:       env["rack.errors"].puts "#{exception.class}: #{exception.message}"
62:       env["rack.errors"].puts exception.backtrace.map { |l| "\t" + l }
63:       env["rack.errors"].flush
64:
65:       [@template.result(binding)]
66:     end


Class: Rack::ShowStatus

Class | Rack::ShowStatus
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb
Parent: | Object

Rack::ShowStatus catches all empty responses the app it wraps and replaces them with a site explaining the error.

Additional details can be put into rack.showstatus.detail and will be shown as HTML. If such details exist, the error page is always rendered, even if the reply was not empty.

Methods

call new

Public Class methods

new(app)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb, line 14
14:     def initialize(app)
15:       @app = app
16:       @template = ERB.new(TEMPLATE)
17:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb, line 19
19:     def call(env)
20:       status, headers, body = @app.call(env)
21:       headers = Utils::HeaderHash.new(headers)
22:       empty = headers['Content-Length'].to_i <= 0
23:
24:       # client or server error, or explicit message
25:       if (status.to_i >= 400 && empty) || env["rack.showstatus.detail"]
26:         req = Rack::Request.new(env)
27:         message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] || status.to_s
28:         detail = env["rack.showstatus.detail"] || message
29:         body = @template.result(binding)
30:         size = Rack::Utils.bytesize(body)
31:         [status, headers.merge("Content-Type" => "text/html", "Content-Length" => size.to_s), [body]]
32:       else
33:         [status, headers, body]
34:       end
35:     end


Class: Rack::Static

Class | Rack::Static
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb
Parent: | Object

The Rack::Static middleware intercepts requests for static files (javascript files, images, stylesheets, etc) based on the url prefixes passed in the options, and serves them using a Rack::File object. This allows a Rack stack to serve both static and dynamic content.

Examples:

    use Rack::Static, :urls => ["/media"]
    will serve all requests beginning with /media from the "media" folder
    located in the current directory (ie media/*).

    use Rack::Static, :urls => ["/css", "/images"], :root => "public"
    will serve all requests beginning with /css or /images from the folder
    "public" in the current directory (ie public/css/* and public/images/*)

Methods

call new

Public Class methods

new(app, options={})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb, line 19
19:     def initialize(app, options={})
20:       @app = app
21:       @urls = options[:urls] || ["/favicon.ico"]
22:       root = options[:root] || Dir.pwd
23:       @file_server = Rack::File.new(root)
24:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/static.rb, line 26
26:     def call(env)
27:       path = env["PATH_INFO"]
28:       can_serve = @urls.any? { |url| path.index(url) == 0 }
29:
30:       if can_serve
31:         @file_server.call(env)
32:       else
33:         @app.call(env)
34:       end
35:     end


Class: Rack::URLMap

Class | Rack::URLMap
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
Parent: | Object

Rack::URLMap takes a hash mapping urls or paths to apps, and dispatches accordingly. Support for HTTP/1.1 host names exists if the URLs start with http:// or https://.

URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part relevant for dispatch is in the SCRIPT_NAME, and the rest in the PATH_INFO. This should be taken care of when you need to reconstruct the URL in order to create links.

URLMap dispatches in such a way that the longest paths are tried first, since they are most specific.

Methods

call new remap

Public Class methods

new(map = {})

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb, line 15
15:     def initialize(map = {})
16:       remap(map)
17:     end

Public Instance methods

call(env)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb, line 36
36:     def call(env)
37:       path = env["PATH_INFO"].to_s.squeeze("/")
38:       script_name = env['SCRIPT_NAME']
39:       hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
40:       @mapping.each { |host, location, app|
41:         next unless (hHost == host || sName == host \
42:           || (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
43:         next unless location == path[0, location.size]
44:         next unless path[location.size] == nil || path[location.size] == ?/
45:
46:         return app.call(
47:           env.merge(
48:             'SCRIPT_NAME' => (script_name + location),
49:             'PATH_INFO'   => path[location.size..-1]))
50:       }
51:       [404, {"Content-Type" => "text/plain"}, ["Not Found: #{path}"]]
52:     end
remap(map)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb, line 19
19:     def remap(map)
20:       @mapping = map.map { |location, app|
21:         if location =~ %r{\Ahttps?://(.*?)(/.*)}
22:           host, location = $1, $2
23:         else
24:           host = nil
25:         end
26:
27:         unless location[0] == ?/
28:           raise ArgumentError, "paths need to start with /"
29:         end
30:         location = location.chomp('/')
31:
32:         [host, location, app]
33:       }.sort_by { |(h, l, a)| [-l.size, h.to_s.size] }  # Longest path first
34:     end


Module: Rack::Utils

Module | Rack::Utils
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb

Rack::Utils contains a grab-bag of useful methods for writing web applications adopted from all kinds of Ruby libraries.

Methods

build_query bytesize bytesize escape escape_html normalize_params parse_nested_query parse_query select_best_encoding unescape

Classes and Modules

Module Rack::Utils::Multipart
Class Rack::Utils::Context
Class Rack::Utils::HeaderHash

Constants

HTTP_STATUS_CODES = { 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported' Every standard HTTP code mapped to the appropriate message. Stolen from Mongrel.
STATUS_WITH_NO_ENTITY_BODY = Set.new((100..199).to_a << 204 << 304) Responses with HTTP status codes that should not have an entity body

Public Instance methods

build_query(params)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 96
 96:     def build_query(params)
 97:       params.map { |k, v|
 98:         if v.class == Array
 99:           build_query(v.map { |x| [k, x] })
100:         else
101:           escape(k) + "=" + escape(v)
102:         end
103:       }.join("&")
104:     end
bytesize(string)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 150
150:       def bytesize(string)
151:         string.bytesize
152:       end
bytesize(string)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 154
154:       def bytesize(string)
155:         string.size
156:       end
escape(s)

Performs URI escaping so that you can construct proper query strings faster. Use this rather than the cgi.rb version since it‘s faster. (Stolen from Camping).

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 12
12:     def escape(s)
13:       s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
14:         '%'+$1.unpack('H2'*$1.size).join('%').upcase
15:       }.tr(' ', '+')
16:     end
escape_html(string)

Escape ampersands, brackets and quotes to their HTML/XML entities.

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 108
108:     def escape_html(string)
109:       string.to_s.gsub("&", "&amp;").
110:         gsub("<", "&lt;").
111:         gsub(">", "&gt;").
112:         gsub("'", "&#39;").
113:         gsub('"', "&quot;")
114:     end
normalize_params(params, name, v = nil)

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 65
65:     def normalize_params(params, name, v = nil)
66:       name =~ %r([\[\]]*([^\[\]]+)\]*)
67:       k = $1 || ''
68:       after = $' || ''
69:
70:       return if k.empty?
71:
72:       if after == ""
73:         params[k] = v
74:       elsif after == "[]"
75:         params[k] ||= []
76:         raise TypeError unless params[k].is_a?(Array)
77:         params[k] << v
78:       elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
79:         child_key = $1
80:         params[k] ||= []
81:         raise TypeError unless params[k].is_a?(Array)
82:         if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
83:           normalize_params(params[k].last, child_key, v)
84:         else
85:           params[k] << normalize_params({}, child_key, v)
86:         end
87:       else
88:         params[k] ||= {}
89:         params[k] = normalize_params(params[k], after, v)
90:       end
91:
92:       return params
93:     end
parse_nested_query(qs, d = '&;')

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 53
53:     def parse_nested_query(qs, d = '&;')
54:       params = {}
55:
56:       (qs || '').split(/[#{d}] */n).each do |p|
57:         k, v = unescape(p).split('=', 2)
58:         normalize_params(params, k, v)
59:       end
60:
61:       return params
62:     end
parse_query(qs, d = '&;')

Stolen from Mongrel, with some small modifications: Parses a query string by breaking it up at the ’&’ and ’;’ characters. You can also use this to parse cookies by changing the characters used in the second parameter (which defaults to ’&;’).

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 32
32:     def parse_query(qs, d = '&;')
33:       params = {}
34:
35:       (qs || '').split(/[#{d}] */n).each do |p|
36:         k, v = unescape(p).split('=', 2)
37:
38:         if cur = params[k]
39:           if cur.class == Array
40:             params[k] << v
41:           else
42:             params[k] = [cur, v]
43:           end
44:         else
45:           params[k] = v
46:         end
47:       end
48:
49:       return params
50:     end
select_best_encoding(available_encodings, accept_encoding)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 117
117:     def select_best_encoding(available_encodings, accept_encoding)
118:       # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
119:
120:       expanded_accept_encoding =
121:         accept_encoding.map { |m, q|
122:           if m == "*"
123:             (available_encodings - accept_encoding.map { |m2, _| m2 }).map { |m2| [m2, q] }
124:           else
125:             [[m, q]]
126:           end
127:         }.inject([]) { |mem, list|
128:           mem + list
129:         }
130:
131:       encoding_candidates = expanded_accept_encoding.sort_by { |_, q| -q }.map { |m, _| m }
132:
133:       unless encoding_candidates.include?("identity")
134:         encoding_candidates.push("identity")
135:       end
136:
137:       expanded_accept_encoding.find_all { |m, q|
138:         q == 0.0
139:       }.each { |m, _|
140:         encoding_candidates.delete(m)
141:       }
142:
143:       return (encoding_candidates & available_encodings)[0]
144:     end
unescape(s)

Unescapes a URI escaped string. (Stolen from Camping).

[Source]

    # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 20
20:     def unescape(s)
21:       s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
22:         [$1.delete('%')].pack('H*')
23:       }
24:     end


Class: Rack::Utils::Context

Class | Rack::Utils::Context
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
Parent: | Object

Context allows the use of a compatible middleware at different points in a request handling stack. A compatible middleware must define context which should take the arguments env and app. The first of which would be the request environment. The second of which would be the rack application that the request would be forwarded to.

Methods

call context new recontext

Attributes

app | [R]
for | [R]

Public Class methods

new(app_f, app_r)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 168
168:       def initialize(app_f, app_r)
169:         raise 'running context does not respond to #context' unless app_f.respond_to? :context
170:         @for, @app = app_f, app_r
171:       end

Public Instance methods

call(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 173
173:       def call(env)
174:         @for.context(env, @app)
175:       end
context(env, app=@app)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 181
181:       def context(env, app=@app)
182:         recontext(app).call(env)
183:       end
recontext(app)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 177
177:       def recontext(app)
178:         self.class.new(@for, app)
179:       end


Class: Rack::Utils::HeaderHash

Class | Rack::Utils::HeaderHash
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
Parent: | Hash

A case-insensitive Hash that preserves the original case of a header when set.

Methods

[] []= delete has_key? include? key? member? merge merge! new to_hash

Public Class methods

new(hash={})

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 189
189:       def initialize(hash={})
190:         @names = {}
191:         hash.each { |k, v| self[k] = v }
192:       end

Public Instance methods

[](k)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 205
205:       def [](k)
206:         super @names[k.downcase]
207:       end
[]=(k, v)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 209
209:       def []=(k, v)
210:         delete k
211:         @names[k.downcase] = k
212:         super k, v
213:       end
delete(k)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 215
215:       def delete(k)
216:         super @names.delete(k.downcase)
217:       end
has_key?(k)

Alias for include?

include?(k)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 219
219:       def include?(k)
220:         @names.has_key? k.downcase
221:       end
key?(k)

Alias for include?

member?(k)

Alias for include?

merge(other)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 232
232:       def merge(other)
233:         hash = dup
234:         hash.merge! other
235:       end
merge!(other)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 227
227:       def merge!(other)
228:         other.each { |k, v| self[k] = v }
229:         self
230:       end
to_hash()

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 194
194:       def to_hash
195:         inject({}) do |hash, (k,v)|
196:           if v.respond_to? :to_ary
197:             hash[k] = v.to_ary.join("\n")
198:           else
199:             hash[k] = v
200:           end
201:           hash
202:         end
203:       end


Module: Rack::Utils::Multipart

Module | Rack::Utils::Multipart
In: | vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb

A multipart form data parser, adapted from IOWA.

Usually, Rack::Request#POST takes care of calling this.

Methods

parse_multipart

Constants

EOL = "\r\n"

Public Class methods

parse_multipart(env)

[Source]

     # File vendor/rails/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb, line 293
293:       def self.parse_multipart(env)
294:         unless env['CONTENT_TYPE'] =~
295:             %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
296:           nil
297:         else
298:           boundary = "--#{$1}"
299:
300:           params = {}
301:           buf = ""
302:           content_length = env['CONTENT_LENGTH'].to_i
303:           input = env['rack.input']
304:
305:           boundary_size = boundary.size + EOL.size
306:           bufsize = 16384
307:
308:           content_length -= boundary_size
309:
310:           status = input.read(boundary_size)
311:           raise EOFError, "bad content body"  unless status == boundary + EOL
312:
313:           rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n
314:
315:           loop {
316:             head = nil
317:             body = ''
318:             filename = content_type = name = nil
319:
320:             until head && buf =~ rx
321:               if !head && i = buf.index("\r\n\r\n")
322:                 head = buf.slice!(0, i+2) # First \r\n
323:                 buf.slice!(0, 2)          # Second \r\n
324:
325:                 filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
326:                 content_type = head[/Content-Type: (.*)\r\n/ni, 1]
327:                 name = head[/Content-Disposition:.* name="?([^\";]*)"?/ni, 1]
328:
329:                 if filename
330:                   body = Tempfile.new("RackMultipart")
331:                   body.binmode  if body.respond_to?(:binmode)
332:                 end
333:
334:                 next
335:               end
336:
337:               # Save the read body part.
338:               if head && (boundary_size+4 < buf.size)
339:                 body << buf.slice!(0, buf.size - (boundary_size+4))
340:               end
341:
342:               c = input.read(bufsize < content_length ? bufsize : content_length)
343:               raise EOFError, "bad content body"  if c.nil? || c.empty?
344:               buf << c
345:               content_length -= c.size
346:             end
347:
348:             # Save the rest.
349:             if i = buf.index(rx)
350:               body << buf.slice!(0, i)
351:               buf.slice!(0, boundary_size+2)
352:
353:               content_length = -1  if $1 == "--"
354:             end
355:
356:             if filename == ""
357:               # filename is blank which means no file has been selected
358:               data = nil
359:             elsif filename
360:               body.rewind
361:
362:               # Take the basename of the upload's original filename.
363:               # This handles the full Windows paths given by Internet Explorer
364:               # (and perhaps other broken user agents) without affecting
365:               # those which give the lone filename.
366:               filename =~ /^(?:.*[:\\\/])?(.*)/m
367:               filename = $1
368:
369:               data = {:filename => filename, :type => content_type,
370:                       :name => name, :tempfile => body, :head => head}
371:             else
372:               data = body
373:             end
374:
375:             Utils.normalize_params(params, name, data) unless data.nil?
376:
377:             break  if buf.empty? || content_length == -1
378:           }
379:
380:           begin
381:             input.rewind if input.respond_to?(:rewind)
382:           rescue Errno::ESPIPE
383:             # Handles exceptions raised by input streams that cannot be rewound
384:             # such as when using plain CGI under Apache
385:           end
386:
387:           params
388:         end
389:       end


Class: RailsEnvironment

Class | RailsEnvironment
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

best_install_method default default= externals externals= find install new use_checkout? use_externals? use_svn?

Attributes

root [R]

Public Class methods

default()

[Source]

    # File vendor/rails/railties/lib/commands/plugin.rb, line 83
83:   def self.default
84:     @default ||= find
85:   end
default=(rails_env)

[Source]

    # File vendor/rails/railties/lib/commands/plugin.rb, line 87
87:   def self.default=(rails_env)
88:     @default = rails_env
89:   end
find(dir=nil)

[Source]

    # File vendor/rails/railties/lib/commands/plugin.rb, line 75
75:   def self.find(dir=nil)
76:     dir ||= pwd
77:     while dir.length > 1
78:       return new(dir) if File.exist?(File.join(dir, 'config', 'environment.rb'))
79:       dir = File.dirname(dir)
80:     end
81:   end
new(dir)

[Source]

    # File vendor/rails/railties/lib/commands/plugin.rb, line 71
71:   def initialize(dir)
72:     @root = dir
73:   end

Public Instance methods

best_install_method()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 125
125:   def best_install_method
126:     return :http unless use_svn?
127:     case
128:       when use_externals? then :externals
129:       when use_checkout? then :checkout
130:       else :export
131:     end
132:   end
externals()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 134
134:   def externals
135:     return [] unless use_externals?
136:     ext = `svn propget svn:externals "#{root}/vendor/plugins"`
137:     lines = ext.respond_to?(:lines) ? ext.lines : ext
138:     lines.reject{ |line| line.strip == '' }.map do |line|
139:       line.strip.split(/\s+/, 2)
140:     end
141:   end
externals=(items)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 143
143:   def externals=(items)
144:     unless items.is_a? String
145:       items = items.map{|name,uri| "#{name.ljust(29)} #{uri.chomp('/')}"}.join("\n")
146:     end
147:     Tempfile.open("svn-set-prop") do |file|
148:       file.write(items)
149:       file.flush
150:       system("svn propset -q svn:externals -F \"#{file.path}\" \"#{root}/vendor/plugins\"")
151:     end
152:   end
install(name_uri_or_plugin)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 91
 91:   def install(name_uri_or_plugin)
 92:     if name_uri_or_plugin.is_a? String
 93:       if name_uri_or_plugin =~ /:\/\//
 94:         plugin = Plugin.new(name_uri_or_plugin)
 95:       else
 96:         plugin = Plugins[name_uri_or_plugin]
 97:       end
 98:     else
 99:       plugin = name_uri_or_plugin
100:     end
101:     unless plugin.nil?
102:       plugin.install
103:     else
104:       puts "Plugin not found: #{name_uri_or_plugin}"
105:     end
106:   end
use_checkout?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 118
118:   def use_checkout?
119:     # this is a bit of a guess. we assume that if the rails environment
120:     # is under subversion then they probably want the plugin checked out
121:     # instead of exported. This can be overridden on the command line
122:     File.directory?("#{root}/.svn")
123:   end
use_externals?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 114
114:   def use_externals?
115:     use_svn? && File.directory?("#{root}/vendor/plugins/.svn")
116:   end
use_svn?()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 108
108:   def use_svn?
109:     require 'active_support/core_ext/kernel'
110:     silence_stderr {`svn --version` rescue nil}
111:     !$?.nil? && $?.success?
112:   end


Class: RailsFCGIHandler

Class | RailsFCGIHandler
In: | vendor/rails/railties/lib/fcgi_handler.rb
Parent: | Object

Methods

close_connection dispatcher_error dispatcher_log exit_handler exit_now_handler gc_countdown install_signal_handler install_signal_handlers logger mark_features! new process! process! process_each_request process_request reload! reload_handler restart! restart_handler restore! run_gc! with_signal_handler

Constants

SIGNALS | = | { 'HUP' => :reload, 'INT' => :exit_now, 'TERM' => :exit_now, 'USR1' => :exit, 'USR2' => :restart
GLOBAL_SIGNALS | = | SIGNALS.keys - %w(USR1)

Attributes

gc_request_period | [RW]
log_file_path | [RW]
when_ready | [R]

Public Class methods

new(log_file_path = nil, gc_request_period = nil) {|self if block_given?| ...}

Initialize the FastCGI instance with the path to a crash log detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log) and the number of requests to process between garbage collection runs (default nil for normal GC behavior.) Optionally, pass a block which takes this instance as an argument for further configuration.

[Source]

    # File vendor/rails/railties/lib/fcgi_handler.rb, line 31
31:   def initialize(log_file_path = nil, gc_request_period = nil)
32:     self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log"
33:     self.gc_request_period = gc_request_period
34:
35:     # Yield for additional configuration.
36:     yield self if block_given?
37:
38:     # Safely install signal handlers.
39:     install_signal_handlers
40:
41:     @app = Dispatcher.new
42:
43:     # Start error timestamp at 11 seconds ago.
44:     @last_error_on = Time.now - 11
45:   end
process!(*args, &block)

Initialize and run the FastCGI instance, passing arguments through to new.

[Source]

    # File vendor/rails/railties/lib/fcgi_handler.rb, line 22
22:   def self.process!(*args, &block)
23:     new(*args, &block).process!
24:   end

Public Instance methods

process!(provider = FCGI)

[Source]

    # File vendor/rails/railties/lib/fcgi_handler.rb, line 47
47:   def process!(provider = FCGI)
48:     mark_features!
49:
50:     dispatcher_log :info, 'starting'
51:     process_each_request provider
52:     dispatcher_log :info, 'stopping gracefully'
53:
54:   rescue Exception => error
55:     case error
56:     when SystemExit
57:       dispatcher_log :info, 'stopping after explicit exit'
58:     when SignalException
59:       dispatcher_error error, 'stopping after unhandled signal'
60:     else
61:       # Retry if exceptions occur more than 10 seconds apart.
62:       if Time.now - @last_error_on > 10
63:         @last_error_on = Time.now
64:         dispatcher_error error, 'retrying after unhandled exception'
65:         retry
66:       else
67:         dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last'
68:       end
69:     end
70:   end

Protected Instance methods

close_connection(request)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 236
236:     def close_connection(request)
237:       request.finish if request
238:     end
dispatcher_error(e, msg = "")

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 126
126:     def dispatcher_error(e, msg = "")
127:       error_message =
128:         "Dispatcher failed to catch: #{e} (#{e.class})\n" +
129:         "  #{e.backtrace.join("\n  ")}\n#{msg}"
130:       dispatcher_log(:error, error_message)
131:     end
dispatcher_log(level, msg)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 118
118:     def dispatcher_log(level, msg)
119:       time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S")
120:       logger.send(level, "[#{time_str} :: #{$$}] #{msg}")
121:     rescue Exception => log_error  # Logger errors
122:       STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n"
123:       STDERR << "  #{log_error.class}: #{log_error.message}\n"
124:     end
exit_handler(signal)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 163
163:     def exit_handler(signal)
164:       dispatcher_log :info, "asked to stop ASAP"
165:       if @processing
166:         @when_ready = :exit
167:       else
168:         throw :exit
169:       end
170:     end
exit_now_handler(signal)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 158
158:     def exit_now_handler(signal)
159:       dispatcher_log :info, "asked to stop immediately"
160:       exit
161:     end
gc_countdown()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 228
228:     def gc_countdown
229:       if gc_request_period
230:         @gc_request_countdown ||= gc_request_period
231:         @gc_request_countdown -= 1
232:         run_gc! if @gc_request_countdown <= 0
233:       end
234:     end
install_signal_handler(signal, handler = nil)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 137
137:     def install_signal_handler(signal, handler = nil)
138:       if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler")
139:         handler ||= method(name).to_proc
140:
141:         begin
142:           trap(signal, handler)
143:         rescue ArgumentError
144:           dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
145:         end
146:       else
147:         dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
148:       end
149:     end
install_signal_handlers()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 133
133:     def install_signal_handlers
134:       GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) }
135:     end
logger()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 114
114:     def logger
115:       @logger ||= Logger.new(@log_file_path)
116:     end
mark_features!()

Make a note of $" so we can safely reload this instance.

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 213
213:     def mark_features!
214:       @features = $".clone
215:     end
process_each_request(provider)

[Source]

    # File vendor/rails/railties/lib/fcgi_handler.rb, line 73
73:     def process_each_request(provider)
74:       request = nil
75:
76:       catch :exit do
77:         provider.each do |request|
78:           process_request(request)
79:
80:           case when_ready
81:             when :reload
82:               reload!
83:             when :restart
84:               close_connection(request)
85:               restart!
86:             when :exit
87:               close_connection(request)
88:               throw :exit
89:           end
90:         end
91:       end
92:     rescue SignalException => signal
93:       raise unless signal.message == 'SIGUSR1'
94:       close_connection(request)
95:     end
process_request(request)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 97
 97:     def process_request(request)
 98:       @processing, @when_ready = true, nil
 99:       gc_countdown
100:
101:       with_signal_handler 'USR1' do
102:         begin
103:           ::Rack::Handler::FastCGI.serve(request, @app)
104:         rescue SignalException, SystemExit
105:           raise
106:         rescue Exception => error
107:           dispatcher_error error, 'unhandled dispatch error'
108:         end
109:       end
110:     ensure
111:       @processing = false
112:     end
reload!()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 205
205:     def reload!
206:       run_gc! if gc_request_period
207:       restore!
208:       @when_ready = nil
209:       dispatcher_log :info, "reloaded"
210:     end
reload_handler(signal)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 172
172:     def reload_handler(signal)
173:       dispatcher_log :info, "asked to reload ASAP"
174:       if @processing
175:         @when_ready = :reload
176:       else
177:         reload!
178:       end
179:     end
restart!()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 190
190:     def restart!
191:       config       = ::Config::CONFIG
192:       ruby         = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
193:       command_line = [ruby, $0, ARGV].flatten.join(' ')
194:
195:       dispatcher_log :info, "restarted"
196:
197:       # close resources as they won't be closed by
198:       # the OS when using exec
199:       logger.close rescue nil
200:       Rails.logger.close rescue nil
201:
202:       exec(command_line)
203:     end
restart_handler(signal)

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 181
181:     def restart_handler(signal)
182:       dispatcher_log :info, "asked to restart ASAP"
183:       if @processing
184:         @when_ready = :restart
185:       else
186:         restart!
187:       end
188:     end
restore!()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 217
217:     def restore!
218:       $".replace @features
219:       Dispatcher.reset_application!
220:       ActionController::Routing::Routes.reload
221:     end
run_gc!()

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 223
223:     def run_gc!
224:       @gc_request_countdown = gc_request_period
225:       GC.enable; GC.start; GC.disable
226:     end
with_signal_handler(signal) {|| ...}

[Source]

     # File vendor/rails/railties/lib/fcgi_handler.rb, line 151
151:     def with_signal_handler(signal)
152:       install_signal_handler(signal)
153:       yield
154:     ensure
155:       install_signal_handler(signal, 'DEFAULT')
156:     end


Class: RecursiveHTTPFetcher

Class | RecursiveHTTPFetcher
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

download fetch fetch_dir links ls new pop_d push_d

Attributes

quiet [RW]

Public Class methods

new(urls_to_fetch, level = 1, cwd = ".")

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 903
903:   def initialize(urls_to_fetch, level = 1, cwd = ".")
904:     @level = level
905:     @cwd = cwd
906:     @urls_to_fetch = RUBY_VERSION >= '1.9' ? urls_to_fetch.lines : urls_to_fetch.to_a
907:     @quiet = false
908:   end

Public Instance methods

download(link)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 942
942:   def download(link)
943:     puts "+ #{File.join(@cwd, File.basename(link))}" unless @quiet
944:     open(link) do |stream|
945:       File.open(File.join(@cwd, File.basename(link)), "wb") do |file|
946:         file.write(stream.read)
947:       end
948:     end
949:   end
fetch(links = @urls_to_fetch)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 951
951:   def fetch(links = @urls_to_fetch)
952:     links.each do |l|
953:       (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l)
954:     end
955:   end
fetch_dir(url)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 957
957:   def fetch_dir(url)
958:     @level += 1
959:     push_d(File.basename(url)) if @level > 0
960:     open(url) do |stream|
961:       contents =  stream.read
962:       fetch(links(url, contents))
963:     end
964:     pop_d if @level > 0
965:     @level -= 1
966:   end
links(base_url, contents)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 931
931:   def links(base_url, contents)
932:     links = []
933:     contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link|
934:       link = link.sub(/href="/i, "")
935:       next if link =~ /svnindex.xsl$/
936:       next if link =~ /^(\w*:|)\/\// || link =~ /^\./
937:       links << File.join(base_url, link)
938:     end
939:     links
940:   end
ls()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 910
910:   def ls
911:     @urls_to_fetch.collect do |url|
912:       if url =~ /^svn(\+ssh)?:\/\/.*/
913:         `svn ls #{url}`.split("\n").map {|entry| "/#{entry}"} rescue nil
914:       else
915:         open(url) do |stream|
916:           links("", stream.read)
917:         end rescue nil
918:       end
919:     end.flatten
920:   end
pop_d()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 927
927:   def pop_d
928:     @cwd = File.dirname(@cwd)
929:   end
push_d(dir)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 922
922:   def push_d(dir)
923:     @cwd = File.join(@cwd, dir)
924:     FileUtils.mkdir_p(@cwd)
925:   end


Class: Repositories

Class | Repositories
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

add all defaults each each exist? find_home find_plugin instance load! new remove save

Included Modules

Enumerable

Public Class methods

each(&block)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 398
398:   def self.each(&block)
399:     self.instance.each(&block)
400:   end
instance()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 394
394:   def self.instance
395:     @instance ||= Repositories.new
396:   end
new(cache_file = File.join(find_home, ".rails-plugin-sources"))

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 316
316:   def initialize(cache_file = File.join(find_home, ".rails-plugin-sources"))
317:     @cache_file = File.expand_path(cache_file)
318:     load!
319:   end

Public Instance methods

add(uri)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 325
325:   def add(uri)
326:     unless find{|repo| repo.uri == uri }
327:       @repositories.push(Repository.new(uri)).last
328:     end
329:   end
all()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 339
339:   def all
340:     @repositories
341:   end
defaults()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 369
369:   def defaults
370:     "http://dev.rubyonrails.com/svn/rails/plugins/\n"
371:   end
each(&block)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 321
321:   def each(&block)
322:     @repositories.each(&block)
323:   end
exist?(uri)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 335
335:   def exist?(uri)
336:     @repositories.detect{|repo| repo.uri == uri }
337:   end
find_home()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 376
376:   def find_home
377:     ['HOME', 'USERPROFILE'].each do |homekey|
378:       return ENV[homekey] if ENV[homekey]
379:     end
380:     if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
381:       return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
382:     end
383:     begin
384:       File.expand_path("~")
385:     rescue StandardError => ex
386:       if File::ALT_SEPARATOR
387:         "C:/"
388:       else
389:         "/"
390:       end
391:     end
392:   end
find_plugin(name)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 343
343:   def find_plugin(name)
344:     @repositories.each do |repo|
345:       repo.each do |plugin|
346:         return plugin if plugin.name == name
347:       end
348:     end
349:     return nil
350:   end
load!()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 352
352:   def load!
353:     contents = File.exist?(@cache_file) ? File.read(@cache_file) : defaults
354:     contents = defaults if contents.empty?
355:     @repositories = contents.split(/\n/).reject do |line|
356:       line =~ /^\s*#/ or line =~ /^\s*$/
357:     end.map { |source| Repository.new(source.strip) }
358:   end
remove(uri)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 331
331:   def remove(uri)
332:     @repositories.reject!{|repo| repo.uri == uri}
333:   end
save()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 360
360:   def save
361:     File.open(@cache_file, 'w') do |f|
362:       each do |repo|
363:         f.write(repo.uri)
364:         f.write("\n")
365:       end
366:     end
367:   end


Class: Repository

Class | Repository
In: | vendor/rails/railties/lib/commands/plugin.rb
Parent: | Object

Methods

each new plugins

Included Modules

Enumerable

Attributes

plugins | [R]
uri | [R]

Public Class methods

new(uri)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 407
407:   def initialize(uri)
408:     @uri = uri.chomp('/') << "/"
409:     @plugins = nil
410:   end

Public Instance methods

each(&block)

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 426
426:   def each(&block)
427:     plugins.each(&block)
428:   end
plugins()

[Source]

     # File vendor/rails/railties/lib/commands/plugin.rb, line 412
412:   def plugins
413:     unless @plugins
414:       if $verbose
415:         puts "Discovering plugins in #{@uri}"
416:         puts index
417:       end
418:
419:       @plugins = index.reject{ |line| line !~ /\/$/ }
420:       @plugins.map! { |name| Plugin.new(File.join(@uri, name), name) }
421:     end
422:
423:     @plugins
424:   end


Class: SourceAnnotationExtractor

Class | SourceAnnotationExtractor
In: | vendor/rails/railties/lib/source_annotation_extractor.rb
Parent: | Object

Implements the logic behind the rake tasks for annotations like

  rake notes
  rake notes:optimize

and friends. See rake -T notes and railties/lib/tasks/annotations.rake.

Annotation objects are triplets :line, :tag, :text that represent the line where the annotation lives, its tag, and its text. Note the filename is not stored.

Annotations are looked for in comments and modulus whitespace they have to start with the tag optionally followed by a colon. Everything up to the end of the line (or closing ERb comment tag) is considered to be their text.

Methods

display enumerate extract_annotations_from find find_in new

Classes and Modules

Class SourceAnnotationExtractor::Annotation

Attributes

tag [R]

Public Class methods

enumerate(tag, options={})

Prints all annotations with tag tag under the root directories app, lib, and test (recursively). Only filenames with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, or +.erb+ are taken into account. The options hash is passed to each annotation‘s to_s.

This class method is the single entry point for the rake tasks.

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 37
37:   def self.enumerate(tag, options={})
38:     extractor = new(tag)
39:     extractor.display(extractor.find, options)
40:   end
new(tag)

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 44
44:   def initialize(tag)
45:     @tag = tag
46:   end

Public Instance methods

display(results, options={})

Prints the mapping from filenames to annotations in results ordered by filename. The options hash is passed to each annotation‘s to_s.

[Source]

     # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 93
 93:   def display(results, options={})
 94:     results.keys.sort.each do |file|
 95:       puts "#{file}:"
 96:       results[file].each do |note|
 97:         puts "  * #{note.to_s(options)}"
 98:       end
 99:       puts
100:     end
101:   end
extract_annotations_from(file, pattern)

If file is the filename of a file that contains annotations this method returns a hash with a single entry that maps file to an array of its annotations. Otherwise it returns an empty hash.

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 81
81:   def extract_annotations_from(file, pattern)
82:     lineno = 0
83:     result = File.readlines(file).inject([]) do |list, line|
84:       lineno += 1
85:       next list unless line =~ pattern
86:       list << Annotation.new(lineno, $1, $2)
87:     end
88:     result.empty? ? {} : { file => result }
89:   end
find(dirs=%w(app lib test))

Returns a hash that maps filenames under dirs (recursively) to arrays with their annotations. Only files with annotations are included, and only those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ are taken into account.

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 52
52:   def find(dirs=%w(app lib test))
53:     dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
54:   end
find_in(dir)

Returns a hash that maps filenames under dir (recursively) to arrays with their annotations. Only files with annotations are included, and only those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ are taken into account.

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 60
60:   def find_in(dir)
61:     results = {}
62:
63:     Dir.glob("#{dir}/*") do |item|
64:       next if File.basename(item)[0] == ?.
65:
66:       if File.directory?(item)
67:         results.update(find_in(item))
68:       elsif item =~ /\.(builder|(r(?:b|xml|js)))$/
69:         results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/))
70:       elsif item =~ /\.(rhtml|erb)$/
71:         results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/))
72:       end
73:     end
74:
75:     results
76:   end


Class: SourceAnnotationExtractor::Annotation

Class | SourceAnnotationExtractor::Annotation
In: | vendor/rails/railties/lib/source_annotation_extractor.rb
Parent: | Struct.new(:line, :tag, :text)

Methods

to_s

Public Instance methods

to_s(options={})

Returns a representation of the annotation that looks like this:

  [126] [TODO] This algorithm is simple and clearly correct, make it faster.

If options has a flag :tag the tag is shown as in the example above. Otherwise the string contains just line and text.

[Source]

    # File vendor/rails/railties/lib/source_annotation_extractor.rb, line 24
24:     def to_s(options={})
25:       s = "[%3d] " % line
26:       s << "[#{tag}] " if options[:tag]
27:       s << text
28:     end


Class: TCPTimeoutSocket

Class | TCPTimeoutSocket
In: | vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb
Parent: | Object

TCPSocket facade class which implements timeouts.

Methods

_socket close closed? gets method_missing new read write

Public Class methods

new(host, port, timeout)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 857
857:   def initialize(host, port, timeout)
858:     Timeout::timeout(MemCache::Server::CONNECT_TIMEOUT, SocketError) do
859:       @sock = TCPSocket.new(host, port)
860:       @len = timeout
861:     end
862:   end

Public Instance methods

_socket()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 882
882:   def _socket
883:     @sock
884:   end
close()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 894
894:   def close
895:     @sock.close
896:   end
closed?()

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 890
890:   def closed?
891:     @sock.closed?
892:   end
gets(*args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 870
870:   def gets(*args)
871:     Timeout::timeout(@len, SocketError) do
872:       @sock.gets(*args)
873:     end
874:   end
method_missing(meth, *args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 886
886:   def method_missing(meth, *args)
887:     @sock.__send__(meth, *args)
888:   end
read(*args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 876
876:   def read(*args)
877:     Timeout::timeout(@len, SocketError) do
878:       @sock.read(*args)
879:     end
880:   end
write(*args)

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/memcache-client-1.6.5/memcache.rb, line 864
864:   def write(*args)
865:     Timeout::timeout(@len, SocketError) do
866:       @sock.write(*args)
867:     end
868:   end


Module: TZInfo
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb

Classes and Modules

Module TZInfo::Definitions
Class TZInfo::AmbiguousTime
Class TZInfo::InvalidTimezoneIdentifier
Class TZInfo::NoOffsetsDefined
Class TZInfo::PeriodNotFound
Class TZInfo::Timezone
Class TZInfo::TimezonePeriod
Class TZInfo::UnknownTimezone


Class: TZInfo::AmbiguousTime

Class | TZInfo::AmbiguousTime
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Parent: | StandardError

Indicate a specified time in a local timezone has more than one possible time in UTC. This happens when switching from daylight savings time to normal time where the clocks are rolled back. Thrown by period_for_local and local_to_utc when using an ambiguous time and not specifying any means to resolve the ambiguity.


Module: TZInfo::Definitions
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb

Classes and Modules

Module TZInfo::Definitions::Africa
Module TZInfo::Definitions::America
Module TZInfo::Definitions::Asia
Module TZInfo::Definitions::Atlantic
Module TZInfo::Definitions::Australia
Module TZInfo::Definitions::Etc
Module TZInfo::Definitions::Europe
Module TZInfo::Definitions::Pacific


Module: TZInfo::Definitions::Africa

Module | TZInfo::Definitions::Africa
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb

Classes and Modules

Module TZInfo::Definitions::Africa::Algiers
Module TZInfo::Definitions::Africa::Cairo
Module TZInfo::Definitions::Africa::Casablanca
Module TZInfo::Definitions::Africa::Harare
Module TZInfo::Definitions::Africa::Johannesburg
Module TZInfo::Definitions::Africa::Monrovia
Module TZInfo::Definitions::Africa::Nairobi


Module: TZInfo::Definitions::Africa::Algiers

Module | TZInfo::Definitions::Africa::Algiers
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Cairo

Module | TZInfo::Definitions::Africa::Cairo
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Casablanca

Module | TZInfo::Definitions::Africa::Casablanca
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Harare

Module | TZInfo::Definitions::Africa::Harare
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Johannesburg

Module | TZInfo::Definitions::Africa::Johannesburg
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Monrovia

Module | TZInfo::Definitions::Africa::Monrovia
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Africa::Nairobi

Module | TZInfo::Definitions::Africa::Nairobi
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb

Classes and Modules

Module TZInfo::Definitions::America::Argentina
Module TZInfo::Definitions::America::Bogota
Module TZInfo::Definitions::America::Caracas
Module TZInfo::Definitions::America::Chicago
Module TZInfo::Definitions::America::Chihuahua
Module TZInfo::Definitions::America::Denver
Module TZInfo::Definitions::America::Godthab
Module TZInfo::Definitions::America::Guatemala
Module TZInfo::Definitions::America::Halifax
Module TZInfo::Definitions::America::Indiana
Module TZInfo::Definitions::America::Juneau
Module TZInfo::Definitions::America::La_Paz
Module TZInfo::Definitions::America::Lima
Module TZInfo::Definitions::America::Los_Angeles
Module TZInfo::Definitions::America::Mazatlan
Module TZInfo::Definitions::America::Mexico_City
Module TZInfo::Definitions::America::Monterrey
Module TZInfo::Definitions::America::New_York
Module TZInfo::Definitions::America::Phoenix
Module TZInfo::Definitions::America::Regina
Module TZInfo::Definitions::America::Santiago
Module TZInfo::Definitions::America::Sao_Paulo
Module TZInfo::Definitions::America::St_Johns
Module TZInfo::Definitions::America::Tijuana


Module: TZInfo::Definitions::America::Argentina

Module | TZInfo::Definitions::America::Argentina
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb

Classes and Modules

Module TZInfo::Definitions::America::Argentina::Buenos_Aires
Module TZInfo::Definitions::America::Argentina::San_Juan


Module: TZInfo::Definitions::America::Argentina::Buenos_Aires

Module | TZInfo::Definitions::America::Argentina::Buenos_Aires
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Argentina::San_Juan

Module | TZInfo::Definitions::America::Argentina::San_Juan
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Bogota

Module | TZInfo::Definitions::America::Bogota
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Caracas

Module | TZInfo::Definitions::America::Caracas
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Chicago

Module | TZInfo::Definitions::America::Chicago
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Chihuahua

Module | TZInfo::Definitions::America::Chihuahua
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Denver

Module | TZInfo::Definitions::America::Denver
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Godthab

Module | TZInfo::Definitions::America::Godthab
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Guatemala

Module | TZInfo::Definitions::America::Guatemala
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Halifax

Module | TZInfo::Definitions::America::Halifax
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Indiana

Module | TZInfo::Definitions::America::Indiana
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb

Classes and Modules

Module TZInfo::Definitions::America::Indiana::Indianapolis


Module: TZInfo::Definitions::America::Indiana::Indianapolis

Module | TZInfo::Definitions::America::Indiana::Indianapolis
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Juneau

Module | TZInfo::Definitions::America::Juneau
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::La_Paz

Module | TZInfo::Definitions::America::La_Paz
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Lima

Module | TZInfo::Definitions::America::Lima
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Los_Angeles

Module | TZInfo::Definitions::America::Los_Angeles
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Mazatlan

Module | TZInfo::Definitions::America::Mazatlan
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Mexico_City

Module | TZInfo::Definitions::America::Mexico_City
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Monterrey

Module | TZInfo::Definitions::America::Monterrey
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::New_York

Module | TZInfo::Definitions::America::New_York
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Phoenix

Module | TZInfo::Definitions::America::Phoenix
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Regina

Module | TZInfo::Definitions::America::Regina
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Santiago

Module | TZInfo::Definitions::America::Santiago
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Sao_Paulo

Module | TZInfo::Definitions::America::Sao_Paulo
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::St_Johns

Module | TZInfo::Definitions::America::St_Johns
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::America::Tijuana

Module | TZInfo::Definitions::America::Tijuana
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb

Classes and Modules

Module TZInfo::Definitions::Asia::Almaty
Module TZInfo::Definitions::Asia::Baghdad
Module TZInfo::Definitions::Asia::Baku
Module TZInfo::Definitions::Asia::Bangkok
Module TZInfo::Definitions::Asia::Chongqing
Module TZInfo::Definitions::Asia::Colombo
Module TZInfo::Definitions::Asia::Dhaka
Module TZInfo::Definitions::Asia::Hong_Kong
Module TZInfo::Definitions::Asia::Irkutsk
Module TZInfo::Definitions::Asia::Jakarta
Module TZInfo::Definitions::Asia::Jerusalem
Module TZInfo::Definitions::Asia::Kabul
Module TZInfo::Definitions::Asia::Kamchatka
Module TZInfo::Definitions::Asia::Karachi
Module TZInfo::Definitions::Asia::Katmandu
Module TZInfo::Definitions::Asia::Kolkata
Module TZInfo::Definitions::Asia::Krasnoyarsk
Module TZInfo::Definitions::Asia::Kuala_Lumpur
Module TZInfo::Definitions::Asia::Kuwait
Module TZInfo::Definitions::Asia::Magadan
Module TZInfo::Definitions::Asia::Muscat
Module TZInfo::Definitions::Asia::Novosibirsk
Module TZInfo::Definitions::Asia::Rangoon
Module TZInfo::Definitions::Asia::Riyadh
Module TZInfo::Definitions::Asia::Seoul
Module TZInfo::Definitions::Asia::Shanghai
Module TZInfo::Definitions::Asia::Singapore
Module TZInfo::Definitions::Asia::Taipei
Module TZInfo::Definitions::Asia::Tashkent
Module TZInfo::Definitions::Asia::Tbilisi
Module TZInfo::Definitions::Asia::Tehran
Module TZInfo::Definitions::Asia::Tokyo
Module TZInfo::Definitions::Asia::Ulaanbaatar
Module TZInfo::Definitions::Asia::Urumqi
Module TZInfo::Definitions::Asia::Vladivostok
Module TZInfo::Definitions::Asia::Yakutsk
Module TZInfo::Definitions::Asia::Yekaterinburg
Module TZInfo::Definitions::Asia::Yerevan


Module: TZInfo::Definitions::Asia::Almaty

Module | TZInfo::Definitions::Asia::Almaty
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Baghdad

Module | TZInfo::Definitions::Asia::Baghdad
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Baku

Module | TZInfo::Definitions::Asia::Baku
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Bangkok

Module | TZInfo::Definitions::Asia::Bangkok
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Chongqing

Module | TZInfo::Definitions::Asia::Chongqing
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Colombo

Module | TZInfo::Definitions::Asia::Colombo
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Dhaka

Module | TZInfo::Definitions::Asia::Dhaka
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Hong_Kong

Module | TZInfo::Definitions::Asia::Hong_Kong
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Irkutsk

Module | TZInfo::Definitions::Asia::Irkutsk
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Jakarta

Module | TZInfo::Definitions::Asia::Jakarta
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Jerusalem

Module | TZInfo::Definitions::Asia::Jerusalem
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Kabul

Module | TZInfo::Definitions::Asia::Kabul
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Kamchatka

Module | TZInfo::Definitions::Asia::Kamchatka
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Karachi

Module | TZInfo::Definitions::Asia::Karachi
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Katmandu

Module | TZInfo::Definitions::Asia::Katmandu
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Kolkata

Module | TZInfo::Definitions::Asia::Kolkata
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Krasnoyarsk

Module | TZInfo::Definitions::Asia::Krasnoyarsk
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Kuala_Lumpur

Module | TZInfo::Definitions::Asia::Kuala_Lumpur
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Kuwait

Module | TZInfo::Definitions::Asia::Kuwait
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Magadan

Module | TZInfo::Definitions::Asia::Magadan
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Muscat

Module | TZInfo::Definitions::Asia::Muscat
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Novosibirsk

Module | TZInfo::Definitions::Asia::Novosibirsk
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Rangoon

Module | TZInfo::Definitions::Asia::Rangoon
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Riyadh

Module | TZInfo::Definitions::Asia::Riyadh
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Seoul

Module | TZInfo::Definitions::Asia::Seoul
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Shanghai

Module | TZInfo::Definitions::Asia::Shanghai
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Singapore

Module | TZInfo::Definitions::Asia::Singapore
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Taipei

Module | TZInfo::Definitions::Asia::Taipei
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Tashkent

Module | TZInfo::Definitions::Asia::Tashkent
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Tbilisi

Module | TZInfo::Definitions::Asia::Tbilisi
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Tehran

Module | TZInfo::Definitions::Asia::Tehran
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Tokyo

Module | TZInfo::Definitions::Asia::Tokyo
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Ulaanbaatar

Module | TZInfo::Definitions::Asia::Ulaanbaatar
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Urumqi

Module | TZInfo::Definitions::Asia::Urumqi
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Vladivostok

Module | TZInfo::Definitions::Asia::Vladivostok
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Yakutsk

Module | TZInfo::Definitions::Asia::Yakutsk
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Yekaterinburg

Module | TZInfo::Definitions::Asia::Yekaterinburg
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Asia::Yerevan

Module | TZInfo::Definitions::Asia::Yerevan
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Atlantic

Module | TZInfo::Definitions::Atlantic
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb

Classes and Modules

Module TZInfo::Definitions::Atlantic::Azores
Module TZInfo::Definitions::Atlantic::Cape_Verde
Module TZInfo::Definitions::Atlantic::South_Georgia


Module: TZInfo::Definitions::Atlantic::Azores

Module | TZInfo::Definitions::Atlantic::Azores
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Atlantic::Cape_Verde

Module | TZInfo::Definitions::Atlantic::Cape_Verde
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Atlantic::South_Georgia

Module | TZInfo::Definitions::Atlantic::South_Georgia
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia

Module | TZInfo::Definitions::Australia
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb

Classes and Modules

Module TZInfo::Definitions::Australia::Adelaide
Module TZInfo::Definitions::Australia::Brisbane
Module TZInfo::Definitions::Australia::Darwin
Module TZInfo::Definitions::Australia::Hobart
Module TZInfo::Definitions::Australia::Melbourne
Module TZInfo::Definitions::Australia::Perth
Module TZInfo::Definitions::Australia::Sydney


Module: TZInfo::Definitions::Australia::Adelaide

Module | TZInfo::Definitions::Australia::Adelaide
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Brisbane

Module | TZInfo::Definitions::Australia::Brisbane
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Darwin

Module | TZInfo::Definitions::Australia::Darwin
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Hobart

Module | TZInfo::Definitions::Australia::Hobart
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Melbourne

Module | TZInfo::Definitions::Australia::Melbourne
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Perth

Module | TZInfo::Definitions::Australia::Perth
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Australia::Sydney

Module | TZInfo::Definitions::Australia::Sydney
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Etc

Module | TZInfo::Definitions::Etc
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb

Classes and Modules

Module TZInfo::Definitions::Etc::UTC


Module: TZInfo::Definitions::Etc::UTC

Module | TZInfo::Definitions::Etc::UTC
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb

Classes and Modules

Module TZInfo::Definitions::Europe::Amsterdam
Module TZInfo::Definitions::Europe::Athens
Module TZInfo::Definitions::Europe::Belgrade
Module TZInfo::Definitions::Europe::Berlin
Module TZInfo::Definitions::Europe::Bratislava
Module TZInfo::Definitions::Europe::Brussels
Module TZInfo::Definitions::Europe::Bucharest
Module TZInfo::Definitions::Europe::Budapest
Module TZInfo::Definitions::Europe::Copenhagen
Module TZInfo::Definitions::Europe::Dublin
Module TZInfo::Definitions::Europe::Helsinki
Module TZInfo::Definitions::Europe::Istanbul
Module TZInfo::Definitions::Europe::Kiev
Module TZInfo::Definitions::Europe::Lisbon
Module TZInfo::Definitions::Europe::Ljubljana
Module TZInfo::Definitions::Europe::London
Module TZInfo::Definitions::Europe::Madrid
Module TZInfo::Definitions::Europe::Minsk
Module TZInfo::Definitions::Europe::Moscow
Module TZInfo::Definitions::Europe::Paris
Module TZInfo::Definitions::Europe::Prague
Module TZInfo::Definitions::Europe::Riga
Module TZInfo::Definitions::Europe::Rome
Module TZInfo::Definitions::Europe::Sarajevo
Module TZInfo::Definitions::Europe::Skopje
Module TZInfo::Definitions::Europe::Sofia
Module TZInfo::Definitions::Europe::Stockholm
Module TZInfo::Definitions::Europe::Tallinn
Module TZInfo::Definitions::Europe::Vienna
Module TZInfo::Definitions::Europe::Vilnius
Module TZInfo::Definitions::Europe::Warsaw
Module TZInfo::Definitions::Europe::Zagreb


Module: TZInfo::Definitions::Europe::Amsterdam

Module | TZInfo::Definitions::Europe::Amsterdam
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Athens

Module | TZInfo::Definitions::Europe::Athens
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Belgrade

Module | TZInfo::Definitions::Europe::Belgrade
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Berlin

Module | TZInfo::Definitions::Europe::Berlin
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Bratislava

Module | TZInfo::Definitions::Europe::Bratislava
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Brussels

Module | TZInfo::Definitions::Europe::Brussels
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Bucharest

Module | TZInfo::Definitions::Europe::Bucharest
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Budapest

Module | TZInfo::Definitions::Europe::Budapest
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Copenhagen

Module | TZInfo::Definitions::Europe::Copenhagen
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Dublin

Module | TZInfo::Definitions::Europe::Dublin
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Helsinki

Module | TZInfo::Definitions::Europe::Helsinki
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Istanbul

Module | TZInfo::Definitions::Europe::Istanbul
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Kiev

Module | TZInfo::Definitions::Europe::Kiev
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Lisbon

Module | TZInfo::Definitions::Europe::Lisbon
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Ljubljana

Module | TZInfo::Definitions::Europe::Ljubljana
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::London

Module | TZInfo::Definitions::Europe::London
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Madrid

Module | TZInfo::Definitions::Europe::Madrid
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Minsk

Module | TZInfo::Definitions::Europe::Minsk
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Moscow

Module | TZInfo::Definitions::Europe::Moscow
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Paris

Module | TZInfo::Definitions::Europe::Paris
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Prague

Module | TZInfo::Definitions::Europe::Prague
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Riga

Module | TZInfo::Definitions::Europe::Riga
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Rome

Module | TZInfo::Definitions::Europe::Rome
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Sarajevo

Module | TZInfo::Definitions::Europe::Sarajevo
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Skopje

Module | TZInfo::Definitions::Europe::Skopje
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Sofia

Module | TZInfo::Definitions::Europe::Sofia
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Stockholm

Module | TZInfo::Definitions::Europe::Stockholm
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Tallinn

Module | TZInfo::Definitions::Europe::Tallinn
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Vienna

Module | TZInfo::Definitions::Europe::Vienna
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Vilnius

Module | TZInfo::Definitions::Europe::Vilnius
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Warsaw

Module | TZInfo::Definitions::Europe::Warsaw
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Europe::Zagreb

Module | TZInfo::Definitions::Europe::Zagreb
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific
In: vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb
vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb

Classes and Modules

Module TZInfo::Definitions::Pacific::Auckland
Module TZInfo::Definitions::Pacific::Fiji
Module TZInfo::Definitions::Pacific::Guam
Module TZInfo::Definitions::Pacific::Honolulu
Module TZInfo::Definitions::Pacific::Majuro
Module TZInfo::Definitions::Pacific::Midway
Module TZInfo::Definitions::Pacific::Noumea
Module TZInfo::Definitions::Pacific::Pago_Pago
Module TZInfo::Definitions::Pacific::Port_Moresby
Module TZInfo::Definitions::Pacific::Tongatapu


Module: TZInfo::Definitions::Pacific::Auckland

Module | TZInfo::Definitions::Pacific::Auckland
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Fiji

Module | TZInfo::Definitions::Pacific::Fiji
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Guam

Module | TZInfo::Definitions::Pacific::Guam
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Honolulu

Module | TZInfo::Definitions::Pacific::Honolulu
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Majuro

Module | TZInfo::Definitions::Pacific::Majuro
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Midway

Module | TZInfo::Definitions::Pacific::Midway
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Noumea

Module | TZInfo::Definitions::Pacific::Noumea
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Pago_Pago

Module | TZInfo::Definitions::Pacific::Pago_Pago
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Port_Moresby

Module | TZInfo::Definitions::Pacific::Port_Moresby
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb

Included Modules

TimezoneDefinition


Module: TZInfo::Definitions::Pacific::Tongatapu

Module | TZInfo::Definitions::Pacific::Tongatapu
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb

Included Modules

TimezoneDefinition


Class: TZInfo::InvalidTimezoneIdentifier

Class | TZInfo::InvalidTimezoneIdentifier
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Parent: | StandardError

Thrown by Timezone#get if the identifier given is not valid.


Class: TZInfo::NoOffsetsDefined

Class | TZInfo::NoOffsetsDefined
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb
Parent: | StandardError

Thrown if no offsets have been defined when calling period_for_utc or periods_for_local. Indicates an error in the timezone data.


Class: TZInfo::PeriodNotFound

Class | TZInfo::PeriodNotFound
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Parent: | StandardError

Thrown to indicate that no TimezonePeriod matching a given time could be found.


Class: TZInfo::Timezone

Class | TZInfo::Timezone
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Parent: | Object

Timezone is the base class of all timezones. It provides a factory method get to access timezones by identifier. Once a specific Timezone has been retrieved, DateTimes, Times and timestamps can be converted between the UTC and the local time for the zone. For example:

  tz = TZInfo::Timezone.get('America/New_York')
  puts tz.utc_to_local(DateTime.new(2005,8,29,15,35,0)).to_s
  puts tz.local_to_utc(Time.utc(2005,8,29,11,35,0)).to_s
  puts tz.utc_to_local(1125315300).to_s

Each time conversion method returns an object of the same type it was passed.

The timezone information all comes from the tz database (see www.twinsun.com/tz/tz-link.htm)

Methods

<=> _dump _load all all_country_zone_identifiers all_country_zones all_data_zone_identifiers all_data_zones all_identifiers all_linked_zone_identifiers all_linked_zones current_period current_period_and_time current_time_and_period eql? friendly_identifier get get_proxy hash identifier inspect local_to_utc name new now period_for_local period_for_utc periods_for_local strftime to_s us_zone_identifiers us_zones utc_to_local

Included Modules

Comparable

Public Class methods

_load(data)

Loads a marshalled Timezone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 489
489:     def self._load(data)
490:       Timezone.get(data)
491:     end
all()

Returns an array containing all the available Timezones.

Returns TimezoneProxy objects to avoid the overhead of loading Timezone definitions until a conversion is actually required.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 138
138:     def self.all
139:       get_proxies(all_identifiers)
140:     end
all_country_zone_identifiers()

Returns all the zone identifiers defined for all Countries. This is not the complete set of zone identifiers as some are not country specific (e.g. ‘Etc/GMT’). You can obtain a Timezone instance for a given identifier with the get method.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 197
197:     def self.all_country_zone_identifiers
198:       Country.all_codes.inject([]) {|zones,country|
199:         zones += Country.get(country).zone_identifiers
200:       }
201:     end
all_country_zones()

Returns all the Timezones defined for all Countries. This is not the complete set of Timezones as some are not country specific (e.g. ‘Etc/GMT’).

Returns TimezoneProxy objects to avoid the overhead of loading Timezone definitions until a conversion is actually required.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 187
187:     def self.all_country_zones
188:       Country.all_codes.inject([]) {|zones,country|
189:         zones += Country.get(country).zones
190:       }
191:     end
all_data_zone_identifiers()

Returns an array containing the identifiers of all the available Timezones that are based on data (are not links to other Timezones)..

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 160
160:     def self.all_data_zone_identifiers
161:       load_index
162:       Indexes::Timezones.data_timezones
163:     end
all_data_zones()

Returns an array containing all the available Timezones that are based on data (are not links to other Timezones).

Returns TimezoneProxy objects to avoid the overhead of loading Timezone definitions until a conversion is actually required.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 154
154:     def self.all_data_zones
155:       get_proxies(all_data_zone_identifiers)
156:     end
all_identifiers()

Returns an array containing the identifiers of all the available Timezones.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 144
144:     def self.all_identifiers
145:       load_index
146:       Indexes::Timezones.timezones
147:     end
all_linked_zone_identifiers()

Returns an array containing the identifiers of all the available Timezones that are links to other Timezones.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 176
176:     def self.all_linked_zone_identifiers
177:       load_index
178:       Indexes::Timezones.linked_timezones
179:     end
all_linked_zones()

Returns an array containing all the available Timezones that are links to other Timezones.

Returns TimezoneProxy objects to avoid the overhead of loading Timezone definitions until a conversion is actually required.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 170
170:     def self.all_linked_zones
171:       get_proxies(all_linked_zone_identifiers)
172:     end
get(identifier)

Returns a timezone by its identifier (e.g. "Europe/London", "America/Chicago" or "UTC").

Raises InvalidTimezoneIdentifier if the timezone couldn‘t be found.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 78
 78:     def self.get(identifier)
 79:       instance = @@loaded_zones[identifier]
 80:       unless instance
 81:         raise InvalidTimezoneIdentifier, 'Invalid identifier' if identifier !~ /^[A-z0-9\+\-_]+(\/[A-z0-9\+\-_]+)*$/
 82:         identifier = identifier.gsub(/-/, '__m__').gsub(/\+/, '__p__')
 83:         begin
 84:           # Use a temporary variable to avoid an rdoc warning
 85:           file = "tzinfo/definitions/#{identifier}"
 86:           require file
 87:
 88:           m = Definitions
 89:           identifier.split(/\//).each {|part|
 90:             m = m.const_get(part)
 91:           }
 92:
 93:           info = m.get
 94:
 95:           # Could make Timezone subclasses register an interest in an info
 96:           # type. Since there are currently only two however, there isn't
 97:           # much point.
 98:           if info.kind_of?(DataTimezoneInfo)
 99:             instance = DataTimezone.new(info)
100:           elsif info.kind_of?(LinkedTimezoneInfo)
101:             instance = LinkedTimezone.new(info)
102:           else
103:             raise InvalidTimezoneIdentifier, "No handler for info type #{info.class}"
104:           end
105:
106:           @@loaded_zones[instance.identifier] = instance
107:         rescue LoadError, NameError => e
108:           raise InvalidTimezoneIdentifier, e.message
109:         end
110:       end
111:
112:       instance
113:     end
get_proxy(identifier)

Returns a proxy for the Timezone with the given identifier. The proxy will cause the real timezone to be loaded when an attempt is made to find a period or convert a time. get_proxy will not validate the identifier. If an invalid identifier is specified, no exception will be raised until the proxy is used.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 120
120:     def self.get_proxy(identifier)
121:       TimezoneProxy.new(identifier)
122:     end
new(identifier = nil)

If identifier is nil calls super(), otherwise calls get. An identfier should always be passed in when called externally.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 126
126:     def self.new(identifier = nil)
127:       if identifier
128:         get(identifier)
129:       else
130:         super()
131:       end
132:     end
us_zone_identifiers()

Returns all US zone identifiers. A shortcut for TZInfo::Country.get(‘US’).zone_identifiers.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 214
214:     def self.us_zone_identifiers
215:       Country.get('US').zone_identifiers
216:     end
us_zones()

Returns all US Timezone instances. A shortcut for TZInfo::Country.get(‘US’).zones.

Returns TimezoneProxy objects to avoid the overhead of loading Timezone definitions until a conversion is actually required.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 208
208:     def self.us_zones
209:       Country.get('US').zones
210:     end

Public Instance methods

<=>(tz)

Compares two Timezones based on their identifier. Returns -1 if tz is less than self, 0 if tz is equal to self and +1 if tz is greater than self.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 468
468:     def <=>(tz)
469:       identifier <=> tz.identifier
470:     end
_dump(limit)

Dumps this Timezone for marshalling.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 484
484:     def _dump(limit)
485:       identifier
486:     end
current_period()

Returns the TimezonePeriod for the current time.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 430
430:     def current_period
431:       period_for_utc(Time.now.utc)
432:     end
current_period_and_time()

Returns the current Time and TimezonePeriod as an array. The first element is the time, the second element is the period.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 436
436:     def current_period_and_time
437:       utc = Time.now.utc
438:       period = period_for_utc(utc)
439:       [period.to_local(utc), period]
440:     end
current_time_and_period()

Alias for current_period_and_time

eql?(tz)

Returns true if and only if the identifier of tz is equal to the identifier of this Timezone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 474
474:     def eql?(tz)
475:       self == tz
476:     end
friendly_identifier(skip_first_part = false)

Returns a friendlier version of the identifier. Set skip_first_part to omit the first part of the identifier (typically a region name) where there is more than one part.

For example:

  Timezone.get('Europe/Paris').friendly_identifier(false)          #=> "Europe - Paris"
  Timezone.get('Europe/Paris').friendly_identifier(true)           #=> "Paris"
  Timezone.get('America/Indiana/Knox').friendly_identifier(false)  #=> "America - Knox, Indiana"
  Timezone.get('America/Indiana/Knox').friendly_identifier(true)   #=> "Knox, Indiana"

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 249
249:     def friendly_identifier(skip_first_part = false)
250:       parts = identifier.split('/')
251:       if parts.empty?
252:         # shouldn't happen
253:         identifier
254:       elsif parts.length == 1
255:         parts[0]
256:       else
257:         if skip_first_part
258:           result = ''
259:         else
260:           result = parts[0] + ' - '
261:         end
262:
263:         parts[1, parts.length - 1].reverse_each {|part|
264:           part.gsub!(/_/, ' ')
265:
266:           if part.index(/[a-z]/)
267:             # Missing a space if a lower case followed by an upper case and the
268:             # name isn't McXxxx.
269:             part.gsub!(/([^M][a-z])([A-Z])/, '\1 \2')
270:             part.gsub!(/([M][a-bd-z])([A-Z])/, '\1 \2')
271:
272:             # Missing an apostrophe if two consecutive upper case characters.
273:             part.gsub!(/([A-Z])([A-Z])/, '\1\'\2')
274:           end
275:
276:           result << part
277:           result << ', '
278:         }
279:
280:         result.slice!(result.length - 2, 2)
281:         result
282:       end
283:     end
hash()

Returns a hash of this Timezone.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 479
479:     def hash
480:       identifier.hash
481:     end
identifier()

The identifier of the timezone, e.g. "Europe/Paris".

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 219
219:     def identifier
220:       raise UnknownTimezone, 'TZInfo::Timezone constructed directly'
221:     end
inspect()

Returns internal object state as a programmer-readable string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 235
235:     def inspect
236:       "#<#{self.class}: #{identifier}>"
237:     end
local_to_utc(local, dst = nil) {|periods| ...}

Converts a time in the local timezone to UTC. local can either be a DateTime, Time or timestamp (Time.to_i). The returned time has the same type as local. Any timezone information in local is ignored (it is treated as a local time).

Warning: There are local times that have no equivalent UTC times (e.g. in the transition from standard time to daylight savings time). There are also local times that have more than one UTC equivalent (e.g. in the transition from daylight savings time to standard time).

In the first case (no equivalent UTC time), a PeriodNotFound exception will be raised.

In the second case (more than one equivalent UTC time), an AmbiguousTime exception will be raised unless the optional dst parameter or block handles the ambiguity.

If the ambiguity is due to a transition from daylight savings time to standard time, the dst parameter can be used to select whether the daylight savings time or local time is used. For example,

  Timezone.get('America/New_York').local_to_utc(DateTime.new(2004,10,31,1,30,0))

would raise an AmbiguousTime exception.

Specifying dst=true would return 2004-10-31 5:30:00. Specifying dst=false would return 2004-10-31 6:30:00.

If the dst parameter does not resolve the ambiguity, and a block is specified, it is called. The block must take a single parameter - an array of the periods that need to be resolved. The block can return a single period to use to convert the time or return nil or an empty array to cause an AmbiguousTime exception to be raised.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 412
412:     def local_to_utc(local, dst = nil)
413:       TimeOrDateTime.wrap(local) {|wrapped|
414:         if block_given?
415:           period = period_for_local(wrapped, dst) {|periods| yield periods }
416:         else
417:           period = period_for_local(wrapped, dst)
418:         end
419:
420:         period.to_utc(wrapped)
421:       }
422:     end
name()

An alias for identifier.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 224
224:     def name
225:       # Don't use alias, as identifier gets overridden.
226:       identifier
227:     end
now()

Returns the current time in the timezone as a Time.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 425
425:     def now
426:       utc_to_local(Time.now.utc)
427:     end
period_for_local(local, dst = nil) {|results| ...}

Returns the TimezonePeriod for the given local time. local can either be a DateTime, Time or integer timestamp (Time.to_i). Any timezone information in local is ignored (it is treated as a time in the current timezone).

Warning: There are local times that have no equivalent UTC times (e.g. in the transition from standard time to daylight savings time). There are also local times that have more than one UTC equivalent (e.g. in the transition from daylight savings time to standard time).

In the first case (no equivalent UTC time), a PeriodNotFound exception will be raised.

In the second case (more than one equivalent UTC time), an AmbiguousTime exception will be raised unless the optional dst parameter or block handles the ambiguity.

If the ambiguity is due to a transition from daylight savings time to standard time, the dst parameter can be used to select whether the daylight savings time or local time is used. For example,

  Timezone.get('America/New_York').period_for_local(DateTime.new(2004,10,31,1,30,0))

would raise an AmbiguousTime exception.

Specifying dst=true would the daylight savings period from April to October 2004. Specifying dst=false would return the standard period from October 2004 to April 2005.

If the dst parameter does not resolve the ambiguity, and a block is specified, it is called. The block must take a single parameter - an array of the periods that need to be resolved. The block can select and return a single period or return nil or an empty array to cause an AmbiguousTime exception to be raised.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 334
334:     def period_for_local(local, dst = nil)
335:       results = periods_for_local(local)
336:
337:       if results.empty?
338:         raise PeriodNotFound
339:       elsif results.size < 2
340:         results.first
341:       else
342:         # ambiguous result try to resolve
343:
344:         if !dst.nil?
345:           matches = results.find_all {|period| period.dst? == dst}
346:           results = matches if !matches.empty?
347:         end
348:
349:         if results.size < 2
350:           results.first
351:         else
352:           # still ambiguous, try the block
353:
354:           if block_given?
355:             results = yield results
356:           end
357:
358:           if results.is_a?(TimezonePeriod)
359:             results
360:           elsif results && results.size == 1
361:             results.first
362:           else
363:             raise AmbiguousTime, "#{local} is an ambiguous local time."
364:           end
365:         end
366:       end
367:     end
period_for_utc(utc)

Returns the TimezonePeriod for the given UTC time. utc can either be a DateTime, Time or integer timestamp (Time.to_i). Any timezone information in utc is ignored (it is treated as a UTC time).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 288
288:     def period_for_utc(utc)
289:       raise UnknownTimezone, 'TZInfo::Timezone constructed directly'
290:     end
periods_for_local(local)

Returns the set of TimezonePeriod instances that are valid for the given local time as an array. If you just want a single period, use period_for_local instead and specify how ambiguities should be resolved. Returns an empty array if no periods are found for the given time.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 296
296:     def periods_for_local(local)
297:       raise UnknownTimezone, 'TZInfo::Timezone constructed directly'
298:     end
strftime(format, utc = Time.now.utc)

Converts a time in UTC to local time and returns it as a string according to the given format. The formatting is identical to Time.strftime and DateTime.strftime, except %Z is replaced with the timezone abbreviation for the specified time (for example, EST or EDT).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 448
448:     def strftime(format, utc = Time.now.utc)
449:       period = period_for_utc(utc)
450:       local = period.to_local(utc)
451:       local = Time.at(local).utc unless local.kind_of?(Time) || local.kind_of?(DateTime)
452:       abbreviation = period.abbreviation.to_s.gsub(/%/, '%%')
453:
454:       format = format.gsub(/(.?)%Z/) do
455:         if $1 == '%'
456:           # return %%Z so the real strftime treats it as a literal %Z too
457:           '%%Z'
458:         else
459:           "#$1#{abbreviation}"
460:         end
461:       end
462:
463:       local.strftime(format)
464:     end
to_s()

Returns a friendlier version of the identifier.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 230
230:     def to_s
231:       friendly_identifier
232:     end
utc_to_local(utc)

Converts a time in UTC to the local timezone. utc can either be a DateTime, Time or timestamp (Time.to_i). The returned time has the same type as utc. Any timezone information in utc is ignored (it is treated as a UTC time).

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb, line 373
373:     def utc_to_local(utc)
374:       TimeOrDateTime.wrap(utc) {|wrapped|
375:         period_for_utc(wrapped).to_local(wrapped)
376:       }
377:     end


Class: TZInfo::TimezonePeriod

Class | TZInfo::TimezonePeriod
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb
Parent: | Object

A period of time in a timezone where the same offset from UTC applies.

All the methods that take times accept instances of Time, DateTime or integer timestamps.

Methods

== abbreviation dst? eql? hash inspect local_after_start? local_before_end? local_end local_start new std_offset to_local to_utc utc_after_start? utc_before_end? utc_end utc_offset utc_start utc_total_offset utc_total_offset_rational valid_for_local? valid_for_utc? zone_identifier

Attributes

end_transition | [R] | The TimezoneTransitionInfo that defines the end of this TimezonePeriod (may be nil if unbounded).
offset | [R] | The TimezoneOffsetInfo for this period.
start_transition | [R] | The TimezoneTransitionInfo that defines the start of this TimezonePeriod (may be nil if unbounded).

Public Class methods

new(start_transition, end_transition, offset = nil)

Initializes a new TimezonePeriod.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 44
44:     def initialize(start_transition, end_transition, offset = nil)
45:       @start_transition = start_transition
46:       @end_transition = end_transition
47:
48:       if offset
49:         raise ArgumentError, 'Offset specified with transitions' if @start_transition || @end_transition
50:         @offset = offset
51:       else
52:         if @start_transition
53:           @offset = @start_transition.offset
54:         elsif @end_transition
55:           @offset = @end_transition.previous_offset
56:         else
57:           raise ArgumentError, 'No offset specified and no transitions to determine it from'
58:         end
59:       end
60:
61:       @utc_total_offset_rational = nil
62:     end

Public Instance methods

==(p)

Returns true if this TimezonePeriod is equal to p. This compares the start_transition, end_transition and offset using ==.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 170
170:     def ==(p)
171:       p.respond_to?(:start_transition) && p.respond_to?(:end_transition) &&
172:         p.respond_to?(:offset) && start_transition == p.start_transition &&
173:         end_transition == p.end_transition && offset == p.offset
174:     end
abbreviation()

The identifier of this period, e.g. "GMT" (Greenwich Mean Time) or "BST" (British Summer Time) for "Europe/London". The returned identifier is a symbol.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 79
79:     def abbreviation
80:       @offset.abbreviation
81:     end
dst?()

true if daylight savings is in effect for this period; otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 120
120:     def dst?
121:       @offset.dst?
122:     end
eql?(p)

Returns true if this TimezonePeriods is equal to p. This compares the start_transition, end_transition and offset using eql?

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 178
178:     def eql?(p)
179:       p.respond_to?(:start_transition) && p.respond_to?(:end_transition) &&
180:         p.respond_to?(:offset) && start_transition.eql?(p.start_transition) &&
181:         end_transition.eql?(p.end_transition) && offset.eql?(p.offset)
182:     end
hash()

Returns a hash of this TimezonePeriod.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 185
185:     def hash
186:       result = @start_transition.hash ^ @end_transition.hash
187:       result ^= @offset.hash unless @start_transition || @end_transition
188:       result
189:     end
inspect()

Returns internal object state as a programmer-readable string.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 192
192:     def inspect
193:       result = "#<#{self.class}: #{@start_transition.inspect},#{@end_transition.inspect}"
194:       result << ",#{@offset.inspect}>" unless @start_transition || @end_transition
195:       result + '>'
196:     end
local_after_start?(local)

true if the given local DateTime is after the start of the period (inclusive); otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 148
148:     def local_after_start?(local)
149:       !@start_transition || @start_transition.local_start <= local
150:     end
local_before_end?(local)

true if the given local DateTime is before the end of the period (exclusive); otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 154
154:     def local_before_end?(local)
155:       !@end_transition || @end_transition.local_end > local
156:     end
local_end()

The end time of the period in local time as a DateTime. May be nil if unbounded.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 115
115:     def local_end
116:       @end_transition ? @end_transition.local_end.to_datetime : nil
117:     end
local_start()

The start time of the period in local time as a DateTime. May be nil if unbounded.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 109
109:     def local_start
110:       @start_transition ? @start_transition.local_start.to_datetime : nil
111:     end
std_offset()

Offset from the local time where daylight savings is in effect (seconds). E.g.: utc_offset could be -5 hours. Normally, std_offset would be 0. During daylight savings, std_offset would typically become +1 hours.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 72
72:     def std_offset
73:       @offset.std_offset
74:     end
to_local(utc)

Converts a UTC DateTime to local time based on the offset of this period.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 159
159:     def to_local(utc)
160:       @offset.to_local(utc)
161:     end
to_utc(local)

Converts a local DateTime to UTC based on the offset of this period.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 164
164:     def to_utc(local)
165:       @offset.to_utc(local)
166:     end
utc_after_start?(utc)

true if the given UTC DateTime is after the start of the period (inclusive); otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 131
131:     def utc_after_start?(utc)
132:       !@start_transition || @start_transition.at <= utc
133:     end
utc_before_end?(utc)

true if the given UTC DateTime is before the end of the period (exclusive); otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 137
137:     def utc_before_end?(utc)
138:       !@end_transition || @end_transition.at > utc
139:     end
utc_end()

The end time of the period in UTC as a DateTime. May be nil if unbounded.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 103
103:     def utc_end
104:       @end_transition ? @end_transition.at.to_datetime : nil
105:     end
utc_offset()

Base offset of the timezone from UTC (seconds).

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 65
65:     def utc_offset
66:       @offset.utc_offset
67:     end
utc_start()

The start time of the period in UTC as a DateTime. May be nil if unbounded.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 98
 98:     def utc_start
 99:       @start_transition ? @start_transition.at.to_datetime : nil
100:     end
utc_total_offset()

Total offset from UTC (seconds). Equal to utc_offset + std_offset.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 85
85:     def utc_total_offset
86:       @offset.utc_total_offset
87:     end
utc_total_offset_rational()

Total offset from UTC (days). Result is a Rational.

[Source]

    # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 90
90:     def utc_total_offset_rational
91:       unless @utc_total_offset_rational
92:         @utc_total_offset_rational = OffsetRationals.rational_for_offset(utc_total_offset)
93:       end
94:       @utc_total_offset_rational
95:     end
valid_for_local?(local)

true if this period is valid for the given local DateTime; otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 142
142:     def valid_for_local?(local)
143:       local_after_start?(local) && local_before_end?(local)
144:     end
valid_for_utc?(utc)

true if this period is valid for the given UTC DateTime; otherwise false.

[Source]

     # File vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb, line 125
125:     def valid_for_utc?(utc)
126:       utc_after_start?(utc) && utc_before_end?(utc)
127:     end
zone_identifier()

Alias for abbreviation


Class: TZInfo::UnknownTimezone

Class | TZInfo::UnknownTimezone
In: | vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb
Parent: | StandardError

Thrown if an attempt is made to use a timezone created with Timezone.new(nil).


Module: Test

Module | Test
In: | vendor/rails/activesupport/lib/active_support/testing/deprecation.rb

Classes and Modules

Module Test::Unit


Module: Test::Unit

Module | Test::Unit
In: | vendor/rails/activesupport/lib/active_support/testing/deprecation.rb


Module: ActiveResource

Module | ActiveResource
In: | vendor/rails/activeresource/lib/active_resource.rb vendor/rails/activeresource/lib/active_resource/base.rb vendor/rails/activeresource/lib/active_resource/connection.rb vendor/rails/activeresource/lib/active_resource/custom_methods.rb vendor/rails/activeresource/lib/active_resource/formats/json_format.rb vendor/rails/activeresource/lib/active_resource/formats/xml_format.rb vendor/rails/activeresource/lib/active_resource/formats.rb vendor/rails/activeresource/lib/active_resource/http_mock.rb vendor/rails/activeresource/lib/active_resource/validations.rb vendor/rails/activeresource/lib/active_resource/version.rb

Included Modules

Validations CustomMethods

Classes and Modules

Module ActiveResource::CustomMethods
Module ActiveResource::Formats
Module ActiveResource::Validations
Class ActiveResource::BadRequest
Class ActiveResource::Base
Class ActiveResource::ClientError
Class ActiveResource::Connection
Class ActiveResource::Errors
Class ActiveResource::ForbiddenAccess
Class ActiveResource::HttpMock
Class ActiveResource::InvalidRequestError
Class ActiveResource::Request
Class ActiveResource::ResourceConflict
Class ActiveResource::ResourceNotFound
Class ActiveResource::Response
Class ActiveResource::ServerError
Class ActiveResource::TimeoutError
Class ActiveResource::UnauthorizedAccess