Active Support is a Rails library containing utility classes and extensions to Ruby’s built-in libraries. It usually doesn’t get much attention on its own—you might even call its modules the supporting cast members of the Rails ensemble.
However, Active Support’s low profile doesn’t diminish its importance in day-to-day Rails programming. To ensure that this book is useful as an offline programming companion, here is a complete, enhanced version of the Rails Active Support API reference, supplemented in most cases with realistic example usages and commentary. As you are reviewing the material in this appendix, note that many of the methods featured here are used primarily by other Rails libraries and are not particularly useful to application developers.
Section headings reflect the name of the class or module where the API method is located and are organized in alphabetical order for easy lookup. Subsections appear according to the name of the Ruby file in which they exist within Active Support’s lib
directory. Finally, the sub-subsections are the API methods themselves.
The following methods provide additional functionality for accessing array elements.
Returns the tail of the array starting from the position
specified. Note that the position is zero-indexed.
>> %w(foo bar baz quux).from(2)
=> ["baz", "quux"]
Returns the beginning elements of the array up to position
specified. Note that the position is zero-indexed.
>> %w(foo bar baz quux).to(2)
=> ["foo", "bar", "baz"]
Equivalent to calling self[1]
.
>> %w(foo bar baz quux).second
=> "bar"
Equivalent to self[2]
.
Equivalent to self[3]
.
Equivalent to self[4]
.
Equivalent to calling self[41]
—a humorous addition to the API by David.
The following methods are used for converting Ruby arrays into other formats.
Two formats are supported: :default
and :db
. The :default
format delegates to the normal to_s
method for an array, which just creates a string representation of the array.
>> %w(foo bar baz quux).to_s
=> "["foo", "bar", "baz", "quux"]"
The much more interesting :db
option returns "null"
if the array is empty or concatenates the id
fields of its member elements into a comma-delimited string with code like this:
collect { |element| element.id }.join(",")
In other words, the :db
formatting is meant to work with Active Record objects (or other types of objects that properly respond to id
). If the contents of the array do not respond to id
, a NoMethodError
exception is raised.
>> %w(foo bar baz quux).to_s(:db)
NoMethodError: undefined method 'id' for "foo":String
The to_s
method of Array
is aliased to to_formatted_s
.
The to_default_s
method of Array
is aliased to to_s
.
Converts the array to a comma-separated sentence in which the last element is joined by a connector word.
>> %w(alcohol tobacco firearms).to_sentence
=> "alcohol, tobacco, and firearms"
The following options are available for to_sentence:
:words_connector The sign or word used to join the elements in arrays with two or more elements (default: ","
).
:two_words_connector The sign or word used to join the elements in arrays with two elements (default: " and"
).
:last_word_connector The sign or word used to join the last element in arrays with three or more elements (default: ", and"
).
:locale If I18n is available, you can set a locale and use the connector options defined on the "support.array"
namespace.
As covered in Chapter 22, “XML,” the to_xml
method on Array
can be used to create an XML collection by iteratively calling to_xml
on its members and wrapping the entire thing in an enclosing element. If the array element does not respond to to_xml
, an XML representation of the object will be returned.
>> ["riding","high"].to_xml
=> "<?xml version="1.0" encoding="UTF-8"?>
<strings type="array">
<string>riding</string>
<string>high</string>
</strings>
"
The following example yields the Builder
object to an optional block so that arbitrary markup can be inserted at the bottom of the generated XML as the last child of the enclosing element.
1 {foo: "foo", bar: 42}.to_xml do |xml|
2 xml.did_it "again"
3 end
This outputs the following XML:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <hash>
3 <bar type="integer">42</bar>
4 <foo>foo</foo>
5 <did_it>again</did_it>
6 </hash>
The options for to_xml
are the following:
:builder Defaults to a new instance of Builder::XmlMarkup
. Specify explicitly if you’re calling to_xml
on this array as part of a larger XML construction routine.
:children Sets the name to use for element tags explicitly. Defaults to singularized version of the :root
name by default.
:dasherize Determines whether or not to turn underscores to dashes in tag names (defaults to true
).
:indent Indent level to use for generated XML (defaults to two spaces).
:root The tag name to use for the enclosing element. If no :root
is supplied and all members of the array are of the same class, the dashed, pluralized form of the first element’s class name is used as a default. Otherwise, the default :root
is objects
.
:skip_instruct Determines whether or not to generate an XML instruction tag by calling instruct!
on Builder
.
:skip_types Determines whether or not to include a type="array"
attribute on the enclosing element.
Active Support provides a method for extracting Rails-style options from a variable-length set of argument parameters.
Extracts options from a variable set of arguments. It’s a bang method because it removes and returns the last element in the array if it’s a hash; otherwise, it returns a blank hash and the source array is unmodified.
1 def options(*args)
2 args.extract_options!
3 end
4
5 >> options(1, 2)
6 => {}
7
8 >> options(1, 2, a: :b)
9 => {:a=>:b}
Methods used for splitting array elements into logical groupings.
The in_groups
method splits an array into a number
of equally sized groups. If a fill_with
parameter is provided, its value is used to pad the groups into equal sizes.
1 %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) { |group| p group }
2 ["1", "2", "3", "4"]
3 ["5", "6", "7", nil]
4 ["8", "9", "10", nil]
5
6 %w(1 2 3 4 5 6 7).in_groups(3, ' ') { |group| p group }
7 ["1", "2", "3"]
8 ["4", "5", " "]
9 ["6", "7", " "]
In the special case that you don’t want equally sized groups (in other words, no padding), then pass false
as the value of fill_with
.
1 %w(1 2 3 4 5 6 7).in_groups(3, false) { |group| p group }
2 ["1", "2", "3"]
3 ["4", "5"]
4 ["6", "7"]
Related to its sibling in_groups
, the in_groups_of
method splits an array into groups of the specified number
size, padding any remaining slots. The fill_with
parameter is used for padding and defaults to nil
. If a block is provided, it is called with each group; otherwise, a two-dimensional array is returned.
>> %w(1 2 3 4 5 6 7).in_groups_of(3)
=> [[1, 2, 3], [4, 5, 6], [7, nil, nil]
>> %w(1 2 3).in_groups_of(2, ' ') { |group| puts group.to_s }
=> ["1", "2"]
["3", " "]
nil
Passing false
to the fill_with
parameter inhibits the fill behavior.
>> %w(1 2 3).in_groups_of(2, false) { |group| puts group.to_s }
=> ["1", "2"]
["3"]
nil
The in_groups_of
method is particularly useful for batch processing model objects and generating table rows in view templates.
Divides an array into one or more subarrays based on either a delimiting value
>> [1, 2, 3, 4, 5].split(3)
=> [[1, 2], [4, 5]]
or the result of an optional block
>> (1..8).to_a.split { |i| i % 3 == 0 }
=> [[1, 2], [4, 5], [7, 8]]
Adds two aliases that are more similar to the human way of thinking about adding items to a list.
The append
method of Array
is aliased to <<
.
A convenience method added to the Array
class.
Wraps the object
in an Array
unless it’s an Array
. If nil
is supplied, an empty list is returned. Otherwise, the wrap
method will convert the supplied object to an Array using to_ary
if it implements that. It differs with Array()
in that it does not call to_a
on the argument:
1 Array(foo: :bar) # => [[:foo, :bar]]
2 Array.wrap(foo: :bar) # => [{:foo => :bar}]
3
4 Array("foo
bar") # => ["foo
bar"]
5 Array.wrap("foo
bar") # => ["foo
bar"]
6
7 Array(nil) # => []
8 Array.wrap(nil) # => []
Alias for empty?
Calls to_param
on all its elements and joins the result with slashes. This is used by the url_for
method in Action Pack.
>> ["riding","high","and","I","want","to","make"].to_param
=> "riding/high/and/I/want/to/make"
Many backtraces include too much information that’s not relevant for the context. This makes it hard to find the signal in the backtrace and adds debugging time. With a custom BacktraceCleaner
, you can set up filters and silencers for your particular context so only the relevant lines are included.
If you want to change the setting of Rails’ built-in BacktraceCleaner
to show as much as possible, you can call BacktraceCleaner.remove_silencers!
in your console, specs, or an application initializer. Also, if you need to reconfigure an existing BacktraceCleaner
so that it does not filter or modify the paths of any lines of the backtrace, you can call BacktraceCleaner#remove_filters!
. These two methods will give you a completely untouched backtrace.
1 bc = ActiveSupport::BacktraceCleaner.new
2 bc.add_filter { |line| line.gsub(Rails.root, '') }
3 bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
4
5 # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
6 bc.clean(exception.backtrace)
This is inspired by the Quiet Backtrace gem by Thoughtbot.
The following method provides additional functionality for returning in benchmark results in a human-readable format.
Benchmark real time in milliseconds.
>> Benchmark.realtime { User.all }
=> 8.0e-05
>> Benchmark.ms { User.all }
=> 0.074
Benchmarkable
allows you to measure the execution time of a block in a template and records the result to the log.
Wrap this block around expensive operations or possible bottlenecks to get a time reading for the operation. For example, let’s say you thought your file-processing method was taking too long. You could wrap it in a benchmark block.
1 benchmark "Process data files" do
2 expensive_files_operation
3 end
That would add an entry like “Process data files (345.2ms)” to the log, which can then be used to compare timings when optimizing your code.
You may give an optional logger level as the :level
option. Valid options are :debug
, :info
, :warn
, and :error
. The default level is :info
.
1 benchmark "Low-level files", level: :debug do
2 lowlevel_files_operation
3 end
Finally, you can pass true as the third argument to silence all log activity inside the block. This is great for boiling down a noisy block to just a single statement:
1 benchmark "Process data files", level: :info, silence: true do
2 expensive_and_chatty_files_operation
3 end
Emits a string representation of the number without any scientific notation and without losing precision.
>> bd = BigDecimal.new("84394878749783498749834734987.839723497347")
=> #<BigDecimal:269fabc,'0.8439487874 9783498749 8347349878 3972349734 7E29',44(48)>
>> bd.to_s
=> "84394878749783498749834734987.839723497347"
The to_s
method of BigDecimal
is aliased to to_formatted_s
.
A BigDecimal would be naturally represented as a JSON number. Most libraries, however, parse noninteger JSON numbers directly as floats. Clients using those libraries would get in general a wrong number and will have no way to recover the lost precision other than manually inspecting the string with the JSON code itself.
That’s why a JSON string is returned. The JSON literal is not numeric, but if the other end knows by contract that the data are supposed to be a BigDecimal, it still has the chance to postprocess the string and get the real value.
An abstract cache store class. There are multiple cache store implementations, each having its own additional features. MemCacheStore
is currently the most popular cache store for large production websites.
Some implementations may not support all methods beyond the basic cache methods of fetch
, read
, write
,exist?
, and delete
.
ActiveSupport::Cache::Store
can store any serializable Ruby object.
>> cache = ActiveSupport::Cache::MemoryStore.new
=> <#ActiveSupport::Cache::MemoryStore entries=0, size=0, options={}>
>> cache.read("city")
=> nil
>> cache.write("city", "Duckburgh")
=> true
>> cache.read("city")
=> "Duckburgh"
Keys are always translated into strings and are case sensitive.
>> cache.read("city") == cache.read(:city)
=> true
When an object is specified as a key, its cache_key
method will be called if it is defined. Otherwise, the to_param
method will be called.
>> r = Report.first
=> #<Report id: 1, name: "Special", created_at: ...>
>> r.cache_key
=> "reports/1-20131001152655016228000"
>> r.to_param
=> "1"
Hashes and arrays can also be used as keys. The elements will be delimited by slashes, and hash elements will be sorted by key so they are consistent.
>> cache.write ["USA","FL","Jacksonville"], "Obie"
=> true
>> cache.read "USA/FL/Jacksonville"
=> "Obie"
Nil values can be cached.
If your cache is on a shared infrastructure, you can define a namespace for your cache entries. If a namespace is defined, it will be prefixed on every key. To set a global namespace, set the :namespace
to the constructor of the cache store. The default value will include the application name and Rails environment.
cache = ActiveSupport::Cache::MemoryStore.new(namespace: 'tr4w')
All caches support autoexpiring content after a specified number of seconds. To set the cache entry time to live, you can specify :expires_in
as an option either to the constructor to have it affect all entries or to the fetch
or write
methods for just one entry.
1 cache = ActiveSupport::Cache::MemoryStore.new(expire_in: 5.minutes)
2 cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry.
It’s a recommended practice to set the :race_condition_ttl
option in conjunction with :expires_in
. When a cache entry is used frequently and the system is under a heavy load, a dog pile effect can occur during expiration. During this scenario, since the cache has expired, multiple processes will try to read the data natively and attempt to regenerate the same cache entry simultaneously. Using :race_condition_ttl
, one can set the number of seconds an expired entry can be reused while a new value is being regenerated. The first process to encounter the stale cache will attempt to write a new value, while other processes will continue to use slightly state data for the period defined in :race_condition_ttl
. Like the :expires_in
option, :race_condition_ttl
can be set globally or in the fetch
or write
methods for a single entry.
Caches can also store values in a compressed format to save space and reduce time spent sending data. Since there is some overhead, values must be large enough to warrant compression. To turn on compression pass compress: true
in the initializer or to fetch
or write
. To specify the threshold at which to compress values, set :compress_threshold
. The default threshold is 16K.
Cleanup the cache by removing expired entries. Not all cache implementations may support this method. Options are passed to the underlying cache implementation.
Clear the entire cache. Not all cache implementations may support this method. You should be careful with this method since it could affect other processes if you are using a shared cache. Options are passed to the underlying cache implementation.
Decrement an integer value in the cache. Options are passed to the underlying cache implementation.
Delete an entry in the cache. Returns true
if there was an entry to delete. Options are passed to the underlying cache implementation.
Delete all entries whose keys match a pattern. Options are passed to the underlying cache implementation.
>> Rails.cache.write :color, :red
=> true
>> Rails.cache.read :color
=> :red
>> Rails.cache.delete_matched "c"
=> ["city", "color", "USA/FL/Jacksonville"]
>> Rails.cache.read :color
=> nil
Return true
if the cache contains an entry with this name. Options are passed to the underlying cache implementation.
Fetches data from the cache using the given key. If there is data in the cache with the given key, then that data are returned.
If there is no such data in the cache (a cache miss occurred), then nil
will be returned. However, if a block has been passed, then that block will be run in the event of a cache miss. The return value of the block will be written to the cache under the given cache key, and that return value will be returned.
1 cache.write("today", "Monday")
2 cache.fetch("today") # => "Monday"
3
4 cache.fetch("city") # => nil
5 cache.fetch("city") do
6 "Duckburgh"
7 end
8 cache.fetch("city") # => "Duckburgh"
You may also specify additional options via the options argument. Setting :force => true
will force a cache miss:
1 cache.write("today", "Monday")
2 cache.fetch("today", force: true) # => nil
Setting :compress
will store a large cache entry set by the call in a compressed format.
Setting :expires_in
will set an expiration time on the cache entry if it is set by call.
Setting :race_condition_ttl
will invoke logic on entries set with an :expires_in
option. If an entry is found in the cache that is expired and it has been expired for less than the number of seconds specified by this option and a block was passed to the method call, then the expiration future time of the entry in the cache will be updated to the amount of seconds in specified in race_condition_ttl
. The block will then be evaluated and written to the cache.
This is very useful in situations where a cache entry is used very frequently under a heavy load. The first process to find an expired cache entry will then become responsible for regenerating that entry while other processes continue to use the slightly out-of-date entry. This can prevent race conditions where too many processes are trying to regenerate the entry all at once. If the process regenerating the entry errors out, the entry will be regenerated after the specified number of seconds.
1 # Set all values to expire after one minute.
2 cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
3
4 cache.write("foo", "original value")
5 val_1 = nil
6 val_2 = nil
7 sleep 60
8
9 Thread.new do
10 val_1 = cache.fetch("foo", race_condition_ttl: 10) do
11 sleep 1
12 "new value 1"
13 end
14 end
15
16 Thread.new do
17 val_2 = cache.fetch("foo", race_condition_ttl: 10) do
18 "new value 2"
19 end
20 end
21
22 # val_1 => "new value 1"
23 # val_2 => "original value"
24 # sleep 10 # First thread extends the life of cache by another 10 seconds
25 # cache.fetch("foo") => "new value 1"
Other options will be handled by the specific cache store implementation. Internally, fetch calls read_entry
and calls write_entry
on a cache miss. Options will be passed to the read and write calls.
For example, MemCacheStore’s write method supports the :raw
option, which tells the Memcached server to store all values as strings. We can use this option with fetch
too:
1 cache = ActiveSupport::Cache::MemCacheStore.new
2 cache.fetch("foo", force: true, raw: true) do
3 :bar
4 end
5 cache.fetch("foo") # => "bar"
Increments an integer value in the cache. Options are passed to the underlying cache implementation.
Silences the logger within a block.
Gets the default options set when the cache was created.
Fetches data from the cache, using the given key. If there are data in the cache with the given key, then those data are returned. Otherwise, nil
is returned. Options are passed to the underlying cache implementation.
Read multiple values at once from the cache. Options can be passed in the last argument. Some cache implementation may optimize this method.
Returns a hash mapping the names provided to the values found.
>> cache.write :color, :red
=> true
>> cache.write :smell, :roses
=> true
>> cache.read_multi :color, :smell
=> {:color=>:red, :smell=>:roses}
Silences the logger.
Writes the given value to the cache with the given key.
You may also specify additional options via the options
argument. The specific cache store implementation will decide what to do with options.
CachingKeyGenerator
is a wrapper around KeyGenerator
, which avoids re-executing the key generation process when it’s called using the same salt
and key_size
.
Creates a new instance of CachingKeyGenerator
.
Returns a derived key suitable for use. The default key_size is chosen to be compatible with the default settings of ActiveSupport::MessageVerifier
, such as OpenSSL::Digest::SHA1#block_length
. Subsequent calls to generate_key
will return a cached key if the supplied salt
and key_size
are the same.
Callbacks are hooks into the lifecycle of an object that allow you to trigger logic before or after an alteration of the object state. Mixing in this module allows you to define callbacks in your class.
For instance, assume you have the following code in your application:
1 class Storage
2 include ActiveSupport::Callbacks
3
4 define_callbacks :save
5 end
6
7 class ConfigStorage < Storage
8 set_callback :save, :before, :saving_message
9
10 def saving_message
11 puts "saving..."
12 end
13
14 set_callback :save, :after do |object|
15 puts "saved"
16 end
17
18 def save
19 run_callbacks :save do
20 puts "- running save callbacks"
21 end
22 end
23 end
Running the preceding code using
1 config = ConfigStorage.new
2 config.save
would output
saving...
- running save callbacks
saved
Note that callback defined on parent classes are inherited.
The following methods are used to configure custom callbacks on your classes and are what Rails itself uses to create callbacks such as before_action
in Action Pack and before_save
in Active Record. Note that this is rather advanced functionality that you typically won’t need in your day-to-day Rails programming.
Define callbacks types for your custom class.
1 module MyOwnORM
2 class Base
3 define_callbacks :validate
4 end
5 end
The following options determine the operation of the callback:
:terminator Indicates when a before
callback is considered to be halted.
1 define_callbacks :validate, terminator: "result == false"
In the previous example, if any before validate callbacks return false
, other callbacks are not executed. Defaults to false
.
:skip_after_callbacks_if_terminated Determines if after
callbacks should be terminated by the :terminator
option. By default, after
callbacks are executed no matter if callback chain was terminated or not.
:scope Specify which methods should be executed when a class is given as callback.
1 class Audit
2 def before(caller)
3 puts 'before is called'
4 end
5
6 def before_save(caller)
7 puts 'before_save is called'
8 end
9 end
10
11 class Account
12 include ActiveSupport::Callbacks
13
14 define_callbacks :save
15 set_callback :save, :before, Audit.new
16
17 def save
18 run_callbacks :save do
19 puts 'saving...'
20 end
21 end
22 end
Calling save
in the previous example will execute Audit#before
. If the callback is defined with a [:kind, :name]
scope
1 define_callbacks :save, scope: [:kind, :name]
the method named "#{kind}_#{name}"
would be invoked in the given class. In this case, Audit#before_save
would be invoked.
The :scope
option defaults to :kind
.
Set callbacks for a given event.
1 set_callback :save, :before, :before_method
2 set_callback :save, :after, :after_method, if: :condition
3 set_callback :save, :around,
4 ->(r, &block) { stuff; result = block.call; stuff }
The second argument indicates whether the callback :before
, :after
, or :around
is to be run. By default, if nothing is set, :before
is assumed. The first example can also be expressed as the following:
set_callback :save, :before_method
The callback that the callback invokes can be specified as a symbol that references the name of an instance method or as a proc, lambda, or block. If a proc, lambda, or block is supplied, its body is evaluated in the context of the current object. A current object can optionally be set.
Skip a previously defined callback for a given type. The options :if
or :unless
may be passed in order to control when the callback is skipped.
Rails extends Ruby’s Class
object with a number class methods that then become available on all other classes in the runtime, regardless of type.
The following method allows for the creation of attributes on Ruby classes.
Declare one or more class-level attributes whose value is inheritable and overwritable by subclasses and instances, like so:
1 class Base
2 class_attribute :setting
3 end
4
5 class Subclass < Base
6 end
7
8 >> Base.setting = "foo"
9 => "foo"
10
11 >> Subclass.setting
12 => "foo"
13
14 >> Subclass.setting = "bar"
15 => "bar"
16
17 >> Subclass.setting
18 => "bar"
19
20 >> Base.setting
21 => "foo"
This behavior matches normal Ruby method inheritance: Think of writing an attribute on a subclass as overriding the parent’s reader method. Instances may overwrite the class value in the same way. (Note that the following code samples create anonymous classes to illustrate usage in a more concise fashion.)
1 klass = Class.new { class_attribute :setting }
2 object = klass.new
3
4 >> klass.setting = "foo
5 => "foo"
6
7 >> object.setting = "bar"
8 => "bar"
9
10 >> klass.setting
11 => "foo"
To opt out of the instance writer method, pass instance_writer: false
.
1 klass = Class.new { class_attribute :setting, instance_writer: false }
2
3 >> klass.new.setting
4 NoMethodError: undefined method `setting='
The class_attribute
method also works with singleton classes, as can be seen in the following example.
1 klass = Class.new { class_attribute :setting }
2
3 >> klass.singleton_class.setting = "foo"
4 => "foo"
Alternatively, setting instance_reader: false
causes class_attribute
to not define a reader method.
For convenience, a predicate method is defined as well, which allows you to see if an attribute has been set on a particular class instance.
1 klass = Class.new { class_attribute :setting }
2
3 >> klass.setting?
4 => false
5
6 >> klass.setting = "foo"
7 => "foo"
8
9 >> klass.setting?
10 => true
To opt out of defining a predicate method, set instance_predicate
to false
.
1 klass = Class.new { class_attribute :setting, instance_predicate: false }
2
3 >> klass.setting?
4 NoMethodError: undefined method `setting?'
Extends the class object with class and instance accessors for class attributes, just like the native attr*
accessors for instance attributes.
Creates both reader and writer methods for supplied method names syms
.
1 class Person
2 cattr_accessor :hair_colors
3 end
4
5 >> Person.hair_colors = [:brown, :black, :blonde, :red]
6
7 >> Person.new.hair_colors
8 => [:brown, :black, :blonde, :red]
Creates class and instance writer methods for supplied method names syms
.
Extends the class object with class and instance accessors for class attributes, just like the native attr*
accessors for instance attributes.
Primarily for internal use by Rails.
Generates class methods name
, name=
, and name?
. These methods dispatch to the private _name
and _name=
methods, making them overridable by subclasses.
If an instances should be able to access the attribute, then pass instance_reader: true
in the options to generate a name
method accessible to instances.
Provides methods that introspect the inheritance hierarchy of a class. Used extensively in Active Record.
Returns an array with the names of the subclasses of self
as strings.
1 Integer.subclasses # => ["Bignum", "Fixnum"]
Returns an array of all class objects found that are subclasses of self
.
The Concern
module is only 26 lines of Ruby code. Using it, you can make your code more modular and have less dependency problems than ever before.
You use Concern
to define common behavior that you want to mix into other application classes or into Rails itself in the case of plugins.
A Concern
module has two elements: the included
block and the ClassMethods
module.
1 require 'active_support/concern'
2
3 module Foo
4 extend ActiveSupport::Concern
5
6 included do
7 self.send(:do_something_in_mixin_class)
8 end
9
10 module ClassMethods
11 def bar
12 ...
13 end
14 end
15
16 def baz
17 ...
18 end
19 end
To use your custom Concern
module, just mix it into a class.
1 class Widget
2 include Foo
3 end
The included
block will be triggered at inclusion time. Methods in ClassMethods
will get added to Widget
as class methods. All other methods will get added to Widget
as instance methods.
See ActiveSupport::Configurable
for a good example of how Concern
is used internally by Rails.
The Latch
class is used internally by Rails to test streaming controllers. It is being included here for completeness. The initializer of Latch
accepts a single argument, representing the number of threads in the test.
Creates lock object for blocks with mutual exclusion and waits until the latch count is greater than zero.
Creates lock object for blocks with mutual exclusion. It decreases the latch count if its greater than zero and wakes up all threads waiting for this lock if the count reaches zero.
This Configurable
module is used internally by Rails to add configuration settings to AbstractController::Base
. You can use it yourself to add configuration to your classes.
The implementation of Configurable
is done as a Concern
that is mixed into other classes.
Return the configuration of the object instance.
Creates configuration properties accessible via class and instance contexts. The names
parameter expects one or more symbols corresponding to property names.
1 module ActionController
2 class Base < Metal
3 config_accessor :assets_dir, :javascripts_dir, :stylesheets_dir
4 end
5 end
Yields config
.
Active Support provides a wide array of extensions to Ruby’s built-in date
and time
classes to simplify conversion and calculation tasks in simple-to-understand language.
Duck types a date
-like class. See Object#acts_like?
for more explanation.
1 class Date
2 def acts_like_date?
3 true
4 end
5 end
The following methods enable the use of calculations with Date
objects.
Rails extends the existing + and -
operator so that a since
calculation is performed when the other
argument is an instance of ActiveSupport::Duration
(the type of object returned by methods such as 10.minutes
and 9.months
).
>> Date.today + 1.day == Date.today.tomorrow
=> true
Provides precise Date
calculations for years, months, and days. The options
parameter takes a hash with any of these keys: :years
, :months
, :weeks
, and :days
.
>> Date.new(2006, 2, 28) == Date.new(2005, 2, 28).advance(years: 1)
=> true
Converts Date
to a Time
(or DateTime
if necessary) with the time portion set to the beginning of the day (0:00) and then subtracts the specified number of seconds.
>> Time.utc(2005, 2, 20, 23, 59, 15) == Date.new(2005, 2, 21).ago(45)
=> true
Converts Date
to a Time
(or DateTime
if necessary), with the time portion set to the beginning of the day (0:00).
>> Time.utc(2005,2,21,0,0,0) == Date.new(2005,2,21).beginning_of_day
=> true
Returns a new Date
object representing the start of the month (first of the month). Objects will have their time set to 0:00.
>> Date.new(2005, 2, 1) == Date.new(2005,2,21).beginning_of_month
=> true
Returns a new Date
object representing the start of the calendar-based quarter (first of January, April, July, and October).
>> Date.new(2005, 4, 1) == Date.new(2005, 6, 30).beginning_of_quarter
=> true
at_beginning_of_week
Alias for beginning_of_week
.
Returns a new Date
object representing the start of the calendar year (first of January).
>> Date.new(2005, 1, 1) == Date.new(2005, 2, 22).beginning_of_year
=> true
Converts Date
to a Time
(or DateTime
if necessary), with the time portion set to the end of the day (23:59:59).
Returns a new Date
object representing the last day of the calendar month.
>> Date.new(2005, 3, 31) == Date.new(2005,3,20).end_of_month
=> true
Returns a new Date
object representing the end of the calendar-based quarter (March 31, June 30, September 30).
Alias for end_of_week
.
Returns a new Date
object representing the end of the year.
>> Date.new(2013, 12, 31) == Date.new(2013, 10, 1).end_of_year
=> true
Returns a new Date
object representing the beginning of the week. By default, based on Date.beginning_of_week
.
>> Date.new(2005, 1, 31) == Date.new(2005, 2, 4).beginning_of_week
=> true
Returns the week start for the current request/thread.
>> Date.beginning_of_week
=> :monday
Can be set Date.beginning_of_week
or configuration option beginning_of_week
in your Rails application configuration.
Sets Date.beginning_of_week
to a week start for current request/thread.
The method accepts the following symbols:
• :monday
• :tuesday
• :wednesday
• :thursday
• :friday
• :saturday
• :sunday
Returns a new Date
where one or more of the elements have been changed according to the options parameter.
The valid options are :year
, :month
, and :day
.
>> Date.new(2007, 5, 12).change(day: 1) == Date.new(2007, 5, 1)
=> true
>> Date.new(2007, 5, 12).change(year: 2005, month: 1) == Date.new(2005, 1, 12)
=> true
The preferred way to get the current date when your Rails application is time zone aware. Returns Time.zone.today
when config.time_zone
is set; otherwise, just returns Date.today
.
Returns a new Date
object minus the specified number of days.
>> Date.new(2013, 10, 1).days_ago(5)
=> Thu, 26 Sep 2013
Returns a new Date
object representing the time a number of specified days into the future.
>> Date.new(2013, 10, 5) == Date.new(2013, 10, 1).days_since(4)
=> true
Returns the number of days to the start of the week.
>> Date.new(2013, 10, 10).days_to_week_start
=> 3
Returns a new Date
object representing the end of the week.
>> Date.new(2013, 10, 13) == Date.new(2013, 10, 10).end_of_week
=> true
Returns the week start day symbol or raises an ArgumentError if an invalid symbol is set.
>> Date.find_beginning_of_week!(:saturday)
=> :saturday
>> Date.find_beginning_of_week!(:foobar)
ArgumentError: Invalid beginning of week: foobar
Returns true
if the Date
instance is in the future.
>> (Date.current + 1.day).future?
=> true
Convenience method for months_ago(1)
.
Convenience method for months_ago(3)
.
Returns a new Date
object representing the given day in the previous week.
Convenience method for years_ago(1)
.
Returns a new Date
object representing the middle of the day.
Convenience method for beginning_of_week(:monday)
.
Returns a new Date
object representing the time a number of specified months ago.
>> Date.new(2005, 1, 1) == Date.new(2005, 3, 1).months_ago(2)
=> true
Returns a new Date
object representing the time a number of specified months into the past or the future. Supply a negative number of months to go back to the past.
>> Date.today.months_ago(1) == Date.today.months_since(-1)
=> true
Convenience method for months_since(1)
.
Convenience method for months_since(3)
.
Returns a new Date
object representing the start of the given day in the following calendar week.
>> Date.new(2005, 3, 4) == Date.new(2005, 2, 22).next_
week(:friday)
=> true
Convenience method for years_since(1)
.
Returns true if Date
is in the past.
>> (Date.current - 1.day).past?
=> true
Converts Date
to a Time
(or DateTime
if necessary) with the time portion set to the beginning of the day (0:00) and then adds the specified number of seconds.
>> Time.local(2005, 2, 21, 0, 0, 45) == Date.new(2005, 2, 21).
since(45)
=> true
Convenience method for end_of_week(:monday)
.
Returns true
if the Date
instance is today.
>> Date.current.today?
=> true
Convenience method that returns a new Date
(or DateTime
) representing the time one day in the future.
>> Date.tomorrow
=> Thu, 10 Oct 2013
>> Date.new(2007, 3, 1) == Date.new(2007, 2, 28).tomorrow
=> true
Returns a new Date
object representing the time a number of specified weeks ago.
>> Date.new(2013, 10, 1) == Date.new(2013, 10, 8).weeks_ago(1)
=> true
Returns a new Date
object representing the time a number of specified weeks into the future.
>> Date.new(2013, 10, 8) == Date.new(2013, 10, 1).weeks_since(1)
=> true
Returns a new Date
object representing the time a number of specified years ago.
>> Date.new(2000, 6, 5) == Date.new(2007, 6, 5).years_ago(7)
=> true
Returns a new Date
object representing the time a number of specified years into the future.
>> Date.new(2007, 6, 5) == Date.new(2006, 6, 5).years_since(1)
=> true
Convenience method that returns a new Date
object representing the time one day in the past.
>> Date.yesterday
=> Tue, 08 Oct 2013
Returns a new Date
object subtracted by one day.
>> Date.new(2007, 2, 21) == Date.new(2007, 2, 22).yesterday
=> true
The following methods facilitate the conversion of date data into various formats.
Overrides the default inspect method with a human-readable one.
>> Date.current
=> Wed, 02 Jun 2010
Converts a Date
object into its string representation, according to the predefined formats in the DATE_FORMATS
constant. (Aliased as to_s
. Original to_s
is aliased as to_default_s
.)
The following hash of formats dictates the behavior of the to_s
method.
1 DATE_FORMATS = {
2 :short => '%e %b',
3 :long => '%B %e, %Y',
4 :db => '%Y-%m-%d',
5 :number => '%Y%m%d',
6 :long_ordinal => lambda { |date|
7 day_format = ActiveSupport::Inflector.ordinalize(date.day)
8 date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007"
9 },
10 :rfc822 => '%e %b %Y'
11 }
Converts a Date
object into a Ruby Time
object; time is set to beginning of day. The time zone can be :local
or :utc
.
>> Time.local(2005, 2, 21) == Date.new(2005, 2, 21).to_time
=> true
Note that Active Support explicitly removes the Date#to_time
method in Ruby 2.0, as it converts local time only.
Returns a string that represents the time as defined by XML Schema within the current time zone (also known as iso8601):
CCYY-MM-DDThh:mm:ssTZD
Note that Active Support explicitly removes the Date#xmlschema
method in Ruby 2.0, as it converts a date to a string without the time component.
Converts Date
object into a Ruby Time
object in the current time zone. If Time.zone
or Time.zone_default
is not set, converts Date
to a Time
via #to_time
.
>> Time.zone = "Eastern Time (US & Canada)"
=> "Eastern Time (US & Canada)"
>> Thu, 10 Oct 2013 00:00:00 EDT -04:00
Returns self
as a JSON string. The ActiveSupport.use_standard_json_time_format
configuration setting determines whether the date string is delimited with dashes or not.
>> Date.today.as_json
=> "2010-06-03"
The following methods extend Ruby’s built-in DateTime
class.
Duck types a DateTime
–like class. See Object#acts_like?
for more explanation.
1 class DateTime
2 def acts_like_date?
3 true
4 end
5
6 def acts_like_time?
7 true
8 endd
9 end
The following methods permit easier use of DateTime
objects in date and time calculations.
Layers additional behavior on DateTime
so that Time
and ActiveSupport::TimeWithZone
instances can be compared with DateTime
instances.
Uses Date
to provide precise Time
calculations for years, months, and days. The options
parameter takes a hash with any of the keys :months
, :days
, and :years
.
Returns a new DateTime
representing the time a number of seconds ago. The opposite of since
.
Convenience method that represents the beginning of a day (00:00:00). Implemented simply as change(hour: 0)
.
Returns a new DateTime
object representing the start of the hour (hh:00:00). Implemented simply as change(min: 0)
.
Returns a new DateTime
object representing the start of the minute (hh:mm:00). Implemented simply as change(sec: 0)
.
Convenience method that represents the end of a day (23:59:59). Implemented simply as change(hour: 23, min: 59, sec: 59)
.
Returns a new DateTime
object representing the end of the hour (hh:59:59). Implemented simply as change(min: 59, sec: 59)
.
Returns a new DateTime
object representing the end of the minute (hh:mm:59). Implemented simply as change(sec: 59)
.
Returns a new DateTime
where one or more of the elements have been changed according to the options
parameter. The valid date options are :year
, :month
, and :day
. The valid time options are :hour
, :min
, :sec
, :offset
, and :start
.
Time zone–aware implementation of Time.now
returns a DateTime
instance.
Tells whether the DateTime
is in the future.
Returns a new DateTime
object representing the middle of the day (12:00:00). Implemented simply as change(hour: 12)
.
Tells whether the DateTime
is in the past.
Returns how many seconds have passed since midnight.
Returns how many seconds left in the day until 23:59:59.
Returns a new DateTime
representing the time a number of seconds since the instance time (aliased as in
). The opposite of ago
.
Returns a new DateTime
with the offset
set to 0
to represent UTC time.
Convenience method returns true
if the offset
is set to 0
.
Returns the offset value in seconds.
The following methods permit conversion of DateTime
objects (and some of their attributes) into other types of data.
Returns the utc_offset
as an HH:MM
formatted string.
datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
>> datetime.formatted_offset
=> "-06:00"
The options provide for tweaking the output of the method by doing things like omitting the colon character.
>> datetime.formatted_offset(false)
=> "-0600"
Returns the fraction of a second as nanoseconds.
Overrides the default inspect method with a human-readable one that looks like this:
1 Mon, 21 Feb 2005 14:30:00 +0000
Converts self
to a Ruby Date
object, discarding time data.
Returns self
to be able to keep Time
, Date
, and DateTime
classes interchangeable on conversions.
Converts self
to a floating-point number of seconds since the Unix epoch. Note the limitations of this methods with dates prior to 1970.
>> Date.new(2000, 4,4).to_datetime.to_f
=> 954806400.0
>> Date.new(1800, 4,4).to_datetime.to_f
=> -5356627200.0
See the options on to_formatted_s
of the Time
class. The primary difference is the appending of the time information.
>> datetime.to_formatted_s(:db)
=> "2007-12-04 00:00:00"
Converts self to an integer number of seconds since the Unix epoch. Note the limitations of this methods with dates prior to 1970.
>> Date.new(2000, 4,4).to_datetime.to_i
=> 954806400
>> Date.new(1800, 4,4).to_datetime.to_i
=> -5356627200
Returns the fraction of a second as microseconds.
The following method allows conversion of a DateTime
into a different time zone.
Returns the simultaneous time in Time.zone
.
>> Time.zone = 'Hawaii'
>> DateTime.new(2000).in_time_zone
=> Fri, 31 Dec 1999 14:00:00 HST -10:00
This method is similar to Time#localtime
except that it uses the Time.zone
argument as the local zone instead of the operating system’s time zone. You can also pass it a string that identifies a TimeZone as an argument, and the conversion will be based on that zone instead. Allowable string parameters are operating-system dependent.
>> DateTime.new(2000).in_time_zone('Alaska')
=> Fri, 31 Dec 1999 15:00:00 AKST -09:00
Returns self
as a JSON string. The ActiveSupport.use_standard_json_time_format
configuration setting determines whether the output is formatted using :xmlschema
or the following pattern:
strftime('%Y/%m/%d %H:%M:%S %z')
This module contains the logic for Rails’ automatic class-loading mechanism, which is what makes it possible to reference any constant in the Rails varied load paths without ever needing to issue a require
directive.
This module extends itself—a cool hack that you can use with modules that you want to use elsewhere in your codebase in a functional manner:
1 module Dependencies
2 extend self
3 ...
As a result, you can call methods directly on the module constant à la Java static class methods, like this:
>> ActiveSupport::Dependencies.search_for_file('person.rb')
=> "/Users/obie/work/time_and_expenses/app/models/person.rb"
You shouldn’t need to use this module in day-to-day Rails coding—it’s mostly for internal use by Rails and plugins. On occasion, it might also be useful to understand the workings of this module when debugging tricky class-loading problems.
The set of directories from which automatically loaded constants are loaded only once. Usually consists of your plugin lib
directories. All directories in this set must also be present in autoload_paths
.
The set of directories from which Rails may automatically load files. Files under these directories will be reloaded on each request in development mode, unless the directory also appears in load_once_paths
.
>> ActiveSupport::Dependencies.load_paths
=> ["/Users/kfaustino/code/active/example_app/app/assets",
"/Users/kfaustino/code/active/example_app/app/controllers",
"/Users/kfaustino/code/active/example_app/app/helpers",
"/Users/kfaustino/code/active/example_app/app/mailers",
"/Users/kfaustino/code/active/example_app/app/models",
"/Users/kfaustino/code/active/example_app/app/controllers/concerns",
"/Users/kfaustino/code/active/example_app/app/models/concerns"]
An internal stack used to record which constants are loaded by any block.
An array of constant names that need to be unloaded on every request. Used to allow arbitrary constants to be marked for unloading.
The set
of all files ever loaded.
The Set
of all files currently loaded.
Set this option to true
to enable logging of const_missing
and file loads. (Defaults to false
.)
A setting that determines whether files are loaded (default) or required. This attribute determines whether Rails reloads classes per request, as in development mode.
>> ActiveSupport::Dependencies.mechanism
=> :load
A setting that determines whether Ruby warnings should be activated on the first load of dependent files. Defaults to true
.
Invokes depend_on
with swallow_load_errors
set to true
. Wrapped by the require_association
method of Object
.
Attempts to autoload the provided module name by searching for a directory matching the expected path suffix
. If found, the module is created and assigned to into
’s constants with the name +const_name+
. Provided that the directory was loaded from a reloadable base path, it is added to the set of constants that are to be unloaded.
Checks whether the provided path_suffix
corresponds to an autoloadable module. Instead of returning a boolean, the autoload base for this module is returned.
Determines if the specified constant
has been automatically loaded.
Clears all loaded items.
Gets the reference for a specified class name. Raises an exception if the class does not exist.
Searches for the file_name
specified and uses require_or_load
to establish a new dependency. If the file fails to load, a LoadError
is raised. Setting message
, one can replace the error message set by LoadError
.
Includes Rails-specific modules into some Ruby classes.
• Object
includes Loadable
.
• Module
includes ModuleConstMissing
.
• Exception
includes Blamable
.
Returns true
if mechanism
is set to :load
.
Loads the file at the specified path
. The const_paths
is a set of fully qualified constant names to load. When the file is loading, Dependencies
will watch for the addition of these constants. Each one that is defined will be marked as autoloaded and will be removed when Dependencies.clear
is next called.
If the second parameter is left off, Dependencies
will construct a set of names that the file at path
may define. See loadable_constants_for_path
for more details.
Returns true
if the specified path
appears in the load_once_path
list.
Loads the constant named const_name
, which is missing from from_mod
. If it is not possible to load the constant from from_mod
, try its parent module by calling const_missing
on it.
Returns an array of constants based on a specified filesystem path
to a Ruby file, which would cause Dependencies
to attempt to load the file.
Marks the specified constant
for unloading. The constant will be unloaded on each request, not just the next one.
Runs the provided block and detects the new constants that were loaded during its execution. Constants may only be regarded as new once. If the block calls new_constants_in
again, the constants defined within the inner call will not be reported in this one.
If the provided block does not run to completion and instead raises an exception, any new constants are regarded as only partially defined and will be removed immediately.
Returns true
if the provided constant path is defined?
.
Returns a qualified path for the specified parent_module
and constant_name
.
Stores a reference to a class.
Removes an explicit constant.
Removes the constants that have been autoloaded and those that have been marked for unloading.
Implements the main class-loading mechanism. Wrapped by the require_or_load
method of Object
.
Gets the reference for class named name
if one exists.
Searches for a file in the autoload paths matching the provided path_suffix
.
Converts the provided constant description to a qualified constant name.
Returns true
if the specified constant is queued for unloading on the next request.
Excludes module ModuleConstMissing
from Module
and Loadable
from Object
.
This module allows you to define autoloads based on Rails conventions.
Autoloads a constant.
1 autoload :Model
Sets the name of a relative directory for all nested autoload
declarations. For example, if the current file was action_controller.rb
, and we call autoload_under("metal")
, the path used to autoload from is action_controller/metal
.
1 module ActionController
2 extend ActiveSupport::Autoload
3
4 autoload_under "metal" do
5 autoload :Compatibility
6 ...
7 end
8 ...
9 end
Sets an explicit path at which to autoload.
1 module ActionView
2 extend ActiveSupport::Autoload
3
4 autoload_at "action_view/template/resolver" do
5 autoload :Resolver
6 ...
7 end
8 ...
9 end
Eager autoloads any nested autoload
declarations.
1 module ActionMailer
2 extend ::ActiveSupport::Autoload
3
4 eager_autoload do
5 autoload :Collector
6 end
7 ...
8 end
Requires each file defined in autoloads
.
Collection of files to be autoloaded.
The deprecate method provides Rails core and application developers with a formal mechanism to be able to explicitly state what methods are deprecated. (Deprecation means to mark for future deletion.) Rails will helpfully log a warning message when deprecated methods are called.
Returns the current behavior or, if one isn’t set, defaults to :stderr
.
Sets the behavior to the specified value. Can be a single value, array, or object that responds to call.
The following are available behaviors:
:stderr Log all deprecation warnings to $stderr
.
:log Log all deprecation warnings to Rails.logger
.
:notify Use ActiveSupport::Notifications
to notify deprecation.rails
.
:silence Do nothing.
Outputs a deprecating warning for a specific method.
>> ActiveSupport::Deprecation.
deprecation_warning(:page_cache_extension, :default_static_extension)
=> "page_cache_extension is deprecated and will be removed from Rails 4.1
(use default_static_extension instead)"
Pass the module and name(s) of the methods as symbols to deprecate.
Silence deprecation warnings within the block.
Outputs a deprecation warning to the output configured by ActiveSupport::Deprecation.behavior
.
1 ActiveSupport::Deprecation.warn('something broke!')
2 # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
A module used internally by Rails to track descendants, which is faster than iterating through ObjectSpace
.
Clears all descendants.
Returns a set of all the descendants of a class.
A convenience method for returning the descendants of a class. Implemented simply as DescendantsTracker.descendants(self)
.
Returns a set of the direct descendants of a class.
A convenience method for returning the direct descendants of a class. Implemented simply as DescendantsTracker.direct_descendants(self)
.
Sets a class as a direct descendant of another base class. Implemented simply as DescendantsTracker.store_inherited(base, self)
.
Adds a direct descendant to a class. Warning: This method is not thread safe, but it is only called during the eager loading phase.
Provides accurate date and time measurements using the advance
method of Date
and Time
. It mainly supports the methods on Numeric
, such as in this example:
1.month.ago # equivalent to Time.now.advance(months: -1)
Adds another Duration
or a Numeric
to this Duration
. Numeric
values are treated as seconds.
>> 2.hours + 2
=> 7202 seconds
Subtracts another Duration
or a Numeric
to this Duration
. Numeric
values are treated as seconds.
>> 2.hours - 2
=> 7198 seconds
Calculates a new Time
or Date
that is as far in the past as this Duration
represents.
>> birth = 35.years.ago
=> Tue, 10 Oct 1978 16:21:34 EDT -04:00
Alias for since
, which reads a little bit more naturally when using the default Time.current
as the time
argument.
>> expiration = 1.year.from_now
=> Fri, 10 Oct 2014 16:22:35 EDT -04:00
Calculates the time resulting from a Duration
expression and formats it as a string appropriate for display in the console. (Remember that IRB and the Rails console automatically invoke inspect
on objects returned to them. You can use that trick with your own objects.)
>> 10.years.ago
=> Fri, 10 Oct 2003 16:23:10 EDT -04:00
Calculates a new Time
or Date
that is as far in the future as this Duration
represents.
expiration = 1.year.since(account.created_at)
Alias for ago
. Reads a little more naturally when specifying a time
argument instead of using the default value, Time.current
.
membership_duration = created_at.until(expires_at)
Extensions to Ruby’s built-in Enumerable
module, which gives arrays and other types of collections iteration abilities.
The following methods are added to all Enumerable
objects.
The negative of the Enumerable#include?
. Returns true
if the collection does not include the object.
Converts an enumerable to a hash based on a block that identifies the keys. The most common usage is with a single attribute name:
>> people.index_by(&:login)
=> { "nextangle" => <Person ...>, "chad" => <Person ...>}
Use full block syntax (instead of the to_proc
hack) to generate more complex keys:
>> people.index_by { |p| "#{p.first_name} #{p.last_name}" }
=> {"Chad Fowler" => <Person ...>, "David Hansson" => <Person ...>}
Returns true
if the enumerable has more than one element.
Use full block syntax to determine if there is more than one element based on a condition:
people.many? { |p| p.age > 26 }
Calculates a sum from the elements of an enumerable based on a block.
payments.sum(&:price)
It’s easier to understand than Ruby’s clumsier inject
method:
payments.inject { |sum, p| sum + p.price }
Use full block syntax (instead of the to_proc
hack) to do more complicated calculations:
payments.sum { |p| p.price * p.tax_rate }
Also, sum
can calculate results without the use of a block:
[5, 15, 10].sum # => 30
The default identity (a fancy way of saying “the sum of an empty list”) is 0
. However, you can override it with anything you want by passing a default
argument:
[].sum(10) { |i| i.amount } # => 10
Returns self.to_a
.
A utility method for escaping HTML tag characters. This method is also aliased as h
.
In your templates, use this method to escape any unsafe (often, anything user submitted) content, like this:
= h @person.name
The method primarily escapes angle brackets and ampersands.
>> puts ERB::Util.html_escape("is a > 0 & a < 10?")
=> "is a > 0 & a < 10?"
>> puts ERB::Util.html_escape_once('1 < 2 & 3')
=> "1 < 2 & 3"
A utility method for escaping HTML entities in JSON strings.
In your ERb templates, use this method to escape any HTML entities:
= json_escape @person.to_json
The method primarily escapes angle brackets and ampersands.
>> puts ERB::Util.json_escape("is a > 0 & a < 10?")
=> "is a \u003E 0 \u0026 a \u003C 10?"
Returns true
.
Returns false
.
Provides an atomic_write
method to Ruby’s File
class.
Writes to a file atomically by writing to a temp file first and then renaming to the target file_name
. Useful for situations where you need to absolutely prevent other processes or threads from seeing half-written files.
1 File.atomic_write("important.file") do |file|
2 file.write("hello")
3 end
If your temp
directory is not on the same filesystem as the file you’re trying to write, you can provide a different temporary directory with the temp_dir
argument.
1 File.atomic_write("/data/something.important", "/data/tmp") do |f|
2 file.write("hello")
3 end
Returns a hash with non-nil
values.
hash = { name: 'Marisa', email: nil }
=> hash.compact
>> { name: 'Marisa' }
Replaces current hash with non-nil
values.
Contains code that adds the ability to convert hashes to and from XML.
Builds a hash from XML just like Hash.from_xml
but also allows Symbol and YAML.
Parses arbitrary strings of XML markup into nested Ruby arrays and hashes. Works great for quick-and-dirty integration of REST-style web services.
Here’s a quick example in the console with some random XML content. The XML only has to be well-formed markup.
1 >> xml = %(<people>
2 <person id="1">
3 <name><family>Boss</family> <given>Big</given></name>
4 <email>[email protected]</email>
5 </person>
6 <person id="2">
7 <name>
8 <family>Worker</family>
9 <given>Two</given></name>
10 <email>[email protected]</email>
11 </person>
12 </people>)
13 => "<people>...</people>"
14
15 >> h = Hash.from_xml(xml)
16 => {"people"=>{"person"=>[{"name"=>{"given"=>"Big", "family"=>"Boss"},
17 "id"=>"1", "email"=>"[email protected]"}, {"name"=>{"given"=>"Two",
18 "family"=>"Worker"}, "id"=>"2", "email"=>"[email protected]"}]}}
Now you can easily access the data from the XML:
>> h["people"]["person"].first["name"]["given"]
=> "Big"
An exception DisallowedType
is raised if the XML contains attributes with type="yaml"
or type="symbol"
.
Collects the keys and values of a hash and composes a simple XML representation.
1 print ({greetings: {
2 english: "hello",
3 spanish: "hola"}}).to_xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <hash>
3 <greetings>
4 <english>hello</english>
5 <spanish>hola</spanish>
6 </greetings>
7 </hash>
Returns a new hash with self
and other_hash
merged recursively.
Modifies self
by merging in other_hash
recursively.
Returns a hash that includes everything but the given keys
. This is useful for limiting a set of parameters to everything but a few known toggles.
1 person.update(params[:person].except(:admin))
If the receiver responds to convert_key
, the method is called on each of the arguments. This allows except
to play nice with hashes with indifferent access.
>> {a: 1}.with_indifferent_access.except(:a)
=> {}
>> {a: 1}.with_indifferent_access.except("a")
=> {}
Replaces the hash without the given keys.
Returns an ActiveSupport::HashWithIndifferentAccess
out of its receiver.
>> {a: 1}.with_indifferent_access["a"]
=> 1
Provides methods that operate on the keys of a hash. The stringify
and symbolize
methods are used liberally throughout the Rails codebase, which is why it generally doesn’t matter if you pass option names as strings or symbols.
You can use assert_valid_keys
method in your own application code, which takes Rails-style option hashes.
Raises an ArgumentError
if the hash contains any keys not specified in valid_keys
.
1 def my_method(some_value, options={})
2 options.assert_valid_keys(:my_conditions, :my_order, ...)
3 ...
4 end
Note that keys are not treated indifferently, meaning if you use strings for keys but assert symbols as keys, this will fail.
>> { name: "Rob", years: "28" }.assert_valid_keys(:name, :age)
=> ArgumentError: Unknown key(s): years
>> { name: "Rob", age: "28" }.assert_valid_keys("name", "age")
=> ArgumentError: Unknown key(s): name, age
>> { name: "Rob", age: "28" }.assert_valid_keys(:name, :age)
=> {:name=>"Rob", :age=>"28"} # passes, returns hash
Returns a copy of the hash with all keys converted to strings. This includes the keys from the root hash and from all nested hashes.
Destructively converts all keys in the hash to strings. This includes the keys from the root hash and from all nested hashes.
Returns a new hash with all keys converted to symbols, as long as they respond to to_sym
. This includes the keys from the root hash and from all nested hashes.
Destructively converts all keys in the hash to symbols, as long as they respond to to_sym
. This includes the keys from the root hash and from all nested hashes.
Returns a copy of the hash with all keys converted by the block operation. This includes the keys from the root hash and from all nested hashes.
Destructively converts all keys in the hash by the block operation. This includes the keys from the root hash and from all nested hashes.
Returns a new copy of the hash with all keys converted to strings.
Destructively converts all keys in the hash to strings.
Returns a new hash with all keys converted to symbols, as long as they respond to to_sym
.
Destructively converts all keys in the hash to symbols.
Destructively converts all keys in the hash by the block operation.
Allows for reverse merging where the keys in the calling hash take precedence over those in the other_hash
. This is particularly useful for initializing an incoming option hash with default values like this:
1 def setup(options = {})
2 options.reverse_merge! size: 25, velocity: 10
3 end
In the example, the default :size
and :velocity
are only set if the options passed in don’t already have those keys set.
Returns a merged version of two hashes, using key values in the other_hash
as defaults, leaving the original hash unmodified.
Destructive versions of reverse_merge
; both modify the original hash in place.
Removes and returns the key/value pairs matching the given keys.
>> { a: 1, b: 2 }.extract!(:a, :x)
=> {:a => 1}
Slice a hash to include only the given keys. This is useful for limiting an options hash to valid keys before passing to a method:
1 def search(criteria = {})
2 assert_valid_keys(:mass, :velocity, :time)
3 end
4
5 search(options.slice(:mass, :velocity, :time))
If you have an array of keys you want to limit to, you should splat them:
1 valid_keys = %i(mass velocity time)
2 search(options.slice(*valid_keys))
Replaces the hash with only the given keys.
>> {a: 1, b: 2, c: 3, d: 4}.slice!(:a, :b)
=> {:c => 3, :d =>4}
Converts a hash into a string suitable for use as a URL query string. An optional namespace
can be passed to enclose the param names (see the following example).
>> { name: 'David', nationality: 'Danish' }.to_param
=> "name=David&nationality=Danish"
>> { name: 'David', nationality: 'Danish' }.to_param('user')
=> "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
Collects the keys and values of a hash and composes a URL-style query string using the ampersand and equals characters.
>> {foo: "hello", bar: "goodbye"}.to_query
=> "bar=goodbye&foo=hello"
Returns self
as a string of JSON.
Alias for empty?
.
A wrapper for the zlib standard library that allows the compression/decompression of strings with gzip.
>> gzip = ActiveSupport::Gzip.compress('compress me!')
=> "x1Fx8Bx00x9Dx18WRx00x03KxCExCF-
(J-.VxC8MUx04x00R>nx83fx00x00x00"
Decompresses a string that has been compressed with gzip.
>> ActiveSupport::Gzip.
decompress("x1Fx8Bx00x9Dx18WRx00x03KxCExCF-
(J-.VxC8MUx04x00R>nx83fx00x00x00")
=> "compress me!"
A subclass of Hash
used internally by Rails.
Implements a hash where keys set as a string or symbol are considered to be the same.
>> hash = HashWithIndifferentAccess.new
=> {}
>> hash[:foo] = "bar"
=> "bar"
>> hash[:foo]
=> "bar"
>> hash["foo"]
=> "bar"
The Inflections
class transforms words from singular to plural, class names to table names, modularized class names to ones without, and class names to foreign keys.
The default inflections for pluralization, singularization, and uncountable words are kept in activesupport/lib/active_support/inflections.rb
and reproduced here for reference.
1 module ActiveSupport
2 Inflector.inflections(:en) do |inflect|
3 inflect.plural(/$/, 's')
4 inflect.plural(/s$/i, 's')
5 inflect.plural(/^(ax|test)is$/i, '1es')
6 inflect.plural(/(octop|vir)us$/i, '1i')
7 inflect.plural(/(octop|vir)i$/i, '1i')
8 inflect.plural(/(alias|status)$/i, '1es')
9 inflect.plural(/(bu)s$/i, '1ses')
10 inflect.plural(/(buffal|tomat)o$/i, '1oes')
11 inflect.plural(/([ti])um$/i, '1a')
12 inflect.plural(/([ti])a$/i, '1a')
13 inflect.plural(/sis$/i, 'ses')
14 inflect.plural(/(?:([^f])fe|([lr])f)$/i, '12ves')
15 inflect.plural(/(hive)$/i, '1s')
16 inflect.plural(/([^aeiouy]|qu)y$/i, '1ies')
17 inflect.plural(/(x|ch|ss|sh)$/i, '1es')
18 inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '1ices')
19 inflect.plural(/^(m|l)ouse$/i, '1ice')
20 inflect.plural(/^(m|l)ice$/i, '1ice')
21 inflect.plural(/^(ox)$/i, '1en')
22 inflect.plural(/^(oxen)$/i, '1')
23 inflect.plural(/(quiz)$/i, '1zes')
24
25 inflect.singular(/s$/i, '')
26 inflect.singular(/(ss)$/i, '1')
27 inflect.singular(/(n)ews$/i, '1ews')
28 inflect.singular(/([ti])a$/i, '1um')
29 inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|
30 (p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '1sis')
31 inflect.singular(/(^analy)(sis|ses)$/i, '1sis')
32 inflect.singular(/([^f])ves$/i, '1fe')
33 inflect.singular(/(hive)s$/i, '1')
34 inflect.singular(/(tive)s$/i, '1')
35 inflect.singular(/([lr])ves$/i, '1f')
36 inflect.singular(/([^aeiouy]|qu)ies$/i, '1y')
37 inflect.singular(/(s)eries$/i, '1eries')
38 inflect.singular(/(m)ovies$/i, '1ovie')
39 inflect.singular(/(x|ch|ss|sh)es$/i, '1')
40 inflect.singular(/^(m|l)ice$/i, '1ouse')
41 inflect.singular(/(bus)(es)?$/i, '1')
42 inflect.singular(/(o)es$/i, '1')
43 inflect.singular(/(shoe)s$/i, '1')
44 inflect.singular(/(cris|test)(is|es)$/i, '1is')
45 inflect.singular(/^(a)x[that is]s$/i, '1xis')
46 inflect.singular(/(octop|vir)(us|i)$/i, '1us')
47 inflect.singular(/(alias|status)(es)?$/i, '1')
48 inflect.singular(/^(ox)en/i, '1')
49 inflect.singular(/(vert|ind)ices$/i, '1ex')
50 inflect.singular(/(matr)ices$/i, '1ix')
51 inflect.singular(/(quiz)zes$/i, '1')
52 inflect.singular(/(database)s$/i, '1')
53
54 inflect.irregular('person', 'people')
55 inflect.irregular('man', 'men')
56 inflect.irregular('child', 'children')
57 inflect.irregular('sex', 'sexes')
58 inflect.irregular('move', 'moves')
59 inflect.irregular('zombie', 'zombies')
60
61 inflect.uncountable(%w(equipment information rice money species
62 series fish sheep jeans police))
63 end
64 end
A singleton instance of Inflections
is yielded by Inflector.inflections
, which can then be used to specify additional inflection rules in an initializer.
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.plural /^(ox)$/i, '1en'
3 inflect.singular /^(ox)en/i, '1'
4 inflect.irregular 'person', 'people'
5 inflect.uncountable %w( fish sheep )
6 end
New rules are added at the top. So in the example, the irregular rule for octopus will now be the first of the pluralization and singularization rules that are checked when an inflection happens. That way Rails can guarantee that your rules run before any of the rules that may already have been loaded.
This API reference lists the inflections methods themselves in the modules where they are actually used: Numeric
and String
. The Inflections
module contains methods used for modifying the rules used by the inflector.
Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore string that contains the acronym will retain the acronym when passed to camelize
, humanize
, or titleize
. A camelized string that contains the acronym will maintain the acronym when titleized or humanized and will convert the acronym into a nondelimited single lowercase word when passed to underscore. An acronym word must start with a capital letter.
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.acronym 'HTML'
3 end
4
5 >> 'html'.titleize
6 => "HTML"
7
8 >> 'html'.camelize
9 => "HTML"
10
11 >> 'MyHTML'.underscore
12 => "my_html"
The acronym must occur as a delimited unit and not be part of another word for conversions to recognize it:
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.acronym 'HTTP'
3 end
4
5 >> 'HTTPS'.underscore
6 => "http_s" # => 'http_s', not 'https'
7
8 # Alternatively
9 ActiveSupport::Inflector.inflections(:en) do |inflect|
10 inflect.acronym 'HTTPS'
11 end
12
13 >> 'HTTPS'.underscore
14 => "https"
Clears the loaded inflections within a given scope
. Give the scope
as a symbol of the inflection type: :plurals
, :singulars
, :uncountables
, or :humans
.
1 ActiveSupport::Inflector.inflections.clear
2 ActiveSupport::Inflector.inflections.clear(:plurals)
Specifies a humanized form of a string by a regular expression rule or by a string mapping. When using a regular expression–based replacement, the normal humanize formatting is called after the replacement. When a string is used, the human form should be specified as desired (e.g., “The name,” not “the_name”)
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.human /_cnt$/i, '1_count'
3 inflect.human "legacy_col_person_name", "Name"
4 end
Yields a singleton instance of ActiveSupport::Inflector::Inflections
so you can specify additional inflector rules. If passed an optional locale, rules for other languages can be specified.
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.uncountable "rails"
3 end
Specifies a new irregular that applies to both pluralization and singularization at the same time. The singular
and plural
arguments must be strings, not regular expressions. Simply pass the irregular word in singular and plural form.
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.irregular 'octopus', 'octopi'
3 inflect.irregular 'person', 'people'
4 end
Specifies a new pluralization rule and its replacement. The rule
can either be a string or a regular expression. The replacement
should always be a string and may include references to the matched data from the rule by using backslash-number syntax, like this:
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.plural /^(ox)$/i, '1en'
3 end
Specifies a new singularization rule and its replacement. The rule
can either be a string or a regular expression. The replacement
should always be a string and may include references to the matched data from the rule by using backslash-number syntax, like this:
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.singular /^(ox)en/i, '1'
3 end
Adds uncountable words that should not be inflected to the list of inflection rules.
1 ActiveSupport::Inflector.inflections(:en) do |inflect|
2 inflect.uncountable "money"
3 inflect.uncountable "money", "information"
Replaces special characters in a string so that it may be used as part of a “pretty” URL. This method replaces accented characters with their ASCII equivalents and discards all other non-ASCII characters by turning them into the string specified as sep
. The method is smart enough to not double up separators. Leading and trailing separators are also removed.
1 class Person < ActiveRecord::Base
2 def to_param
3 "#{id}-#{name.parameterize}"
4 end
5 end
6
7 >> @person = Person.find(1)
8 => #<Person id: 1, name: "Donald E. Knuth">
9
10 >> helper.link_to(@person.name, person_path(@person))
11 => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
Replaces a non-ASCII character with an ASCII approximation or, if none exists, a replacement character that defaults to “?.”
1 transliterate("Ærøskøbing")
2 # => "AEroskobing"
Default approximations are provided for Western/Latin characters—for example, “ø,” “ñ,” “é,” “ß,” and so on.
This method is I18n aware, so you can set up custom approximations for a locale. This can be useful, for example, to transliterate German’s “ü” and “ö” to “ue” and “oe” or to add support for transliterating Russian to ASCII.
In order to make your custom transliterations available, you must set them as the i18n.transliterate.rule
I18n key:
1 # Store the transliterations in locales/de.yml
2 i18n:
3 transliterate:
4 rule:
5 ü: "ue"
6 ö: "oe"
1 # Or set them using Ruby
2 I18n.backend.store_translations(:de, i18n: {
3 transliterate: {
4 rule: {
5 "ü" => "ue",
6 "ö" => "oe"
7 }
8 }
9 })
The value for i18n.transliterate.rule
can be a simple hash that maps characters to ASCII approximations as shown earlier or, for more complex requirements, a proc:
1 I18n.backend.store_translations(:de, i18n: {
2 transliterate: {
3 rule: ->(string) { MyTransliterator.transliterate(string) }
4 }
5 })
Now you can have different transliterations for each locale:
1 I18n.locale = :en
2 transliterate("Jürgen")
3 # => "Jurgen"
1 I18n.locale = :de
2 transliterate("Jürgen")
3 # => "Juergen"
Extensions to Ruby’s built-in Integer
class.
Returns the suffix used to denote the position in an ordered sequence, such as 1st, 2nd, 3rd, 4th, and so on.
1 1.ordinal # => "st"
2 2.ordinal # => "nd"
3 1002.ordinal # => "nd"
4 1003.ordinal # => "rd"
Turns an integer into an ordinal string used to denote the position in an ordered sequence, such as 1st, 2nd, 3rd, 4th, and so on.
1 1.ordinalize # => "1st"
2 2.ordinalize # => "2nd"
3 1002.ordinalize # => "1002nd"
4 1003.ordinalize # => "1003rd"
Returns true
if the integer is a multiple of number
.
1 9.multiple_of? 3 # => true
The JSON
module adds JSON decoding and encoding support to Rails, which takes advantage of the JSON gem.
Parses a JSON string or IO
object and converts it into a hash.
Dumps object in JSON.
>> ActiveSupport::JSON.encode({a: 1, b: 2})
=> "{"a":1,"b":2}"
Methods added to Ruby’s Kernel
class are available in all contexts.
Makes backticks behave (somewhat more) similarly on all platforms. On win32 nonexistent_command
raises Errno::ENOENT
, but on Unix, the spawned shell prints a message to stderr and sets $?
.
Starts a debugging session if the debugger
gem has been loaded. Use rails server --debugger
to start Rails with the debugger enabled.
Captures the given stream and returns it.
1 stream = capture(:stdout) { puts 'notice' }
2 stream # => "notice
"
Sets $VERBOSE
to true for the duration of the block provided and back to its original value afterward.
Silences any stream for the duration of the block provided.
1 silence_stream(STDOUT) do
2 puts 'This will never be seen'
3 end
4
5 puts 'But this will'
Sets $VERBOSE
to false for the duration of the block provided and back to its original value afterward.
A method that should be named swallow
. Suppresses raising of any exception classes specified inside of the block provided. Use with caution.
Forces class_eval
to behave like singleton_class.class_eval
.
Creates a new instance of MessageEncryptor
.
Returns a derived key suitable for use. The default key_size is chosen to be compatible with the default settings of ActiveSupport::MessageVerifier
, such as OpenSSL::Digest::SHA1#block_length
.
>> key_generator = ActiveSupport::KeyGenerator.new('my_secret_key')
=> #<ActiveSupport::KeyGenerator:0x007fde6788b5d8
@secret="my_secret_key", @iterations=65536>
>> key_generator.generate_key('my_salt')
=> "xB6o5xB2vxBAx03x8ExE0xA0x06[7<>x81xBBxD6BxB6,
xF3@ax153xB5xC1x8Cx8BxEFx04x1CxB9x8Dx93I~`
xCDxCB"IKw\uxE9vx15xEElx99"xBDxC7ax92Yx1EYx94dxFB"
18.191.178.211