1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge branch 'master' of github.com:rails/docrails

This commit is contained in:
Vijay Dev 2015-01-15 07:28:21 +00:00
commit 3f96b6973b
6 changed files with 138 additions and 99 deletions

View file

@ -51,7 +51,7 @@ module ActionController
# #
# def show # def show
# @article = Article.find(params[:id]) # @article = Article.find(params[:id])
# fresh_when(etag: @article, last_modified: @article.created_at, public: true) # fresh_when(etag: @article, last_modified: @article.updated_at, public: true)
# end # end
# #
# This will render the show template if the request isn't sending a matching ETag or # This will render the show template if the request isn't sending a matching ETag or
@ -115,7 +115,7 @@ module ActionController
# def show # def show
# @article = Article.find(params[:id]) # @article = Article.find(params[:id])
# #
# if stale?(etag: @article, last_modified: @article.created_at) # if stale?(etag: @article, last_modified: @article.updated_at)
# @statistics = @article.really_expensive_call # @statistics = @article.really_expensive_call
# respond_to do |format| # respond_to do |format|
# # all the supported formats # # all the supported formats

View file

@ -22,49 +22,49 @@ module ActiveSupport
# pluralized using rules defined for that language. By default, # pluralized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>. # this parameter is set to <tt>:en</tt>.
# #
# 'post'.pluralize # => "posts" # pluralize('post') # => "posts"
# 'octopus'.pluralize # => "octopi" # pluralize('octopus') # => "octopi"
# 'sheep'.pluralize # => "sheep" # pluralize('sheep') # => "sheep"
# 'words'.pluralize # => "words" # pluralize('words') # => "words"
# 'CamelOctopus'.pluralize # => "CamelOctopi" # pluralize('CamelOctopus') # => "CamelOctopi"
# 'ley'.pluralize(:es) # => "leyes" # pluralize('ley', :es) # => "leyes"
def pluralize(word, locale = :en) def pluralize(word, locale = :en)
apply_inflections(word, inflections(locale).plurals) apply_inflections(word, inflections(locale).plurals)
end end
# The reverse of +pluralize+, returns the singular form of a word in a # The reverse of #pluralize, returns the singular form of a word in a
# string. # string.
# #
# If passed an optional +locale+ parameter, the word will be # If passed an optional +locale+ parameter, the word will be
# singularized using rules defined for that language. By default, # singularized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>. # this parameter is set to <tt>:en</tt>.
# #
# 'posts'.singularize # => "post" # singularize('posts') # => "post"
# 'octopi'.singularize # => "octopus" # singularize('octopi') # => "octopus"
# 'sheep'.singularize # => "sheep" # singularize('sheep') # => "sheep"
# 'word'.singularize # => "word" # singularize('word') # => "word"
# 'CamelOctopi'.singularize # => "CamelOctopus" # singularize('CamelOctopi') # => "CamelOctopus"
# 'leyes'.singularize(:es) # => "ley" # singularize('leyes', :es) # => "ley"
def singularize(word, locale = :en) def singularize(word, locale = :en)
apply_inflections(word, inflections(locale).singulars) apply_inflections(word, inflections(locale).singulars)
end end
# By default, +camelize+ converts strings to UpperCamelCase. If the argument # Converts strings to UpperCamelCase.
# to +camelize+ is set to <tt>:lower</tt> then +camelize+ produces # If the +uppercase_first_letter+ parameter is set to false, then produces
# lowerCamelCase. # lowerCamelCase.
# #
# +camelize+ will also convert '/' to '::' which is useful for converting # Also converts '/' to '::' which is useful for converting
# paths to namespaces. # paths to namespaces.
# #
# 'active_model'.camelize # => "ActiveModel" # camelize('active_model') # => "ActiveModel"
# 'active_model'.camelize(:lower) # => "activeModel" # camelize('active_model', false) # => "activeModel"
# 'active_model/errors'.camelize # => "ActiveModel::Errors" # camelize('active_model/errors') # => "ActiveModel::Errors"
# 'active_model/errors'.camelize(:lower) # => "activeModel::Errors" # camelize('active_model/errors', false) # => "activeModel::Errors"
# #
# As a rule of thumb you can think of +camelize+ as the inverse of # As a rule of thumb you can think of +camelize+ as the inverse of
# +underscore+, though there are cases where that does not hold: # #underscore, though there are cases where that does not hold:
# #
# 'SSLError'.underscore.camelize # => "SslError" # camelize(underscore('SSLError')) # => "SslError"
def camelize(term, uppercase_first_letter = true) def camelize(term, uppercase_first_letter = true)
string = term.to_s string = term.to_s
if uppercase_first_letter if uppercase_first_letter
@ -81,13 +81,13 @@ module ActiveSupport
# #
# Changes '::' to '/' to convert namespaces to paths. # Changes '::' to '/' to convert namespaces to paths.
# #
# 'ActiveModel'.underscore # => "active_model" # underscore('ActiveModel') # => "active_model"
# 'ActiveModel::Errors'.underscore # => "active_model/errors" # underscore('ActiveModel::Errors') # => "active_model/errors"
# #
# As a rule of thumb you can think of +underscore+ as the inverse of # As a rule of thumb you can think of +underscore+ as the inverse of
# +camelize+, though there are cases where that does not hold: # #camelize, though there are cases where that does not hold:
# #
# 'SSLError'.underscore.camelize # => "SslError" # camelize(underscore('SSLError')) # => "SslError"
def underscore(camel_cased_word) def underscore(camel_cased_word)
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
word = camel_cased_word.to_s.gsub(/::/, '/') word = camel_cased_word.to_s.gsub(/::/, '/')
@ -101,14 +101,14 @@ module ActiveSupport
# Tweaks an attribute name for display to end users. # Tweaks an attribute name for display to end users.
# #
# Specifically, +humanize+ performs these transformations: # Specifically, performs these transformations:
# #
# * Applies human inflection rules to the argument. # * Applies human inflection rules to the argument.
# * Deletes leading underscores, if any. # * Deletes leading underscores, if any.
# * Removes a "_id" suffix if present. # * Removes a "_id" suffix if present.
# * Replaces underscores with spaces, if any. # * Replaces underscores with spaces, if any.
# * Downcases all words except acronyms. # * Downcases all words except acronyms.
# * Capitalizes the first word. # * Capitalizes the first word.
# #
# The capitalization of the first word can be turned off by setting the # The capitalization of the first word can be turned off by setting the
# +:capitalize+ option to false (default is true). # +:capitalize+ option to false (default is true).
@ -148,34 +148,34 @@ module ActiveSupport
# #
# +titleize+ is also aliased as +titlecase+. # +titleize+ is also aliased as +titlecase+.
# #
# 'man from the boondocks'.titleize # => "Man From The Boondocks" # titleize('man from the boondocks') # => "Man From The Boondocks"
# 'x-men: the last stand'.titleize # => "X Men: The Last Stand" # titleize('x-men: the last stand') # => "X Men: The Last Stand"
# 'TheManWithoutAPast'.titleize # => "The Man Without A Past" # titleize('TheManWithoutAPast') # => "The Man Without A Past"
# 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark" # titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark"
def titleize(word) def titleize(word)
humanize(underscore(word)).gsub(/\b(?<!['`])[a-z]/) { $&.capitalize } humanize(underscore(word)).gsub(/\b(?<!['`])[a-z]/) { $&.capitalize }
end end
# Create the name of a table like Rails does for models to table names. This # Creates the name of a table like Rails does for models to table names.
# method uses the +pluralize+ method on the last word in the string. # This method uses the #pluralize method on the last word in the string.
# #
# 'RawScaledScorer'.tableize # => "raw_scaled_scorers" # tableize('RawScaledScorer') # => "raw_scaled_scorers"
# 'egg_and_ham'.tableize # => "egg_and_hams" # tableize('egg_and_ham') # => "egg_and_hams"
# 'fancyCategory'.tableize # => "fancy_categories" # tableize('fancyCategory') # => "fancy_categories"
def tableize(class_name) def tableize(class_name)
pluralize(underscore(class_name)) pluralize(underscore(class_name))
end end
# Create a class name from a plural table name like Rails does for table # Creates a class name from a plural table name like Rails does for table
# names to models. Note that this returns a string and not a Class (To # names to models. Note that this returns a string and not a Class (To
# convert to an actual class follow +classify+ with +constantize+). # convert to an actual class follow +classify+ with #constantize).
# #
# 'egg_and_hams'.classify # => "EggAndHam" # classify('egg_and_hams') # => "EggAndHam"
# 'posts'.classify # => "Post" # classify('posts') # => "Post"
# #
# Singular names are not handled correctly: # Singular names are not handled correctly:
# #
# 'calculus'.classify # => "Calculu" # classify('calculus') # => "Calculu"
def classify(table_name) def classify(table_name)
# strip out any leading schema name # strip out any leading schema name
camelize(singularize(table_name.to_s.sub(/.*\./, ''))) camelize(singularize(table_name.to_s.sub(/.*\./, '')))
@ -183,19 +183,19 @@ module ActiveSupport
# Replaces underscores with dashes in the string. # Replaces underscores with dashes in the string.
# #
# 'puni_puni'.dasherize # => "puni-puni" # dasherize('puni_puni') # => "puni-puni"
def dasherize(underscored_word) def dasherize(underscored_word)
underscored_word.tr('_', '-') underscored_word.tr('_', '-')
end end
# Removes the module part from the expression in the string. # Removes the module part from the expression in the string.
# #
# 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections" # demodulize('ActiveRecord::CoreExtensions::String::Inflections') # => "Inflections"
# 'Inflections'.demodulize # => "Inflections" # demodulize('Inflections') # => "Inflections"
# '::Inflections'.demodulize # => "Inflections" # demodulize('::Inflections') # => "Inflections"
# ''.demodulize # => "" # demodulize('') # => ""
# #
# See also +deconstantize+. # See also #deconstantize.
def demodulize(path) def demodulize(path)
path = path.to_s path = path.to_s
if i = path.rindex('::') if i = path.rindex('::')
@ -207,13 +207,13 @@ module ActiveSupport
# Removes the rightmost segment from the constant expression in the string. # Removes the rightmost segment from the constant expression in the string.
# #
# 'Net::HTTP'.deconstantize # => "Net" # deconstantize('Net::HTTP') # => "Net"
# '::Net::HTTP'.deconstantize # => "::Net" # deconstantize('::Net::HTTP') # => "::Net"
# 'String'.deconstantize # => "" # deconstantize('String') # => ""
# '::String'.deconstantize # => "" # deconstantize('::String') # => ""
# ''.deconstantize # => "" # deconstantize('') # => ""
# #
# See also +demodulize+. # See also #demodulize.
def deconstantize(path) def deconstantize(path)
path.to_s[0, path.rindex('::') || 0] # implementation based on the one in facets' Module#spacename path.to_s[0, path.rindex('::') || 0] # implementation based on the one in facets' Module#spacename
end end
@ -222,9 +222,9 @@ module ActiveSupport
# +separate_class_name_and_id_with_underscore+ sets whether # +separate_class_name_and_id_with_underscore+ sets whether
# the method should put '_' between the name and 'id'. # the method should put '_' between the name and 'id'.
# #
# 'Message'.foreign_key # => "message_id" # foreign_key('Message') # => "message_id"
# 'Message'.foreign_key(false) # => "messageid" # foreign_key('Message', false) # => "messageid"
# 'Admin::Post'.foreign_key # => "post_id" # foreign_key('Admin::Post') # => "post_id"
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
end end
@ -280,8 +280,8 @@ module ActiveSupport
# Tries to find a constant with the name specified in the argument string. # Tries to find a constant with the name specified in the argument string.
# #
# 'Module'.safe_constantize # => Module # safe_constantize('Module') # => Module
# 'Test::Unit'.safe_constantize # => Test::Unit # safe_constantize('Test::Unit') # => Test::Unit
# #
# The name is assumed to be the one of a top-level constant, no matter # The name is assumed to be the one of a top-level constant, no matter
# whether it starts with "::" or not. No lexical context is taken into # whether it starts with "::" or not. No lexical context is taken into
@ -290,16 +290,16 @@ module ActiveSupport
# C = 'outside' # C = 'outside'
# module M # module M
# C = 'inside' # C = 'inside'
# C # => 'inside' # C # => 'inside'
# 'C'.safe_constantize # => 'outside', same as ::C # safe_constantize('C') # => 'outside', same as ::C
# end # end
# #
# +nil+ is returned when the name is not in CamelCase or the constant (or # +nil+ is returned when the name is not in CamelCase or the constant (or
# part of it) is unknown. # part of it) is unknown.
# #
# 'blargle'.safe_constantize # => nil # safe_constantize('blargle') # => nil
# 'UnknownModule'.safe_constantize # => nil # safe_constantize('UnknownModule') # => nil
# 'UnknownModule::Foo::Bar'.safe_constantize # => nil # safe_constantize('UnknownModule::Foo::Bar') # => nil
def safe_constantize(camel_cased_word) def safe_constantize(camel_cased_word)
constantize(camel_cased_word) constantize(camel_cased_word)
rescue NameError => e rescue NameError => e

View file

@ -67,17 +67,8 @@ module ActiveSupport
# Replaces special characters in a string so that it may be used as part of # Replaces special characters in a string so that it may be used as part of
# a 'pretty' URL. # a 'pretty' URL.
# #
# class Person # parameterize("Donald E. Knuth") # => "donald-e-knuth"
# def to_param # parameterize("^trés|Jolie-- ") # => "tres-jolie"
# "#{id}-#{name.parameterize}"
# end
# end
#
# @person = Person.find(1)
# # => #<Person id: 1, name: "Donald E. Knuth">
#
# <%= link_to(@person.name, person_path(@person)) %>
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
def parameterize(string, sep = '-') def parameterize(string, sep = '-')
# replace accented chars with their ascii equivalents # replace accented chars with their ascii equivalents
parameterized_string = transliterate(string) parameterized_string = transliterate(string)
@ -92,6 +83,5 @@ module ActiveSupport
end end
parameterized_string.downcase parameterized_string.downcase
end end
end end
end end

View file

@ -78,7 +78,8 @@ end
Enqueue a job like so: Enqueue a job like so:
```ruby ```ruby
# Enqueue a job to be performed as soon the queueing system is free. # Enqueue a job to be performed as soon the queueing system is
# free.
MyJob.perform_later record MyJob.perform_later record
``` ```
@ -114,8 +115,9 @@ You can easily set your queueing backend:
# config/application.rb # config/application.rb
module YourApp module YourApp
class Application < Rails::Application class Application < Rails::Application
# Be sure to have the adapter's gem in your Gemfile and follow # Be sure to have the adapter's gem in your Gemfile
# the adapter's specific installation and deployment instructions. # and follow the adapter's specific installation
# and deployment instructions.
config.active_job.queue_adapter = :sidekiq config.active_job.queue_adapter = :sidekiq
end end
end end
@ -153,8 +155,8 @@ class GuestsCleanupJob < ActiveJob::Base
end end
# Now your job will run on queue production_low_priority on your # Now your job will run on queue production_low_priority on your
# production environment and on staging_low_priority on your staging # production environment and on staging_low_priority
# environment # on your staging environment
``` ```
The default queue name prefix delimiter is '\_'. This can be changed by setting The default queue name prefix delimiter is '\_'. This can be changed by setting
@ -176,8 +178,8 @@ class GuestsCleanupJob < ActiveJob::Base
end end
# Now your job will run on queue production.low_priority on your # Now your job will run on queue production.low_priority on your
# production environment and on staging.low_priority on your staging # production environment and on staging.low_priority
# environment # on your staging environment
``` ```
If you want more control on what queue a job will be run you can pass a `:queue` If you want more control on what queue a job will be run you can pass a `:queue`
@ -295,7 +297,7 @@ end
``` ```
This works with any class that mixes in `GlobalID::Identification`, which This works with any class that mixes in `GlobalID::Identification`, which
by default has been mixed into Active Model classes. by default has been mixed into Active Record classes.
Exceptions Exceptions

View file

@ -692,7 +692,7 @@ development:
pool: 5 pool: 5
``` ```
Prepared Statements are enabled by default on PostgreSQL. You can be disable prepared statements by setting `prepared_statements` to `false`: Prepared Statements are enabled by default on PostgreSQL. You can disable prepared statements by setting `prepared_statements` to `false`:
```yaml ```yaml
production: production:

View file

@ -528,6 +528,19 @@ All of request types have equivalent methods that you can use. In a typical C.R.
NOTE: Functional tests do not verify whether the specified request type is accepted by the action, we're more concerned with the result. Request tests exist for this use case to make your tests more purposeful. NOTE: Functional tests do not verify whether the specified request type is accepted by the action, we're more concerned with the result. Request tests exist for this use case to make your tests more purposeful.
### Testing XHR (AJAX) requests
`xhr` accepts method (listed in the section above), action name and parameters:
```ruby
test "ajax request responds with no layout" do
xhr :get, :show, id: articles(:first).id
assert_template :index
assert_template layout: nil
end
```
### The Four Hashes of the Apocalypse ### The Four Hashes of the Apocalypse
After a request has been made and processed, you will have 4 Hash objects ready for use: After a request has been made and processed, you will have 4 Hash objects ready for use:
@ -740,10 +753,8 @@ class ArticlesControllerTest < ActionController::TestCase
# called after every single test # called after every single test
def teardown def teardown
# as we are re-initializing @article before every test # when controller is using cache it may be a good idea to reset it afterwards
# setting it to nil here is not essential but I hope Rails.cache.clear
# you understand how you can use the teardown method
@article = nil
end end
test "should show article" do test "should show article" do
@ -769,6 +780,41 @@ end
Similar to other callbacks in Rails, the `setup` and `teardown` methods can also be used by passing a block, lambda, or method name as a symbol to call. Similar to other callbacks in Rails, the `setup` and `teardown` methods can also be used by passing a block, lambda, or method name as a symbol to call.
### Test helpers
To avoid code duplication, you can add your own test helpers.
Sign in helper can be a good example:
```ruby
test/test_helper.rb
module SignInHelper
def sign_in(user)
session[:user_id] = user.id
end
end
class ActionController::TestCase
include SignInHelper
end
```
```ruby
require 'test_helper'
class ProfileControllerTest < ActionController::TestCase
test "should show profile" do
# helper is now reusable from any controller test case
sign_in users(:david)
get :show
assert_response :success
assert_equal users(:david), assigns(:user)
end
end
```
Testing Routes Testing Routes
-------------- --------------
@ -1050,9 +1096,10 @@ require 'test_helper'
class UserMailerTest < ActionMailer::TestCase class UserMailerTest < ActionMailer::TestCase
test "invite" do test "invite" do
# Send the email, then test that it got queued # Send the email, then test that it got queued
email = UserMailer.create_invite('me@example.com', assert_emails 1 do
'friend@example.com', Time.now).deliver_now email = UserMailer.create_invite('me@example.com',
assert_not ActionMailer::Base.deliveries.empty? 'friend@example.com', Time.now).deliver_now
end
# Test the body of the sent email contains what we expect it to # Test the body of the sent email contains what we expect it to
assert_equal ['me@example.com'], email.from assert_equal ['me@example.com'], email.from