diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/4_2_release_notes.md | 293 | ||||
-rw-r--r-- | guides/source/active_record_querying.md | 206 | ||||
-rw-r--r-- | guides/source/active_record_validations.md | 4 |
3 files changed, 271 insertions, 232 deletions
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md index 8c5abb54ea..12db528b91 100644 --- a/guides/source/4_2_release_notes.md +++ b/guides/source/4_2_release_notes.md @@ -59,22 +59,32 @@ Please refer to the [Changelog][railties] for detailed changes. ### Removals -* The `rails application` command has been removed without replacement. - ([Pull Request](https://github.com/rails/rails/pull/11616)) +* The `rails application` command has been removed without replacement. + ([Pull Request](https://github.com/rails/rails/pull/11616)) + +### Deprecations + +* Deprecated `Rails::Rack::LogTailer` without replacement. + ([Commit](https://github.com/rails/rails/commit/84a13e019e93efaa8994b3f8303d635a7702dbce)) ### Notable changes -* Introduced `bin/setup` script to bootstrap an application. - ([Pull Request](https://github.com/rails/rails/pull/15189)) +* Introduced `--skip-gems` option in the app generator to skip gems such as + `turbolinks` and `coffee-rails` that does not have their own specific flags. + ([Commit](https://github.com/rails/rails/commit/10565895805887d4faf004a6f71219da177f78b7)) + +* Introduced `bin/setup` script to bootstrap an application. + ([Pull Request](https://github.com/rails/rails/pull/15189)) + +* Changed default value for `config.assets.digest` to `true` in development. + ([Pull Request](https://github.com/rails/rails/pull/15155)) -* Changed default value for `config.assets.digest` to `true` in development. - ([Pull Request](https://github.com/rails/rails/pull/15155)) +* Introduced an API to register new extensions for `rake notes`. + ([Pull Request](https://github.com/rails/rails/pull/14379)) -* Introduced an API to register new extensions for `rake notes`. - ([Pull Request](https://github.com/rails/rails/pull/14379)) +* Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`. + ([Pull Request](https://github.com/rails/rails/pull/14101)) -* Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`. - ([Pull Request](https://github.com/rails/rails/pull/14101)) Action Pack ----------- @@ -83,8 +93,8 @@ Please refer to the [Changelog][action-pack] for detailed changes. ### Deprecations -* Deprecated support for setting the `:to` option of a router to a symbol or a - string that does not contain a `#` character: +* Deprecated support for setting the `:to` option of a router to a symbol or a + string that does not contain a `#` character: ```ruby get '/posts', to: MyRackApp => (No change necessary) @@ -97,8 +107,17 @@ Please refer to the [Changelog][action-pack] for detailed changes. ### Notable changes -* The `*_filter` family methods has been removed from the documentation. Their - usage are discouraged in favor of the `*_action` family methods: +* `render nothing: true` or rendering a `nil` body no longer add a single + space padding to the response body. + ([Pull Request](https://github.com/rails/rails/pull/14883)) + +* Introduced the `always_permitted_parameters` option to configure which + parameters are permitted globally. The default value of this configuration + is `['controller', 'action']`. + ([Pull Request](https://github.com/rails/rails/pull/15933)) + +* The `*_filter` family methods has been removed from the documentation. Their + usage are discouraged in favor of the `*_action` family methods: ``` after_filter => after_action @@ -123,22 +142,21 @@ Please refer to the [Changelog][action-pack] for detailed changes. (Commit [1](https://github.com/rails/rails/commit/6c5f43bab8206747a8591435b2aa0ff7051ad3de), [2](https://github.com/rails/rails/commit/489a8f2a44dc9cea09154ee1ee2557d1f037c7d4)) +* Added HTTP method `MKCALENDAR` from RFC-4791 + ([Pull Request](https://github.com/rails/rails/pull/15121)) -* Added HTTP method `MKCALENDAR` from RFC-4791 - ([Pull Request](https://github.com/rails/rails/pull/15121)) - -* `*_fragment.action_controller` notifications now include the controller and action name - in the payload. - ([Pull Request](https://github.com/rails/rails/pull/14137)) +* `*_fragment.action_controller` notifications now include the controller and action name + in the payload. + ([Pull Request](https://github.com/rails/rails/pull/14137)) -* Segments that are passed into URL helpers are now automatically escaped. - ([Commit](https://github.com/rails/rails/commit/5460591f0226a9d248b7b4f89186bd5553e7768f)) +* Segments that are passed into URL helpers are now automatically escaped. + ([Commit](https://github.com/rails/rails/commit/5460591f0226a9d248b7b4f89186bd5553e7768f)) -* Improved Routing Error page with fuzzy matching for route search. - ([Pull Request](https://github.com/rails/rails/pull/14619)) +* Improved Routing Error page with fuzzy matching for route search. + ([Pull Request](https://github.com/rails/rails/pull/14619)) -* Added option to disable logging of CSRF failures. - ([Pull Request](https://github.com/rails/rails/pull/14280)) +* Added option to disable logging of CSRF failures. + ([Pull Request](https://github.com/rails/rails/pull/14280)) Action View @@ -148,17 +166,21 @@ Please refer to the [Changelog][action-view] for detailed changes. ### Deprecations -* Deprecated `AbstractController::Base.parent_prefixes`. - Override `AbstractController::Base.local_prefixes` when you want to change - where to find views. - ([Pull Request](https://github.com/rails/rails/pull/15026)) +* Deprecated `AbstractController::Base.parent_prefixes`. + Override `AbstractController::Base.local_prefixes` when you want to change + where to find views. + ([Pull Request](https://github.com/rails/rails/pull/15026)) -* Deprecated `ActionView::Digestor#digest(name, format, finder, options = {})`, - arguments should be passed as a hash instead. - ([Pull Request](https://github.com/rails/rails/pull/14243)) +* Deprecated `ActionView::Digestor#digest(name, format, finder, options = {})`, + arguments should be passed as a hash instead. + ([Pull Request](https://github.com/rails/rails/pull/14243)) ### Notable changes +* The form helpers no longer generate a `<div>` element with inline CSS around + the hidden fields. + ([Pull Request](https://github.com/rails/rails/pull/14738)) + Action Mailer ------------- @@ -167,6 +189,10 @@ Please refer to the [Changelog][action-mailer] for detailed changes. ### Notable changes +* Added the `show_previews` configuration option for enabling mailer previews + outside of the development environment. + ([Pull Request](https://github.com/rails/rails/pull/15970)) + Active Record ------------- @@ -177,91 +203,114 @@ for detailed changes. ### Removals -* Removed deprecated method `ActiveRecord::Base.quoted_locking_column`. - ([Pull Request](https://github.com/rails/rails/pull/15612)) +* Removed `cache_attributes` and friends. All attributes are cached. + ([Pull Request](https://github.com/rails/rails/pull/15429)) -* Removed deprecated `ActiveRecord::Migrator.proper_table_name`. Use the - `proper_table_name` instance method on `ActiveRecord::Migration` instead. - ([Pull Request](https://github.com/rails/rails/pull/15512)) +* Removed deprecated method `ActiveRecord::Base.quoted_locking_column`. + ([Pull Request](https://github.com/rails/rails/pull/15612)) -* Removed `cache_attributes` and friends. All attributes are cached. - ([Pull Request](https://github.com/rails/rails/pull/15429)) +* Removed deprecated `ActiveRecord::Migrator.proper_table_name`. Use the + `proper_table_name` instance method on `ActiveRecord::Migration` instead. + ([Pull Request](https://github.com/rails/rails/pull/15512)) -* Removed unused `:timestamp` type. Transparently alias it to `:datetime` - in all cases. Fixes inconsistencies when column types are sent outside of - `ActiveRecord`, such as for XML Serialization. - ([Pull Request](https://github.com/rails/rails/pull/15184)) +* Removed unused `:timestamp` type. Transparently alias it to `:datetime` + in all cases. Fixes inconsistencies when column types are sent outside of + `ActiveRecord`, such as for XML Serialization. + ([Pull Request](https://github.com/rails/rails/pull/15184)) ### Deprecations -* Deprecated returning `nil` from `column_for_attribute` when no column exists. - It will return a null object in Rails 5.0 - ([Pull Request](https://github.com/rails/rails/pull/15878)) +* Deprecated broken support for automatic detection of counter caches on + `has_many :through` associations. You should instead manually specify the + counter cache on the `has_many` and `belongs_to` associations for the + through records. + ([Pull Request](https://github.com/rails/rails/pull/15754)) -* Deprecated `serialized_attributes` without replacement. - ([Pull Request](https://github.com/rails/rails/pull/15704)) +* Deprecated `serialized_attributes` without replacement. + ([Pull Request](https://github.com/rails/rails/pull/15704)) -* Deprecated using `.joins`, `.preload` and `.eager_load` with associations that - depends on the instance state (i.e. those defined with a scope that takes an - argument) without replacement. - ([Commit](https://github.com/rails/rails/commit/ed56e596a0467390011bc9d56d462539776adac1)) +* Deprecated returning `nil` from `column_for_attribute` when no column + exists. It will return a null object in Rails 5.0 + ([Pull Request](https://github.com/rails/rails/pull/15878)) -* Deprecated passing Active Record objects to `.find` or `.exists?`. Call `#id` - on the objects first. - (Commit [1](https://github.com/rails/rails/commit/d92ae6ccca3bcfd73546d612efaea011270bd270), - [2](https://github.com/rails/rails/commit/d35f0033c7dec2b8d8b52058fb8db495d49596f7)) +* Deprecated using `.joins`, `.preload` and `.eager_load` with associations + that depends on the instance state (i.e. those defined with a scope that + takes an argument) without replacement. + ([Commit](https://github.com/rails/rails/commit/ed56e596a0467390011bc9d56d462539776adac1)) -* Deprecated half-baked support for PostgreSQL range values with excluding - beginnings. We currently map PostgreSQL ranges to Ruby ranges. This conversion - is not fully possible because the Ruby range does not support excluded - beginnings. +* Deprecated passing Active Record objects to `.find` or `.exists?`. Call + `#id` on the objects first. + (Commit [1](https://github.com/rails/rails/commit/d92ae6ccca3bcfd73546d612efaea011270bd270), + [2](https://github.com/rails/rails/commit/d35f0033c7dec2b8d8b52058fb8db495d49596f7)) + +* Deprecated half-baked support for PostgreSQL range values with excluding + beginnings. We currently map PostgreSQL ranges to Ruby ranges. This conversion + is not fully possible because the Ruby range does not support excluded + beginnings. The current solution of incrementing the beginning is not correct and is now deprecated. For subtypes where we don't know how to increment - (e.g. `#succ` is not defined) it will raise an `ArgumentError` for ranges with - excluding beginnings. + (e.g. `#succ` is not defined) it will raise an `ArgumentError` for ranges + with excluding beginnings. ([Commit](https://github.com/rails/rails/commit/91949e48cf41af9f3e4ffba3e5eecf9b0a08bfc3)) -* Deprecated broken support for automatic detection of counter caches on - `has_many :through` associations. You should instead manually specify the - counter cache on the `has_many` and `belongs_to` associations for the through - records. - ([Pull Request](https://github.com/rails/rails/pull/15754)) - ### Notable changes -* Added support for `#pretty_print` in `ActiveRecord::Base` objects. - ([Pull Request](https://github.com/rails/rails/pull/15172)) +* Added a `:required` option to singular associations, which defines a + presence validation on the association. + ([Pull Request](https://github.com/rails/rails/pull/16056)) + +* Introduced `ActiveRecord::Base#validate!` that raises `RecordInvalid` if the + record is invalid. + ([Pull Request](https://github.com/rails/rails/pull/8639)) + +* `ActiveRecord::Base#reload` now behaves the same as `m = Model.find(m.id)`, + meaning that it no longer retains the extra attributes from custom + `select`s. + ([Pull Request](https://github.com/rails/rails/pull/15866)) + +* Introduced the `bin/rake db:purge` task to empty the database for the + current environment. + ([Commit](https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d)) -* PostgreSQL and SQLite adapters no longer add a default limit of 255 characters - on string columns. - ([Pull Request](https://github.com/rails/rails/pull/14579)) +* `ActiveRecord::Dirty` now detects in-place changes to mutable values. + Serialized attributes on ActiveRecord models will no longer save when + unchanged. This also works with other types such as string columns and json + columns on PostgreSQL. + (Pull Requests [1](https://github.com/rails/rails/pull/15674), + [2](https://github.com/rails/rails/pull/15786), + [3](https://github.com/rails/rails/pull/15788)) -* `sqlite3:///some/path` now resolves to the absolute system path `/some/path`. - For relative paths, use `sqlite3:some/path` instead. (Previously, `sqlite3:///some/path` - resolved to the relative path `some/path`. This behaviour was deprecated on - Rails 4.1.) - ([Pull Request](https://github.com/rails/rails/pull/14569)) +* Added support for `#pretty_print` in `ActiveRecord::Base` objects. + ([Pull Request](https://github.com/rails/rails/pull/15172)) -* Introduced `#validate` as an alias for `#valid?`. - ([Pull Request](https://github.com/rails/rails/pull/14456)) +* PostgreSQL and SQLite adapters no longer add a default limit of 255 + characters on string columns. + ([Pull Request](https://github.com/rails/rails/pull/14579)) -* `#touch` now accepts multiple attributes to be touched at once. - ([Pull Request](https://github.com/rails/rails/pull/14423)) +* `sqlite3:///some/path` now resolves to the absolute system path + `/some/path`. For relative paths, use `sqlite3:some/path` instead. + (Previously, `sqlite3:///some/path` resolved to the relative path + `some/path`. This behaviour was deprecated on Rails 4.1.) + ([Pull Request](https://github.com/rails/rails/pull/14569)) -* Added support for fractional seconds for MySQL 5.6 and above. - (Pull Request [1](https://github.com/rails/rails/pull/8240), [2](https://github.com/rails/rails/pull/14359)) +* Introduced `#validate` as an alias for `#valid?`. + ([Pull Request](https://github.com/rails/rails/pull/14456)) -* Added support for the `citext` column type in PostgreSQL adapter. - ([Pull Request](https://github.com/rails/rails/pull/12523)) +* `#touch` now accepts multiple attributes to be touched at once. + ([Pull Request](https://github.com/rails/rails/pull/14423)) -* Added support for user-created range types in PostgreSQL adapter. - ([Commit](https://github.com/rails/rails/commit/4cb47167e747e8f9dc12b0ddaf82bdb68c03e032)) +* Added support for fractional seconds for MySQL 5.6 and above. + (Pull Request [1](https://github.com/rails/rails/pull/8240), + [2](https://github.com/rails/rails/pull/14359)) + +* Added support for the `citext` column type in PostgreSQL adapter. + ([Pull Request](https://github.com/rails/rails/pull/12523)) + +* Added support for user-created range types in PostgreSQL adapter. + ([Commit](https://github.com/rails/rails/commit/4cb47167e747e8f9dc12b0ddaf82bdb68c03e032)) -* Added a `:required` option to singular associations, which defines a - presence validation on the association. - ([Pull Request](https://github.com/rails/rails/pull/16056)) Active Model ------------ @@ -270,13 +319,21 @@ Please refer to the [Changelog][active-model] for detailed changes. ### Removals -* Removed deprecated `Validator#setup` without replacement. - ([Pull Request](https://github.com/rails/rails/pull/15617)) +* Removed deprecated `Validator#setup` without replacement. + ([Pull Request](https://github.com/rails/rails/pull/15617)) ### Notable changes -* Introduced `#validate` as an alias for `#valid?`. - ([Pull Request](https://github.com/rails/rails/pull/14456)) +* Introduced `undo_changes` method in `ActiveModel::Dirty` to restore the + changed (dirty) attributes to their previous values. + ([Pull Request](https://github.com/rails/rails/pull/14861)) + +* `has_secure_password` now verifies that the given password is less than 72 + characters if validations are enabled. + ([Pull Request](https://github.com/rails/rails/pull/15708)) + +* Introduced `#validate` as an alias for `#valid?`. + ([Pull Request](https://github.com/rails/rails/pull/14456)) Active Support @@ -286,44 +343,46 @@ Please refer to the [Changelog][active-support] for detailed changes. ### Removals -* Removed deprecated `Numeric#ago`, `Numeric#until`, `Numeric#since`, - `Numeric#from_now`. ([Commit](https://github.com/rails/rails/commit/f1eddea1e3f6faf93581c43651348f48b2b7d8bb)) +* Removed deprecated `Numeric#ago`, `Numeric#until`, `Numeric#since`, + `Numeric#from_now`. + ([Commit](https://github.com/rails/rails/commit/f1eddea1e3f6faf93581c43651348f48b2b7d8bb)) -* Removed deprecated string based terminators for `ActiveSupport::Callbacks`. - ([Pull Request](https://github.com/rails/rails/pull/15100)) +* Removed deprecated string based terminators for `ActiveSupport::Callbacks`. + ([Pull Request](https://github.com/rails/rails/pull/15100)) ### Deprecations -* Deprecated `Class#superclass_delegating_accessor`, use `Class#class_attribute` - instead. ([Pull Request](https://github.com/rails/rails/pull/14271)) +* Deprecated `Class#superclass_delegating_accessor`, use + `Class#class_attribute` instead. + ([Pull Request](https://github.com/rails/rails/pull/14271)) -* Deprecated `ActiveSupport::SafeBuffer#prepend!` as `ActiveSupport::SafeBuffer#prepend` - now performs the same function. ([Pull Request](https://github.com/rails/rails/pull/14529)) +* Deprecated `ActiveSupport::SafeBuffer#prepend!` as + `ActiveSupport::SafeBuffer#prepend` now performs the same function. + ([Pull Request](https://github.com/rails/rails/pull/14529)) ### Notable changes -* The `humanize` inflector helper now strips any leading underscores. - ([Commit](https://github.com/rails/rails/commit/daaa21bc7d20f2e4ff451637423a25ff2d5e75c7)) +* Added `Hash#transform_values` and `Hash#transform_values!` to simplify a + common pattern where the values of a hash must change, but the keys are left + the same. + ([Pull Request](https://github.com/rails/rails/pull/15819)) -* Added `SecureRandom::uuid_v3` and `SecureRandom::uuid_v5`. - ([Pull Request](https://github.com/rails/rails/pull/12016)) +* The `humanize` inflector helper now strips any leading underscores. + ([Commit](https://github.com/rails/rails/commit/daaa21bc7d20f2e4ff451637423a25ff2d5e75c7)) -* Introduce `Concern#class_methods` as an alternative to `module ClassMethods`, - as well as `Kernel#concern` to avoid the `module Foo; extend ActiveSupport::Concern; end` - boilerplate. ([Commit](https://github.com/rails/rails/commit/b16c36e688970df2f96f793a759365b248b582ad)) +* Introduce `Concern#class_methods` as an alternative to + `module ClassMethods`, as well as `Kernel#concern` to avoid the + `module Foo; extend ActiveSupport::Concern; end` boilerplate. + ([Commit](https://github.com/rails/rails/commit/b16c36e688970df2f96f793a759365b248b582ad)) -* Added `Hash#transform_values` and `Hash#transform_values!` to simplify a - common pattern where the values of a hash must change, but the keys are left - the same. - ([Pull Request](https://github.com/rails/rails/pull/15819)) Credits ------- See the [full list of contributors to Rails](http://contributors.rubyonrails.org/) for -the many people who spent many hours making Rails, the stable and robust -framework it is. Kudos to all of them. +the many people who spent many hours making Rails the stable and robust +framework it is today. Kudos to all of them. [railties]: https://github.com/rails/rails/blob/4-2-stable/railties/CHANGELOG.md [action-pack]: https://github.com/rails/rails/blob/4-2-stable/actionpack/CHANGELOG.md diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 486e7b80ff..c9e265de08 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -93,9 +93,9 @@ The primary operation of `Model.find(options)` can be summarized as: Active Record provides several different ways of retrieving a single object. -#### Using a Primary Key +#### `find` -Using `Model.find(primary_key)`, you can retrieve the object corresponding to the specified _primary key_ that matches any supplied options. For example: +Using the `find` method, you can retrieve the object corresponding to the specified _primary key_ that matches any supplied options. For example: ```ruby # Find the client with primary key (id) 10. @@ -109,215 +109,180 @@ The SQL equivalent of the above is: SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1 ``` -`Model.find(primary_key)` will raise an `ActiveRecord::RecordNotFound` exception if no matching record is found. +The `find` method will raise an `ActiveRecord::RecordNotFound` exception if no matching record is found. -#### `take` - -`Model.take` retrieves a record without any implicit ordering. For example: +You can also use this method to query for multiple objects. Call the `find` method and pass in an array of primary keys. The return will be an array containing all of the matching records for the supplied _primary keys_. For example: ```ruby -client = Client.take -# => #<Client id: 1, first_name: "Lifo"> +# Find the clients with primary keys 1 and 10. +client = Client.find([1, 10]) # Or even Client.find(1, 10) +# => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">] ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients LIMIT 1 +SELECT * FROM clients WHERE (clients.id IN (1,10)) ``` -`Model.take` returns `nil` if no record is found and no exception will be raised. - -TIP: The retrieved record may vary depending on the database engine. +WARNING: The `find` method will raise an `ActiveRecord::RecordNotFound` exception unless a matching record is found for **all** of the supplied primary keys. -#### `first` +#### `take` -`Model.first` finds the first record ordered by the primary key. For example: +The `take` method retrieves a record without any implicit ordering. For example: ```ruby -client = Client.first +client = Client.take # => #<Client id: 1, first_name: "Lifo"> ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1 +SELECT * FROM clients LIMIT 1 ``` -`Model.first` returns `nil` if no matching record is found and no exception will be raised. - -#### `last` +The `take` method returns `nil` if no record is found and no exception will be raised. -`Model.last` finds the last record ordered by the primary key. For example: +You can pass in a numerical argument to the `take` method to return up to that number of results. For example ```ruby -client = Client.last -# => #<Client id: 221, first_name: "Russel"> +client = Client.take(2) +# => [ + #<Client id: 1, first_name: "Lifo">, + #<Client id: 220, first_name: "Sara"> +] ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 +SELECT * FROM clients LIMIT 2 ``` -`Model.last` returns `nil` if no matching record is found and no exception will be raised. +The `take!` method behaves exactly like `take`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. -#### `find_by` +TIP: The retrieved record may vary depending on the database engine. -`Model.find_by` finds the first record matching some conditions. For example: +#### `first` + +The `first` method finds the first record ordered by the primary key. For example: ```ruby -Client.find_by first_name: 'Lifo' +client = Client.first # => #<Client id: 1, first_name: "Lifo"> - -Client.find_by first_name: 'Jon' -# => nil ``` -It is equivalent to writing: +The SQL equivalent of the above is: -```ruby -Client.where(first_name: 'Lifo').take +```sql +SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1 ``` -#### `take!` +The `first` method returns `nil` if no matching record is found and no exception will be raised. -`Model.take!` retrieves a record without any implicit ordering. For example: +You can pass in a numerical argument to the `first` method to return up to that number of results. For example ```ruby -client = Client.take! -# => #<Client id: 1, first_name: "Lifo"> +client = Client.first(3) +# => [ + #<Client id: 1, first_name: "Lifo">, + #<Client id: 2, first_name: "Fifo">, + #<Client id: 3, first_name: "Filo"> +] ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients LIMIT 1 +SELECT * FROM clients ORDER BY clients.id ASC LIMIT 3 ``` -`Model.take!` raises `ActiveRecord::RecordNotFound` if no matching record is found. +The `first!` method behaves exactly like `first`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. -#### `first!` +#### `last` -`Model.first!` finds the first record ordered by the primary key. For example: +The `last` method finds the last record ordered by the primary key. For example: ```ruby -client = Client.first! -# => #<Client id: 1, first_name: "Lifo"> +client = Client.last +# => #<Client id: 221, first_name: "Russel"> ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1 +SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 ``` -`Model.first!` raises `ActiveRecord::RecordNotFound` if no matching record is found. - -#### `last!` +The `last` method returns `nil` if no matching record is found and no exception will be raised. -`Model.last!` finds the last record ordered by the primary key. For example: +You can pass in a numerical argument to the `last` method to return up to that number of results. For example ```ruby -client = Client.last! -# => #<Client id: 221, first_name: "Russel"> +client = Client.last(3) +# => [ + #<Client id: 219, first_name: "James">, + #<Client id: 220, first_name: "Sara">, + #<Client id: 221, first_name: "Russel"> +] ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 +SELECT * FROM clients ORDER BY clients.id DESC LIMIT 3 ``` -`Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found. +The `last!` method behaves exactly like `last`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. -#### `find_by!` +#### `find_by` -`Model.find_by!` finds the first record matching some conditions. It raises `ActiveRecord::RecordNotFound` if no matching record is found. For example: +The `find_by` method finds the first record matching some conditions. For example: ```ruby -Client.find_by! first_name: 'Lifo' +Client.find_by first_name: 'Lifo' # => #<Client id: 1, first_name: "Lifo"> -Client.find_by! first_name: 'Jon' -# => ActiveRecord::RecordNotFound +Client.find_by first_name: 'Jon' +# => nil ``` It is equivalent to writing: ```ruby -Client.where(first_name: 'Lifo').take! +Client.where(first_name: 'Lifo').take ``` -### Retrieving Multiple Objects - -#### Using Multiple Primary Keys - -`Model.find(array_of_primary_key)` accepts an array of _primary keys_, returning an array containing all of the matching records for the supplied _primary keys_. For example: +The `find_by!` method behaves exactly like `find_by`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. For example: ```ruby -# Find the clients with primary keys 1 and 10. -client = Client.find([1, 10]) # Or even Client.find(1, 10) -# => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">] -``` - -The SQL equivalent of the above is: - -```sql -SELECT * FROM clients WHERE (clients.id IN (1,10)) +Client.find_by! first_name: 'does not exist' +# => ActiveRecord::RecordNotFound ``` -WARNING: `Model.find(array_of_primary_key)` will raise an `ActiveRecord::RecordNotFound` exception unless a matching record is found for **all** of the supplied primary keys. - -#### take - -`Model.take(limit)` retrieves the first number of records specified by `limit` without any explicit ordering: +This is equivalent to writing: ```ruby -Client.take(2) -# => [#<Client id: 1, first_name: "Lifo">, - #<Client id: 2, first_name: "Raf">] -``` - -The SQL equivalent of the above is: - -```sql -SELECT * FROM clients LIMIT 2 +Client.where(first_name: 'does not exist').take! ``` -#### first +#### `last!` -`Model.first(limit)` finds the first number of records specified by `limit` ordered by primary key: +`Model.last!` finds the last record ordered by the primary key. For example: ```ruby -Client.first(2) -# => [#<Client id: 1, first_name: "Lifo">, - #<Client id: 2, first_name: "Raf">] +client = Client.last! +# => #<Client id: 221, first_name: "Russel"> ``` The SQL equivalent of the above is: ```sql -SELECT * FROM clients ORDER BY id ASC LIMIT 2 -``` - -#### last - -`Model.last(limit)` finds the number of records specified by `limit` ordered by primary key in descending order: - -```ruby -Client.last(2) -# => [#<Client id: 10, first_name: "Ryan">, - #<Client id: 9, first_name: "John">] +SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 ``` -The SQL equivalent of the above is: - -```sql -SELECT * FROM clients ORDER BY id DESC LIMIT 2 -``` +`Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found. ### Retrieving Multiple Objects in Batches @@ -344,7 +309,15 @@ The `find_each` method retrieves a batch of records and then yields _each_ recor ```ruby User.find_each do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver +end +``` + +To add conditions to a `find_each` operation you can chain other Active Record methods such as `where`: + +```ruby +User.where(weekly_subscriber: true).find_each do |user| + NewsMailer.weekly(user).deliver end ``` @@ -707,7 +680,7 @@ Overriding Conditions You can specify certain conditions to be removed using the `unscope` method. For example: ```ruby -Article.where('id > 10').limit(20).order('id asc').except(:order) +Article.where('id > 10').limit(20).order('id asc').unscope(:order) ``` The SQL that would be executed: @@ -720,7 +693,7 @@ SELECT * FROM articles WHERE id > 10 ORDER BY id asc LIMIT 20 ``` -You can additionally unscope specific where clauses. For example: +You can also unscope specific `where` clauses. For example: ```ruby Article.where(id: 10, trashed: false).unscope(where: :id) @@ -759,8 +732,6 @@ The `reorder` method overrides the default scope order. For example: ```ruby class Article < ActiveRecord::Base - .. - .. has_many :comments, -> { order('posted_at DESC') } end @@ -1487,6 +1458,11 @@ If you'd like to use your own SQL to find records in a table you can use `find_b Client.find_by_sql("SELECT * FROM clients INNER JOIN orders ON clients.id = orders.client_id ORDER BY clients.created_at desc") +# => [ + #<Client id: 1, first_name: "Lucas" >, + #<Client id: 2, first_name: "Jan" >, + # ... +] ``` `find_by_sql` provides you with a simple way of making custom calls to the database and retrieving instantiated objects. @@ -1496,7 +1472,11 @@ Client.find_by_sql("SELECT * FROM clients `find_by_sql` has a close relative called `connection#select_all`. `select_all` will retrieve objects from the database using custom SQL just like `find_by_sql` but will not instantiate them. Instead, you will get an array of hashes where each hash indicates a record. ```ruby -Client.connection.select_all("SELECT * FROM clients WHERE id = '1'") +Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE id = '1'") +# => [ + {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"}, + {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"} +] ``` ### `pluck` diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index 7ec4ab312d..582bb240dd 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -910,8 +910,8 @@ end The easiest way to add custom validators for validating individual attributes is with the convenient `ActiveModel::EachValidator`. In this case, the custom validator class must implement a `validate_each` method which takes three -arguments: record, attribute and value which correspond to the instance, the -attribute to be validated and the value of the attribute in the passed +arguments: record, attribute, and value. These correspond to the instance, the +attribute to be validated, and the value of the attribute in the passed instance. ```ruby |