Accessible via the logger
property in various Rails contexts such as Active Record models and controller classes. Always accessible via Rails.logger
. Use of the logger is explained in Chapter 1, “Rails Environments and Configuration.”
Generates an anonymous module that is used to extend an existing logger, which adds the behavior to broadcast to multiple loggers. For instance, when initializing a Rails console, Rails.logger
is extended to broadcast to STDERR
, causing Rails to log to both a log file and STDERR
.
1 console = ActiveSupport::Logger.new(STDERR)
2 Rails.logger.extend ActiveSupport::Logger.broadcast(console)
Silences the logger for the duration of the block.
MessageEncryptor
is a simple way to encrypt values that get stored somewhere you don’t trust. The cipher text and initialization vector are base64 encoded and returned to you. This can be used in situations similar to the MessageVerifier
but where you don’t want users to be able to determine the value of the payload.
Creates a new instance of MessageEncryptor
. The supplied secret
must be at least as long as the cipher key size. By default, the cipher is aes-256-cbc
, which would require a cipher key size of at least 256 bits. If you are using a user-entered secret, you can generate a suitable key with OpenSSL::Digest::SHA256.new(user_secret).digest
.
The following are available options:
:cipher The cipher to use. Can be any cipher returned by OpenSSL::Cipher.ciphers
.
OpenSSL::Cipher.ciphers Default is aes-256-cbc
.
:serializer Object serializer to use. Default is Marshal.
Encrypt and sign a value
. The value
needs to be signed to avoid padding attacks.
Decrypts and verifies a value
. The value
needs to be verified to avoid padding attacks.
MessageVerifier
makes it easy to generate and verify signed messages to prevent tampering.
>> v = ActiveSupport::MessageVerifier.new("A_SECRET_STRING")
=> #<ActiveSupport::MessageVerifier:0x007fde68036918
@secret="A_SECRET_STRING", @digest="SHA1", @serializer=Marshal>
>> msg = v.generate([1, 2.weeks.from_now])
=> "BAhbB2kGVTogQWN0aXZlU3VwcG9ydDo..."
>> id, time = v.verify(msg)
=> [1, Fri, 25 Oct 2013 18:03:27 UTC +00:00]
This is useful for cases like remember-me tokens and autounsubscribe links where the session store isn’t suitable or available.
Creates a new MessageVerifier
with the supplied secret
.
The following are available options:
:digest Default is SHA1
.
:serializer Object serializer to use. Default is Marshal.
Generate a signed message.
cookies[:remember_me] = verifier.generate([user.id, 2.weeks.from_now])
Verify a signed message.
1 id, time = @verifier.verify(cookies[:remember_me])
2 if time < Time.now
3 self.current_user = User.find(id)
4 end
Extensions to Ruby’s Module
class; it is available in all contexts.
This useful method allows you to easily make aliases for attributes, including their reader, writer, and query methods.
In the following example, the Content
class is serving as the base class for Email
using STI, but emails should have a subject, not a title:
1 class Content < ActiveRecord::Base
2 # has column named 'title'
3 end
4
5 class Email < Content
6 alias_attribute :subject, :title
7 end
As a result of the alias_attribute
, you can see in the following example that the title
and subject
attributes become interchangeable:
>> e = Email.find(:first)
>> e.title
=> "Superstars"
>> e.subject
=> "Superstars"
>> e.subject?
=> true
>> e.subject = "Megastars"
=> "Megastars"
>> e.title
=> "Megastars"
Encapsulates the following common pattern:
alias_method :foo_without_feature, :foo
alias_method :foo, :foo_with_feature
With alias_method_chain
, you simply do one line of code and both aliases are set up for you:
alias_method_chain :foo, :feature
Query and bang methods keep the same punctuation. The following syntax
alias_method_chain :foo?, :feature
is equivalent to
alias_method :foo_without_feature?, :foo?
alias_method :foo?, :foo_with_feature?
so you can safely chain foo
, foo?
, and foo!
.
Returns true
if self
does not have a name.
A module gets a name when it is first assigned to a constant, via the module
or class
keyword
1 module M
2 end
3
4 >> M.name
5 => "M"
6
7 m = Module.new
8
9 >> m.name
10 => ""
or by an explicit assignment
1 m = Module.new
2
3 >> M = m # m gets a name here as a side effect
4
5 >> m.name
6 => "M"
Alias for attr_internal_accessor
.
Declares attributes backed by internal instance variables names (using an @_
naming convention). Basically just a mechanism to enhance controlled access to sensitive attributes.
For instance, Object
’s copy_instance_variables_from
will not copy internal instance variables.
Declares an attribute reader backed by an internally named instance variable.
Declares an attribute writer backed by an internally named instance variable.
Defines one or more module attribute reader and writer methods in the style of the native attr*
accessors—for instance, attributes.
Defines one or more module attribute reader methods.
Defines one or more module attribute writer methods.
Equivalent to defining an inline module within a class, having it extend ActiveSupport::Concern
, and then mixing it into the class.
1 class Foo < ActiveRecord::Base
2 concerning :Bar do
3 included do
4 has_many :things
5 end
6
7 private
8
9 def baz
10 ...
11 end
12 end
13 end
Shorthand form of defining an ActiveSupport::Concern
.
1 concern :Bar do
2 ...
3 end
4
5 # equivalent to
6
7 module Bar
8 extend ActiveSupport::Concern
9 ...
10 end
Provides a delegate class method to easily expose contained objects’ methods as your own. Pass one or more methods (specified as symbols or strings) and the name of the target object via the :to
option (also a symbol or string). At least one method name and the :to
option are required.
Delegation is particularly useful with Active Record associations:
1 class Greeter < ActiveRecord::Base
2 def hello
3 "hello"
4 end
5
6 def goodbye
7 "goodbye"
8 end
9 end
1 class Foo < ActiveRecord::Base
2 belongs_to :greeter
3 delegate :hello, to: :greeter
4 end
1 Foo.new.hello # => "hello"
2 Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
Multiple delegates to the same target are allowed:
1 class Foo < ActiveRecord::Base
2 belongs_to :greeter
3 delegate :hello, :goodbye, to: :greeter
4 end
1 Foo.new.goodbye # => "goodbye"
Methods can be delegated to instance variables, class variables, or constants by providing them as a symbols:
1 class Foo
2 CONSTANT_ARRAY = [0,1,2,3]
3 @@class_array = [4,5,6,7]
4
5 def initialize
6 @instance_array = [8,9,10,11]
7 end
8 delegate :sum, to: :CONSTANT_ARRAY
9 delegate :min, to: :@@class_array
10 delegate :max, to: :@instance_array
11 end
12
13 Foo.new.sum # => 6
14 Foo.new.min # => 4
15 Foo.new.max # => 11
Delegates can optionally be prefixed using the :prefix
option. If the value is true
, the delegate methods are prefixed with the name of the object being delegated to.
1 Person = Struct.new(:name, :address)
2
3 class Invoice < Struct.new(:client)
4 delegate :name, :address, to: :client, prefix: true
5 end
6
7 john_doe = Person.new("John Doe", "Vimmersvej 13")
8 invoice = Invoice.new(john_doe)
9 invoice.client_name # => "John Doe"
10 invoice.client_address # => "Vimmersvej 13"
It is also possible to supply a custom prefix.
1 class Invoice < Struct.new(:client)
2 delegate :name, :address, to: :client, prefix: :customer
3 end
4
5 invoice = Invoice.new(john_doe)
6 invoice.customer_name # => "John Doe"
7 invoice.customer_address # => "Vimmersvej 13"
If the delegate object is nil
, an exception is raised, and that happens no matter whether nil
responds to the delegated method. You can get a nil
instead with the :allow_nil
option.
1 class Foo
2 attr_accessor :bar
3 def initialize(bar = nil)
4 @bar = bar
5 end
6 delegate :zoo, to: :bar
7 end
8
9 Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
10
11 class Foo
12 attr_accessor :bar
13 def initialize(bar = nil)
14 @bar = bar
15 end
16 delegate :zoo, to: :bar, allow_nil: true
17 end
18
19 Foo.new.zoo # returns nil
Provides a deprecate
class method to easily deprecate methods. Convenience wrapper for ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
.
1 deprecate :foo
2 deprecate bar: 'message'
3 deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
Returns the constants that have been defined locally by this object and not in an ancestor.
Returns the module that contains this one; if this is a root module, such as ::MyModule
, then Object
is returned.
>> ActiveRecord::Validations.parent
=> ActiveRecord
Returns the name of the module containing this one.
1 >> ActiveRecord::Validations.parent_name
2 => "ActiveRecord"
Returns all the parents of this module according to its name, ordered from nested outward. The receiver is not contained within the result.
1 module M
2 module N
3 end
4 end
5 X = M::N
6
7 >> M.parents
8 => [Object]
9
10 >> M::N.parents
11 => [M, Object]
12
13 >> X.parents
14 => [M, Object]
Extends the API for constants to be able to deal with relative qualified constant names.
Returns true
if the qualified constant is defined and nil
otherwise.
Object.qualified_const_defined?("Math::PI") # => true
>> Object.const_defined?("Math::PI")
NameError: wrong constant name Math::PI
>> Object.qualified_const_defined?("Math::PI")
=> true
Returns the relative qualified constant given a path
.
>> Object.qualified_const_get("Math::PI")
=> 3.141592653589793
Sets a relative qualified constant.
>> Object.qualified_const_set("Math::Phi", 1.618034)
=> 1.618034
Returns true
if a named module is reachable through its corresponding constant.
1 module M
2 end
3
4 M.reachable? # => true
However, since constants and modules are decoupled, modules can become unreachable.
>> orphan = Object.send(:remove_const, :M)
=> M
>> orphan.reachable?
=> false
Removes a method definition if it exists.
The method define_method
in Ruby allows the definition of methods dynamically. However, define_method
doesn’t check for the existence of the method beforehand, which issues a warning if it does exist. The method redefine_method
resolves this by first removing the method definition if it exists and internally calling define_method
.
The const_missing
callback is invoked when Ruby can’t find a specified constant in the current scope, which is what makes Rails autoclass loading possible. See the Dependencies
module for more detail.
The chars
proxy enables you to work transparently with multibyte encodings in the Ruby String
class without having extensive knowledge about encoding.
A Chars
object accepts a string upon initialization and proxies String
methods in an encoding-safe manner. All the normal String
methods are proxied through the Chars
object and can be accessed through the mb_chars
method. Methods that would normally return a String
object now return a Chars
object so that methods can be chained together safely.
1 >> "The Perfect String".mb_chars.downcase.strip.normalize
2 => #<ActiveSupport::Multibyte::Chars:0x007ffdcac6f7d0
3 @wrapped_string="the perfect string">
Chars
objects are perfectly interchangeable with String
objects as long as no explicit class checks are made. If certain methods do explicitly check the class, call to_s
before you pass Chars
objects to them to go back to a normal String
object:
1 bad.explicit_checking_method("T".chars.downcase.to_s)
The default Chars
implementation assumes that the encoding of the string is UTF-8. If you want to handle different encodings, you can write your own multibyte string handler and configure it through ActiveSupport::Multibyte.proxy_class
.
1 class CharsForUTF32
2 def size
3 @wrapped_string.size / 4
4 end
5
6 def self.accepts?(string)
7 string.length % 4 == 0
8 end
9 end
10
11 ActiveSupport::Multibyte.proxy_class = CharsForUTF32
Note that a few methods are defined on Chars
instead of the handler because they are defined on Object
or Kernel
, and method_missing
(the method used for delegation) can’t catch them.
Returns -1, 0, or +1, depending on whether the Chars
object is to be sorted before, equal to, or after the object on the right side of the operation. In other words, it works exactly as you would expect it to.
Converts the first character to uppercase and the remainder to lowercase.
>> 'über'.mb_chars.capitalize.to_s
=> "Über"
Performs composition on all the characters.
Performs canonical decomposition on all the characters.
>> 'VÉDA A VÝZKUM'.mb_chars.downcase.to_s
=> "véda a výzkum"
Returns the number of grapheme clusters in the string.
Limits the byte size of the string to a number of bytes without breaking characters.
Tries to forward all undefined methods to the enclosed string instance. Also responsible for making the bang (!
) methods destructive, since a handler doesn’t have access to change an enclosed string instance.
Returns the KC normalization of the string by default. NFKC is considered the best normalization form for passing strings to databases and validations.
A normalization form can be one of the following:
• :c
• :kc
• :d
• :kd
Default is ActiveSupport::Multibyte::Unicode#default_normalization_form
.
Reverses all characters in the string.
>> 'Café'.mb_chars.reverse.to_s
=> 'éfaC'
Works like String
’s slice!
, with the exception that the items in the resulting list are Char
instances instead of String
.
Works just like the normal String
’s split
method, with the exception that the items in the resulting list are Chars
instances instead of String
, which makes chaining calls easier.
>> 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s }
=> ["CAF", " P", "RIFERÔL"]
Converts characters in the string to the opposite case.
>> "El Cañón".mb_chars.swapcase.to_s
=> "eL cAÑÓN"
Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent, resulting in a valid UTF-8 string.
Passing true
will forcibly tidy all bytes, assuming that the string’s encoding is entirely CP1252 or ISO-8859-1.
> "obie".mb_chars.tidy_bytes
=> #<ActiveSupport::Multibyte::Chars:0x007ffdcb76ecf8
@wrapped_string="obie">
Contains methods handling Unicode strings.
Composes decomposed characters to the composed form.
Decomposes composed characters to the decomposed form. The type
argument accepts :canonical
or :compatibility
.
Converts a Unicode string to lowercase.
Detects whether the codepoint is in a certain character class. Returns true
when it’s in the specified character class and false
otherwise. Valid character classes are :cr
, :lf
, :l
, :v
, :lv
, :lvt
, and :t
.
Returns the KC normalization of the string by default. NFKC is considered the best normalization form for passing strings to databases and validations. The form
specifies the form you want to normalize in and should be one of the following: :c
, :kc
, :d
, or :kd
. Default form is stored in the ActiveSupport::Multibyte.default_normalization_form
attribute and is overridable in an initializer.
Reverses operation of unpack_graphemes
.
Reorders codepoints so the string becomes canonical.
Swapcase on a Unicode string.
Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent, resulting in a valid UTF-8 string.
Unpack the string at grapheme boundaries. Returns a list of character lists.
>> ActiveSupport::Multibyte::Unicode.unpack_graphemes('ffff')
=> [[102], [102], [102], [102]]
>> ActiveSupport::Multibyte::Unicode.unpack_graphemes('Café')
=> [[67], [97], [102], [233]]
Converts a Unicode string to uppercase.
Remember that everything in Ruby is an object, even nil
, which is a special reference to a singleton instance of the NilClass
.
Returns true
.
Returns null
.
Notifications provides an instrumentation API for Ruby. To instrument an action in Ruby, you just need to do the following:
1 ActiveSupport::Notifications.instrument(:render, extra: :information) do
2 render text: "Foo"
3 end
You can consume those events and the information they provide by registering a log subscriber. For instance, let’s store all instrumented events in an array:
1 @events = []
2
3 ActiveSupport::Notifications.subscribe do |*args|
4 @events << ActiveSupport::Notifications::Event.new(*args)
5 end
6
7 ActiveSupport::Notifications.instrument(:render, extra: :information) do
8 render text: "Foo"
9 end
10
11 event = @events.first
12 event.name # => :render
13 event.duration # => 10 (in milliseconds)
14 event.result # => "Foo"
15 event.payload # => { :extra => :information }
When subscribing to Notifications
, you can pass a pattern to only consume events that match the pattern:
1 ActiveSupport::Notifications.subscribe(/render/) do |event|
2 @render_events << event
3 end
Notifications ships with a queue implementation that consumes and publishes events to log subscribers in a thread. You can use any queue implementation you want.
Extensions to Ruby’s Numeric
class.
Returns false
.
Returns self
.
Returns self.to_s
.
Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
.
The following constants are defined in bytes.rb
.
1 class Numeric
2 KILOBYTE = 1024
3 MEGABYTE = KILOBYTE * 1024
4 GIGABYTE = MEGABYTE * 1024
5 TERABYTE = GIGABYTE * 1024
6 PETABYTE = TERABYTE * 1024
7 EXABYTE = PETABYTE * 1024
8 ...
9 end
Returns the value of self
. Enables the use of byte calculations and declarations, like 45.bytes
+ 2.6.megabytes
.
Returns self * 1024
.
Returns self * 1024.kilobytes
.
Returns self * 1024.megabytes
.
Returns self * 1024.gigabytes
.
Returns self * 1024.terabytes
.
Returns self * 1024.petabytes
.
Generates a formatted string representation of a number. Options are provided for phone numbers, currency, percentage, precision, positional notation, file size, and pretty printing.
Aliased as to_s
.
:currency Formats a number into a currency string. The :currency
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ","
.
:format Sets the format for nonnegative numbers. Defaults to "%u%n"
.
:locale Sets the locale to be used for formatting. Defaults to current locale.
:negative_format Sets the format for negative numbers. Defaults to prepending a hyphen to the formatted number.
:precision Sets the level of precision. Defaults to 2.
:separator Sets the separator between the units. Defaults to "."
.
:unit Sets the denomination of the currency. Defaults to "$"
.
>> 1234567890.50.to_s(:currency)
=> $1,234,567,890.50
>> 1234567890.506.to_s(:currency)
=> $1,234,567,890.51
>> 1234567890.506.to_s(:currency, precision: 3)
=> $1,234,567,890.506
>> 1234567890.506.to_s(:currency, locale: :fr)
=> 1 234 567 890,51
>> -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
=> ($1,234,567,890.50)
>> 1234567890.50.to_s(:currency, unit: '£', separator: ',',
delimiter: '')
=> £1234567890,50
:delimited Formats a number with grouped thousands using delimiter. The :delimited
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ","
.
:locale Sets the locale to be used for formatting. Defaults to current locale.
:separator Sets the separator between the units. Defaults to "."
.
>> 12345678.to_s(:delimited)
=> 12,345,678
>> 12345678.05.to_s(:delimited)
=> 12,345,678.05
>> 12345678.to_s(:delimited, delimiter: '.')
=> 12.345.678
:human Formats a number that is more readable to humans. Useful for numbers that are extremely large. The :human
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ""
.
:format Sets the format for nonnegative numbers. Defaults to "%n %u"
. The field types are the following:
• %u
(the quantifier)
• %n
(the number)
:locale Sets the locale to be used for formatting. Defaults to current locale.
:precision Sets the level of precision. Defaults to 3.
:separator Sets the separator between fractional and integer digits. Defaults to "."
.
:significant If true, precision will be the number of significant_digits; otherwise, the number of fractional digits are used. Defaults to true.
:strip_insignificant_zeros Setting to true removes insignificant zeros after the decimal separator. Defaults to true.
:units A hash of unit quantifier names or a string containing an I18n scope where to find this hash. It might have the following keys:
• integers
: :unit
, :ten
, *:hundred
, :thousand
, :million
, *:billion
, :trillion
, *:quadrillion
• fractionals
: :deci
, :centi
, *:milli
, :micro
, :nano
, *:pico
, :femto
>> 123.to_s(:human)
=> "123"
>> 1234.to_s(:human)
=> "1.23 Thousand"
>> 1234567.to_s(:human)
=> "1.23 Million"
>> 489939.to_s(:human, precision: 4)
=> "489.9 Thousand"
:human_size Formats the bytes in size into a more understandable representation. Useful for reporting file sizes to users. The :human_size
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ""
.
:format Sets the format for nonnegative numbers. Defaults to "%u%n"
.
:locale Sets the locale to be used for formatting. Defaults to current locale.
:precision Sets the level of precision. Defaults to 3.
:prefix Setting to :si
formats the number using the SI prefix. Defaults to :binary
.
:separator Sets the separator between fractional and integer digits. Defaults to "."
.
:significant If true, precision will be the number of significant_digits; otherwise, the number of fractional digits are used. Defaults to true.
:strip_insignificant_zeros Setting to true removes insignificant zeros after the decimal separator. Defaults to true.
:raise Setting to true
raises InvalidNumberError
when the number is invalid.
1 >> 123.to_s(:human_size)
2 => 123 Bytes
3
4 >> 1234.to_s(:human_size)
5 => 1.21 KB
6
7 >> 12345.to_s(:human_size)
8 => 12.1 KB
9
10 >> 1234567.to_s(:human_size)
11 => 1.18 MB
12
13 >> 1234567.to_s(:human_size, precision: 2)
14 => 1.2 MB
:percentage Formats a number as a percentage string. The :percentage
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ""
.
:format Sets the format of the percentage string. Defaults to "%n%"
.
:locale Sets the locale to be used for formatting. Defaults to current locale.
:precision Sets the level of precision. Defaults to 3.
:separator Sets the separator between the units. Defaults to ".".
:significant If true, precision will be the number of significant_digits; otherwise, the number of fractional digits are used. Defaults to false.
:strip_insignificant_zeros Setting to true removes insignificant zeros after the decimal separator. Defaults to false.
>> 100.to_s(:percentage)
=> 100.000%
>> 100.to_s(:percentage, precision: 0)
=> 100%
>> 1000.to_s(:percentage, delimiter: '.', separator: ',')
=> 1.000,000%
>> 302.24398923423.to_s(:percentage, precision: 5)
=> 302.24399%
>> 1000.to_s(:percentage, locale: :fr)
=> 1 000,000%
>> 100.to_s(:percentage, format: '%n %')
=> 100 %
:phone Formats a number into a US phone number. The :phone
formatting option can be combined with the following:
:area_code Adds parentheses around the area code.
:country_code Sets the country code for the phone number.
:delimiter Specifies the delimiter to use. Defaults to "-"
.
:extension Specifies an extension to add to the end of the generated number.
>> 5551234.to_s(:phone)
=> 555-1234
>> 1235551234.to_s(:phone)
=> 123-555-1234
>> 1235551234.to_s(:phone, area_code: true)
=> (123) 555-1234
>> 1235551234.to_s(:phone, delimiter: ' ')
=> 123 555 1234
>> 1235551234.to_s(:phone, area_code: true, extension: 555)
=> (123) 555-1234 x 555
>> 1235551234.to_s(:phone, country_code: 1)
=> +1-123-555-1234
>> 1235551234.to_s(:phone, country_code: 1, extension: 1343, de-
limiter: '.')
=> +1.123.555.1234 x 1343
:round Formats a number with the specified level of precision. The :rounded
formatting option can be combined with the following:
:delimiter Sets the thousands delimiter. Defaults to ""
.
:locale Sets the locale to be used for formatting. Defaults to current locale.
:precision Sets the level of precision. Defaults to 3.
:separator Sets the separator between the units. Defaults to "."
.
:significant If true, precision will be the number of significant_digits; otherwise, the number of fractional digits are used. Defaults to false.
:strip_insignificant_zeros Setting to true removes insignificant zeros after the decimal separator. Defaults to false.
>> 111.2345.to_s(:rounded)
=> 111.235
>> 111.2345.to_s(:rounded, precision: 2)
=> 111.23
>> 13.to_s(:rounded, precision: 5)
=> 13.00000
>> 389.32314.to_s(:rounded, precision: 0)
=> 389
>> 111.2345.to_s(:rounded, significant: true)
=> 111
>> 111.2345.to_s(:rounded, precision: 1, significant: true)
=> 100
Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years
.
These methods use Time#advance
for precise date calculations when using from_now
, ago
, and so on, as well as adding or subtracting their results from a Time
object. The following is an example:
1 # equivalent to Time.now.advance(months: 1)
2 1.month.from_now
3
4 # equivalent to Time.now.advance(years: 2)
5 2.years.from_now
6
7 # equivalent to Time.now.advance(months: 4, years: 5)
8 (4.months + 5.years).from_now
While these methods provide precise calculation when used as in the previous examples, care should be taken to note that this is not true if the result of “months,” “years,” and so on is converted before use:
1 # equivalent to 30.days.to_i.from_now
2 1.month.to_i.from_now
3
4 # equivalent to 365.25.days.to_f.from_now
5 1.year.to_f.from_now
In such cases, Ruby’s core Date
and Time
should be used for precision date and time arithmetic.
Append to a numeric time value to express a moment in the past.
1 10.minutes.ago
A duration equivalent to self * 24.hours
.
A duration equivalent to self * 2.weeks
.
An amount of time in the future from a specified time (which defaults to Time.current
).
A duration equivalent to self * 3600.seconds
.
An equivalent to self * 1000
. This value can be set in JavaScript functions like getTime()
.
A duration equivalent to self * 60.seconds
.
A duration equivalent to self * 30.days
.
A duration in seconds equivalent to self
.
A duration equivalent to self * 7.days
.
A duration equivalent to self * 365.25.days
.
Rails mixes quite a few methods into the Object
class, meaning they are available via every other object at runtime.
A duck-type assistant method. For example, Active Support extends Date
to define an acts_like_date?
method and extends Time
to define acts_like_time?
. As a result, we can do x.acts_like?(:time)
and x.acts_like?(:date)
to do duck-type safe comparisons, since classes that we want to act like Time
simply need to define an acts_like_time?
method.
An object is blank if it’s false
, empty, or a whitespace string. For example, ""
, " "
, nil
, []
, and {}
are blank.
This simplifies
if !address.nil? && !address.empty?
to
unless address.blank?
Returns object if it’s present?
; otherwise, returns nil
. The expression object.presence
is equivalent to object.present? ? object : nil
.
This is handy for any representation of objects where blank is the same as not present at all. For example, this simplifies a common check for HTTP POST/query parameters:
state = params[:state] if params[:state].present?
country = params[:country] if params[:country].present?
region = state || country || 'US'
becomes
region = params[:state].presence || params[:country].presence || 'US'
An object is present if it’s not blank.
Returns a deep copy of object if it’s duplicable. If it’s not duplicable, returns self
.
Most objects are cloneable, but not all. For example, you can’t duplicate nil
:
nil.dup # => TypeError: can't dup NilClass
Classes may signal their instances are not duplicable by removing dup
and clone
or raising exceptions from them. So to dup
an arbitrary object, you normally use an optimistic approach and are ready to catch an exception, such as the following:
arbitrary_object.dup rescue object
Rails dups objects in a few critical spots where they are not that arbitrary. That rescue
is very expensive (like 40 times slower than a predicate), and it is often triggered.
That’s why we hard-code the following cases and check duplicable?
instead of using the rescue idiom.
Is it possible to safely duplicate this object? Returns false
for nil
, false
, true
, symbols
, numbers
, class, and module objects, true
otherwise.
Returns true
if this object is included in the argument. The argument must respond to include?
.
1 characters = %w(Hulk Thor Hawkeye)
2
3 >> "Thor".in?(characters)
4 => true
Returns a hash that maps instance variable names without “@” to their corresponding values. Keys are strings in both Ruby 1.8 and 1.9.
1 class C
2 def initialize(x, y)
3 @x, @y = x, y
4 end
5 end
6
7 C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
Returns an array of instance variable names including “@.”
1 class C
2 def initialize(x, y)
3 @x, @y = x, y
4 end
5 end
6
7 C.new(0, 1).instance_variable_names # => ["@y", "@x"]
A basic definition of to_json
that prevents calls to to_json
from going directly to the json
gem on the following core classes:
• Object
• Array
• FalseClass
• Float
• Hash
• Integer
• NilClass
• String
• TrueClass
Alias of to_s
.
Converts an object into a string suitable for use as a URL query string, using the given key
as the param name.
Attempts to call a public method whose name is the first argument. Unlike public_send
, if the object does not respond to the method, nil
is returned rather than an exception being raised.
This simplifies
@person ? @person.name : nil
to
@person.try(:name)
If try
is invoked without arguments, it yields the receiver unless it’s nil
.
@person.try do |p|
...
end
Arguments and blocks are forwarded to the method if invoked:
@posts.try(:each_slice, 2) do |a, b|
...
end
An elegant way to refactor out common options.
1 class Post < ActiveRecord::Base
2 with_options(dependent: :destroy) do |post|
3 post.has_many :comments
4 post.has_many :photos
5 end
6 end
Rails overrides Ruby’s built-in load
method to tie it into the Dependencies
subsystem.
Rails overrides Ruby’s built-in require
method to tie it into the Dependencies
subsystem.
Used internally by Rails. Invokes Dependencies.depend_on(file_name)
.
Used internally by Rails. Invokes Dependencies.require_or_load(file_name)
.
Marks the specified constant as unloadable. Unloadable constants are removed each time dependencies are cleared.
Note that marking a constant for unloading needs to only be done once. Setup or init scripts may list each unloadable constant that will need unloading; constants marked in this way will be removed on every subsequent Dependencies.clear
, as opposed to the first clear only.
The provided constant descriptor const_desc
may be a (nonanonymous) module or class or a qualified constant name as a string or symbol.
Returns true
if the constant was not previously marked for unloading and false
otherwise.
A hash implementation that preserves the ordering of its elements. It’s namespaced to prevent conflicts with other implementations, but you can assign it to a top-level namespace if you don’t want to constantly use the fully qualified name:
>> oh = ActiveSupport::OrderedHash.new
=> []
>> oh[:one] = 1
=> 1
>> oh[:two] = 2
=> 2
>> oh[:three] = 3
=> 3
>> oh
=> [[:one, 1], [:two, 2], [:three, 3]]
Note that as of Ruby 1.9, hashes preserve their insertion order.
A subclass of Hash
that adds a method-missing implementation so that hash elements can be accessed and modified using normal attribute semantics dot notation:
1 def method_missing(name, *args)
2 if name.to_s =~ /(.*)=$/
3 self[$1.to_sym] = args.first
4 else
5 self[name]
6 end
7 end
A module that encapsulates access to thread local variables, which prevents the polluting of the thread locals namespace. Instead of setting and getting variables via Thread.current
, like this:
Thread.current[:handler]
you can define a class that extends ActiveSupport::PerThreadRegistry
.
1 class Registry
2 extend ActiveSupport::PerThreadRegistry
3
4 attr_accessor :handler
5 end
This creates class-level methods to get/set attributes on the current thread based on the defined accessors.
>> Registry.handler
=> nil
>> Registry.handler = handler
=> #<Object:0x007fbeb326ea20>
>> Registry.handler
=> #<Object:0x007fbeb326ea20>
The key on Thread.current
for the previous example would be the class name “Registry.”
>> Thread.current["Registry"]
=> #<Registry:0x007fbeb3279880 @handler=#<Object:0x007fbeb326ea20>>
A class with no predefined methods that behaves similarly to Builder’s BlankSlate
. Used for proxy classes and can come in handy when implementing domain-specific languages in your application code.
The implementation of ProxyObject
inherits from BasicObject
, undefines two methods, and allows exceptions to be raised. The implementation is reproduced here for your reference.
1 class ProxyObject < ::BasicObject
2 undef_method :==
3 undef_method :equal?
4
5 # Let ActiveSupport::ProxyObject at least raise exceptions.
6 def raise(*args)
7 ::Object.send(:raise, *args)
8 end
9 end
Contains Active Support’s initialization routine for itself and the I18n subsystem.
If you’re depending on Active Support outside of Rails, you should be aware of what happens in this Railtie in case you end up needing to replicate it in your code.
1 module ActiveSupport
2 class Railtie < Rails::Railtie # :nodoc:
3 config.active_support = ActiveSupport::OrderedOptions.new
4
5 config.eager_load_namespaces << ActiveSupport
6
7 initializer "active_support.deprecation_behavior" do |app|
8 if deprecation = app.config.active_support.deprecation
9 ActiveSupport::Deprecation.behavior = deprecation
10 end
11 end
12
13 # Sets the default value for Time.zone
14 # If assigned value cannot be matched to a TimeZone, an exception will be raised.
15 initializer "active_support.initialize_time_zone" do |app|
16 require 'active_support/core_ext/time/zones'
17 zone_default = Time.find_zone!(app.config.time_zone)
18
19 unless zone_default
20 raise 'Value assigned to config.time_zone not recognized. '
21 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
22 end
23
24 Time.zone_default = zone_default
25 end
26
27 # Sets the default week start
28 # If assigned value is not a valid day symbol
29 # (e.g., :sunday, :monday, ...), an exception will be raised.
30 initializer "active_support.initialize_beginning_of_week" do |app|
31 require 'active_support/core_ext/date/calculations'
32 beginning_of_week_default = Date.
33 find_beginning_of_week!(app.config.beginning_of_week)
34
35 Date.beginning_of_week_default = beginning_of_week_default
36 end
37
38 initializer "active_support.set_configs" do |app|
39 app.config.active_support.each do |k, v|
40 k = "#{k}="
41 ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
42 end
43 end
44 end
45 end
Extensions to Ruby’s Range
class.
Generates a formatted string representation of the range.
>> (20.days.ago..10.days.ago).to_formatted_s
=> "Fri Aug 10 22:12:33 -0400 2007..Mon Aug 20 22:12:33 -0400 2007"
>> (20.days.ago..10.days.ago).to_formatted_s(:db)
=> "BETWEEN '2007-08-10 22:12:36' AND '2007-08-20 22:12:36'"
For internal use by Rails. Disables the ability to iterate over a range of ActiveSupport::TimeWithZone
due to significant performance issues.
Extends the default Range#include?
to support range comparisons.
>> (1..5).include?(1..5)
=> true
>> (1..5).include?(2..3)
=> true
>> (1..5).include?(2..6)
=> false
The native include?
behavior is untouched.
>> ("a".."f").include?("c")
=> true
>> (5..9).include?(11)
=> false
Compares two ranges and see if they overlap each other.
>> (1..5).overlaps?(4..6)
=> true
>> (1..5).overlaps?(7..9)
=> false
Optimize range sum to use arithmetic progression if a block is not given and we have a range of numeric values.
Extensions to Ruby’s Regexp
class.
Returns true
if a multiline regular expression.
Returns self.to_s
.
The Rescuable
module is a Concern
that adds support for easier exception handling. Used within Rails primarily in controller actions, but potentially very useful in your own libraries too.
The rescue_from
method receives a series of exception classes or class names and a trailing :with
option with the name of a method or a Proc
object to be called to handle them. Alternatively, a block can be given.
Handlers that take one argument will be called with the exception so that the exception can be inspected when dealing with it.
Handlers are inherited. They are searched from right to left, from bottom to top, and up the hierarchy. The handler of the first class for which exception.is_a?(klass)
returns true
is the one invoked, if any.
Here’s some example code taken from Action Controller.
1 class ApplicationController < ActionController::Base
2 rescue_from User::NotAuthorized, with: :deny_access
3 rescue_from ActiveRecord::RecordInvalid, with: :show_errors
4
5 rescue_from 'MyAppError::Base' do |exception|
6 render xml: exception, status: 500
7 end
8
9 protected
10 def deny_access
11 ...
12 end
13
14 def show_errors(exception)
15 exception.record.new? ? ...
16 end
17 end
Extensions to Ruby’s String
class.
Returns self
.
Returns true
if the string consists of only whitespace.
1 class String
2 def blank?
3 self !~ /S/
4 end
5 end
Returns the character at position
, treating the string as an array (where 0 is the first character). Returns nil
if the position exceeds the length of the string.
>> "hello".at(0)
=> "h"
>> "hello".at(4)
=> "o"
>> "hello".at(10)
=> nil
Returns the first number
of characters in a string.
1 "hello".first # => "h"
2 "hello".first(2) # => "he"
3 "hello".first(10) # => "hello"
Returns the remaining characters of a string from the position
, treating the string as an array (where 0 is the first character). Returns nil
if the position exceeds the length of the string.
1 "hello".at(0) # => "hello"
2 "hello".at(2) # => "llo"
3 "hello".at(10) # => nil
1 "hello".last # => "o"
2 "hello".last(2) # => "lo"
3 "hello".last(10) # => "hello"
Returns the beginning of the string up to the position
, treating the string as an array (where 0 is the first character). Doesn’t produce an error when the position
exceeds the length of the string.
1 "hello".at(0) # => "h"
2 "hello".at(2) # => "hel"
3 "hello".at(10) # => "hello"
Duck types as a String
-like class. See Object#acts_like?
for more explanation.
1 class String
2 def acts_like_time?
3 true
4 end
5 end
Uses Date.parse
to turn a string into a Date
.
Uses Date.parse
to turn a string into a DateTime
.
Uses Date.parse
to turn a string into a Time
, either using either :utc
or :local
(default).
The inverse of include?
. Returns true
if self
does not include the other
string.
A convenience method for gsub(pattern, '')
. It returns a new string with all occurrences of the pattern removed.
Performs a destructive remove
. See remove
.
Returns the string, first removing all whitespace on both ends of the string and then changing remaining consecutive whitespace groups into one space each.
>> %{ Multi-line
string }.squish
=> "Multi-line string"
>> " foo bar
boo".squish
=> "foo bar boo"
Performs a destructive squish. See squish
.
Truncates a given text
after a given length
if text
is longer than length
. The last characters will be replaced with the :omission
(which defaults to “...”) for a total length not exceeding :length
.
Pass a :separator
to truncate text
at a natural break.
>> "Once upon a time in a world far far away".truncate(30)
=> "Once upon a time in a world..."
>> "Once upon a time in a world far far away".truncate(30, separator: ' ')
=> "Once upon a time in a world..."
>> "Once upon a time in a world far far away".truncate(14)
=> "Once upon a..."
>> "And they found that many people were sleeping better.".
truncate(25, omission: "... (continued)")
=> "And they f... (continued)"
Indents a string by the given amount
.
>> "foo".indent(2)
=> " foo"
=> "foo
bar"
>> " foo
bar"
The second argument—indent_string
—specifies what indent string to use. If no indent_string
is specified, it will use the first indented line; otherwise, a space is used. If indent_empty_lines
is set to true
, empty lines will also be indented.
Performs a destructive indent. See indent
.
String inflections define new methods on the String
class to transform names for different purposes.
For instance, you can figure out the name of a database from the name of a class:
>> "ScaleScore".tableize
=> "scale_scores"
If you get frustrated by the limitations of Rails inflections, try the most excellent linguistics library by Michael Granger at https://github.com/ged/linguistics
. It doesn’t do all the same inflections as Rails, but the ones that it does do, it does better. (See titleize
for an example.)
Alias for camelize
.
By default, camelize
converts strings to UpperCamelCase. If the argument to camelize
is set to :lower
, then camelize
produces lowerCamelCase. Also converts “/” to “::,” which is useful for converting paths to namespaces.
>> "active_record".camelize
=> "ActiveRecord"
>> "active_record".camelize(:lower)
=> "activeRecord"
>> "active_record/errors".camelize
=> "ActiveRecord::Errors"
>> "active_record/errors".camelize(:lower)
=> "activeRecord::Errors"
Creates a class name from a table name; used by Active Record to turn table names to model classes. Note that the classify
method returns a string and not a Class
. (To convert to an actual class, follow classify
with constantize
.)
>> "egg_and_hams".classify
=> "EggAndHam"
>> "post".classify
=> "Post"
The constantize
method tries to find a declared constant with the name specified in the string. It raises a NameError
if a matching constant is not located.
>> "Module".constantize
=> Module
>> "Class".constantize
=> Class
Replaces underscores with dashes in the string.
>> "puni_puni"
=> "puni-puni"
Removes the module prefixes from a fully qualified module or class name.
>> "ActiveRecord::CoreExtensions::String::Inflections".demodulize
=> "Inflections"
>> "Inflections".demodulize
=> "Inflections"
Creates a foreign key name from a class name.
"Message".foreign_key # => "message_id"
"Message".foreign_key(false) # => "messageid"
"Admin::Post".foreign_key # => "post_id"
Capitalizes the first word of a string, turns underscores into spaces, and strips _id
. Similar to the titleize
method in that it is intended for creating pretty output.
>> "employee_salary".humanize
=> "Employee salary"
>> "author_id".humanize
=> "Author"
Setting the :capitalize
option to false
results in the string being humanized without being capitalized.
>> "employee_salary".humanize(capitalize: false)
=> "employee salary"
Replaces special characters in a string with sep
string so that it may be used as part of a pretty URL.
Returns the plural form of the word in the string.
1 "post".pluralize # => "posts"
2 "octopus".pluralize # => "octopi"
3 "sheep".pluralize # => "sheep"
4 "words".pluralize # => "words"
5 "the blue mailman".pluralize # => "the blue mailmen"
6 "CamelOctopus".pluralize # => "CamelOctopi"
The safe_constantize
method tries to find a declared constant with the name specified in the string. It returns nil
when the name is not in CamelCase or is not initialized.
1 "posts".singularize # => "post"
2 "octopi".singularize # => "octopus"
3 "sheep".singluarize # => "sheep"
4 "word".singluarize # => "word"
5 "the blue mailmen".singularize # => "the blue mailman"
6 "CamelOctopi".singularize # => "CamelOctopus"
Creates a plural and underscored database table name based on Rails conventions. Used by Active Record to determine the proper table name for a model class. This method uses the pluralize
method on the last word in the string.
1 "RawScaledScorer".tableize # => "raw_scaled_scorers"
2 "egg_and_ham".tableize # => "egg_and_hams"
3 "fancyCategory".tableize # => "fancy_categories"
Alias for titleize
.
Capitalizes all the words and replaces some characters in the string to create a nicer-looking title. The titleize
method is meant for creating pretty output and is not used in the Rails internals.
>> "The light on the beach was like a sinus headache".titleize
=> "The Light On The Beach Was Like A Sinus Headache"
It’s also not perfect. Among other things, it capitalizes words inside the sentence that it probably shouldn’t, like “a” and “the.”
The reverse of camelize
. Makes an underscored form from the expression in the string. Changes “::” to “/” to convert namespaces to paths.
1 "ActiveRecord".underscore # => "active_record"
2 "ActiveRecord::Errors".underscore # => active_record/errors
Wraps the current string in the ActiveSupport::StringInquirer
class, providing an elegant way to test for equality.
1 env = 'production'.inquiry
2 env.production? # => true
3 env.development? # => false
Defines a multibyte safe proxy for string methods.
The mb_chars
method creates and returns an instance of ActiveSupport::Multibyte::Chars
, encapsulating the original string. A Unicode-safe version of all the String
methods are defined on the proxy class. If the proxy class doesn’t respond to a certain method, it’s forwarded to the encapsulated string.
>> name = 'Claus Müller'
>> name.reverse
=> "rell??M sualC"
>> name.length
=> 13
>> name.mb_chars.reverse.to_s
=> "rellüM sualC"
>> name.mb_chars.length
=> 12
All the methods on the Chars
proxy that normally return a string will return a Chars
object. This allows method chaining on the result of any of these methods.
>> name.mb_chars.reverse.length
=> 12
The Chars
object tries to be as interchangeable with String
objects as possible, sorting and comparing between String
and Char
work like expected. The bang! methods change the internal string representation in the Chars
object. Interoperability problems can be resolved easily with a to_s
call.
For more information about the methods defined on the Chars
proxy, see ActiveSupport::Multibyte::Chars
. For information about how to change the default Multibyte
behavior, see ActiveSupport::Multibyte
.
Returns true
if the string has UTF-8 semantics versus strings that are simply being used as byte streams.
Returns an HTML-escaped version of self
. See ERB::Util#html_escape
for more information.
Provides String
with additional condition methods.
Alias for start_with?
.
Alias for end_with?
.
Strips indentation in heredocs. For example,
1 if options[:usage]
2 puts <<-USAGE.strip_heredoc
3 This command does such and such.
4
5 Supported options are:
6 -h This message
7 ...
8 USAGE
9 end
would cause the user to see the usage message aligned against the left margin.
Converts the string to a TimeWithZone
in the current zone if Time.zone
or Time.zone_default
are set. Otherwise, returns String#to_time
.
Wrapping a string in this class gives you a prettier way to test for equality. The value returned by Rails.env
is wrapped in a StringInquirer
object, so instead of calling
Rails.env == "production"
you can call
Rails.env.production?
This class is really simple, so you only really want to do this with strings that contain no whitespace or special characters.
>> s = ActiveSupport::StringInquirer.new("obie")
=> "obie"
>> s.obie?
=> true
Extensions to Ruby’s Struct
class.
Backports of Struct#to_h
from Ruby 2.0 unless defined.
The ActiveSupport::Subscriber
object is used to consume ActiveSupport::Notifications
. The subscriber dispatches notifications to a registered object based on its given namespace.
For example, a subscriber could collect statistics about Active Record queries:
1 module ActiveRecord
2 class StatsSubscriber < ActiveSupport::Subscriber
3 def sql(event)
4 Statsd.timing("sql.#{event.payload[:name]}", event.duration)
5 end
6 end
7 end
To attach a subscriber to a namespace, use the attach_to
method.
1 ActiveRecord::StatsSubscriber.attach_to :active_record
Extensions to Ruby’s Symbol
class.
Returns to_s
version of itself.
Wraps any standard Logger
object to provide tagging capabilities.
Clears all tags and invoke the parent definition if it exists.
Prefixes tags
to each log message in the yielded block.
1 logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
2 logger.tagged("tr4w") { logger.info "Stuff" } # [tr4w] Stuff
Inheriting from MiniTest::Unit::TestCase
, adds Rails specific testing methods and behavior.
Alias for refute_match
for Test::Unit
backward compatibility.
Alias for refute_equal
for Test::Unit
backward compatibility.
Alias for refute_in_delta
for Test::Unit
backward compatibility.
Alias for refute_in_epsilon
for Test::Unit
backward compatibility.
Alias for refute_includes
for Test::Unit
backward compatibility.
Alias for refute_instance_of
for Test::Unit
backward compatibility.
Alias for refute_kind_of
for Test::Unit
backward compatibility.
Alias for refute_nil
for Test::Unit
backward compatibility.
Alias for refute_operator
for Test::Unit
backward compatibility.
Alias for refute_predicate
for Test::Unit
backward compatibility.
Alias for refute_respond_to
for Test::Unit
backward compatibility.
Alias for refute_same
for Test::Unit
backward compatibility.
Tests if the block doesn’t raise an exception.
Rails adds a number of assertions to the basic ones provided with MiniTest
.
Tests whether a numeric difference in the return value of an expression is a result of what is evaluated in the yielded block. (Easier to demonstrate than to explain!)
The following example evaluation’s the expression Article.count
, and it saves the result. Then it yields to the block, which will execute the post :create
and return control to the assert_difference
method. At that point, Article.count
is evaluated again, and the difference is asserted to be 1
(the default difference).
1 assert_difference 'Article.count' do
2 post :create, article: {...}
3 end
Any arbitrary expression can be passed in and evaluated:
1 assert_difference 'assigns(:article).comments(:reload).size' do
2 post :create, comment: {...}
3 end
Arbitrary difference values may be specified. The default is 1, but negative numbers are OK too:
1 assert_difference 'Article.count', -1 do
2 post :delete, id: ...
3 end
An array of expressions can also be passed in—each will be evaluated:
1 assert_difference [ 'Article.count', 'Post.count' ], 2 do
2 post :create, article: {...}
3 end
A lambda or a list of lambdas can be passed in and evaluated:
1 assert_difference ->{ Article.count }, 2 do
2 post :create, article: {...}
3 end
4
5 assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
6 post :create, article: {...}
7 end
A error message can be specified:
1 assert_difference 'Article.count', -1, "Article should be destroyed" do
2 post :delete, id: ...
3 end
Tests that the return value of the supplied expression does not change as a result of what is evaluated in the yielded block.
1 assert_no_difference 'Article.count' do
2 post :create, article: invalid_attributes
3 end
Assert that an expression is not true.
1 assert_not nil # => true
2 assert_not false # => true
3 assert_not 'foo' # => 'foo' is not nil or false
Changes the current time to the time in the future or in the past by a given time difference. This is accomplished by stubbing Time.now
and Date.today
.
1 Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
2 travel 1.day
3 Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
4 Date.current # => Sun, 10 Nov 2013
Changes the current time to the supplied date or time. This is accomplished by stubbing Time.now
and Date.today
.
Extensions to Ruby’s built-in Thread
class.
Returns true
if the given string (or symbol) exists as a thread local variable.
>> current_thread = Thread.current
=> #<Thread:0x007fd2c08c0da8 run>
>> current_thread.thread_variable?(:tr4w)
=> false
>> current_thread.thread_variable_set(:tr4w, 'is awesome')
=> "is awesome"
>> current_thread.thread_variable?(:tr4w)
=> true
Returns the value of a thread local variable that has been set.
Set a thread local variable.
>> Thread.current.thread_variable_set(:tr4w, 'is awesome')
=> "is awesome"
Returns an array of thread local variables represented as symbols.
>> Thread.current.thread_variables
=> [:tr4w]
Extensions to Ruby’s built-in Time
class.
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")} #{formatted_offset(false)})
Duck types as a Time-like class. See Object#acts_like?
for more explanation.
1 class Time
2 def acts_like_time?
3 true
4 end
5 end
Contains methods that facilitate time calculations.
Overriding case equality method so that it returns true
for ActiveSupport::TimeWithZone
instances.
Implemented by the plus_with_duration
method. It allows addition of times like this:
expiration_time = Time.now + 3.days
Implemented by the minus_with_duration
method. It allows addition of times like this:
two_weeks_ago = Time.now - 2.weeks
Implemented by the compare_with_coercion
method. Layers additional behavior on Time#eql?
so that ActiveSupport::TimeWithZone
instances can be compared with Time
instances.
Provides precise Time
calculations. The options
parameter takes a hash with any of the following keys: :months
, :days
, :years
, :hours
, :minutes
, and :seconds
.
Returns a new Time
representing the time a number of seconds into the past; this is basically a wrapper around the Numeric
extension of the same name. For the best accuracy, do not use this method in combination with x.months
; use months_ago
instead!
Convenience method for beginning_of_day..end_of_day
. Returns a range representing the whole day of the current time.
Convenience method for beginning_of_month..end_of_month
. Returns a range representing the whole month of the current time.
Convenience method for beginning_of_quarter..end_of_quarter
. Returns a range representing the whole quarter of the current time.
Convenience method for beginning_of_week(start_day)..end_of_week(start_day)
. Returns a range representing the whole week of the current time.
Convenience method for beginning_of_year..end_of_year
. Returns a range representing the whole year of the current time.
Returns a new Time
object representing the “start” of the current instance’s day, hard-coded to 00:00 hours.
Returns a new Time
object representing the start of the hour (hh:00:00). Implemented simply as change(min: 0)
.
Returns a new Time
object representing the start of the minute (hh:mm:00). Implemented simply as change(sec: 0)
.
Returns a new Time
object representing the start of the calendar quarter (first of January, April, July, October, 00:00 hours).
Alias for beginning_of_week
.
Returns a new Time
object representing the start of the year (first of January, 00:00 hours).
Returns a new Time
object representing the end of a day (23:59:59). Implemented simply as change(hour: 23, min: 59, sec: 59)
.
Returns a new Time
object representing the end of the hour (hh:59:59). Implemented simply as change(min: 59, sec: 59)
.
Returns a new Time
object representing the end of the minute (hh:mm:59). Implemented simply as change(sec: 59)
.
Returns a new Time
object representing the end of the month (last day of the month at 23:59:59 hours).
Returns a new Time
object representing the end of the quarter (March 30, June 30, September 30, December 31, etc., at 23:59:59 hours).
Alias for end_of_week
.
Returns a new Time
object representing the end of the year (last day of the year at 23:59:59 hours).
Returns a new Time
object representing the “start” of the current instance’s week, defaulting to Date.beginning_of_week
.
Returns a new Time
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
.
Returns Time.zone.now
when Time.zone
or config.time_zone
are set; otherwise, returns Time.now
.
Returns a new Time
object minus the specified number of days.
Returns the number of days in the given month. If a year is given, February will return the correct number of days for leap years. Otherwise, this method will always report February as having 28 days.
>> Time.days_in_month(7, 1974)
=> 31
Returns a new Time
object representing the time a number of specified days into the future.
Returns the number of days to the start of the week.
Returns a new Time
object representing the “end” of the current instance’s week, with the week start_day
defaulting to Date.beginning_of_week
.
Returns true
if the Time
instance is in the future.
Returns a new Time
object representing the middle of the day (12:00:00). Implemented simply as change(hour: 12)
.
Convenience method for months_ago(1)
.
Convenience method for months_ago(3)
.
Returns a new Time
object representing the given day in the previous week, with the week start_day
defaulting to Date.beginning_of_week
.
Convenience method for years_ago(1)
.
Convenience method for beginning_of_week(:monday)
.
Returns a new Time
object representing the time a number of specified months
into the past.
The opposite of months_ago
. Returns a new Time
object representing the time a number of specified months
into the future.
Convenience method for months_since(1)
.
Convenience method for months_since(3)
.
Returns a new Time
object representing the start of the given day in the following calendar week.
Returns the number of seconds that have transpired since midnight.
Returns how many seconds left in the day until 23:59:59.
Returns a new Time
representing the time a number of seconds
into the future starting from the instance time. This method is basically a wrapper around the Numeric
extension of the same name. For best accuracy, do not use this method in combination with x.months
; use months_since
instead!
Convenience method for end_of_week(:monday)
.
Returns true
if the Time
is today.
Returns a new Time
object advanced by one day.
Returns a new Time
object representing the time a number of specified weeks ago.
Returns a new Time
object representing the time a number of specified weeks into the future.
Returns a new Time
object representing the time a number of specified years
into the past.
The opposite of years_ago
. Returns a new Time
object representing the time a number of specified years
into the future.
Extensions to Ruby’s Time
class to convert time objects into different convenient string representations and other objects.
The DATE_FORMATS
hash constant holds formatting patterns used by the to_formatted_s
method to convert a Time
object into a string representation:
1 DATE_FORMATS = {
2 :db => '%Y-%m-%d %H:%M:%S',
3 :number => '%Y%m%d%H%M%S',
4 :nsec => '%Y%m%d%H%M%S%9N',
5 :time => '%H:%M',
6 :short => '%d %b %H:%M',
7 :long => '%B %d, %Y %H:%M',
8 :long_ordinal => lambda { |time|
9 day_format = ActiveSupport::Inflector.ordinalize(time.day)
10 time.strftime("%B #{day_format}, %Y %H:%M")
11 },
12 :rfc822 => lambda { |time|
13 offset_format = time.formatted_offset(false)
14 time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
15 }
16 }
Returns the UTC offset as an HH:MM
formatted string.
1 Time.local(2000).formatted_offset # => "-06:00"
2 Time.local(2000).formatted_offset(false) # => "-0600"
Converts a Time
object into a string representation. The :default
option corresponds to the Time
object’s own to_s
method.
>> time = Time.now
=> Thu Jan 18 06:10:17 CST 2007
>> time.to_formatted_s(:time)
=> "06:10"
>> time.to_formatted_s(:db)
=> "2007-01-18 06:10:17"
>> time.to_formatted_s(:number)
=> "20070118061017"
>> time.to_formatted_s(:short)
=> "18 Jan 06:10"
>> time.to_formatted_s(:long)
=> "January 18, 2007 06:10"
>> time.to_formatted_s(:long_ordinal)
=> "January 18th, 2007 06:10"
>> time.to_formatted_s(:rfc822)
=> "Thu, 18 Jan 2007 06:10:17 -0600"
Aliased to to_formatted_s
.
Rails layers behavior on the _dump
and _load
methods so that utc instances can be flagged on dump and coerced back to utc on load.
Ruby 1.9.2 adds utc_offset
and zone to Time
, but marshaling only preserves utc_offset
. Rails preserves zone also, even though it may not work in some edge cases.
Extensions to Time
having to do with support for time zones.
Returns a TimeZone
instance or nil
if it does not exist.
>> Time.find_zone("Eastern Time (US & Canada)")
=> #<ActiveSupport::TimeZone:0x007fd2c0bc49c8
@name="Eastern Time (US & Canada)", ...>
Same as find_zone
, except it raises an ArgumentError
if an invalid time_zone
is provided.
>> Time.zone = 'Hawaii'
=> "Hawaii"
>> Time.utc(2000).in_time_zone
=> Fri, 31 Dec 1999 14:00:00 HST -10:00
Allows override of Time.zone
locally inside supplied block; resets Time.zone
to existing value when done.
>> Date.today
=> Wed, 02 Jun 2010
>> Time.use_zone(ActiveSupport::TimeZone['Hong Kong']) { Date.today }
=> Thu, 03 Jun 2010
Returns the TimeZone
for the current request if this has been set (via Time.zone=
). If Time.zone
has not been set for the current request, returns the TimeZone
specified in config.time_zone
.
Sets Time.zone
to a TimeZone
object for the current request/thread.
This method accepts any of the following:
• A Rails TimeZone
object
• An identifier for a Rails TimeZone
object (e.g., “Eastern Time (US & Canada),” -5.hours
)
• A TZInfo::TimeZone
object
• An identifier for a TZInfo::TimeZone
object (e.g., “America/New_York”)
Here’s an example of how you might set Time.zone
on a per request basis. The code assumes that current_user.time_zone
returns a string identifying the user’s preferred TimeZone
:
1 class ApplicationController < ActionController::Base
2 before_action :set_time_zone
3
4 def set_time_zone
5 Time.zone = current_user.time_zone
6 end
7 end
A Time
-like class that can represent a time in any time zone. Necessary because standard Ruby Time
instances are limited to UTC and the system’s ENV['TZ']
zone.
You shouldn’t ever need to create a TimeWithZone
instance directly via new
. Rails provides the methods local
, parse
, at
, and now
on TimeZone
instances and in_time_zone
on Time
and DateTime
instances for a more user-friendly syntax.
>> Time.zone = 'Eastern Time (US & Canada)'
=> 'Eastern Time (US & Canada)'
>> Time.zone.local(2007, 2, 10, 15, 30, 45)
=> Sat, 10 Feb 2007 15:30:45 EST -05:00
>> Time.zone.parse('2007-02-01 15:30:45')
=> Sat, 10 Feb 2007 15:30:45 EST -05:00
>> Time.zone.at(1170361845)
=> Sat, 10 Feb 2007 15:30:45 EST -05:00
>> Time.zone.now
=> Sun, 18 May 2008 13:07:55 EDT -04:00
>> Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone
=> Sat, 10 Feb 2007 15:30:45 EST -05:00
See Time
and ActiveSupport::TimeZone
for further documentation of these methods.
TimeWithZone
instances implement the same API as Ruby Time instances so that Time and TimeWithZone
instances are interchangeable.
>> t = Time.zone.now
=> Sun, 18 May 2008 13:27:25 EDT -04:00
>> t.class
=> ActiveSupport::TimeWithZone
>> t.hour
=> 13
>> t.dst?
=> true
>> t.utc_offset
=> -14400
>> t.zone
=> "EDT"
>> t.to_s(:rfc822)
=> "Sun, 18 May 2008 13:27:25 -0400"
>> t + 1.day
=> Mon, 19 May 2008 13:27:25 EDT -04:00
>> t.beginning_of_year
=> Tue, 01 Jan 2008 00:00:00 EST -05:00
>> t > Time.utc(1999)
=> true
>> t.is_a?(Time)
=> true
The TimeZone
class serves as a wrapper around TZInfo::TimeZone
instances. It allows Rails to do the following:
• Limit the set of zones provided by TZInfo
to a meaningful subset of 146 zones.
• Retrieve and display zones with a friendlier name (e.g., “Eastern Time (US & Canada)” instead of “America/New_York”).
• Lazily load TZInfo::TimeZone
instances only when they’re needed.
• Create ActiveSupport::TimeWithZone
instances via TimeZone’s local
, parse
, at
, and now
methods.
If you set config.time_zone
in an initializer, you can access this TimeZone
object via Time.zone
:
1 config.time_zone = "Eastern Time (US & Canada)"
2
3 Time.zone # => #<TimeZone:0x514834...>
4 Time.zone.name # => "Eastern Time (US & Canada)"
5 Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
The version of TZInfo
bundled with Active Support only includes the definitions necessary to support the zones defined by the TimeZone
class. If you need to use zones that aren’t defined by TimeZone
, you’ll need to install the TZInfo
gem. If a recent version of the gem is installed locally, this will be used instead of the bundled version.
Compares this time zone to the parameter. The two are compared first based on their offsets and then by name.
Compare name and TZInfo
identifier to a supplied regular expression. Returns true
if a match is found.
Locates a specific time zone object. If the argument is a string, it is interpreted to mean the name of the time zone to locate.
>> ActiveSupport::TimeZone['Dublin']
=> #<TimeZone:0x3208390 @name="Dublin", @utc_offset=nil ...>
If it is a numeric value it is either the hour offset or the second offset of the time zone to find. (The first one with that offset will be returned.)
Returns nil
if no such time zone is known to the system.
Returns an array of all 146 TimeZone
objects. There are multiple TimeZone
objects per time zone (in many cases) to make it easier for users to find their own time zone.
>> ActiveSupport::TimeZone.all
=> [#<ActiveSupport::TimeZone:0x551c34...
Creates a new ActiveSupport::TimeWithZone
instance in time zone of self
from the number of seconds since the Unix epoch.
1 Time.zone = 'Hawaii' # => "Hawaii"
2 Time.utc(2000).to_f # => 946684800.0
3 Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00
>> ActiveSupport::TimeZone.create("Atlanta", -5.hours)
=> #<ActiveSupport::TimeZone:0x007fd2c136b118 @name="Atlanta",
@utc_offset=-18000 seconds, @tzinfo=#<TZInfo::TimeZoneProxy: Atlanta>,
@current_period=nil>
Returns a TZInfo
instance matching the specified name
.
Returns the offset of this time zone as a formatted string in the format HH:MM
. If the offset is zero, this method will return an empty string. If colon
is false
, a colon will not be inserted into the output.
Create a new TimeZone
object with the given name
and offset
. The offset
is the number of seconds that this time zone is offset from UTC (GMT). Seconds were chosen as the offset unit because that is the unit that Ruby uses to represent time zone offsets (see Time#utc_offset
). The tzinfo
parameter can be explicitly passed in; otherwise, the name
will be used to find it: TimeZone.find_tzinfo(name)
.
Creates a new ActiveSupport::TimeWithZone
instance in time zone of self
from given values.
Adjust the given time to the simultaneous time in UTC. Returns a Time.utc()
instance.
Returns Time.now
adjusted to this time zone.
>> Time.now
=> 2013-10-16 17:45:49 -0400
>> ActiveSupport::TimeZone['Hawaii'].now
=> Wed, 16 Oct 2013 11:46:05 HST -10:00
Creates a new ActiveSupport::TimeWithZone
instance in time zone of self
from parsed string.
>> Time.zone = 'Hawaii'
=> "Hawaii"
>> Time.zone.parse('1999-12-31 14:00:00')
=> Fri, 31 Dec 1999 14:00:00 HST -10:00
Method exists so that TimeZone
instances respond like TZInfo::TimeZone
.
Method exists so that TimeZone
instances respond like TZInfo::TimeZone
.
Assumes self
represents an offset from UTC in seconds (as returned from Time#utc_offset
) and turns this into an +HH:MM formatted string.
1 ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
Returns a textual representation of this time zone.
1 ActiveSupport::TimeZone['Dublin'].to_s # => "(GMT+00:00) Dublin"
Returns the current date in this time zone.
>> Date.today
=> Wed, 16 Oct 2013
>> ActiveSupport::TimeZone['Darwin'].today
=> Thu, 17 Oct 2013
A convenience method for returning a collection of TimeZone
objects for time zones in the United States.
>> ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona",
"Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern
Time (US & Canada)", "Indiana (East)"]
Returns the offset of this time zone from UTC in seconds.
Returns false
.
Returns true
.
The XmlMini
module contains code that allows Rails to serialize/deserialize and parse XML using a number of different libraries.
• JDOM (requires JRuby)
• LibXML (fast native XML parser)
• Nokogiri (requires nokogiri
gem)
If you’re doing anything of significance with XML in your application, you should definitely use the fast native libxml
parser. Install the binaries (instructions vary depending on platform) and then the Ruby binding:
gem 'libxml-ruby', '=0.9.7'
Set XmlMini
to use libxml
in application.rb
or an initializer.
XmlMini.backend = 'LibXML'
The TYPE_NAMES
constant holds a mapping of Ruby types to their representation when serialized as XML.
1 TYPE_NAMES = {
2 "Symbol" => "symbol",
3 "Fixnum" => "integer",
4 "Bignum" => "integer",
5 "BigDecimal" => "decimal",
6 "Float" => "float",
7 "TrueClass" => "boolean",
8 "FalseClass" => "boolean",
9 "Date" => "date",
10 "DateTime" => "dateTime",
11 "Time" => "dateTime",
12 "Array" => "array",
13 "Hash" => "hash"
14 }
The FORMATTING
constant holds a mapping of lambdas that define how Ruby values are serialized to strings for representation in XML.
1 FORMATTING = {
2 "symbol" => Proc.new { |symbol| symbol.to_s },
3 "date" => Proc.new { |date| date.to_s(:db) },
4 "dateTime" => Proc.new { |time| time.xmlschema },
5 "binary" => Proc.new { |binary| ::Base64.encode64(binary) },
6 "yaml" => Proc.new { |yaml| yaml.to_yaml }
7 }
The PARSING
constant holds a mapping of lambdas used to deserialize values stored in XML back into Ruby objects.
1 PARSING = {
2 "symbol" => Proc.new { |symbol| symbol.to_sym },
3 "date" => Proc.new { |date| ::Date.parse(date) },
4 "datetime" => Proc.new {
5 |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
6 "integer" => Proc.new { |integer| integer.to_i },
7 "float" => Proc.new { |float| float.to_f },
8 "decimal" => Proc.new { |number| BigDecimal(number) },
9 "boolean" => Proc.new {
10 |boolean| %w(1 true).include?(boolean.strip) },
11 "string" => Proc.new { |string| string.to_s },
12 "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
13 "base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) },
14 "binary" => Proc.new { |bin, entity| _parse_binary(bin, entity) },
15 "file" => Proc.new { |file, entity| _parse_file(file, entity) }
16 }
1 PARSING.update(
2 "double" => PARSING["float"],
3 "dateTime" => PARSING["datetime"]
4 )
18.218.228.99