提交 5e212471 编写于 作者: X Xavier Noria

Merge branch 'master' of git://github.com/lifo/docrails

Conflicts:
	activerecord/RUNNING_UNIT_TESTS
......@@ -106,7 +106,7 @@ module Basic
module ControllerMethods
extend ActiveSupport::Concern
module ClassMethods
def http_basic_authenticate_with(options = {})
before_filter(options.except(:name, :password, :realm)) do
......@@ -116,7 +116,7 @@ def http_basic_authenticate_with(options = {})
end
end
end
def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
end
......
......@@ -64,7 +64,7 @@ module ActionController
# end
#
# will try to check if +Admin::User+ or +User+ model exists, and use it to
# determine the wrapper key respectively. If both of the model doesn't exists,
# determine the wrapper key respectively. If both models don't exist,
# it will then fallback to use +user+ as the key.
module ParamsWrapper
extend ActiveSupport::Concern
......@@ -88,14 +88,14 @@ module ClassMethods
# # wraps parameters into +params[:person]+ hash
#
# wrap_parameters Person
# # wraps parameters by determine the wrapper key from Person class
# # wraps parameters by determining the wrapper key from Person class
# (+person+, in this case) and the list of attribute names
#
# wrap_parameters :include => [:username, :title]
# # wraps only +:username+ and +:title+ attributes from parameters.
#
# wrap_parameters false
# # disable parameters wrapping for this controller altogether.
# # disables parameters wrapping for this controller altogether.
#
# ==== Options
# * <tt>:format</tt> - The list of formats in which the parameters wrapper
......
......@@ -260,4 +260,3 @@ def _render_template(options) #:nodoc:
end
end
end
\ No newline at end of file
......@@ -35,9 +35,9 @@ def safe_concat(value)
def html_safe?
true
end
def html_safe
self
end
end
end
\ No newline at end of file
end
......@@ -202,13 +202,13 @@ def convert_to_model(object)
#
# is equivalent to something like:
#
# <%= form_for @post, :as => :post, :url => post_path(@post), :html => { :class => "new_post", :id => "new_post" } do |f| %>
# <%= form_for @post, :as => :post, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>
# ...
# <% end %>
#
# You can also overwrite the individual conventions, like this:
#
# <%= form_for(@post, :url => super_post_path(@post)) do |f| %>
# <%= form_for(@post, :url => super_posts_path) do |f| %>
# ...
# <% end %>
#
......
......@@ -427,7 +427,7 @@ def option_groups_from_collection_for_select(collection, group_method, group_lab
#
# Sample usage (Hash):
# grouped_options = {
# 'North America' => [['United States','US], 'Canada'],
# 'North America' => [['United States','US'], 'Canada'],
# 'Europe' => ['Denmark','Germany','France']
# }
# grouped_options_for_select(grouped_options)
......
......@@ -342,7 +342,7 @@ def number_to_human_size(number, options = {})
options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
base = options[:prefix] == :si ? 1000 : 1024
if number.to_i < base
......
......@@ -10,7 +10,7 @@ module ActionView
# this key is generated just once during the request, it speeds up all cache accesses.
class LookupContext #:nodoc:
attr_accessor :prefixes
mattr_accessor :fallbacks
@@fallbacks = FallbackFileSystemResolver.instances
......
......@@ -34,7 +34,7 @@ def query(path, exts, formats)
templates << Template.new(source, _path, handler,
:virtual_path => path.virtual, :format => format, :updated_at => updated_at)
end
templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
end
end
......
......@@ -248,7 +248,7 @@ def add_on_blank(attributes, options = {})
#
# company = Company.create(:address => '123 First St.')
# company.errors.full_messages # =>
# ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"]
# ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
def full_messages
map { |attribute, message|
if attribute == :base
......
......@@ -22,13 +22,13 @@ module JSON
# of +as_json+. If true (the default) +as_json+ will emit a single root
# node named after the object's type. For example:
#
# konata = User.find(1)
# konata.as_json
# user = User.find(1)
# user.as_json
# # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true} }
#
# ActiveRecord::Base.include_root_in_json = false
# konata.as_json
# user.as_json
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true}
#
......@@ -38,30 +38,30 @@ module JSON
# Without any +options+, the returned JSON string will include all the model's
# attributes. For example:
#
# konata = User.find(1)
# konata.as_json
# user = User.find(1)
# user.as_json
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true}
#
# The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the attributes
# included, and work similar to the +attributes+ method. For example:
#
# konata.as_json(:only => [ :id, :name ])
# user.as_json(:only => [ :id, :name ])
# # => {"id": 1, "name": "Konata Izumi"}
#
# konata.as_json(:except => [ :id, :created_at, :age ])
# user.as_json(:except => [ :id, :created_at, :age ])
# # => {"name": "Konata Izumi", "awesome": true}
#
# To include the result of some method calls on the model use <tt>:methods</tt>:
#
# konata.as_json(:methods => :permalink)
# user.as_json(:methods => :permalink)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "permalink": "1-konata-izumi"}
#
# To include associations use <tt>:include</tt>:
#
# konata.as_json(:include => :posts)
# user.as_json(:include => :posts)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
......@@ -69,7 +69,7 @@ module JSON
#
# Second level and higher order associations work as well:
#
# konata.as_json(:include => { :posts => {
# user.as_json(:include => { :posts => {
# :include => { :comments => {
# :only => :body } },
# :only => :title } })
......
......@@ -139,8 +139,8 @@ def add_procs
# Without any +options+, the returned XML string will include all the model's
# attributes. For example:
#
# konata = User.find(1)
# konata.to_xml
# user = User.find(1)
# user.to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <user>
......
......@@ -62,14 +62,14 @@ module HelperMethods
# Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:
#
# class Person < ActiveRecord::Base
# validates_length_of :first_name, :maximum=>30
# validates_length_of :last_name, :maximum=>30, :message=>"less than 30 if you don't mind"
# validates_length_of :first_name, :maximum => 30
# validates_length_of :last_name, :maximum => 30, :message => "less than 30 if you don't mind"
# validates_length_of :fax, :in => 7..32, :allow_nil => true
# validates_length_of :phone, :in => 7..32, :allow_blank => true
# validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
# validates_length_of :zip_code, :minimum => 5, :too_short => "please enter at least 5 characters"
# validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with 4 characters... don't play me."
# validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least 100 words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
# validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least 100 words.", :tokenizer => lambda { |str| str.scan(/\w+/) }
# end
#
# Configuration options:
......
......@@ -240,7 +240,6 @@
def up
create_table :posts do |t|
t.belongs_to :user
t.timestamps
end
......
......@@ -3,7 +3,7 @@
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,
class and an existing table in the database. In the 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*.
......@@ -70,7 +70,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Validations.html]
* Callbacks available for the entire life cycle (instantiation, saving, destroying, validating, etc.)
* Callbacks available for the entire life cycle (instantiation, saving, destroying, validating, etc.).
class Person < ActiveRecord::Base
before_destroy :invalidate_payment_plan
......@@ -80,7 +80,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Callbacks.html]
* Observers that react to changes in a model
* Observers that react to changes in a model.
class CommentObserver < ActiveRecord::Observer
def after_create(comment) # is called just after Comment#save
......@@ -91,7 +91,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Observer.html]
* Inheritance hierarchies
* Inheritance hierarchies.
class Company < ActiveRecord::Base; end
class Firm < Company; end
......@@ -101,7 +101,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Base.html]
* Transactions
* Transactions.
# Database transaction
Account.transaction do
......@@ -112,7 +112,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Transactions/ClassMethods.html]
* Reflections on columns, associations, and aggregations
* Reflections on columns, associations, and aggregations.
reflection = Firm.reflect_on_association(:clients)
reflection.klass # => Client (class)
......@@ -121,7 +121,7 @@ A short rundown of some of the major features:
{Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html]
* Database abstraction through simple adapters
* Database abstraction through simple adapters.
# connect to SQLite3
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "dbfile.sqlite3")
......@@ -141,13 +141,13 @@ A short rundown of some of the major features:
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]
* Logging support for Log4r[http://log4r.sourceforge.net] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc].
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")
* Database agnostic schema management with Migrations
* Database agnostic schema management with Migrations.
class AddSystemSettings < ActiveRecord::Migration
def self.up
......
......@@ -22,4 +22,11 @@ environment variable:
You can run all the tests for a given database via rake:
$ rake test_postgresql
To setup the testing environment for PostgreSQL use this command:
rake postgresql:build_databases
The incantation for running a particular test looks like this
rake test TEST=test/cases/datatype_test_postgresql.rb TESTOPTS="--name=test_timestamp_with_zone_values_without_rails_time_zone_support"
......@@ -452,12 +452,12 @@ def association_instance_set(name, association)
# end
#
# Some extensions can only be made to work with knowledge of the association's internals.
# Extensions can access relevant state using the following methods (where 'items' is the
# Extensions can access relevant state using the following methods (where +items+ is the
# name of the association):
#
# * +record.association(:items).owner+ - Returns the object the association is part of.
# * +record.association(:items).reflection+ - Returns the reflection object that describes the association.
# * +record.association(:items).target+ - Returns the associated object for +belongs_to+ and +has_one+, or
# * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
# * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
# * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
# the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
#
# === Association Join Models
......
......@@ -48,7 +48,7 @@ def get_primary_key(base_name) #:nodoc:
end
attr_accessor :original_primary_key
# Attribute writer for the primary key column
def primary_key=(value)
@quoted_primary_key = nil
......
......@@ -53,7 +53,7 @@ def initialize(name)
#
# This migration will add a boolean flag to the accounts table and remove it
# if you're backing out of the migration. It shows how all migrations have
# two class methods +up+ and +down+ that describes the transformations
# two methods +up+ and +down+ that describes the transformations
# required to implement or remove the migration. These methods can consist
# of both the migration specific methods like add_column and remove_column,
# but may also contain regular Ruby code for generating data needed for the
......
module ActiveRecord
class Migration
# ActiveRecord::Migration::CommandRecorder records commands done during
# <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
# a migration and knows how to reverse those commands. The CommandRecorder
# knows how to invert the following commands:
#
......@@ -23,7 +23,7 @@ def initialize(delegate = nil)
# record +command+. +command+ should be a method name and arguments.
# For example:
#
# recorder.record(:method_name, [:arg1, arg2])
# recorder.record(:method_name, [:arg1, :arg2])
def record(*command)
@commands << command
end
......@@ -34,7 +34,7 @@ def record(*command)
# recorder.record(:rename_table, [:old, :new])
# recorder.inverse # => [:rename_table, [:new, :old]]
#
# This method will raise an IrreversibleMigration exception if it cannot
# This method will raise an +IrreversibleMigration+ exception if it cannot
# invert the +commands+.
def inverse
@commands.reverse.map { |name, args|
......@@ -50,9 +50,9 @@ def respond_to?(*args) # :nodoc:
[:create_table, :rename_table, :add_column, :remove_column, :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, :change_column, :change_column_default].each do |method|
class_eval <<-EOV, __FILE__, __LINE__ + 1
def #{method}(*args)
record(:"#{method}", args)
end
def #{method}(*args) # def create_table(*args)
record(:"#{method}", args) # record(:create_table, args)
end # end
EOV
end
......
......@@ -165,7 +165,7 @@ class TransactionError < ActiveRecordError # :nodoc:
# writing, the only database that we're aware of that supports true nested
# transactions, is MS-SQL. Because of this, Active Record emulates nested
# transactions by using savepoints on MySQL and PostgreSQL. See
# http://dev.mysql.com/doc/refman/5.0/en/savepoints.html
# http://dev.mysql.com/doc/refman/5.0/en/savepoint.html
# for more information about savepoints.
#
# === Callbacks
......
......@@ -20,8 +20,8 @@ class Schema # :nodoc:
# end
#
# The schema stores the name and type of each attribute. That is then
# read out by the schema method to populate the actual
# Resource's schema
# read out by the schema method to populate the schema of the actual
# resource.
def initialize
@attrs = {}
end
......@@ -40,6 +40,12 @@ def attribute(name, type, options = {})
# The following are the attribute types supported by Active Resource
# migrations.
KNOWN_ATTRIBUTE_TYPES.each do |attr_type|
# def string(*args)
# options = args.extract_options!
# attr_names = args
#
# attr_names.each { |name| attribute(name, 'string', options) }
# end
class_eval <<-EOV, __FILE__, __LINE__ + 1
def #{attr_type.to_s}(*args)
options = args.extract_options!
......
......@@ -59,7 +59,7 @@ def suppress(*exception_classes)
raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
end
end
# Captures the given stream and returns it:
#
# stream = capture(:stdout) { puts "Cool" }
......
......@@ -9,7 +9,7 @@ module ActiveSupport
module Testing
module Performance
extend ActiveSupport::Concern
included do
superclass_delegating_accessor :profile_options
self.profile_options = {}
......@@ -20,7 +20,7 @@ module Performance
include ForClassicTestUnit
end
end
# each implementation should define metrics and freeze the defaults
DEFAULTS =
if ARGV.include?('--benchmark') # HAX for rake test
......@@ -32,7 +32,7 @@ module Performance
:output => 'tmp/performance',
:benchmark => false }
end
def full_profile_options
DEFAULTS.merge(profile_options)
end
......@@ -40,7 +40,7 @@ def full_profile_options
def full_test_name
"#{self.class.name}##{method_name}"
end
module ForMiniTest
def run(runner)
@runner = runner
......@@ -53,7 +53,7 @@ def run(runner)
end
end
end
return
end
......@@ -122,7 +122,7 @@ def run_test(metric, mode)
protected
# overridden by each implementation
def run_gc; end
def run_warmup
run_gc
......@@ -132,7 +132,7 @@ def run_warmup
run_gc
end
def run_profile(metric)
klass = full_profile_options[:benchmark] ? Benchmarker : Profiler
performer = klass.new(self, metric)
......@@ -163,7 +163,7 @@ def output_filename
"#{full_profile_options[:output]}/#{full_test_name}_#{@metric.name}"
end
end
# overridden by each implementation
class Profiler < Performer
def time_with_block
......@@ -171,7 +171,7 @@ def time_with_block
yield
Time.now - before
end
def run; end
def record; end
end
......@@ -181,10 +181,10 @@ def initialize(*args)
super
@supported = @metric.respond_to?('measure')
end
def run
return unless @supported
full_profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
@total = @metric.total
end
......@@ -237,7 +237,7 @@ def output_filename
"#{super}.csv"
end
end
module Metrics
def self.[](name)
const_get(name.to_s.camelize)
......@@ -247,7 +247,7 @@ def self.[](name)
class Base
include ActionView::Helpers::NumberHelper
attr_reader :total
def initialize
......@@ -265,15 +265,15 @@ def benchmark
@total += (measure - before)
end
end
# overridden by each implementation
def profile; end
protected
# overridden by each implementation
def with_gc_stats; end
end
class Time < Base
def measure
::Time.now.to_f
......@@ -287,19 +287,19 @@ def format(measurement)
end
end
end
class Amount < Base
def format(measurement)
number_with_delimiter(measurement.floor)
end
end
class DigitalInformationUnit < Base
def format(measurement)
number_to_human_size(measurement, :precision => 2)
end
end
# each implementation provides its own metrics like ProcessTime, Memory or GcRuns
end
end
......
require 'jruby/profiler'
require 'java'
require 'java'
java_import java.lang.management.ManagementFactory
module ActiveSupport
......@@ -12,21 +12,21 @@ module Performance
{ :metrics => [:wall_time],
:formats => [:flat, :graph] }
end).freeze
protected
def run_gc
ManagementFactory.memory_mx_bean.gc
end
end
class Profiler < Performer
def initialize(*args)
super
@supported = @metric.is_a?(Metrics::WallTime)
end
def run
return unless @supported
@total = time_with_block do
@data = JRuby::Profiler.profile do
full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
......@@ -36,7 +36,7 @@ def run
def record
return unless @supported
klasses = full_profile_options[:formats].map { |f| JRuby::Profiler.const_get("#{f.to_s.camelize}ProfilePrinter") }.compact
klasses.each do |klass|
......@@ -61,7 +61,7 @@ def output_filename(printer_class)
end
end
module Metrics
module Metrics
class Base
def profile
yield
......@@ -85,7 +85,7 @@ def measure
ManagementFactory.thread_mx_bean.get_current_thread_cpu_time / 1000 / 1000 / 1000.0 # seconds
end
end
class UserTime < Time
def measure
ManagementFactory.thread_mx_bean.get_current_thread_user_time / 1000 / 1000 / 1000.0 # seconds
......@@ -97,7 +97,7 @@ def measure
ManagementFactory.memory_mx_bean.non_heap_memory_usage.used + ManagementFactory.memory_mx_bean.heap_memory_usage.used
end
end
class GcRuns < Amount
def measure
ManagementFactory.garbage_collector_mx_beans.inject(0) { |total_runs, current_gc| total_runs += current_gc.collection_count }
......
......@@ -10,12 +10,12 @@ module Performance
{ :metrics => [:wall_time],
:formats => [:flat, :graph] }
end).freeze
protected
def run_gc
GC.run(true)
end
class Performer; end
class Profiler < Performer
......@@ -23,35 +23,35 @@ def initialize(*args)
super
@supported = @metric.is_a?(Metrics::WallTime)
end
def run
return unless @supported
@profiler = Rubinius::Profiler::Instrumenter.new
@total = time_with_block do
@profiler.profile(false) do
full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
end
end
end
def record
return unless @supported
if(full_profile_options[:formats].include?(:flat))
create_path_and_open_file(:flat) do |file|
@profiler.show(file)
end
end
if(full_profile_options[:formats].include?(:graph))
create_path_and_open_file(:graph) do |file|
@profiler.show(file)
end
end
end
protected
def create_path_and_open_file(printer_name)
fname = "#{output_filename}_#{printer_name}.txt"
......@@ -62,10 +62,10 @@ def create_path_and_open_file(printer_name)
end
end
module Metrics
module Metrics
class Base
attr_reader :loopback
def profile
yield
end
......
......@@ -16,7 +16,7 @@ module Performance
:metrics => [:process_time, :memory, :objects],
:formats => [:flat, :graph_html, :call_tree, :call_stack] }
end).freeze
protected
def run_gc
GC.start
......@@ -77,7 +77,7 @@ class Base
def measure_mode
self.class::Mode
end
def profile
RubyProf.resume
yield
......@@ -91,7 +91,7 @@ def with_gc_stats
yield
end
end
class ProcessTime < Time
Mode = RubyProf::PROCESS_TIME if RubyProf.const_defined?(:PROCESS_TIME)
......
......@@ -15,7 +15,7 @@ def with_gc_stats
end
end
end
class Memory < DigitalInformationUnit
# Ruby 1.8 + ruby-prof wrapper
if RubyProf.respond_to?(:measure_memory)
......@@ -24,7 +24,7 @@ def measure
end
end
end
class Objects < Amount
# Ruby 1.8 + ruby-prof wrapper
if RubyProf.respond_to?(:measure_allocations)
......@@ -33,7 +33,7 @@ def measure
end
end
end
class GcRuns < Amount
# Ruby 1.8 + ruby-prof wrapper
if RubyProf.respond_to?(:measure_gc_runs)
......@@ -42,7 +42,7 @@ def measure
end
end
end
class GcTime < Time
# Ruby 1.8 + ruby-prof wrapper
if RubyProf.respond_to?(:measure_gc_time)
......@@ -55,5 +55,3 @@ def measure
end
end
end
......@@ -15,7 +15,7 @@ def with_gc_stats
end
end
end
class Memory < DigitalInformationUnit
# Ruby 1.9 + GCdata patch
if GC.respond_to?(:malloc_allocated_size)
......@@ -24,7 +24,7 @@ def measure
end
end
end
class Objects < Amount
# Ruby 1.9 + GCdata patch
if GC.respond_to?(:malloc_allocations)
......@@ -33,7 +33,7 @@ def measure
end
end
end
class GcRuns < Amount
# Ruby 1.9
if GC.respond_to?(:count)
......@@ -42,7 +42,7 @@ def measure
end
end
end
class GcTime < Time
# Ruby 1.9 with GC::Profiler
if defined?(GC::Profiler) && GC::Profiler.respond_to?(:total_time)
......
......@@ -929,7 +929,7 @@ Creates a scope around a specific model object like form_for, but doesn‘t crea
h5. file_field
Returns an file upload input tag tailored for accessing a specified attribute.
Returns a file upload input tag tailored for accessing a specified attribute.
<ruby>
file_field(:user, :avatar)
......@@ -1037,7 +1037,7 @@ Sample usage (selecting the associated Author for an instance of Post, +@post+):
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true})
</ruby>
If @post.author_id is already 1, this would return:
If <tt>@post.author_id</tt> is 1, this would return:
<html>
<select name="post[author_id]">
......@@ -1080,8 +1080,6 @@ Sample usage:
option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
</ruby>
TODO check above textile output looks right
Possible output:
<html>
......@@ -1132,13 +1130,13 @@ h5. select
Create a select tag and a series of contained option tags for the provided object and method.
Example with @post.person_id => 1:
Example:
<ruby>
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true })
</ruby>
could become:
If <tt>@post.person_id</tt> is 1, this would become:
<html>
<select name="post[person_id]">
......@@ -1189,7 +1187,7 @@ h5. file_field_tag
Creates a file upload field.
If you are using file uploads then you will also need to set the multipart option for the form tag:
Prior to Rails 3.1, if you are using file uploads, then you will need to set the multipart option for the form tag. Rails 3.1+ does this automatically.
<ruby>
<%= form_tag { :action => "post" }, { :multipart => true } do %>
......@@ -1400,102 +1398,6 @@ number_with_precision(111.2345) # => 111.235
number_with_precision(111.2345, 2) # => 111.23
</ruby>
h5. evaluate_remote_response
Returns +eval(request.responseText)+ which is the JavaScript function that form_remote_tag can call in +:complete+ to evaluate a multiple update return document using +update_element_function+ calls.
h5. form_remote_tag
Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement. Even though it‘s using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side.
For example, this:
<ruby>
form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") }
</ruby>
would generate the following:
<html>
<form action="/some/place" method="post" onsubmit="new Ajax.Request('',
{asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
</html>
h5. link_to_remote
Returns a link to a remote action that's called in the background using XMLHttpRequest. You can generate a link that uses AJAX in the general case, while degrading gracefully to plain link behavior in the absence of JavaScript. For example:
<ruby>
link_to_remote "Delete this post",
{ :update => "posts", :url => { :action => "destroy", :id => post.id } },
:href => url_for(:action => "destroy", :id => post.id)
</ruby>
h5. observe_field
Observes the field specified and calls a callback when its contents have changed.
<ruby>
observe_field("my_field", :function => "alert('Field changed')")
</ruby>
h5. observe_form
Observes the form specified and calls a callback when its contents have changed. The options for observe_form are the same as the options for observe_field.
<ruby>
observe_field("my_form", :function => "alert('Form changed')")
</ruby>
h5. periodically_call_remote
Periodically calls the specified url as often as specified. Usually used to update a specified div with the results of the remote call. The following example will call update every 20 seconds and update the news_block div:
<ruby>
periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
# => PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
</ruby>
h5. remote_form_for
Creates a form that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement and a scope around a specific resource that is used as a base for questioning about values for the fields.
<ruby>
<%= remote_form_for(@post) do |f| %>
...
<% end %>
</ruby>
h5. remote_function
Returns the JavaScript needed for a remote function. Takes the same arguments as +link_to_remote+.
<ruby>
<select id="options" onchange="<%= remote_function(:update => "options", :url => { :action => :update_options }) %>">
<option value="0">Hello</option>
<option value="1">World</option>
</select>
# => <select id="options" onchange="new Ajax.Updater('options', '/testing/update_options', {asynchronous:true, evalScripts:true})">
</ruby>
h5. submit_to_remote
Returns a button input tag that will submit form using XMLHttpRequest in the background instead of a regular POST request that reloads the page.
For example, the following:
<ruby>
submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' }
</ruby>
would generate:
<html>
<input name="create_btn" onclick="new Ajax.Request('/testing/create',
{asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
return false;" type="button" value="Create" />
</html>
h3. Localized Views
Action View has the ability render different templates depending on the current locale.
......@@ -1520,6 +1422,7 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht
h3. Changelog
* May 29, 2011: Removed references to remote_* helpers - Vijay Dev
* April 16, 2011: Added 'Using Action View with Rails', 'Templates' and 'Partials' sections. "Sebastian Martinez":http://wyeworks.com
* 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
......@@ -64,8 +64,8 @@ There are also some optional column names that will create additional features t
* *created_on* - Automatically gets set to the current date when the record is first created.
* *updated_at* - Automatically gets set to the current date and time whenever the record is updated.
* *updated_on* - Automatically gets set to the current date whenever the record is updated.
* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.com/classes/ActiveRecord/Locking.html to a model.
* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.com/classes/ActiveRecord/Base.html
* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.org/classes/ActiveRecord/Locking.html to a model.
* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.org/classes/ActiveRecord/Base.html
* *(table_name)_count* - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post.
NOTE: While these column names are optional they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
......
......@@ -483,16 +483,16 @@ SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You
For example:
<ruby>
Order.group("date(created_at)").having("created_at > ?", 1.month.ago)
Order.group("date(created_at)").having("created_at < ?", 1.month.ago)
</ruby>
The SQL that would be executed would be something like this:
<sql>
SELECT * FROM orders GROUP BY date(created_at) HAVING created_at > '2009-01-15'
SELECT * FROM orders GROUP BY date(created_at) HAVING created_at < '2011-04-27'
</sql>
This will return single order objects for each day, but only for the last month.
This will return single order objects for each day, but only those that are at least one month old.
h3. Overriding Conditions
......@@ -675,7 +675,7 @@ class Post < ActiveRecord::Base
has_many :tags
end
class Comments < ActiveRecord::Base
class Comment < ActiveRecord::Base
belongs_to :post
has_one :guest
end
......@@ -683,6 +683,10 @@ end
class Guest < ActiveRecord::Base
belongs_to :comment
end
class Tag < ActiveRecord::Base
belongs_to :post
end
</ruby>
Now all of the following will produce the expected join queries using +INNER JOIN+:
......@@ -700,6 +704,8 @@ SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id
</sql>
Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)").
h5. Joining Multiple Associations
<ruby>
......@@ -714,18 +720,40 @@ SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
</sql>
Or, in English: "return all posts that have a category and at least one comment". Note again that posts with multiple comments will show up multiple times.
h5. Joining Nested Associations (Single Level)
<ruby>
Post.joins(:comments => :guest)
</ruby>
This produces:
<sql>
SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
INNER JOIN guests ON guests.comment_id = comments.id
</sql>
Or, in English: "return all posts that have a comment made by a guest."
h5. Joining Nested Associations (Multiple Level)
<ruby>
Category.joins(:posts => [{:comments => :guest}, :tags])
</ruby>
This produces:
<sql>
SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id
INNER JOIN comments ON comments.post_id = posts.id
INNER JOIN guests ON guests.comment_id = comments.id
INNER JOIN tags ON tags.post_id = posts.id
</sql>
h4. Specifying Conditions on the Joined Tables
You can specify conditions on the joined tables using the regular "Array":#array-conditions and "String":#pure-string-conditions conditions. "Hash conditions":#hash-conditions provides a special syntax for specifying conditions for the joined tables:
......
......@@ -82,6 +82,7 @@ The following methods skip validations, and will save the object to the database
* +increment!+
* +increment_counter+
* +toggle!+
* +touch+
* +update_all+
* +update_attribute+
* +update_column+
......@@ -429,7 +430,7 @@ end
The +validates_with+ helper takes a class, or a list of classes to use for validation. There is no default error message for +validates_with+. You must manually add errors to the record's errors collection in the validator class.
To implement the validate method, you must have an +record+ parameter defined, which is the record to be validated.
To implement the validate method, you must have a +record+ parameter defined, which is the record to be validated.
Like all other validations, +validates_with+ takes the +:if+, +:unless+ and +:on+ options. If you pass any other options, it will send those options to the validator class as +options+:
......@@ -911,20 +912,20 @@ h4. Creating an Object
* +before_validation+
* +after_validation+
* +before_save+
* +after_save+
* +before_create+
* +around_create+
* +after_create+
* +after_save+
h4. Updating an Object
* +before_validation+
* +after_validation+
* +before_save+
* +after_save+
* +before_update+
* +around_update+
* +after_update+
* +after_save+
h4. Destroying an Object
......@@ -1007,6 +1008,7 @@ Just as with validations, it's also possible to skip callbacks. These methods sh
* +increment+
* +increment_counter+
* +toggle+
* +touch+
* +update_column+
* +update_all+
* +update_counters+
......
......@@ -868,7 +868,7 @@ The macro accepts several methods:
delegate :name, :age, :address, :twitter, :to => :profile
</ruby>
When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such a expression is evaluated in the context of the receiver:
When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such an expression is evaluated in the context of the receiver:
<ruby>
# delegates to the Rails constant
......@@ -3024,7 +3024,7 @@ Date.new(2010, 1, 31).change(:month => 2)
h5(#date-durations). Durations
Durations can be added and substracted to dates:
Durations can be added to and subtracted from dates:
<ruby>
d = Date.current
......@@ -3232,7 +3232,7 @@ DateTime.current.change(:month => 2, :day => 30)
h5(#datetime-durations). Durations
Durations can be added and substracted to datetimes:
Durations can be added to and subtracted from datetimes:
<ruby>
now = DateTime.current
......@@ -3353,7 +3353,7 @@ If the time to be constructed lies beyond the range supported by +Time+ in the r
h5(#time-durations). Durations
Durations can be added and substracted to time objects:
Durations can be added to and subtracted from time objects:
<ruby>
now = Time.current
......
......@@ -72,7 +72,7 @@ link_to_remote "Add to cart",
If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the DOM id +error+ is updated rather than the +cart+ element.
** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
** *position* By default (i.e. when not specifying this option, like in the examples before) the response is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
*** +:before+ Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element.
*** +:after+ Similar behavior to +:before+, but in this case the response is inserted after the target element.
*** +:top+ Inserts the text into the target element, before it's original content. If the target element was empty, this is equivalent with not specifying +:position+ at all.
......
......@@ -41,8 +41,8 @@ h3. Example Code
Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.
Use two spaces to indent chunks of code.—that is two spaces with respect to the left margin; the examples
themselves should use "Rails code conventions":http://rails.lighthouseapp.com/projects/8994/source-style.
Use two spaces to indent chunks of code--that is two spaces with respect to the left margin; the examples
themselves should use "Rails coding conventions":contributing_to_ruby_on_rails.html#follow-the-coding-conventions.
Short docs do not need an explicit "Examples" label to introduce snippets, they just follow paragraphs:
......
......@@ -4,26 +4,54 @@ This guide will cover the ideology of the asset pipeline introduced in Rails 3.1
By referring to this guide you will be able to:
* Properly organize your application assets
* Understand the benefits of the asset pipline
* Adding a preproccessor to the pipeline
* Package assets with your plugin
* Understand the benefits of the asset pipeline
* Adding a preprocessor to the pipeline
* Package assets with a gem
endprologue.
h3. What Is The Asset Pipeline?
h4. Why Should I Use it?
The asset pipeline is a new feature introduced in Rails 3.1 using the "Sprockets":http://getsprockets.org/ engine. It allows developers to place design elements in +app/assets+ instead of +public+, there are many advantages to this. A big one is that they are now processed by Rails instead of your webserver, allowing you to use preprocessors like CoffeeScript, SCSS, or ERB. Another advantage is that your CSS and JavaScript is compiled into one file by default, this allows users to cache all the CSS and JavaScript data so your pages render faster. Not to mention how much cleaner your application will become.
h3. How to Use the Asset Pipeline
The asset pipeline is easy to migrate to and use. There are a few things that you'll need to learn first, like where to place your files, how to create a manifest, and how to add any preproccesors if you desire.
h4. Asset Organization
h4. Default Files Loaded
WIP
Sprockets will automatically load manifest files by searching directories in app/assets and including the first file with a basename of index. (Confirm and add: does it load app/assets/index?)
h4. Directives
h4. Stacking Preproccessors
WIP
Sprockets, the rails tie that powers the asset pipeline, provides three directives which are like Ruby's methods. They are: +require+, +require_tree+, and +require_self+. These directives must be called at the top of a file in a comment with an equal sign before it. (note: CSS directives need *= if in a continuous comment -- confirm please)
The require directive loads a file with the supplied basename from the following paths: app/assets/*, lib/assets/*, vendor/assets/*, as well as any of your gem's asset files.
Require tree does...
Require self does...
h4. Stacking Preprocessors
h3. Packaging Assets with Your Plugin
Sprockets allows you to stack preprocessors. The stack is ran off the file extensions in a last in, first out method (like popping an array). For example if we want to make a JavaScript asset with both CoffeeScript and ERB the file would be named: +name.js.coffee.erb+. If it were named +name.js.erb.coffee+ CoffeeScript would raise an error because it doesn't understand ERB tags.
h4. Adding a Preproccessor
WIP
https://github.com/rtomayko/tilt for gems or config.register_processor('text/css', MyAwesomeProccessor) for local stuff
h3. Packaging Assets with Your Gems
You may find it useful to package certain assets with your gem. A good example would be the "pjax_rails":https://github.com/rails/pjax_rails/ gem. This gem bundles the latest "PJAX":https://github.com/defunkt/jquery-pjax library and some helper methods. If you take a look at the source of pjax_rails, you'll see that it bundles the assets in +lib/assets+ just the same way as you would in +app/assets+. Doing so allows pjax_rails to update JavaScripts without asking users to copy them into their public folder
If you want the user to load your JavaScript files in their template, you will have to ask them to add a directive to do so. Also avoid any common names such as +form_check.js+ instead try using +mygem/form_check.js+ so it's clear where it's coming from. This will also make it unlikely that your users will create a file with the same name causing the asset pipeline to choose the user's file over yours.
h3. More on Sprockets
Sprockets is the engine that handles the asset pipeline in Rails 3.1 and above. Their official website is available at "http://getsprockets.org/":http://getsprockets.org/ and the source code is "available on github":https://github.com/sstephenson/sprockets.
......@@ -345,7 +345,7 @@ ActionController::Base.cache_store = MyCacheStore.new
h4. Cache Keys
The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. ActiveRecord will generate keys based on the class name and record id.
The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. Active Record will generate keys based on the class name and record id.
You can use Hashes and Arrays of values as cache keys.
......
......@@ -55,7 +55,7 @@ INFO: This output will seem very familiar when we get to the +generate+ command.
h4. +rails server+
Let's try it! The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to view your work through a web browser.
The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to view your work through a web browser.
INFO: WEBrick isn't your only option for serving Rails. We'll get to that in a later section.
......@@ -65,7 +65,7 @@ Without any prodding of any kind, +rails server+ will run our new shiny Rails ap
$ cd commandsapp
$ rails server
=> Booting WEBrick
=> Rails 3.0.0 application starting in development on http://0.0.0.0:3000
=> Rails 3.1.0 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-04-18 03:20:33] INFO WEBrick 1.3.1
......@@ -75,6 +75,8 @@ $ rails server
With just three commands we whipped up a Rails server listening on port 3000. Go to your browser and open "http://localhost:3000":http://localhost:3000, you will see a basic Rails app running.
You can also use the alias "s" to start the server: <tt>rails s</tt>.
h4. +rails generate+
The +rails generate+ command uses templates to create a whole lot of things. You can always find out what's available by running +rails generate+ by itself. Let's do that:
......@@ -237,7 +239,7 @@ dependency model
create test/unit/high_score_test.rb
create test/fixtures/high_scores.yml
exists db/migrate
create db/migrate/20081217071914_create_high_scores.rb
create db/migrate/20100209025147_create_high_scores.rb
</shell>
The generator checks that there exist the directories for models, controllers, helpers, layouts, functional and unit tests, stylesheets, creates the views, controller, model and database migration for HighScore (creating the +high_scores+ table and fields), takes care of the route for the *resource*, and new tests for everything.
......@@ -267,11 +269,13 @@ h4. +rails console+
The +console+ command lets you interact with your Rails application from the command line. On the underside, +rails console+ uses IRB, so if you've ever used it, you'll be right at home. This is useful for testing out quick ideas with code and changing data server-side without touching the website.
You can also use the alias "c" to invoke the console: <tt>rails c</tt>.
If you wish to test out some code without changing any data, you can do that by invoking +rails console --sandbox+.
<shell>
$ rails console --sandbox
Loading development environment in sandbox (Rails 3.0.0)
Loading development environment in sandbox (Rails 3.1.0)
Any modifications you make will be rolled back on exit
irb(main):001:0>
</shell>
......@@ -280,6 +284,8 @@ h4. +rails dbconsole+
+rails dbconsole+ figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3.
You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>.
h4. +rails plugin+
The +rails plugin+ command simplifies plugin management; think a miniature version of the Gem utility. Let's walk through installing a plugin. You can call the sub-command +discover+, which sifts through repositories looking for plugins, or call +source+ to add a specific repository of plugins, or you can specify the plugin location directly.
......@@ -306,7 +312,7 @@ $ rails runner "Model.long_running_method"
h4. +rails destroy+
Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it. Believe you-me, the creation of this tutorial used this command many times!
Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it.
<shell>
$ rails generate model Oops
......@@ -333,9 +339,29 @@ $ rails destroy model Oops
notempty app
</shell>
h4. +rake about+
h3. Rake
Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.
You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need.
<shell>
$ rake --tasks
(in /home/foobar/commandsapp)
rake db:abort_if_pending_migrations # Raises an error if there are pending migrations
rake db:charset # Retrieves the charset for the current environment's database
rake db:collation # Retrieves the collation for the current environment's database
rake db:create # Create the database defined in config/database.yml for the current Rails.env
...
...
rake tmp:pids:clear # Clears all files in tmp/pids
rake tmp:sessions:clear # Clears all files in tmp/sessions
rake tmp:sockets:clear # Clears all files in tmp/sockets
</shell>
h4. +about+
Check it: Version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version! +about+ is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
<tt>rake about</tt> gives information about version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version. It is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
<shell>
$ rake about
......@@ -343,17 +369,55 @@ About your application's environment
Ruby version 1.8.7 (x86_64-linux)
RubyGems version 1.3.6
Rack version 1.1
Rails version 3.0.0
Active Record version 3.0.0
Action Pack version 3.0.0
Active Resource version 3.0.0
Action Mailer version 3.0.0
Active Support version 3.0.0
Rails version 3.1.0
Active Record version 3.1.0
Action Pack version 3.1.0
Active Resource version 3.1.0
Action Mailer version 3.1.0
Active Support version 3.1.0
Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Callbacks, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::MethodOverride, ActionDispatch::Head
Application root /home/foobar/commandsapp
Environment development
</shell>
h4. +assets+
You can precompile the assets in <tt>app/assets</tt> using <tt>rake assets:precompile</tt> and remove compiled assets using <tt>rake assets:clean</tt>.
h4. +db+
The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
h4. +doc+
If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
h4. +notes+
These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them.
h4. +routes+
+rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
h4. +test+
INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
The +test:+ namespace helps in running the different tests you will (hopefully!) write.
h4. +tmp+
The <tt>Rails.root/tmp</tt> directory is, like the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry.
h4. Miscellaneous
* +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
* +rake secret+ will give you a pseudo-random key to use for your session secret.
* <tt>rake time:zones:all</tt> lists all the timezones Rails knows about.
h3. The Rails Advanced Command Line
More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
......@@ -437,7 +501,7 @@ Successfully installed mongrel-1.1.5
Installing RDoc documentation for mongrel-1.1.5...
$ rails server mongrel
=> Booting Mongrel (use 'rails server webrick' to force WEBrick)
=> Rails 3.0.0 application starting on http://0.0.0.0:3000
=> Rails 3.1.0 application starting on http://0.0.0.0:3000
...
</shell>
......@@ -534,60 +598,3 @@ I got assigned some args:
</shell>
Tada!
h4. Rake is Ruby Make
Rake is a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.
You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need.
<shell>
$ rake --tasks
(in /home/foobar/commandsapp)
rake db:abort_if_pending_migrations # Raises an error if there are pending migrations
rake db:charset # Retrieves the charset for the current environment's database
rake db:collation # Retrieves the collation for the current environment's database
rake db:create # Create the database defined in config/database.yml for the current Rails.env
...
...
rake tmp:pids:clear # Clears all files in tmp/pids
rake tmp:sessions:clear # Clears all files in tmp/sessions
rake tmp:sockets:clear # Clears all files in tmp/sockets
</shell>
h5. +db:+ Database
The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
h5. +doc:+ Documentation
If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
h5. +notes:+ Code note enumeration
These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them.
h5. +test:+ Rails tests
INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
The +test:+ namespace helps in running the different tests you will (hopefully!) write.
h5. +time:+ Timezones
You can list all the timezones Rails knows about with +rake time:zones:all+, which is useful just in day-to-day life.
h5. +tmp:+ Temporary files
The tmp directory is, like in the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry.
h5. Miscellaneous Tasks
+rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
+rake secret+ will give you a pseudo-random key to use for your session secret.
+rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
......@@ -52,7 +52,7 @@ end
* +config.asset_host+ sets the host for the assets. Useful when CDNs are used for hosting assets, or when you want to work around the concurrency constraints builtin in browsers using different domain aliases. Shorter version of +config.action_controller.asset_host+.
* +config.asset_path+ can take a callable, a string, or be +nil+. Default is +nil+. If set, this configuration parameter let's you decorate asset paths. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. *This option is ignored if the asset pipeline is enabled, which is by default*. Shorter version of +config.action_controller.asset_path+.
* +config.asset_path+ can take a callable, a string, or be +nil+. Default is +nil+. If set, this configuration parameter lets you decorate asset paths. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. *This option is ignored if the asset pipeline is enabled, which is by default*. Shorter version of +config.action_controller.asset_path+.
<ruby>
config.asset_path = proc { |path| "/blog/public#{path}" }
......@@ -121,10 +121,10 @@ h4. Configuring Generators
Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block:
<ruby>
config.generators do |g|
g.orm :active_record
g.test_framework :test_unit
end
config.generators do |g|
g.orm :active_record
g.test_framework :test_unit
end
</ruby>
The full set of methods that can be used in this block are as follows:
......@@ -167,31 +167,31 @@ Every Rails application comes with a standard set of middleware which it uses in
Besides these usual middleware, you can add your own by using the +config.middleware.use+ method:
<ruby>
config.middleware.use Magical::Unicorns
config.middleware.use Magical::Unicorns
</ruby>
This will put the +Magical::Unicorns+ middleware on the end of the stack. If you wish to put this middleware before another use +insert_before+:
<ruby>
config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
</ruby>
There's also +insert_after+ which will insert a middleware _after_ another:
<ruby>
config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
</ruby>
Middlewares can also be completely swapped out and replaced with others:
<ruby>
config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
</ruby>
They can also be removed from the stack completely:
<ruby>
config.middleware.delete ActionDispatch::BestStandardsSupport
config.middleware.delete ActionDispatch::BestStandardsSupport
</ruby>
h4. Configuring i18n
......@@ -204,7 +204,7 @@ h4. Configuring Active Record
<tt>config.active_record</tt> includes a variety of configuration options:
* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8.x Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to nil to disable logging.
* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8.x Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to +nil+ to disable logging.
* +config.active_record.primary_key_prefix_type+ lets you adjust the naming for primary key columns. By default, Rails assumes that primary key columns are named +id+ (and this configuration option doesn't need to be set.) There are two other choices:
** +:table_name+ would make the primary key for the Customer class +customerid+
......@@ -216,19 +216,19 @@ h4. Configuring Active Record
* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to +true+ (the default), then the Customer class will use the +customers+ table. If set to +false+, then the Customers class will use the +customer+ table.
* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although ActiveRecord defaults to +:local+ when used outside of Rails.
* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although Active Record defaults to +:local+ when used outside of Rails.
* +config.active_record.schema_format+ controls the format for dumping the database schema to a file. The options are +:ruby+ (the default) for a database-independent version that depends on migrations, or +:sql+ for a set of (potentially database-dependent) SQL statements.
* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is +true+, to use timestamps, which are preferred if there are multiple developers working on the same application.
* +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+.
* +config.active_record.lock_optimistically+ controls whether Active Record will use optimistic locking. By default this is +true+.
* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.
The MySQL adapter adds one additional configuration option:
* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
The schema dumper adds one additional configuration option:
......@@ -250,7 +250,7 @@ h4. Configuring Action Controller
* +config.action_controller.default_charset+ specifies the default character set for all renders. The default is "utf-8".
* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to +nil+ to disable logging.
* +config.action_controller.request_forgery_protection_token+ sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ sets it to +:authenticity_token+ by default.
......@@ -292,7 +292,7 @@ There are only a few configuration options for Action View, starting with four o
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging.
* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging.
* +config.action_view.erb_trim_mode+ gives the trim mode to be used by ERB. It defaults to +'-'+. See the "ERB documentation":http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/ for more information.
......@@ -326,7 +326,7 @@ h4. Configuring Action Mailer
There are a number of settings available on +config.action_mailer+:
* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging.
* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging.
* +config.action_mailer.smtp_settings+ allows detailed configuration for the +:smtp+ delivery method. It accepts a hash of options, which can include any of these options:
** +:address+ - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
......@@ -348,17 +348,17 @@ There are a number of settings available on +config.action_mailer+:
* +config.action_mailer.default+ configures Action Mailer defaults. These default to:
<ruby>
:mime_version => "1.0",
:charset => "UTF-8",
:content_type => "text/plain",
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
:mime_version => "1.0",
:charset => "UTF-8",
:content_type => "text/plain",
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
</ruby>
h4. Configuring Active Resource
There is a single configuration setting available on +config.active_resource+:
* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Active Resource. Set to nil to disable logging.
* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Active Resource. Set to +nil+ to disable logging.
h4. Configuring Active Support
......
......@@ -14,7 +14,7 @@ h3. How to Contribute?
* 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.
* You're encouraged to validate XHTML for the generated guides before committing your changes by running +bundle exec rake validate_guides+ in the +railties+ directory.
* Edge guides "can be consulted online":http://edgeguides.rubyonrails.org/. That website is generated periodically from docrails.
h3. What to Contribute?
......@@ -33,7 +33,7 @@ h3. What to Contribute?
h3. How is the process?
* The preferred way to contribute is to commit to docrails directly.
* A new guide is only edited by its author until finished though. In that case feedback can be given in its LH ticket.
* A new guide is only edited by its author until finished though.
* If you are writing a new guide freely commit to docrails partial work and ping lifo or fxn when done with a first draft.
* Guides reviewers will then provide feedback, some of it possibly in form of direct commits to agilize the process.
* Eventually the guide will be approved and added to the index.
......@@ -53,7 +53,7 @@ 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":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.
All authors should read and follow the "Rails Guides Conventions":ruby_on_rails_guides_guidelines.html and the "Rails API Documentation Conventions":api_documentation_guidelines.html.
h3. Translations
......
......@@ -24,7 +24,7 @@ If you've found a problem in Ruby on Rails which is not a security risk do a sea
At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need to at least post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating a issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
h4. Special Treatment for Security Issues
......@@ -90,7 +90,7 @@ This command will install all dependencies except the MySQL and PostgreSQL Ruby
$ rake test
</shell>
You can also run tests for an specific framework, like Action Pack, by going into its directory and executing the same command:
You can also run tests for a specific framework, like Action Pack, by going into its directory and executing the same command:
<shell>
$ cd actionpack
......@@ -309,7 +309,7 @@ Rails follows a simple set of coding style conventions.
* a = b and not a=b.
* Follow the conventions you see used in the source already.
These are some guidelines and please use your best judgement in using them.
These are some guidelines and please use your best judgment in using them.
h4. Sanity Check
......
......@@ -545,7 +545,7 @@ NOTE: In many cases the built-in date pickers are clumsy as they do not aid the
h4. Individual Components
Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overriden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value.
Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overridden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value.
The first parameter specifies which value should be selected and can either be an instance of a Date, Time or DateTime, in which case the relevant component will be extracted, or a numerical value. For example
......
......@@ -46,7 +46,7 @@ class InitializerGenerator < Rails::Generators::Base
end
</ruby>
NOTE: +create_file+ is a method provided by +Thor::Actions+ and the documentation for it and its brethren can be found at "rdoc.info":http://rdoc.info/github/wycats/thor/master/Thor/Actions.
NOTE: +create_file+ is a method provided by +Thor::Actions+. Documentation for +create_file+ and other Thor methods can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
......@@ -131,7 +131,7 @@ And let's execute our generator:
$ rails generate initializer core_extensions
</shell>
We can see that now a initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
We can see that now an initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
The methods that are available for generators are covered in the "final section":#generator-methods of this guide.
......@@ -365,7 +365,7 @@ $ rails generate scaffold Comment body:text
Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
h3. Application templates
h3. Application Templates
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template".
......
......@@ -503,7 +503,7 @@ def index
end
</ruby>
+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in a instance variable called +@posts+.
+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in an instance variable called +@posts+.
TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html.
......
......@@ -809,7 +809,7 @@ That does not mean you're stuck with these limitations, though. The Ruby I18n ge
I18n.backend = Globalize::Backend::Static.new
</ruby>
You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the ActiveRecord backend and fall back to the (default) Simple backend:
You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the Active Record backend and fall back to the (default) Simple backend:
<ruby>
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
......
......@@ -123,7 +123,7 @@ Cache-Control: no-cache
$
</shell>
We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgement that the request was completed.
We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgment that the request was completed.
TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers.
......
......@@ -55,6 +55,8 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration
end
</ruby>
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered
to have already opted in, so we use the User model to set the flag to +true+ for existing users.
......@@ -73,11 +75,9 @@ class CreateProducts < ActiveRecord::Migration
end
</ruby>
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
h4. Migrations are Classes
A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two class methods: +up+ (perform the required transformations) and +down+ (revert them).
A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two methods: +up+ (perform the required transformations) and +down+ (revert them).
Active Record provides methods that perform common data definition tasks in a database independent way (you'll read about them in detail later):
......@@ -115,7 +115,7 @@ h4. Changing Migrations
Occasionally you will make a mistake when writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless. Just use some common sense.
In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless.
h3. Creating a Migration
......
......@@ -276,7 +276,7 @@ measurement,created_at,app,rails,ruby,platform
h5(#output-profiling). Profiling
In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependant on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependent on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
h6. Command Line
......
......@@ -111,11 +111,11 @@ h5. Adding a Middleware
You can add a new middleware to the middleware stack using any of the following methods:
* +config.middleware.use(new_middleware, args)+ - Adds the new middleware at the bottom of the middleware stack.
* <tt>config.middleware.use(new_middleware, args)</tt> - Adds the new middleware at the bottom of the middleware stack.
* +config.middleware.insert_before(existing_middleware, new_middleware, args)+ - Adds the new middleware before the specified existing middleware in the middleware stack.
* <tt>config.middleware.insert_before(existing_middleware, new_middleware, args)</tt> - Adds the new middleware before the specified existing middleware in the middleware stack.
* +config.middleware.insert_after(existing_middleware, new_middleware, args)+ - Adds the new middleware after the specified existing middleware in the middleware stack.
* <tt>config.middleware.insert_after(existing_middleware, new_middleware, args)</tt> - Adds the new middleware after the specified existing middleware in the middleware stack.
<ruby>
# config/environment.rb
......@@ -154,20 +154,20 @@ h4. Internal Middleware Stack
Much of Action Controller's functionality is implemented as Middlewares. The following table explains the purpose of each of them:
|_.Middleware|_.Purpose|
|+Rack::Lock+|Sets +env["rack.multithread"]+ flag to +true+ and wraps the application within a Mutex.|
|+Rack::Lock+|Sets <tt>env["rack.multithread"]</tt> flag to +true+ and wraps the application within a Mutex.|
|+ActionController::Failsafe+|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.|
|+ActiveRecord::QueryCache+|Enables the Active Record query cache.|
|+ActionController::Session::CookieStore+|Uses the cookie based session store.|
|+ActionController::Session::MemCacheStore+|Uses the memcached based session store.|
|+ActiveRecord::SessionStore+|Uses the database based session store.|
|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or +env["HTTP_X_HTTP_METHOD_OVERRIDE"]+.|
|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or <tt>env["HTTP_X_HTTP_METHOD_OVERRIDE"]</tt>.|
|+Rack::Head+|Discards the response body if the client sends a +HEAD+ request.|
TIP: It's possible to use any of the above middlewares in your custom Rack stack.
h4. Customizing Internal Middleware Stack
It's possible to replace the entire middleware stack with a custom stack using +ActionController::Dispatcher.middleware=+.
It's possible to replace the entire middleware stack with a custom stack using <tt>ActionController::Dispatcher.middleware=</tt>.
Put the following in an initializer:
......
......@@ -288,7 +288,7 @@ When using +magazine_ad_path+, you can pass in instances of +Magazine+ and +Ad+
You can also use +url_for+ with a set of objects, and Rails will automatically determine which route you want:
<erb>
<%= link_to "Ad details", url_for(@magazine, @ad) %>
<%= link_to "Ad details", url_for([@magazine, @ad]) %>
</erb>
In this case, Rails will see that +@magazine+ is a +Magazine+ and +@ad+ is an +Ad+ and will therefore use the +magazine_ad_path+ helper. In helpers like +link_to+, you can specify just the object in place of the full +url_for+ call:
......
......@@ -65,7 +65,7 @@ It is also recommended that you work with +WARNINGS=1+. This detects duplicate I
If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +GUIDES_LANGUAGE+ environment variable:
<plain>
rake generate_guides GUIDES_LANGUAGE=es
bundle exec rake generate_guides GUIDES_LANGUAGE=es
</plain>
h3. HTML Validation
......@@ -73,7 +73,7 @@ h3. HTML Validation
Please validate the generated HTML with:
<plain>
rake validate_guides
bundle exec rake validate_guides
</plain>
Particularly, titles get an ID generated from their content and this often leads to duplicates. Please set +WARNINGS=1+ when generating guides to detect them. The warning messages suggest a way to fix them.
......
......@@ -929,8 +929,8 @@ class UserControllerTest < ActionController::TestCase
end
invite_email = ActionMailer::Base.deliveries.first
assert_equal invite_email.subject, "You have been invited by me@example.com"
assert_equal invite_email.to[0], 'friend@example.com'
assert_equal "You have been invited by me@example.com", invite_email.subject
assert_equal 'friend@example.com', invite_email.to[0]
assert_match /Hi friend@example.com/, invite_email.body
end
end
......
......@@ -95,7 +95,7 @@
benchmarker See how fast a piece of code runs
profiler Get profile information from a piece of code
plugin Install a plugin
runner Run a piece of code in the application environment
runner Run a piece of code in the application environment (short-cut alias: "r")
All commands can be run with -h for more information.
EOT
......
......@@ -9,7 +9,7 @@
def options
options = {}
defaults = ActiveSupport::Testing::Performance::DEFAULTS
OptionParser.new do |opt|
opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
......@@ -17,13 +17,13 @@ def options
opt.on('-m', '--metrics a,b,c', Array, 'Metrics to use.', "Default: #{defaults[:metrics].join(",")}") { |m| options[:metrics] = m.map(&:to_sym) }
opt.parse!(ARGV)
end
options
end
class BenchmarkerTest < ActionDispatch::PerformanceTest
self.profile_options = options
ARGV.each do |expression|
eval <<-RUBY
def test_#{expression.parameterize('_')}
......
......@@ -6,7 +6,7 @@
def options
options = {}
defaults = ActiveSupport::Testing::Performance::DEFAULTS
OptionParser.new do |opt|
opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
......@@ -15,13 +15,13 @@ def options
opt.on('-f', '--formats x,y,z', Array, 'Formats to output to.', "Default: #{defaults[:formats].join(",")}") { |m| options[:formats] = m.map(&:to_sym) }
opt.parse!(ARGV)
end
options
end
class ProfilerTest < ActionDispatch::PerformanceTest
self.profile_options = options
ARGV.each do |expression|
eval <<-RUBY
def test_#{expression.parameterize('_')}
......
# Be sure to restart your server when you modify this file.
#
# This file contains the settings for ActionController::ParametersWrapper
# which will be enabled by default in the upcoming version of Ruby on Rails.
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActionController::Base.wrap_parameters <%= key_value :format, "[:json]" %>
......
......@@ -5,7 +5,7 @@ class BrowsingTest < ActionDispatch::PerformanceTest
# Refer to the documentation for all available options
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
# :output => 'tmp/performance', :formats => [:flat] }
def test_homepage
get '/'
end
......
......@@ -7,7 +7,7 @@ Description:
This generates a JavaScript stub in app/assets/javascripts and a stylesheet
stub in app/assets/stylesheets.
If CoffeeScript is available, JavaScripts will be generated with the .coffee extension.
If Sass 3 is available, stylesheets will be generated with the .scss extension.
......
......@@ -5,7 +5,7 @@ class <%= class_name %>Test < ActionDispatch::PerformanceTest
# Refer to the documentation for all available options
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
# :output => 'tmp/performance', :formats => [:flat] }
def test_homepage
get '/'
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册