Merge branch 'master' into nested_has_many_through

This commit is contained in:
Jon Leighton 2011-03-10 19:35:20 +00:00
commit 582edaa1ff
49 changed files with 231 additions and 129 deletions

@ -74,7 +74,7 @@ Or you can just chain the methods together like:
== Receiving emails
To receive emails, you need to implement a public instance method called <tt>receive</tt> that takes a
To receive emails, you need to implement a public instance method called <tt>receive</tt> that takes an
email object as its single parameter. The Action Mailer framework has a corresponding class method,
which is also called <tt>receive</tt>, that accepts a raw, unprocessed email as a string, which it then turns
into the email object and calls the receive instance method.
@ -128,7 +128,7 @@ The latest version of Action Mailer can be installed with Rubygems:
Source code can be downloaded as part of the Rails project on GitHub
* http://github.com/rails/rails/tree/master/actionmailer/
* https://github.com/rails/rails/tree/master/actionmailer/
== License

@ -4,7 +4,7 @@ module MailHelper
# each line, and wrapped at 72 columns.
def block_format(text)
formatted = text.split(/\n\r\n/).collect { |paragraph|
simple_format(paragraph)
format_paragraph(paragraph)
}.join("\n")
# Make list points stand on their own line
@ -29,8 +29,15 @@ def attachments
@_message.attachments
end
private
def simple_format(text, len = 72, indent = 2)
# Returns +text+ wrapped at +len+ columns and indented +indent+ spaces.
#
# === Examples
#
# my_text = "Here is a sample text with more than 40 characters"
#
# format_paragraph(my_text, 25, 4)
# # => " Here is a sample text with\n more than 40 characters"
def format_paragraph(text, len = 72, indent = 2)
sentences = [[]]
text.split.each do |word|

@ -14,6 +14,14 @@ def use_mail_helper
end
end
def use_format_paragraph
@text = "But soft! What light through yonder window breaks?"
mail_with_defaults do |format|
format.html { render(:inline => "<%= format_paragraph @text, 15, 1 %>") }
end
end
def use_mailer
mail_with_defaults do |format|
format.html { render(:inline => "<%= mailer.message.subject %>") }
@ -50,5 +58,10 @@ def test_use_message
mail = HelperMailer.use_message
assert_match "using helpers", mail.body.encoded
end
def test_use_format_paragraph
mail = HelperMailer.use_format_paragraph
assert_match " But soft! What\r\n light through\r\n yonder window\r\n breaks?", mail.body.encoded
end
end

@ -1,5 +1,9 @@
*Rails 3.1.0 (unreleased)*
* URL parameters which return false for to_param now appear in the query string (previously they were removed) [Andrew White]
* URL parameters which return nil for to_param are now removed from the query string [Andrew White]
* ActionDispatch::MiddlewareStack now uses composition over inheritance. It is
no longer an array which means there may be methods missing that were not
tested.

@ -323,7 +323,7 @@ The latest version of Action Pack can be installed with Rubygems:
Source code can be downloaded as part of the Rails project on GitHub
* http://github.com/rails/rails/tree/master/actionpack/
* https://github.com/rails/rails/tree/master/actionpack/
== License

@ -41,7 +41,7 @@ def url_for(options = {})
path = options.delete(:path) || ''
params = options[:params] || {}
params.reject! {|k,v| !v }
params.reject! {|k,v| v.to_param.nil? }
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
rewritten_url << "?#{params.to_query}" unless params.empty?

@ -1,3 +1,5 @@
require 'active_support/core_ext/module/deprecation'
module ActionDispatch
module Routing
class Route #:nodoc:
@ -45,6 +47,7 @@ def segment_keys
def to_a
[@app, @conditions, @defaults, @name]
end
deprecate :to_a
def to_s
@to_s ||= begin

@ -333,7 +333,7 @@ def empty?
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
route = Route.new(self, app, conditions, requirements, defaults, name, anchor)
@set.add_route(*route)
@set.add_route(route.app, route.conditions, route.defaults, route.name)
named_routes[name] = route if name
routes << route
route

@ -266,8 +266,8 @@ module FormHelper
# === Removing hidden model id's
#
# The form_for method automatically includes the model id as a hidden field in the form.
# This is used to maintain the correlation between the form data and it's associated model.
# Some ORM systems do not use id's on nested models so in this case you want to be able
# This is used to maintain the correlation between the form data and its associated model.
# Some ORM systems do not use IDs on nested models so in this case you want to be able
# to disable the hidden id.
#
# In the following example the Post model has many Comments stored within it in a NoSQL database,

@ -103,7 +103,7 @@ module PrototypeHelper
:form, :with, :update, :script, :type ]).merge(CALLBACKS)
# Returns the JavaScript needed for a remote function.
# See the link_to_remote documentation at http://github.com/rails/prototype_legacy_helper as it takes the same arguments.
# See the link_to_remote documentation at https://github.com/rails/prototype_legacy_helper as it takes the same arguments.
#
# Example:
# # Generates: <select id="options" onchange="new Ajax.Updater('options',
@ -131,7 +131,6 @@ def remote_function(options)
"new Ajax.Updater(#{update}, "
url_options = options[:url]
url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
function << "'#{ERB::Util.html_escape(escape_javascript(url_for(url_options)))}'"
function << ", #{javascript_options})"

@ -185,6 +185,7 @@ def view
@request
@routes
@templates
@options
@test_passed
@view
@view_context_class

@ -311,6 +311,14 @@ def test_with_hash_with_indifferent_access
assert_equal("/c/a", W.new.url_for(HashWithIndifferentAccess.new('controller' => 'c', 'action' => 'a', 'only_path' => true)))
end
def test_url_params_with_nil_to_param_are_not_in_url
assert_equal("/c/a", W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => Struct.new(:to_param).new(nil)))
end
def test_false_url_params_are_included_in_query
assert_equal("/c/a?show=false", W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :show => false))
end
private
def extract_params(url)
url.split('?', 2).last.split('&').sort

@ -3,8 +3,6 @@ module ActiveModel
#
# Handles default conversions: to_model, to_key and to_param.
#
# == Example
#
# Let's take for example this non persisted object.
#
# class ContactMessage

@ -54,9 +54,7 @@ module ClassMethods
# 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.
#
# == Example
# tampering with URLs or forms. Example:
#
# class Customer
# include ActiveModel::MassAssignmentSecurity

@ -36,8 +36,8 @@ module ActiveModel
# person.invalid? # => true
# person.errors # => #<OrderedHash {:first_name=>["starts with z."]}>
#
# Note that ActiveModel::Validations automatically adds an +errors+ method
# to your instances initialized with a new ActiveModel::Errors object, so
# Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method
# to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so
# there is no need for you to do this manually.
#
module Validations
@ -165,7 +165,7 @@ def inherited(base)
end
end
# Returns the Errors object that holds all information about attribute error messages.
# Returns the +Errors+ object that holds all information about attribute error messages.
def errors
@errors ||= Errors.new(self)
end

@ -50,9 +50,9 @@ module ClassMethods
# end
#
# Configuration options:
# * <tt>on</tt> - Specifies when this validation is active
# * <tt>:on</tt> - Specifies when this validation is active
# (<tt>:create</tt> or <tt>:update</tt>
# * <tt>if</tt> - Specifies a method, proc or string to call to determine
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
# if the validation should occur (e.g. <tt>:if => :allow_validation</tt>,
# or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
# The method, proc or string should return or evaluate to a true or false value.

@ -63,7 +63,7 @@ module ActiveModel #:nodoc:
# end
#
# The easiest way to add custom validators for validating individual attributes
# is with the convenient ActiveModel::EachValidator for example:
# is with the convenient <tt>ActiveModel::EachValidator</tt>. For example:
#
# class TitleValidator < ActiveModel::EachValidator
# def validate_each(record, attribute, value)
@ -72,18 +72,18 @@ module ActiveModel #:nodoc:
# end
#
# This can now be used in combination with the +validates+ method
# (see ActiveModel::Validations::ClassMethods.validates for more on this)
# (see <tt>ActiveModel::Validations::ClassMethods.validates</tt> for more on this)
#
# class Person
# include ActiveModel::Validations
# attr_accessor :title
#
# validates :title, :presence => true, :title => true
# validates :title, :presence => true
# end
#
# Validator may also define a +setup+ instance method which will get called
# with the class that using that validator as it's argument. This can be
# useful when there are prerequisites such as an attr_accessor being present
# with the class that using that validator as its argument. This can be
# useful when there are prerequisites such as an +attr_accessor+ being present
# for example:
#
# class MyValidator < ActiveModel::Validator
@ -98,9 +98,7 @@ module ActiveModel #:nodoc:
class Validator
attr_reader :options
# Returns the kind of the validator.
#
# == Examples
# Returns the kind of the validator. Examples:
#
# PresenceValidator.kind # => :presence
# UniquenessValidator.kind # => :uniqueness
@ -126,11 +124,11 @@ def validate(record)
end
end
# EachValidator is a validator which iterates through the attributes given
# in the options hash invoking the validate_each method passing in the
# +EachValidator+ is a validator which iterates through the attributes given
# in the options hash invoking the <tt>validate_each</tt> method passing in the
# record, attribute and value.
#
# All Active Model validations are built on top of this Validator.
# All Active Model validations are built on top of this validator.
class EachValidator < Validator
attr_reader :attributes
@ -163,14 +161,13 @@ def validate_each(record, attribute, value)
# Hook method that gets called by the initializer allowing verification
# that the arguments supplied are valid. You could for example raise an
# ArgumentError when invalid options are supplied.
# +ArgumentError+ when invalid options are supplied.
def check_validity!
end
end
# BlockValidator is a special EachValidator which receives a block on initialization
# and call this block for each attribute being validated. +validates_each+ uses this
# Validator.
# +BlockValidator+ is a special +EachValidator+ which receives a block on initialization
# and call this block for each attribute being validated. +validates_each+ uses this validator.
class BlockValidator < EachValidator
def initialize(options, &block)
@block = block

@ -203,7 +203,7 @@ The latest version of Active Record can be installed with Rubygems:
Source code can be downloaded as part of the Rails project on GitHub
* http://github.com/rails/rails/tree/master/activerecord/
* https://github.com/rails/rails/tree/master/activerecord/
== License

@ -1,4 +1,4 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
# Read about fixtures at http://api.rubyonrails.org/classes/Fixtures.html
first_task:
id: 1
starting: 2005-03-30t06:30:00.00+01:00

@ -14,7 +14,7 @@ The latest version of Active Support can be installed with Rubygems:
Source code can be downloaded as part of the Rails project on GitHub
* http://github.com/rails/rails/tree/master/activesupport/
* https://github.com/rails/rails/tree/master/activesupport/
== License

@ -225,7 +225,10 @@ def end(key=nil, object=nil)
# end
[@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
when :around
"end"
<<-RUBY_EVAL
value
end
RUBY_EVAL
end
end
@ -423,7 +426,7 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
#
# set_callback :save, :before, :before_meth
# set_callback :save, :after, :after_meth, :if => :condition
# set_callback :save, :around, lambda { |r| stuff; yield; stuff }
# set_callback :save, :around, lambda { |r| stuff; result = yield; stuff }
#
# The second arguments indicates whether the callback is to be run +:before+,
# +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
@ -443,6 +446,9 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
# Before and around callbacks are called in the order that they are set; after
# callbacks are called in the reverse order.
#
# Around callbacks can access the return value from the event, if it
# wasn't halted, from the +yield+ call.
#
# ===== Options
#
# * <tt>:if</tt> - A symbol naming an instance method or a proc; the callback

@ -1,5 +1,5 @@
class Array
# Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
# Backport of Array#sample based on Marc-Andre Lafortune's https://github.com/marcandre/backports/
# Returns a random element or +n+ random elements from the array.
# If the array is empty and +n+ is nil, returns <tt>nil</tt>. if +n+ is passed, returns <tt>[]</tt>.
#

@ -81,6 +81,29 @@ def end_of_day
change(:hour => 23, :min => 59, :sec => 59)
end
# 1.9.3 defines + and - on DateTime, < 1.9.3 do not.
if DateTime.public_instance_methods(false).include?(:+)
def plus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
else
plus_without_duration(other)
end
end
alias_method :plus_without_duration, :+
alias_method :+, :plus_with_duration
def minus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
plus_with_duration(-other)
else
minus_without_duration(other)
end
end
alias_method :minus_without_duration, :-
alias_method :-, :minus_with_duration
end
# Adjusts DateTime to UTC by adding its offset value; offset is set to 0
#
# Example:

@ -16,4 +16,4 @@ def round(precision = nil)
precisionless_round
end
end
end
end if RUBY_VERSION < '1.9'

@ -32,14 +32,21 @@ def to_param
end
class Hash
# Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
# passed to enclose the param names (see example below). The string pairs "key=value" that conform the query
# string are sorted lexicographically in ascending order.
# Returns a string representation of the receiver suitable for use as a URL
# query string:
#
# ==== Examples
# { :name => 'David', :nationality => 'Danish' }.to_param # => "name=David&nationality=Danish"
# {:name => 'David', :nationality => 'Danish'}.to_param
# # => "name=David&nationality=Danish"
#
# { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
# An optional namespace can be passed to enclose the param names:
#
# {:name => 'David', :nationality => 'Danish'}.to_param('user')
# # => "user[name]=David&user[nationality]=Danish"
#
# The string pairs "key=value" that conform the query string
# are sorted lexicographically in ascending order.
#
# This method is also aliased as +to_query+.
def to_param(namespace = nil)
collect do |key, value|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)

@ -1,5 +1,5 @@
# Some code from jeremymcanally's "pending"
# http://github.com/jeremymcanally/pending/tree/master
# https://github.com/jeremymcanally/pending/tree/master
module ActiveSupport
module Testing

@ -300,6 +300,32 @@ def save
end
end
class AroundPersonResult < MySuper
attr_reader :result
set_callback :save, :after, :tweedle_1
set_callback :save, :around, :tweedle_dum
set_callback :save, :after, :tweedle_2
def tweedle_dum
@result = yield
end
def tweedle_1
:tweedle_1
end
def tweedle_2
:tweedle_2
end
def save
run_callbacks :save do
:running
end
end
end
class HyphenatedCallbacks
include ActiveSupport::Callbacks
define_callbacks :save
@ -339,6 +365,14 @@ def test_save_around
end
end
class AroundCallbackResultTest < Test::Unit::TestCase
def test_save_around
around = AroundPersonResult.new
around.save
assert_equal :running, around.result
end
end
class SkipCallbacksTest < Test::Unit::TestCase
def test_skip_person
person = PersonSkipper.new

@ -262,8 +262,7 @@ def test_yesterday_constructor
def test_yesterday_constructor_when_zone_is_not_set
with_env_tz 'UTC' do
with_tz_default do
Time.stubs(:now).returns Time.local(2000, 1, 1)
assert_equal Date.new(1999, 12, 31), Date.yesterday
assert_equal(Date.today - 1, Date.yesterday)
end
end
end
@ -284,8 +283,7 @@ def test_tomorrow_constructor
def test_tomorrow_constructor_when_zone_is_not_set
with_env_tz 'UTC' do
with_tz_default do
Time.stubs(:now).returns Time.local(1999, 12, 31)
assert_equal Date.new(2000, 1, 1), Date.tomorrow
assert_equal(Date.today + 1, Date.tomorrow)
end
end
end
@ -410,17 +408,14 @@ def test_future
def test_current_returns_date_today_when_zone_not_set
with_env_tz 'US/Central' do
Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
assert_equal Date.new(1999, 12, 31), Date.today
assert_equal Date.new(1999, 12, 31), Date.current
assert_equal Date.today, Date.current
end
end
def test_current_returns_time_zone_today_when_zone_is_set
Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
with_env_tz 'US/Central' do
Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
assert_equal Date.new(1999, 12, 31), Date.today
assert_equal Date.new(2000, 1, 1), Date.current
assert_equal ::Time.zone.today, Date.current
end
ensure
Time.zone = nil

@ -27,7 +27,7 @@ $ sudo shutdown -r now
$ sudo aptitude update
* Use cinabox to perform rest of ruby/ccrb setup:
* http://github.com/thewoolleyman/cinabox/tree/master/README.txt
* https://github.com/thewoolleyman/cinabox/tree/master/README.txt
# This is not yet properly supported by RubyGems...
# * Configure RubyGems to not require root access for gem installation

@ -423,27 +423,36 @@ Now, the +LoginsController+'s +new+ and +create+ actions will work as before wit
h4. After Filters and Around Filters
In addition to before filters, you can run filters after an action has run or both before and after. The after filter is similar to the before filter, but because the action has already been run it has access to the response data that's about to be sent to the client. Obviously, after filters can not stop the action from running.
In addition to before filters, you can also run filters after an action has been executed, or both before and after.
Around filters are responsible for running the action, but they can choose not to, which is the around filter's way of stopping it.
After filters are similar to before filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, after filters cannot stop the action from running.
Around filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:
<ruby>
# Example taken from the Rails API filter documentation:
# http://ap.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html
class ApplicationController < ActionController::Base
around_filter :catch_exceptions
class ChangesController < ActionController::Base
around_filter :wrap_in_transaction, :only => :show
private
def catch_exceptions
yield
rescue => exception
logger.debug "Caught exception! #{exception}"
raise
def wrap_in_transaction
ActiveRecord::Base.transaction do
begin
yield
ensure
raise ActiveRecord::Rollback
end
end
end
end
</ruby>
Note that an around filter wraps also rendering. In particular, if in the example above the view itself reads from the database via a scope or whatever, it will do so within the transaction and thus present the data to preview.
They can choose not to yield and build the response themselves, in which case the action is not run.
h4. Other Ways to Use Filters
While the most common way to use filters is by creating private methods and using *_filter to add them, there are two other ways to do the same thing.
@ -481,7 +490,7 @@ Again, this is not an ideal example for this filter, because it's not run in the
h3. Verification
Verifications make sure certain criteria are met in order for a controller or action to run. They can specify that a certain key (or several keys in the form of an array) is present in the +params+, +session+ or +flash+ hashes or that a certain HTTP method was used or that the request was made using +XMLHttpRequest+ (Ajax). The default action taken when these criteria are not met is to render a 400 Bad Request response, but you can customize this by specifying a redirect URL or rendering something else and you can also add flash messages and HTTP headers to the response. It is described in the "API documentation":http://ap.rubyonrails.org/classes/ActionController/Verification/ClassMethods.html as "essentially a special kind of before_filter".
Verifications make sure certain criteria are met in order for a controller or action to run. They can specify that a certain key (or several keys in the form of an array) is present in the +params+, +session+ or +flash+ hashes or that a certain HTTP method was used or that the request was made using +XMLHttpRequest+ (Ajax). The default action taken when these criteria are not met is to render a 400 Bad Request response, but you can customize this by specifying a redirect URL or rendering something else and you can also add flash messages and HTTP headers to the response.
Here's an example of using verification to make sure the user supplies a username and a password in order to log in:
@ -558,7 +567,7 @@ In every controller there are two accessor methods pointing to the request and t
h4. The +request+ Object
The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the "API documentation":http://ap.rubyonrails.org/classes/ActionController/AbstractRequest.html. Among the properties that you can access on this object are:
The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the "API documentation":http://api.rubyonrails.org/classes/ActionDispatch/Request.html. Among the properties that you can access on this object are:
|_.Property of +request+|_.Purpose|
|host|The hostname used for this request.|

@ -1472,5 +1472,5 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht
h3. Changelog
* September 3, 2009: Continuing work by Trevor Turk, leveraging the "Action Pack docs":http://ap.rubyonrails.org/ and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
* September 3, 2009: Continuing work by Trevor Turk, leveraging the Action Pack docs and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
* April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs

@ -1818,7 +1818,7 @@ h3. Extensions to +Float+
h4. +round+
The built-in method +Float#round+ rounds a float to the nearest integer. Active Support adds an optional parameter to let you specify a precision:
The built-in method +Float#round+ rounds a float to the nearest integer. In Ruby 1.9 this method takes an optional argument to let you specify a precision. Active Support adds that functionality to +round+ in previous versions of Ruby:
<ruby>
Math::E.round(4) # => 2.7183

@ -7,11 +7,11 @@ endprologue.
h3. How to Contribute?
* We have an open commit policy: anyone is welcome to contribute and to review contributions.
* "docrails is hosted on GitHub":http://github.com/lifo/docrails and has public write access.
* "docrails is hosted on GitHub":https://github.com/lifo/docrails and has public write access.
* Guides are written in Textile, and reside at +railties/guides/source+ in the docrails project.
* Follow the "Rails Guides Conventions":http://wiki.github.com/lifo/docrails/rails-guides-conventions.
* Follow the "Rails Guides Conventions":https://wiki.github.com/lifo/docrails/rails-guides-conventions.
* Assets are stored in the +railties/guides/assets+ directory.
* Sample format : "Active Record Associations":http://github.com/lifo/docrails/blob/3e56a3832415476fdd1cb963980d0ae390ac1ed3/railties/guides/source/association_basics.textile.
* Sample format : "Active Record Associations":https://github.com/lifo/docrails/blob/3e56a3832415476fdd1cb963980d0ae390ac1ed3/railties/guides/source/association_basics.textile.
* Sample output : "Active Record Associations":association_basics.html.
* You can build the Guides during testing by running +bundle exec rake generate_guides+ in the +railties+ directory.
* You're encouraged to validate XHTML for the generated guides before commiting your changes by running +bundle exec rake validate_guides+ in the +railties+ directory.
@ -53,11 +53,11 @@ h3. Rules
* If the same guide writer wants to write multiple guides, that's ideally the situation we'd love to be in! However, that guide writer will only receive the cash prize for all the subsequent guides (and not the GitHub or RPM prizes).
* Our review team will have the final say on whether the guide is complete and of good enough quality.
All authors should read and follow the "Rails Guides Conventions":http://wiki.github.com/lifo/docrails/rails-guides-conventions and the "Rails API Documentation Conventions":http://wiki.github.com/lifo/docrails/rails-api-documentation-conventions.
All authors should read and follow the "Rails Guides Conventions":https://wiki.github.com/lifo/docrails/rails-guides-conventions and the "Rails API Documentation Conventions":https://wiki.github.com/lifo/docrails/rails-api-documentation-conventions.
h3. Translations
The translation effort for the Rails Guides is just getting underway. We know about projects to translate the Guides into Spanish, Portuguese, Polish, and French. For more details or to get involved see the "Translating Rails Guides":http://wiki.github.com/lifo/docrails/translating-rails-guides page.
The translation effort for the Rails Guides is just getting underway. We know about projects to translate the Guides into Spanish, Portuguese, Polish, and French. For more details or to get involved see the "Translating Rails Guides":https://wiki.github.com/lifo/docrails/translating-rails-guides page.
h3. Mailing List

@ -48,7 +48,7 @@ Ruby on Rails uses git for source code control. The "git homepage":http://git-sc
* "Everyday Git":http://www.kernel.org/pub/software/scm/git/docs/everyday.html will teach you just enough about git to get by.
* The "PeepCode screencast":https://peepcode.com/products/git on git ($9) is easier to follow.
* "GitHub":http://github.com/guides/home offers links to a variety of git resources.
* "GitHub":https://github.com/guides/home offers links to a variety of git resources.
* "Pro Git":http://progit.org/book/ is an entire book about git with a Creative Commons license.
h4. Clone the Ruby on Rails Repository
@ -261,7 +261,7 @@ h3. Contributing to the Rails Documentation
Ruby on Rails has two main sets of documentation: The guides help you to learn Ruby on Rails, and the API is a reference.
You can create a ticket in Lighthouse to fix or expand documentation. However, if you're confident about your changes you can push them yourself directly via "docrails":http://github.com/lifo/docrails/tree/master. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation.
You can create a ticket in Lighthouse to fix or expand documentation. However, if you're confident about your changes you can push them yourself directly via "docrails":https://github.com/lifo/docrails/tree/master. docrails is a branch with an *open commit policy* and public write access. Commits to docrails are still reviewed, but that happens after they are pushed. docrails is merged with master regularly, so you are effectively editing the Ruby on Rails documentation.
When working with documentation, please take into account the "API Documentation Guidelines":api_documentation_guidelines.html and the "Ruby on Rails Guides Guidelines":ruby_on_rails_guides_guidelines.html.

@ -44,7 +44,7 @@ Ruby on Rails Guides: Credits
<% end %>
<%= author('Mikel Lindsaar', 'raasdnil') do %>
Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby <a href="http://github.com/mikel/mail">Mail gem</a> and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of <a href="http://rubyx.com/">RubyX</a>, has a <a href="http://lindsaar.net/">blog</a> and <a href="http://twitter.com/raasdnil">tweets</a>.
Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby <a href="https://github.com/mikel/mail">Mail gem</a> and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of <a href="http://rubyx.com/">RubyX</a>, has a <a href="http://lindsaar.net/">blog</a> and <a href="http://twitter.com/raasdnil">tweets</a>.
<% end %>
<%= author('Cássio Marques', 'cmarques') do %>

@ -619,7 +619,7 @@ In this section, you will learn how to find and fix such leaks by using tools su
h4. BleakHouse
"BleakHouse":http://github.com/fauna/bleak_house/tree/master is a library for finding memory leaks.
"BleakHouse":https://github.com/fauna/bleak_house/tree/master is a library for finding memory leaks.
If a Ruby object does not go out of scope, the Ruby Garbage Collector won't sweep it since it is referenced somewhere. Leaks like this can grow slowly and your application will consume more and more memory, gradually affecting the overall system performance. This tool will help you find leaks on the Ruby heap.
@ -668,7 +668,7 @@ To analyze it, just run the listed command. The top 20 leakiest lines will be li
This way you can find where your application is leaking memory and fix it.
If "BleakHouse":http://github.com/fauna/bleak_house/tree/master doesn't report any heap growth but you still have memory growth, you might have a broken C extension, or real leak in the interpreter. In that case, try using Valgrind to investigate further.
If "BleakHouse":https://github.com/fauna/bleak_house/tree/master doesn't report any heap growth but you still have memory growth, you might have a broken C extension, or real leak in the interpreter. In that case, try using Valgrind to investigate further.
h4. Valgrind
@ -682,12 +682,12 @@ h3. Plugins for Debugging
There are some Rails plugins to help you to find errors and debug your application. Here is a list of useful plugins for debugging:
* "Footnotes":http://github.com/josevalim/rails-footnotes: Every Rails page has footnotes that give request information and link back to your source via TextMate.
* "Query Trace":http://github.com/ntalbott/query_trace/tree/master: Adds query origin tracing to your logs.
* "Query Stats":http://github.com/dan-manges/query_stats/tree/master: A Rails plugin to track database queries.
* "Footnotes":https://github.com/josevalim/rails-footnotes: Every Rails page has footnotes that give request information and link back to your source via TextMate.
* "Query Trace":https://github.com/ntalbott/query_trace/tree/master: Adds query origin tracing to your logs.
* "Query Stats":https://github.com/dan-manges/query_stats/tree/master: A Rails plugin to track database queries.
* "Query Reviewer":http://code.google.com/p/query-reviewer/: This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of warnings for each query that it analyzed.
* "Exception Notifier":http://github.com/rails/exception_notification/tree/master: Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
* "Exception Logger":http://github.com/defunkt/exception_logger/tree/master: Logs your Rails exceptions in the database and provides a funky web interface to manage them.
* "Exception Notifier":https://github.com/rails/exception_notification/tree/master: Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
* "Exception Logger":https://github.com/defunkt/exception_logger/tree/master: Logs your Rails exceptions in the database and provides a funky web interface to manage them.
h3. References

@ -475,7 +475,7 @@ To leverage time zone support in Rails, you have to ask your users what time zon
There is also +time_zone_options_for_select+ helper for a more manual (therefore more customizable) way of doing this. Read the API documentation to learn about the possible arguments for these two methods.
Rails _used_ to have a +country_select+ helper for choosing countries, but this has been extracted to the "country_select plugin":http://github.com/rails/country_select/tree/master. When using this, be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from Rails).
Rails _used_ to have a +country_select+ helper for choosing countries, but this has been extracted to the "country_select plugin":https://github.com/rails/country_select/tree/master. When using this, be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from Rails).
h3. Using Date and Time Form Helpers
@ -589,7 +589,7 @@ def upload
end
</ruby>
Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are "Attachment-Fu":http://github.com/technoweenie/attachment_fu and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are "Attachment-Fu":https://github.com/technoweenie/attachment_fu and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
NOTE: If the user has not selected a file the corresponding parameter will be an empty string.
@ -805,9 +805,9 @@ Many apps grow beyond simple forms editing a single object. For example when cre
* As of Rails 2.3, Rails includes "Nested Attributes":./2_3_release_notes.html#nested-attributes and "Nested Object Forms":./2_3_release_notes.html#nested-object-forms
* Ryan Bates' series of Railscasts on "complex forms":http://railscasts.com/episodes/75
* Handle Multiple Models in One Form from "Advanced Rails Recipes":http://media.pragprog.com/titles/fr_arr/multiple_models_one_form.pdf
* Eloy Duran's "complex-forms-examples":http://github.com/alloy/complex-form-examples/ application
* Lance Ivy's "nested_assignment":http://github.com/cainlevy/nested_assignment/tree/master plugin and "sample application":http://github.com/cainlevy/complex-form-examples/tree/cainlevy
* James Golick's "attribute_fu":http://github.com/jamesgolick/attribute_fu plugin
* Eloy Duran's "complex-forms-examples":https://github.com/alloy/complex-form-examples/ application
* Lance Ivy's "nested_assignment":https://github.com/cainlevy/nested_assignment/tree/master plugin and "sample application":https://github.com/cainlevy/complex-form-examples/tree/cainlevy
* James Golick's "attribute_fu":https://github.com/jamesgolick/attribute_fu plugin
h3. Changelog

@ -34,7 +34,7 @@ $ rails generate helper --help
h3. Creating Your First Generator
Since Rails 3.0, generators are built on top of "Thor":http://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
Since Rails 3.0, generators are built on top of "Thor":https://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
The first step is to create a file at +lib/generators/initializer_generator.rb+ with the following content:
@ -319,7 +319,7 @@ If you generate another resource, you can see that we get exactly the same resul
h3. Adding Generators Fallbacks
One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit like "shoulda":http://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit like "shoulda":https://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
We can easily simulate this behavior by changing our +config/application.rb+ once again:

@ -153,7 +153,7 @@ TIP. If you're working on Windows, you should be aware that the vast majority of
h4. Creating the Blog Application
The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can literally follow along step by step. If you need to see the completed code, you can download it from "Getting Started Code":http://github.com/mikel/getting-started-code.
The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can literally follow along step by step. If you need to see the completed code, you can download it from "Getting Started Code":https://github.com/mikel/getting-started-code.
To begin, open a terminal, navigate to a folder where you have rights to create files, and type:

@ -87,11 +87,11 @@ en:
hello: "Hello world"
</ruby>
This means, that in the +:en+ locale, the key _hello_ will map to the _Hello world_ string. Every string inside Rails is internationalized in this way, see for instance Active Record validation messages in the "+activerecord/lib/active_record/locale/en.yml+":http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml file or time and date formats in the "+activesupport/lib/active_support/locale/en.yml+":http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.
This means, that in the +:en+ locale, the key _hello_ will map to the _Hello world_ string. Every string inside Rails is internationalized in this way, see for instance Active Record validation messages in the "+activerecord/lib/active_record/locale/en.yml+":https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml file or time and date formats in the "+activesupport/lib/active_support/locale/en.yml+":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.
The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, +:en+ will be used for looking up translations.
NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":http://github.com/joshmh/globalize2/tree/master may help you implement it.
NOTE: The i18n library takes a *pragmatic approach* to locale keys (after "some discussion":http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like +:en+, +:pl+, not the _region_ part, like +:en-US+ or +:en-UK+, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as +:cz+, +:th+ or +:es+ (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the +:en-US+ locale you would have $ as a currency symbol, while in +:en-UK+, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a +:en-UK+ dictionary. Various "Rails I18n plugins":http://rails-i18n.org/wiki such as "Globalize2":https://github.com/joshmh/globalize2/tree/master may help you implement it.
The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.
@ -253,7 +253,7 @@ match '/:locale' => 'dashboard#index'
Do take special care about the *order of your routes*, so this route declaration does not "eat" other ones. (You may want to add it directly before the +root :to+ declaration.)
NOTE: Have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master.
NOTE: Have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":https://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":https://github.com/raul/translate_routes/tree/master.
h4. Setting the Locale from the Client Supplied Information
@ -278,7 +278,7 @@ def extract_locale_from_accept_language_header
end
</ruby>
Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":http://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":http://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb.
Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":https://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb.
h5. Using GeoIP (or Similar) Database
@ -390,7 +390,7 @@ So that would give you:
!images/i18n/demo_localized_pirate.png(rails i18n demo localized time to pirate)!
TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails' defaults for your locale*. See the "rails-i18n repository at Github":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use.
TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails' defaults for your locale*. See the "rails-i18n repository at Github":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use.
h4. Localized Views
@ -778,23 +778,23 @@ Rails uses fixed strings and other localizations, such as format strings and oth
h5. Action View Helper Methods
* +distance_of_time_in_words+ translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See "datetime.distance_in_words":http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L51 translations.
* +distance_of_time_in_words+ translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See "datetime.distance_in_words":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L51 translations.
* +datetime_select+ and +select_month+ use translated month names for populating the resulting select tag. See "date.month_names":http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L15 for translations. +datetime_select+ also looks up the order option from "date.order":http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L18 (unless you pass the option explicitly). All date selection helpers translate the prompt using the translations in the "datetime.prompts":http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L83 scope if applicable.
* +datetime_select+ and +select_month+ use translated month names for populating the resulting select tag. See "date.month_names":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L15 for translations. +datetime_select+ also looks up the order option from "date.order":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L18 (unless you pass the option explicitly). All date selection helpers translate the prompt using the translations in the "datetime.prompts":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L83 scope if applicable.
* The +number_to_currency+, +number_with_precision+, +number_to_percentage+, +number_with_delimiter+, and +number_to_human_size+ helpers use the number format settings located in the "number":http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2 scope.
* The +number_to_currency+, +number_with_precision+, +number_to_percentage+, +number_with_delimiter+, and +number_to_human_size+ helpers use the number format settings located in the "number":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2 scope.
h5. Active Record Methods
* +model_name.human+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
* +model_name.human+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
* +ActiveRecord::Errors#generate_message+ (which is used by Active Record validations but may also be used manually) uses +model_name.human+ and +human_attribute_name+ (see above). It also translates the error message and supports translations for inherited class names as explained above in "Error message scopes".
*+ ActiveRecord::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "activerecord.errors.format.separator":http://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L91 (and which defaults to +'&nbsp;'+).
*+ ActiveRecord::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "activerecord.errors.format.separator":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L91 (and which defaults to +'&nbsp;'+).
h5. Active Support Methods
* +Array#to_sentence+ uses format settings as given in the "support.array":http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L30 scope.
* +Array#to_sentence+ uses format settings as given in the "support.array":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L30 scope.
h3. Customize your I18n Setup
@ -867,15 +867,15 @@ I18n support in Ruby on Rails was introduced in the release 2.2 and is still evo
Thus we encourage everybody to experiment with new ideas and features in plugins or other libraries and make them available to the community. (Don't forget to announce your work on our "mailing list":http://groups.google.com/group/rails-i18n!)
If you find your own locale (language) missing from our "example translations data":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale repository for Ruby on Rails, please "_fork_":http://github.com/guides/fork-a-project-and-submit-your-modifications the repository, add your data and send a "pull request":http://github.com/guides/pull-requests.
If you find your own locale (language) missing from our "example translations data":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale repository for Ruby on Rails, please "_fork_":https://github.com/guides/fork-a-project-and-submit-your-modifications the repository, add your data and send a "pull request":https://github.com/guides/pull-requests.
h3. Resources
* "rails-i18n.org":http://rails-i18n.org - Homepage of the rails-i18n project. You can find lots of useful resources on the "wiki":http://rails-i18n.org/wiki.
* "Google group: rails-i18n":http://groups.google.com/group/rails-i18n - The project's mailing list.
* "Github: rails-i18n":http://github.com/svenfuchs/rails-i18n/tree/master - Code repository for the rails-i18n project. Most importantly you can find lots of "example translations":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for Rails that should work for your application in most cases.
* "Github: i18n":http://github.com/svenfuchs/i18n/tree/master - Code repository for the i18n gem.
* "Github: rails-i18n":https://github.com/svenfuchs/rails-i18n/tree/master - Code repository for the rails-i18n project. Most importantly you can find lots of "example translations":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for Rails that should work for your application in most cases.
* "Github: i18n":https://github.com/svenfuchs/i18n/tree/master - Code repository for the i18n gem.
* "Lighthouse: rails-i18n":http://i18n.lighthouseapp.com/projects/14948-rails-i18n/overview - Issue tracker for the rails-i18n project.
* "Lighthouse: i18n":http://i18n.lighthouseapp.com/projects/14947-ruby-i18n/overview - Issue tracker for the i18n gem.

@ -8,7 +8,7 @@ Ruby on Rails Guides
<% if @edge %>
<p>
These are <b>Edge Guides</b>, based on the current
<a href="http://github.com/rails/rails/tree/master">master branch</a>.
<a href="https://github.com/rails/rails/tree/master">master branch</a>.
</p>
<p>
If you are looking for the ones for the stable version please check

@ -586,7 +586,7 @@ The Active Record way claims that intelligence belongs in your models, not in th
Validations such as +validates :foreign_key, :uniqueness => true+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":http://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":https://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
h3. Changelog

@ -500,8 +500,8 @@ h4. Rails Plugins and Gems
* "Rails Analyzer":http://rails-analyzer.rubyforge.org
* "Palmist":http://www.flyingmachinestudios.com/projects/
* "Rails Footnotes":http://github.com/josevalim/rails-footnotes/tree/master
* "Query Reviewer":http://github.com/dsboulder/query_reviewer/tree/master
* "Rails Footnotes":https://github.com/josevalim/rails-footnotes/tree/master
* "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master
h4. Generic Tools

@ -282,7 +282,7 @@ h4. File Uploads
Many web applications allow users to upload files. _(highlight)File names, which the user may choose (partly), should always be filtered_ as an attacker could use a malicious file name to overwrite any file on the server. If you store file uploads at /var/www/uploads, and the user enters a file name like “../../../etc/passwd”, it may overwrite an important file. Of course, the Ruby interpreter would need the appropriate permissions to do so one more reason to run web servers, database servers and other programs as a less privileged Unix user.
When filtering user input file names, _(highlight)don't try to remove malicious parts_. Think of a situation where the web application removes all “../” in a file name and an attacker uses a string such as “....//” - the result will be “../”. It is best to use a whitelist approach, which _(highlight)checks for the validity of a file name with a set of accepted characters_. This is opposed to a blacklist approach which attempts to remove not allowed characters. In case it isn't a valid file name, reject it (or replace not accepted characters), but don't remove them. Here is the file name sanitizer from the "attachment_fu plugin":http://github.com/technoweenie/attachment_fu/tree/master:
When filtering user input file names, _(highlight)don't try to remove malicious parts_. Think of a situation where the web application removes all “../” in a file name and an attacker uses a string such as “....//” - the result will be “../”. It is best to use a whitelist approach, which _(highlight)checks for the validity of a file name with a set of accepted characters_. This is opposed to a blacklist approach which attempts to remove not allowed characters. In case it isn't a valid file name, reject it (or replace not accepted characters), but don't remove them. Here is the file name sanitizer from the "attachment_fu plugin":https://github.com/technoweenie/attachment_fu/tree/master:
<ruby>
def sanitize_filename(filename)

@ -939,8 +939,8 @@ h3. Other Testing Approaches
The built-in +test/unit+ based testing is not the only way to test Rails applications. Rails developers have come up with a wide variety of other approaches and aids for testing, including:
* "NullDB":http://avdi.org/projects/nulldb/, a way to speed up testing by avoiding database use.
* "Factory Girl":http://github.com/thoughtbot/factory_girl/tree/master, as replacement for fixtures.
* "Machinist":http://github.com/notahat/machinist/tree/master, another replacement for fixtures.
* "Factory Girl":https://github.com/thoughtbot/factory_girl/tree/master, as replacement for fixtures.
* "Machinist":https://github.com/notahat/machinist/tree/master, another replacement for fixtures.
* "Shoulda":http://www.thoughtbot.com/projects/shoulda, an extension to +test/unit+ with additional helpers, macros, and assertions.
* "RSpec":http://rspec.info/, a behavior-driven development framework

@ -382,9 +382,9 @@ def isolate_namespace(mod)
# Finds engine with given path
def find(path)
path = path.to_s
Rails::Engine::Railties.engines.find { |r|
File.expand_path(r.root.to_s) == File.expand_path(path)
expanded_path = File.expand_path path.to_s
Rails::Engine::Railties.engines.find { |engine|
File.expand_path(engine.root.to_s) == expanded_path
}
end
end

@ -1,5 +1,5 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"

@ -48,7 +48,7 @@
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => "welcome#index"
# root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"

@ -1,4 +1,4 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
# Read about fixtures at http://api.rubyonrails.org/classes/Fixtures.html
<% unless attributes.empty? -%>
one: