@@ -95,9 +95,9 @@ The following methods skip validations, and will save the object to the database
*`update_columns`
*`update_counters`
Note that `save` also has the ability to skip validations if passed `:validate => false` as argument. This technique should be used with caution.
Note that `save` also has the ability to skip validations if passed `validate: false` as argument. This technique should be used with caution.
*`save(:validate => false)`
*`save(validate: false)`
### `valid?` and `invalid?`
...
...
@@ -105,11 +105,11 @@ To verify whether or not an object is valid, Rails uses the `valid?` method. You
```ruby
classPerson<ActiveRecord::Base
validates:name,:presence=>true
validates:name,presence:true
end
Person.create(:name=>"John Doe").valid?# => true
Person.create(:name=>nil).valid?# => false
Person.create(name:"John Doe").valid?# => true
Person.create(name:nil).valid?# => false
```
After Active Record has performed validations, any errors found can be accessed through the `errors` instance method, which returns a collection of errors. By definition, an object is valid if this collection is empty after running validations.
...
...
@@ -118,7 +118,7 @@ Note that an object instantiated with `new` will not report errors even if it's
```ruby
classPerson<ActiveRecord::Base
validates:name,:presence=>true
validates:name,presence:true
end
>>p=Person.new
...
...
@@ -129,12 +129,12 @@ end
>>p.valid?
#=> false
>>p.errors
#=> {:name=>["can't be blank"]}
#=> {name:["can't be blank"]}
>>p=Person.create
#=> #<Person id: nil, name: nil>
>>p.errors
#=> {:name=>["can't be blank"]}
#=> {name:["can't be blank"]}
>>p.save
#=> false
...
...
@@ -156,7 +156,7 @@ This method is only useful _after_ validations have been run, because it only in
```ruby
classPerson<ActiveRecord::Base
validates:name,:presence=>true
validates:name,presence:true
end
>>Person.new.errors[:name].any?# => false
...
...
@@ -180,7 +180,7 @@ Validates that a checkbox on the user interface was checked when a form was subm
```ruby
classPerson<ActiveRecord::Base
validates:terms_of_service,:acceptance=>true
validates:terms_of_service,acceptance:true
end
```
...
...
@@ -190,7 +190,7 @@ It can receive an `:accept` option, which determines the value that will be cons
@@ -368,7 +368,7 @@ This helper validates that the specified attributes are not empty. It uses the `
```ruby
classPerson<ActiveRecord::Base
validates:name,:login,:email,:presence=>true
validates:name,:login,:email,presence:true
end
```
...
...
@@ -377,13 +377,13 @@ If you want to be sure that an association is present, you'll need to test wheth
```ruby
classLineItem<ActiveRecord::Base
belongs_to:order
validates:order_id,:presence=>true
validates:order_id,presence:true
end
```
If you validate the presence of an object associated via a `has_one` or `has_many` relationship, it will check that the object is neither `blank?` nor `marked_for_destruction?`.
Since `false.blank?` is true, if you want to validate the presence of a boolean field you should use `validates :field_name, :inclusion => { :in => [true, false] }`.
Since `false.blank?` is true, if you want to validate the presence of a boolean field you should use `validates :field_name, inclusion: { in: [true, false] }`.
The default error message is "_can't be empty_".
...
...
@@ -393,7 +393,7 @@ This helper validates that the attribute's value is unique right before the obje
```ruby
classAccount<ActiveRecord::Base
validates:email,:uniqueness=>true
validates:email,uniqueness:true
end
```
...
...
@@ -403,8 +403,8 @@ There is a `:scope` option that you can use to specify other attributes that are
```ruby
classHoliday<ActiveRecord::Base
validates:name,:uniqueness=>{:scope=>:year,
:message=>"should happen once per year"}
validates:name,uniqueness: {scope: :year,
message:"should happen once per year"}
end
```
...
...
@@ -412,7 +412,7 @@ There is also a `:case_sensitive` option that you can use to define whether the
@@ -513,18 +513,18 @@ As you've already seen, the `:message` option lets you specify the message that
### `:on`
The `:on` option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use `:on => :create` to run the validation only when a new record is created or `:on => :update` to run the validation only when a record is updated.
The `:on` option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use `on: :create` to run the validation only when a new record is created or `on: :update` to run the validation only when a record is updated.
```ruby
classPerson<ActiveRecord::Base
# it will be possible to update email with a duplicated value
validates:email,:uniqueness=>true,:on=>:create
validates:email,uniqueness: true,on: :create
# it will be possible to create the record with a non-numerical age
validates:age,:numericality=>true,:on=>:update
validates:age,numericality: true,on: :update
# the default (validates on both create and update)
validates:name,:presence=>true,:on=>:save
validates:name,presence: true,on: :save
end
```
...
...
@@ -535,7 +535,7 @@ You can also specify validations to be strict and raise `ActiveModel::StrictVali
```ruby
classPerson<ActiveRecord::Base
validates:name,:presence=>{:strict=>true}
validates:name,presence: {strict:true}
end
Person.new.valid?#=> ActiveModel::StrictValidationFailed: Name can't be blank
...
...
@@ -545,7 +545,7 @@ There is also an ability to pass custom exception to `:strict` option
@@ -915,9 +915,9 @@ The displayed text for each error message will always be formed by the capitaliz
Both the `form.error_messages` and the `error_messages_for` helpers accept options that let you customize the `div` element that holds the messages, change the header text, change the message below the header, and specify the tag used for the header element. For example,
@@ -358,13 +358,13 @@ Arrays return the result of applying `to_query` to each element with `_key_[]` a
Hashes also respond to `to_query` but with a different signature. If no argument is passed a call generates a sorted series of key/value assignments calling `to_query(key)` on its values. Then it joins the result with "&":
```ruby
{:c=>3,:b=>2,:a=>1}.to_query# => "a=1&b=2&c=3"
{c: 3,b: 2,a:1}.to_query# => "a=1&b=2&c=3"
```
The method `Hash#to_query` accepts an optional namespace for the keys:
```ruby
{:id=>89,:name=>"John Smith"}.to_query('user')
{id: 89,name:"John Smith"}.to_query('user')
# => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
```
...
...
@@ -378,10 +378,10 @@ Given a default options hash, `with_options` yields a proxy object to a block. W
```ruby
classAccount<ActiveRecord::Base
has_many:customers,:dependent=>:destroy
has_many:products,:dependent=>:destroy
has_many:invoices,:dependent=>:destroy
has_many:expenses,:dependent=>:destroy
has_many:customers,dependent: :destroy
has_many:products,dependent: :destroy
has_many:invoices,dependent: :destroy
has_many:expenses,dependent: :destroy
end
```
...
...
@@ -389,7 +389,7 @@ this way:
```ruby
classAccount<ActiveRecord::Base
with_options:dependent=>:destroydo|assoc|
with_optionsdependent: :destroydo|assoc|
assoc.has_many:customers
assoc.has_many:products
assoc.has_many:invoices
...
...
@@ -401,9 +401,9 @@ end
That idiom may convey _grouping_ to the reader as well. For example, say you want to send a newsletter whose language depends on the user. Somewhere in the mailer you could group locale-dependent bits like this:
When interpolated into a string, the `:to` option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such an expression is evaluated in the context of the receiver:
```ruby
# delegates to the Rails constant
delegate:logger,:to=>:Rails
delegate:logger,to: :Rails
# delegates to the receiver's class
delegate:table_name,:to=>'self.class'
delegate:table_name,to:'self.class'
```
WARNING: If the `:prefix` option is `true` this is less generic, see below.
...
...
@@ -921,7 +921,7 @@ WARNING: If the `:prefix` option is `true` this is less generic, see below.
By default, if the delegation raises `NoMethodError` and the target is `nil` the exception is propagated. You can ask that `nil` is returned instead with the `:allow_nil` option:
```ruby
delegate:name,:to=>:profile,:allow_nil=>true
delegate:name,to: :profile,allow_nil:true
```
With `:allow_nil` the call `user.name` returns `nil` if the user has no profile.
...
...
@@ -929,7 +929,7 @@ With `:allow_nil` the call `user.name` returns `nil` if the user has no profile.
The option `:prefix` adds a prefix to the name of the generated method. This may be handy for example to get a better name:
```ruby
delegate:street,:to=>:address,:prefix=>true
delegate:street,to: :address,prefix:true
```
The previous example generates `address_street` rather than `street`.
...
...
@@ -939,7 +939,7 @@ WARNING: Since in this case the name of the generated method is composed of the
A custom prefix may also be configured:
```ruby
delegate:size,:to=>:attachment,:prefix=>:avatar
delegate:size,to: :attachment,prefix: :avatar
```
In the previous example the macro generates `avatar_size` rather than `size`.
...
...
@@ -1003,10 +1003,10 @@ For example `ActionMailer::Base` defines:
Produce a string representation of a number as a human-readable number of bytes:
...
...
@@ -2042,7 +2042,7 @@ Addition only assumes the elements respond to `+`:
```ruby
[[1,2],[2,3],[3,4]].sum# => [1, 2, 2, 3, 3, 4]
%w(foo bar baz).sum# => "foobarbaz"
{:a=>1,:b=>2,:c=>3}.sum# => [:b, 2, :c, 3, :a, 1]
{a: 1,b: 2,c:3}.sum# => [:b, 2, :c, 3, :a, 1]
```
The sum of an empty collection is zero by default, but this is customizable:
...
...
@@ -2176,7 +2176,7 @@ NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
When the last argument in a method call is a hash, except perhaps for a `&block` argument, Ruby allows you to omit the brackets:
```ruby
User.exists?(:email=>params[:email])
User.exists?(email:params[:email])
```
That syntactic sugar is used a lot in Rails to avoid positional arguments where there would be too many, offering instead interfaces that emulate named parameters. In particular it is very idiomatic to use a trailing hash for options.
...
...
@@ -2305,7 +2305,7 @@ If there's any element that does not belong to the type of the first one the roo
If the receiver is an array of hashes the root element is by default also "objects":
```ruby
[{:a=>1,:b=>2},{:c=>3}].to_xml
[{a: 1,b: 2},{c:3}].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <objects type="array">
...
...
@@ -2326,7 +2326,7 @@ The name of children nodes is by default the name of the root node singularized.
The default XML builder is a fresh instance of `Builder::XmlMarkup`. You can configure your own builder via the `:builder` option. The method also accepts options like `:dasherize` and friends, they are forwarded to the builder:
@@ -2372,8 +2372,8 @@ This method is similar in purpose to `Kernel#Array`, but there are some differen
The last point is particularly worth comparing for some enumerables:
```ruby
Array.wrap(:foo=>:bar)# => [{:foo => :bar}]
Array(:foo=>:bar)# => [[:foo, :bar]]
Array.wrap(foo: :bar)# => [{foo: :bar}]
Array(foo: :bar)# => [[:foo, :bar]]
```
There's also a related idiom that uses the splat operator:
...
...
@@ -2556,8 +2556,8 @@ NOTE: Defined in `active_support/core_ext/hash/conversions.rb`.
Ruby has a built-in method `Hash#merge` that merges two hashes:
```ruby
{:a=>1,:b=>1}.merge(:a=>0,:c=>2)
# => {:a => 0, :b => 1, :c => 2}
{a: 1,b: 1}.merge(a: 0,c:2)
# => {a: 0, b: 1, c: 2}
```
Active Support defines a few more ways of merging hashes that may be convenient.
...
...
@@ -2567,19 +2567,19 @@ Active Support defines a few more ways of merging hashes that may be convenient.
In case of collision the key in the hash of the argument wins in `merge`. You can support option hashes with default values in a compact way with this idiom:
WARNING. Take into account that `reverse_merge!` may change the hash in the caller, which may or may not be a good idea.
...
...
@@ -2601,8 +2601,8 @@ As you can see in the previous example if a key is found in both hashes the valu
Active Support defines `Hash#deep_merge`. In a deep merge, if a key is found in both hashes and their values are hashes in turn, then their _merge_ becomes the value in the resulting hash:
```ruby
{:a=>{:b=>1}}.deep_merge(:a=>{:c=>2})
# => {:a => {:b => 1, :c => 2}}
{a: {b: 1}}.deep_merge(a: {c:2})
# => {a: {b: 1, c: 2}}
```
The method `deep_merge!` performs a deep merge in place.
...
...
@@ -2614,7 +2614,7 @@ NOTE: Defined in `active_support/core_ext/hash/deep_merge.rb`.
The method `Hash.deep_dup` duplicates itself and all keys and values inside recursively with ActiveSupport method `Object#deep_dup`. It works like `Enumerator#each_with_object` with sending `deep_dup` method to each pair inside.
```ruby
hash={:a=>1,:b=>{:c=>2,:d=>[3,4]}}
hash={a: 1,b: {c: 2,d:[3,4]}}
dup=hash.deep_dup
dup[:b][:e]=5
...
...
@@ -2637,21 +2637,21 @@ The method `diff` returns a hash that represents a diff of the receiver and the
* The rest is just merged.
```ruby
{:a=>1}.diff(:a=>1)
{a: 1}.diff(a:1)
# => {}, first rule
{:a=>1}.diff(:a=>2)
# => {:a => 1}, second rule
{a: 1}.diff(a:2)
# => {a: 1}, second rule
{:a=>1}.diff(:b=>2)
# => {:a => 1, :b => 2}, third rule
{a: 1}.diff(b:2)
# => {a: 1, b: 2}, third rule
{:a=>1,:b=>2,:c=>3}.diff(:b=>1,:c=>3,:d=>4)
# => {:a => 1, :b => 2, :d => 4}, all rules
{a: 1,b: 2,c: 3}.diff(b: 1,c: 3,d:4)
# => {a: 1, b: 2, d: 4}, all rules
{}.diff({})# => {}
{:a=>1}.diff({})# => {:a => 1}
{}.diff(:a=>1)# => {:a => 1}
{a: 1}.diff({})# => {a: 1}
{}.diff(a: 1)# => {a: 1}
```
An important property of this diff hash is that you can retrieve the original hash by applying `diff` twice:
...
...
@@ -2671,14 +2671,14 @@ NOTE: Defined in `active_support/core_ext/hash/diff.rb`.
The method `except` returns a hash with the keys in the argument list removed, if present:
```ruby
{:a=>1,:b=>2}.except(:a)# => {:b => 2}
{a: 1,b: 2}.except(:a)# => {b: 2}
```
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 for instance:
# => {"A" => 2}, in my test, can't rely on this result though
```
...
...
@@ -2725,7 +2725,7 @@ There's also the bang variant `transform_keys!` that applies the block operation
Besides that, one can use `deep_transform_keys` and `deep_transform_keys!` to perform the block operation on all the keys in the given hash and all the hashes nested into it. An example of the result is:
@@ -2736,14 +2736,14 @@ NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
The method `stringify_keys` returns a hash that has a stringified version of the keys in the receiver. It does so by sending `to_s` to them:
```ruby
{nil=>nil,1=>1,:a=>:a}.stringify_keys
{nil=>nil,1=>1,a: :a}.stringify_keys
# => {"" => nil, "a" => :a, "1" => 1}
```
The result in case of collision is undefined:
```ruby
{"a"=>1,:a=>2}.stringify_keys
{"a"=>1,a:2}.stringify_keys
# => {"a" => 2}, in my test, can't rely on this result though
```
...
...
@@ -2764,7 +2764,7 @@ There's also the bang variant `stringify_keys!` that stringifies keys in the ver
Besides that, one can use `deep_stringify_keys` and `deep_stringify_keys!` to stringify all the keys in the given hash and all the hashes nested into it. An example of the result is:
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
...
...
@@ -2822,8 +2822,8 @@ NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
The method `assert_valid_keys` receives an arbitrary number of arguments, and checks whether the receiver has any key outside that white list. If it does `ArgumentError` is raised.
```ruby
{:a=>1}.assert_valid_keys(:a)# passes
{:a=>1}.assert_valid_keys("a")# ArgumentError
{a:1}.assert_valid_keys(:a)# passes
{a:1}.assert_valid_keys("a")# ArgumentError
```
Active Record does not accept unknown options when building associations, for example. It implements that control via `assert_valid_keys`.
...
...
@@ -2835,18 +2835,18 @@ NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
```ruby
{:a=>1,:b=>2,:c=>3}.slice(:a,:c)
# => {:c => 3, :a => 1}
{a: 1,b: 2,c:3}.slice(:a,:c)
# => {c: 3, a: 1}
{:a=>1,:b=>2,:c=>3}.slice(:b,:X)
# => {:b => 2} # non-existing keys are ignored
{a: 1,b: 2,c:3}.slice(:b,:X)
# => {b: 2} # non-existing keys are ignored
```
If the receiver responds to `convert_key` keys are normalized:
```ruby
{:a=>1,:b=>2}.with_indifferent_access.slice("a")
# => {:a => 1}
{a: 1,b:2}.with_indifferent_access.slice("a")
# => {a: 1}
```
NOTE. Slicing may come in handy for sanitizing option hashes with a white list of keys.
...
...
@@ -2854,9 +2854,9 @@ NOTE. Slicing may come in handy for sanitizing option hashes with a white list o
There's also `slice!` which in addition to perform a slice in place returns what's removed:
```ruby
hash={:a=>1,:b=>2}
rest=hash.slice!(:a)# => {:b => 2}
hash# => {:a => 1}
hash={a: 1,b:2}
rest=hash.slice!(:a)# => {b: 2}
hash# => {a: 1}
```
NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
...
...
@@ -2866,9 +2866,9 @@ NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
The method `extract!` removes and returns the key/value pairs matching the given keys.
```ruby
hash={:a=>1,:b=>2}
rest=hash.extract!(:a)# => {:a => 1}
hash# => {:b => 2}
hash={a: 1,b:2}
rest=hash.extract!(:a)# => {a: 1}
hash# => {b: 2}
```
NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
...
...
@@ -2878,7 +2878,7 @@ NOTE: Defined in `active_support/core_ext/hash/slice.rb`.
The method `with_indifferent_access` returns an `ActiveSupport::HashWithIndifferentAccess` out of its receiver:
```ruby
{:a=>1}.with_indifferent_access["a"]# => 1
{a:1}.with_indifferent_access["a"]# => 1
```
NOTE: Defined in `active_support/core_ext/hash/indifferent_access.rb`.
...
...
@@ -2982,7 +2982,7 @@ An unbound method is not callable as is, you need to bind it first to an object
```ruby
clear=Hash.instance_method(:clear)
clear.bind({:a=>1}).call# => {}
clear.bind({a:1}).call# => {}
```
Active Support defines `Proc#bind` with an analogous purpose:
...
...
@@ -3241,8 +3241,8 @@ The most generic way to jump to other days is `advance`. This method receives a
```ruby
date=Date.new(2010,6,6)
date.advance(:years=>1,:weeks=>2)# => Mon, 20 Jun 2011
date.advance(:months=>2,:days=>-2)# => Wed, 04 Aug 2010
date.advance(years: 1,weeks:2)# => Mon, 20 Jun 2011
date.advance(months: 2,days:-2)# => Wed, 04 Aug 2010
```
Note in the previous example that increments may be negative.
...
...
@@ -3252,14 +3252,14 @@ To perform the computation the method first increments years, then months, then
The method `advance` advances first one month, and then one day, the result is:
```ruby
Date.new(2010,2,28).advance(:months=>1,:days=>1)
Date.new(2010,2,28).advance(months: 1,days:1)
# => Sun, 29 Mar 2010
```
While if it did it the other way around the result would be different: