Merge remote branch 'docrails/master'

This commit is contained in:
Xavier Noria
2010-07-26 00:23:57 +02:00
16 changed files with 240 additions and 417 deletions

View File

@@ -119,33 +119,29 @@ The Base class has the full list of configuration options. Here's an example:
: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.
Additionally, Action Mailer requires the Mail gem, http://github.com/mikel/mail
== Download
== Download and installation
The latest version of Action Mailer can be installed with Rubygems:
* gem install actionmailer
% [sudo] gem install actionmailer
Documentation can be found at
Source code can be downloaded as part of the Rails project on GitHub
* http://github.com/rails/rails/tree/master/actionmailer/
* http://api.rubyonrails.org
== License
Action Mailer is released under the MIT license.
== Support
The Action Mailer homepage is http://www.rubyonrails.org. You can find
the Action Mailer RubyForge page at http://rubyforge.org/projects/actionmailer.
And as Jim from Rake says:
API documentation is at
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.
* http://api.rubyonrails.com
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets

View File

@@ -1,25 +1,35 @@
= Action Pack -- On rails from request to response
= Action Pack -- 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 is a framework for handling and responding to web requests. It it
provides mechanisms for *routing* (mapping request URLs to actions), defining
*controllers* that implement actions, and generating responses by rendering
*views*, which are templates of various formats. In short, Action Pack
provides the view and controller layers in the MVC paradigm.
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.
It consists of several modules:
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.
* Action Dispatch, which parses information about the web request, handles
routing as defined by the user, and does advanced processing related to HTTP
such as MIME-type negotiation, decoding parameters in POST/PUT bodies,
handling HTTP caching logic, cookies and sessions.
A short rundown of the major features:
* Action Controller, which provides a base controller class that can be
subclassed to implement filters and actions to handle requests. The result
of an action is typically content generated from views.
* Action View, which handles view template lookup and rendering, and provides
view helpers that assist when building HTML forms, Atom feeds and more.
Template formats that Action View handles are ERb (embedded Ruby, typically
used to inline short Ruby snippets inside HTML), XML Builder and RJS
(dynamically generated JavaScript from Ruby code).
With the Ruby on Rails framework, users only directly interface with the
Action Controller module. Necessary Action Dispatch functionality is activated
by default and Action View rendering is implicitly triggered by Action
Controller. However, these modules are designed to function on their own and
can be used outside of Rails.
A short rundown of some of the major features:
* Actions grouped in controller as methods instead of separate command objects
and can therefore share helper methods
@@ -31,26 +41,29 @@ A short rundown of the major features:
def update
@customer = find_customer
@customer.attributes = params[:customer]
@customer.save ?
redirect_to(:action => "show") :
render(:action => "edit")
if @customer.update_attributes(params[:customer])
redirect_to :action => "show"
else
render :action => "edit"
end
end
private
def find_customer() Customer.find(params[:id]) end
def find_customer
Customer.find params[:id]
end
end
{Learn more}[link:classes/ActionController/Base.html]
* Embedded Ruby for templates (no new "easy" template language)
* ERb templates (static content mixed with dynamic output from ruby)
<% for post in @posts %>
Title: <%= post.title %>
<% end %>
All post titles: <%= @posts.collect{ |p| p.title }.join ", " %>
All post titles: <%= @posts.collect{ |p| p.title }.join(", ") %>
<% unless @person.is_client? %>
Not for clients to see...
@@ -59,7 +72,7 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionView.html]
* Builder-based templates (great for XML content, like RSS)
* "Builder" templates (great for XML content, like RSS)
xml.rss("version" => "2.0") do
xml.channel do
@@ -84,11 +97,16 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionView/Base.html]
* Filters for pre and post processing of the response (as methods, procs, and classes)
* Filters for pre- and post-processing of the response
class WeblogController < ActionController::Base
# filters as methods
before_filter :authenticate, :cache, :audit
# filter as a proc
after_filter { |c| c.response.body = Gzip::compress(c.response.body) }
# class filter
after_filter LocalizeFilter
def index
@@ -111,16 +129,14 @@ A short rundown of the major features:
* Helpers for forms, dates, action links, and text
<%= text_field "post", "title", "size" => 30 %>
<%= html_date_select(Date.today) %>
<%= text_field_tag "post", "title", "size" => 30 %>
<%= link_to "New post", :controller => "post", :action => "new" %>
<%= truncate(post.title, :length => 25) %>
{Learn more}[link:classes/ActionView/Helpers.html]
* Layout sharing for template reuse (think simple version of Struts
Tiles[http://jakarta.apache.org/struts/userGuide/dev_tiles.html])
* Layout sharing for template reuse
class WeblogController < ActionController::Base
layout "weblog_layout"
@@ -141,22 +157,22 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionController/Layout/ClassMethods.html]
* Routing makes pretty urls incredibly easy
* Routing makes pretty URLs incredibly easy
map.connect 'clients/:client_name/:project_name/:controller/:action'
match '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]
Accessing "/clients/37signals/basecamp/project/index" calls ProjectController#index with
{ "client_name" => "37signals", "project_name" => "basecamp" } in `params`
From that URL, you can rewrite the redirect in a number of ways:
From that action, you can write the redirect in a number of ways:
redirect_to(:action => "edit") =>
/clients/37signals/basecamp/project/dash
/clients/37signals/basecamp/project/edit
redirect_to(:client_name => "nextangle", :project_name => "rails") =>
/clients/nextangle/rails/project/dash
/clients/nextangle/rails/project/index
{Learn more}[link:classes/ActionController/Base.html]
{Learn more}[link:classes/ActionDispatch/Routing.html]
* Easy testing of both controller and rendered template through ActionController::TestCase
@@ -233,62 +249,6 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionController/Rescue.html]
* 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}[link:classes/ActionController/Scaffolding/ClassMethods.html]
* 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}[link:classes/ActionView/Helpers/ActiveRecordHelper.html]
* 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
@@ -355,15 +315,15 @@ 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
== Download and installation
The latest version of Action Pack can be installed with Rubygems:
* gem install actionpack
% [sudo] gem install actionpack
Documentation can be found at
Source code can be downloaded as part of the Rails project on GitHub
* http://api.rubyonrails.org
* http://github.com/rails/rails/tree/master/actionpack/
== License
@@ -373,10 +333,10 @@ Action Pack is released under the MIT license.
== Support
The Action Pack homepage is http://www.rubyonrails.org. You can find
the Action Pack RubyForge page at http://rubyforge.org/projects/actionpack.
And as Jim from Rake says:
API documentation is at
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.
* http://api.rubyonrails.com
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets

View File

@@ -102,7 +102,7 @@ module ActionView
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
# Returns the JavaScript needed for a remote function.
# Takes the same arguments as link_to_remote.
# See the link_to_remote documentation at http://github.com/rails/prototype_legacy_helper as it takes the same arguments.
#
# Example:
# # Generates: <select id="options" onchange="new Ajax.Updater('options',

View File

@@ -1,21 +1,21 @@
= Active Model - defined interfaces for Rails
Prior to Rails 3.0, if a plugin or gem developer wanted to be able to have
an object interact with Action Pack helpers, it was required to either
copy chunks of code from Rails, or monkey patch entire helpers to make them
handle objects that did not look like Active Record. This generated code
duplication and fragile applications that broke on upgrades.
Active Model is a solution for this problem.
Active Model provides a known set of interfaces that your objects can implement
to then present a common interface to the Action Pack helpers. You can include
functionality from the following modules:
= Active Model -- model interfaces for Rails
* Adding attribute magic to your objects
Active Model provides a known set of interfaces for usage in model classes.
They allow for Action Pack helpers to interact with non-ActiveRecord models,
for example. Active Model also helps building custom ORMs for use outside of
the Rails framework.
Prior to Rails 3.0, if a plugin or gem developer wanted to have an object
interact with Action Pack helpers, it was required to either copy chunks of
code from Rails, or monkey patch entire helpers to make them handle objects
that did not exacly conform to the Active Record interface. This would result
in code duplication and fragile applications that broke on upgrades.
Active Model solves this. You can include functionality from the following
modules:
* Add attribute magic to objects
Add prefixes and suffixes to defined attribute methods...
class Person
include ActiveModel::AttributeMethods
@@ -23,17 +23,18 @@ functionality from the following modules:
define_attribute_methods [:name, :age]
attr_accessor :name, :age
def clear_attribute(attr)
send("#{attr}=", nil)
end
end
...gives you clear_name, clear_age.
person.clear_name
person.clear_age
{Learn more}[link:classes/ActiveModel/AttributeMethods.html]
* Adding callbacks to your objects
* Callbacks for certain operations
class Person
extend ActiveModel::Callbacks
@@ -45,26 +46,16 @@ functionality from the following modules:
end
end
end
...gives you before_create, around_create and after_create class methods that
wrap your create method.
This generates +before_create+, +around_create+ and +after_create+
class methods that wrap your create method.
{Learn more}[link:classes/ActiveModel/CallBacks.html]
* For classes that already look like an Active Record object
* Tracking value changes
class Person
include ActiveModel::Conversion
end
...returns the class itself when sent :to_model
The ActiveModel::Dirty module allows for tracking attribute changes:
{Learn more}[link:classes/ActiveModel/Conversion.html]
* Tracking changes in your object
Provides all the value tracking features implemented by ActiveRecord...
person = Person.new
person.name # => nil
person.changed? # => false
@@ -75,14 +66,14 @@ functionality from the following modules:
person.name = 'robert'
person.save
person.previous_changes # => {'name' => ['bob, 'robert']}
{Learn more}[link:classes/ActiveModel/Dirty.html]
* Adding +errors+ support to your object
* Adding +errors+ interface to objects
Provides the error messages to allow your object to interact with Action Pack
helpers seamlessly...
Exposing error messages allows objects to interact with Action Pack
helpers seamlessly.
class Person
def initialize
@@ -102,51 +93,38 @@ functionality from the following modules:
end
... gives you...
person.errors.full_messages
# => ["Name Can not be nil"]
person.errors.full_messages
# => ["Name Can not be nil"]
{Learn more}[link:classes/ActiveModel/Errors.html]
* Testing the compliance of your object
* Model name introspection
Use ActiveModel::Lint to test the compliance of your object to the
basic ActiveModel API...
{Learn more}[link:classes/ActiveModel/Lint/Tests.html]
* Providing a human face to your object
ActiveModel::Naming provides your model with the model_name convention
and a human_name attribute...
class NamedPerson
extend ActiveModel::Naming
end
...gives you...
NamedPerson.model_name #=> "NamedPerson"
NamedPerson.model_name.human #=> "Named person"
{Learn more}[link:classes/ActiveModel/Naming.html]
* Adding observer support to your objects
* Observer support
ActiveModel::Observers allows your object to implement the Observer
pattern in a Rails App and take advantage of all the standard observer
functions.
ActiveModel::Observers allows your object to implement the Observer
pattern in a Rails App and take advantage of all the standard observer
functions.
{Learn more}[link:classes/ActiveModel/Observer.html]
* Making your object serializable
* Making objects serializable
ActiveModel::Serialization provides a standard interface for your object
to provide to_json or to_xml serialization...
ActiveModel::Serialization provides a standard interface for your object
to provide +to_json+ or +to_xml+ serialization.
s = SerialPerson.new
s.serializable_hash # => {"name"=>nil}
s.to_json # => "{\"name\":null}"
@@ -154,36 +132,36 @@ functionality from the following modules:
{Learn more}[link:classes/ActiveModel/Serialization.html]
* Integrating with Rail's internationalization (i18n) handling through
ActiveModel::Translations...
* Internationalization (i18n) support
class Person
extend ActiveModel::Translation
end
Person.human_attribute_name('my_attribute')
#=> "My attribute"
{Learn more}[link:classes/ActiveModel/Translation.html]
* Providing a full Validation stack for your objects...
* Validation support
class Person
include ActiveModel::Validations
attr_accessor :first_name, :last_name
validates_each :first_name, :last_name do |record, attr, value|
record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
end
end
person = Person.new
person.first_name = 'zoolander'
person.valid? #=> false
person.valid? #=> false
{Learn more}[link:classes/ActiveModel/Validations.html]
* Make custom validators
* Custom validators
class Person
include ActiveModel::Validations
@@ -196,7 +174,7 @@ functionality from the following modules:
record.errors[:name] = "must exist" if record.name.blank?
end
end
p = ValidatorPerson.new
p.valid? #=> false
p.errors.full_messages #=> ["Name must exist"]

View File

@@ -1,49 +1,52 @@
= Active Record -- Object-relation mapping put on rails
= Active Record -- Object-relational 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[http://www.martinfowler.com/eaaCatalog/activeRecord.html]
by the same name as described by Martin Fowler:
Active Record connects classes to relational database tables to establish an
almost zero-configuration persistence layer for applications. The library
provides a base class that, when subclassed, sets up a mapping between the new
class and an existing table in the database. In context of an application,
these classes are commonly referred to as *models*. Models can also be
connected to other models; this is done by defining *associations*.
"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 relies heavily on naming in that it uses class and association
names to establish mappings between respective database tables and foreign key
columns. Although these mappings can be defined explicitly, it's recommended
to follow naming conventions, especially when getting started with the
library.
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:
A short rundown of some of the major features:
* Automated mapping between classes and tables, attributes and columns.
class Product < ActiveRecord::Base; end
class Product < ActiveRecord::Base
end
...is automatically mapped to the table named "products", such as:
The Product class is automatically mapped to the table named "products",
which might look like this:
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)
This would also define the following accessors: `Product#name` and
`Product#name=(new_name)`
{Learn more}[link:classes/ActiveRecord/Base.html]
* Associations between objects controlled by simple meta-programming macros.
* Associations between objects defined by simple class methods.
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :conglomorate
belongs_to :conglomerate
end
{Learn more}[link:classes/ActiveRecord/Associations/ClassMethods.html]
* Aggregations of value objects controlled by simple meta-programming macros.
* Aggregations of value objects.
class Account < ActiveRecord::Base
composed_of :balance, :class_name => "Money",
@@ -65,23 +68,19 @@ A short rundown of the major features:
end
{Learn more}[link:classes/ActiveRecord/Validations.html]
* Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
* Callbacks available for 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})'
before_destroy :invalidate_payment_plan
# the `invalidate_payment_plan` method gets called just before Person#destroy
end
{Learn more}[link:classes/ActiveRecord/Callbacks.html]
* Observers for the entire lifecycle
* Observers that react to changes in a model
class CommentObserver < ActiveRecord::Observer
def after_create(comment) # is called just after Comment#save
@@ -122,40 +121,24 @@ A short rundown of the major features:
{Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html]
* Direct manipulation (instead of service invocation)
* Database abstraction through simple adapters
So instead of (Hibernate[http://www.hibernate.org/] example):
# connect to SQLite3
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "dbfile.sqlite3")
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
# connect to MySQL with authentication
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "me",
:password => "secret",
:database => "activerecord"
)
Active Record lets you:
pkId = 1234
cat = Cat.find(pkId)
# something even more interesting involving the same cat...
cat.save
{Learn more}[link:classes/ActiveRecord/Base.html]
* 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}[link:classes/ActiveRecord/Base.html#M000081] and read about the built-in support for
MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html], PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], SQLite[link:classes/ActiveRecord/ConnectionAdapters/SQLiteAdapter.html], Oracle[link:classes/ActiveRecord/ConnectionAdapters/OracleAdapter.html], SQLServer[link:classes/ActiveRecord/ConnectionAdapters/SQLServerAdapter.html], and DB2[link:classes/ActiveRecord/ConnectionAdapters/DB2Adapter.html].
{Learn more}[link:classes/ActiveRecord/Base.html] and read about the built-in support for
MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html],
PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], and
SQLite3[link:classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html].
* Logging support for Log4r[http://log4r.sourceforge.net] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc]
@@ -169,11 +152,11 @@ A short rundown of the major features:
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
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
@@ -186,111 +169,16 @@ A short rundown of the major features:
{Learn more}[link:classes/ActiveRecord/Migration.html]
== 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 is an implementation of the object-relational mapping (ORM)
pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] by the same
name 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 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
@@ -307,15 +195,15 @@ Admit the Database:
* Doesn't attempt to duplicate or replace data definitions
== Download
== Download and installation
The latest version of Active Record can be installed with Rubygems:
* gem install activerecord
% [sudo] gem install activerecord
Documentation can be found at
Source code can be downloaded as part of the Rails project on GitHub
* http://api.rubyonrails.org
* http://github.com/rails/rails/tree/master/activerecord/
== License
@@ -325,12 +213,10 @@ Active Record is released under the MIT license.
== Support
The Active Record homepage is http://www.rubyonrails.com. You can find the Active Record
RubyForge page at http://rubyforge.org/projects/activerecord. And as Jim from Rake says:
API documentation is at
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.
* http://api.rubyonrails.com
For other information, feel free to ask on the rubyonrails-talk
(http://groups.google.com/group/rubyonrails-talk) mailing list.
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets

View File

@@ -1030,7 +1030,7 @@ module ActiveRecord #:nodoc:
# class Article < ActiveRecord::Base
# def self.find_with_exclusive_scope
# with_scope(:find => where(:blog_id => 1).limit(1)) do
# with_exclusive_scope(:find => limit(10))
# with_exclusive_scope(:find => limit(10)) do
# all # => SELECT * from articles LIMIT 10
# end
# end

View File

@@ -50,7 +50,7 @@ module ActiveRecord
# 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 (<tt>:has_many</tt>, <tt>:has_one</tt>,
# <tt>:belongs_to</tt>) for that as the first parameter.
# <tt>:belongs_to</tt>) as the first parameter.
#
# Example:
#
@@ -62,9 +62,9 @@ module ActiveRecord
macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections
end
# Returns the AssociationReflection object for the named +association+ (use the symbol). Example:
# Returns the AssociationReflection object for the +association+ (use the symbol).
#
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
# Invoice.reflect_on_association(:line_items).macro # returns :has_many
#
def reflect_on_association(association)
@@ -88,34 +88,37 @@ module ActiveRecord
@macro, @name, @options, @active_record = macro, name, options, active_record
end
# Returns the name of the macro. For example, <tt>composed_of :balance,
# :class_name => 'Money'</tt> will return <tt>:balance</tt> or for
# <tt>has_many :clients</tt> it will return <tt>:clients</tt>.
# Returns the name of the macro.
# <tt>composed_of :balance, :class_name => 'Money'</tt> will return <tt>:balance</tt>
# <tt>has_many :clients</tt> will return <tt>:clients</tt>
def name
@name
end
# Returns the macro type. For example,
# Returns the macro type.
# <tt>composed_of :balance, :class_name => 'Money'</tt> will return <tt>:composed_of</tt>
# or for <tt>has_many :clients</tt> will return <tt>:has_many</tt>.
# <tt>has_many :clients</tt> will return <tt>:has_many</tt>
def macro
@macro
end
# Returns the hash of options used for the macro. For example, it would return <tt>{ :class_name => "Money" }</tt> for
# <tt>composed_of :balance, :class_name => 'Money'</tt> or +{}+ for <tt>has_many :clients</tt>.
# Returns the hash of options used for the macro.
# <tt>composed_of :balance, :class_name => 'Money'</tt> will return <tt>{ :class_name => "Money" }</tt>
# <tt>has_many :clients</tt> will return +{}+
def options
@options
end
# Returns the class for the macro. For example, <tt>composed_of :balance, :class_name => 'Money'</tt> returns the Money
# class and <tt>has_many :clients</tt> returns the Client class.
# Returns the class for the macro.
# <tt>composed_of :balance, :class_name => 'Money'</tt> will return the Money class
# <tt>has_many :clients</tt> will return the Client class
def klass
@klass ||= class_name.constantize
end
# Returns the class name for the macro. For example, <tt>composed_of :balance, :class_name => 'Money'</tt> returns <tt>'Money'</tt>
# and <tt>has_many :clients</tt> returns <tt>'Client'</tt>.
# Returns the class name for the macro.
# <tt>composed_of :balance, :class_name => 'Money'</tt> will return <tt>'Money'</tt>
# <tt>has_many :clients</tt> will return <tt>'Client'</tt>
def class_name
@class_name ||= options[:class_name] || derive_class_name
end

View File

@@ -1,19 +1,20 @@
= Active Support -- Utility classes and standard library extensions from Rails
= Active Support -- Utility classes and Ruby 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.
Active Support is a collection of utility classes and standard library
extensions that were found useful for the Rails framework. These additions
reside in this package so they can be loaded as needed in Ruby projects
outside of Rails.
== Download
== Download and installation
The latest version of Active Support can be installed with Rubygems:
* gem install activesupport
% [sudo] gem install activesupport
Documentation can be found at
Source code can be downloaded as part of the Rails project on GitHub
* http://api.rubyonrails.org
* http://github.com/rails/rails/tree/master/activesupport/
== License
@@ -23,12 +24,10 @@ Active Support is released under the MIT license.
== Support
The Active Support homepage is http://www.rubyonrails.com. You can find the Active Support
RubyForge page at http://rubyforge.org/projects/activesupport. And as Jim from Rake says:
API documentation is at
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.
* http://api.rubyonrails.com
For other information, feel free to ask on the ruby-talk mailing list
(which is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com.
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets

View File

@@ -4,8 +4,8 @@ require 'active_support/core_ext/object/acts_like'
module ActiveSupport
# 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:
# Time#advance, respectively. It mainly supports the methods on Numeric.
# Example:
#
# 1.month.ago # equivalent to Time.now.advance(:months => -1)
class Duration < BasicObject

View File

@@ -21,7 +21,7 @@ module ActiveSupport
# ActiveRecord::LogSubscriber.attach_to :active_record
#
# Since we need to know all instance methods before attaching the log subscriber,
# the line above shuold be called after your ActiveRecord::LogSubscriber definition.
# the line above should be called after your ActiveRecord::LogSubscriber definition.
#
# After configured, whenever a "sql.active_record" notification is published,
# it will properly dispatch the event (ActiveSupport::Notifications::Event) to

View File

@@ -5,9 +5,9 @@ module ActiveSupport
# 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 <tt>ENV['TZ']</tt> zone.
#
# You shouldn't ever need to create a TimeWithZone instance directly via <tt>new</tt> -- 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:
# You shouldn't ever need to create a TimeWithZone instance directly via <tt>new</tt> . Instead use methods
# +local+, +parse+, +at+ and +now+ on TimeZone instances, and +in_time_zone+ on Time and DateTime instances.
# 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
@@ -18,7 +18,8 @@ module ActiveSupport
#
# See Time and TimeZone for further documentation of these methods.
#
# TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangeable. Examples:
# TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangeable.
# Examples:
#
# t = Time.zone.now # => Sun, 18 May 2008 13:27:25 EDT -04:00
# t.hour # => 13
@@ -113,8 +114,8 @@ module ActiveSupport
end
alias_method :iso8601, :xmlschema
# Coerces the date to a string for JSON encoding. The default format is ISO 8601. You can get
# %Y/%m/%d %H:%M:%S +offset style by setting ActiveSupport::JSON::Encoding.use_standard_json_time_format
# Coerces time to a string for JSON encoding. The default format is ISO 8601. You can get
# %Y/%m/%d %H:%M:%S +offset style by setting <tt>ActiveSupport::JSON::Encoding.use_standard_json_time_format</tt>
# to false.
#
# ==== Examples

View File

@@ -9,7 +9,7 @@ module ActiveSupport
module XmlMini
extend self
# This module exists to decorate files deserialized using Hash.from_xml with
# This module decorates files deserialized using Hash.from_xml with
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
module FileLike #:nodoc:
attr_writer :original_filename, :content_type

View File

@@ -799,7 +799,7 @@ h4. Customizing the Error Messages CSS
The selectors to customize the style of error messages are:
* +.fieldWithErrors+ - Style for the form fields and labels with errors.
* +.field_with_errors+ - Style for the form fields and labels with errors.
* +#errorExplanation+ - Style for the +div+ element with the error messages.
* +#errorExplanation h2+ - Style for the header of the +div+ element.
* +#errorExplanation p+ - Style for the paragraph that holds the message that appears right below the header of the +div+ element.
@@ -811,7 +811,7 @@ The name of the class and the id can be changed with the +:class+ and +:id+ opti
h4. Customizing the Error Messages HTML
By default, form fields with errors are displayed enclosed by a +div+ element with the +fieldWithErrors+ CSS class. However, it's possible to override that.
By default, form fields with errors are displayed enclosed by a +div+ element with the +field_with_errors+ CSS class. However, it's possible to override that.
The way form fields with errors are treated is defined by +ActionView::Base.field_error_proc+. This is a +Proc+ that receives two parameters:

View File

@@ -181,7 +181,7 @@ There are only a few configuration options for Action View, starting with four o
* +config.action_view.warn_cache_misses+ tells Rails to display a warning whenever an action results in a cache miss on your view paths. The default is +false+.
* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| "&lt;div class=\"fieldWithErrors\"&gt;#{html_tag}&lt;/div&gt;" }</tt>
* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| "&lt;div class=\"field_with_errors\"&gt;#{html_tag}&lt;/div&gt;" }</tt>
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.

View File

@@ -3,7 +3,7 @@ h2. Rails Routing from the Outside In
This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:
* Understand the code in +routes.rb+
* Construct your own routes, using either the preferred resourceful style or with the @match@ method
* Construct your own routes, using either the preferred resourceful style or with the <tt>match</tt> method
* Identify what parameters to expect an action to receive
* Automatically create paths and URLs using route helpers
* Use advanced techniques such as constraints and Rack endpoints

View File

@@ -70,7 +70,7 @@ module Rails
#
# class MyRailtie < Rails::Railtie
# initializer "my_railtie.configure_rails_initialization" do |app|
# app.middlewares.use MyRailtie::Middleware
# app.middleware.use MyRailtie::Middleware
# end
# end
#