diff options
Diffstat (limited to 'activerecord/CHANGELOG.md')
-rw-r--r-- | activerecord/CHANGELOG.md | 2198 |
1 files changed, 824 insertions, 1374 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 58f6153e96..c1739f113a 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,1954 +1,1404 @@ -## Rails 4.0.0 (unreleased) ## +* Deprecate unused `ActiveRecord::Base.symbolized_base_class` + and `ActiveRecord::Base.symbolized_sti_name` without replacement. -* `default_scopes?` is deprecated. Check for `default_scopes.empty?` instead. - - *Agis Anastasopoulos* - -* Default values for PostgreSQL bigint types now get parsed and dumped to the - schema correctly. - - *Erik Peterson* - -* Fix associations with `:inverse_of` option when building association - with a block. Inside the block the parent object was different then - after the block. - - Example: - - parent.association.build do |child| - child.parent.equal?(parent) # false - end - - # vs - - child = parent.association.build - child.parent.equal?(parent) # true - - *Michal Cichra* - -* `has_many` using `:through` now obeys the order clause mentioned in - through association. Fixes #10016. - - *Neeraj Singh* - -* `belongs_to :touch` behavior now touches old association when - transitioning to new association. - - class Passenger < ActiveRecord::Base - belongs_to :car, touch: true - end - - car_1 = Car.create - car_2 = Car.create - - passenger = Passenger.create car: car_1 - - passenger.car = car_2 - passenger.save - - Previously only car_2 would be touched. Now both car_1 and car_2 - will be touched. - - *Adam Gamble* - -* Extract and deprecate Firebird / Sqlserver / Oracle database tasks, because - These tasks should be supported by 3rd-party adapter. - - *kennyj* + *Yves Senn* -* Allow `ActiveRecord::Base.connection_handler` to have thread affinity and be - settable, this effectively allows Active Record to be used in a multi threaded - setup with multiple connections to multiple dbs. +* Since the `test_help.rb` in Railties now automatically maintains + your test schema, the `rake db:test:*` tasks are deprecated. This + doesn't stop you manually running other tasks on your test database + if needed: - *Sam Saffron* + rake db:schema:load RAILS_ENV=test -* `rename_column` preserves `auto_increment` in MySQL migrations. - Fixes #3493. + *Jon Leighton* - *Vipul A M* +* Fix presence validator for association when the associated record responds to `to_a`. -* PostgreSQL geometric type point is now supported by Active Record. Fixes #7324. + *gmarik* - *Martin Schuerrer* +* Fixed regression on preload/includes with multiple arguments failing in certain conditions, + raising a NoMethodError internally by calling `reflect_on_association` for `NilClass:Class`. -* Add support for concurrent indexing in PostgreSQL adapter via the - `algorithm: :concurrently` option. + Fixes #13437. - add_index(:people, :last_name, algorithm: :concurrently) + *Vipul A M*, *khustochka* - Also add support for MySQL index algorithms (`COPY`, `INPLACE`, - `DEFAULT`) via the `:algorithm` option. +* Add the ability to nullify the `enum` column. - add_index(:people, :last_name, algorithm: :copy) # or :inplace/:default + Example: - *Dan McClain* + class Conversation < ActiveRecord::Base + enum gender: [:female, :male] + end -* Add support for fulltext and spatial indexes on MySQL tables with MyISAM database - engine via the `type: 'FULLTEXT'` / `type: 'SPATIAL'` option. + Conversation::GENDER # => { female: 0, male: 1 } - add_index(:people, :last_name, type: 'FULLTEXT') - add_index(:people, :last_name, type: 'SPATIAL') + # conversation.update! gender: 0 + conversation.female! + conversation.female? # => true + conversation.gender # => "female" - *Ken Mazaika* + # conversation.update! gender: nil + conversation.gender = nil + conversation.gender.nil? # => true + conversation.gender # => nil -* Add an `add_index` override in PostgreSQL adapter and MySQL adapter - to allow custom index type support. Fixes #6101. + *Amr Tamimi* - add_index(:wikis, :body, :using => 'gin') +* Connection specification now accepts a "url" key. The value of this + key is expected to contain a database URL. The database URL will be + expanded into a hash and merged. - *Stefan Huber* and *Doabit* + *Richard Schneeman* -* After extraction of mass-assignment attributes (which protects [id, type] - by default) we can pass id to `update_attributes` and it will update - another record because id will be used in where statement. We never have - to change id in where statement because we try to set/replace fields for - already loaded record but we have to try to set new id for that record. +* An `ArgumentError` is now raised on a call to `Relation#where.not(nil)`. - *Dmitry Vorotilin* + Example: -* Models with multiple counter cache associations now update correctly on destroy. - See #7706. + User.where.not(nil) - *Ian Young* + # Before + # => 'SELECT `users`.* FROM `users` WHERE (NOT (NULL))' -* If `:inverse_of` is true on an association, then when one calls `find()` on - the association, Active Record will first look through the in-memory objects - in the association for a particular id. Then, it will go to the DB if it - is not found. This is accomplished by calling `find_by_scan` in - collection associations whenever `options[:inverse_of]` is not nil. + # After + # => ArgumentError, 'Invalid argument for .where.not(), got nil.' - Fixes #9470. + *Kuldeep Aggarwal* - *John Wang* +* Deprecated use of string argument as a configuration lookup in + `ActiveRecord::Base.establish_connection`. Instead, a symbol must be given. -* `rake db:create` does not change permissions of the MySQL root user. - Fixes #8079. +* Deprecated use of string argument as a configuration lookup in `ActiveRecord::Base.establish_connection`. Instead, a symbol must be given. - *Yves Senn* + *José Valim* -* The length of the `version` column in the `schema_migrations` table - created by the `mysql2` adapter is 191 if the encoding is "utf8mb4". +* Fixed `update_column`, `update_columns`, and `update_all` to correctly serialize + values for `array`, `hstore` and `json` column types in PostgreSQL. - The "utf8" encoding in MySQL has support for a maximum of 3 bytes per character, - and only contains characters from the BMP. The recently added - [utf8mb4](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html) - encoding extends the support to four bytes. As of this writing, said encoding - is supported in the betas of the `mysql2` gem. + Fixes #12261. - Setting the encoding to "utf8mb4" has - [a few implications](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-upgrading.html). - This change addresses the max length for indexes, which is 191 instead of 255. + *Tadas Tamosauskas*, *Carlos Antonio da Silva* - *Xavier Noria* +* Do not consider PostgreSQL array columns as number or text columns. -* Counter caches on associations will now stay valid when attributes are - updated (not just when records are created or destroyed), for example, - when calling `update_attributes`. The following code now works: + The code uses these checks in several places to know what to do with a + particular column, for instance AR attribute query methods has a branch + like this: - class Comment < ActiveRecord::Base - belongs_to :post, counter_cache: true + if column.number? + !value.zero? end - class Post < ActiveRecord::Base - has_many :comments - end + This should never be true for array columns, since it would be the same + as running [].zero?, which results in a NoMethodError exception. - post = Post.create - comment = Comment.create + Fixing this by ensuring that array columns in PostgreSQL never return + true for number?/text? checks. - post.comments << comment - post.save.reload.comments_count # => 1 - comment.update_attributes(post_id: nil) + *Carlos Antonio da Silva* - post.save.reload.comments_count # => 0 +* When connecting to a non-existant database, the error: + `ActiveRecord::NoDatabaseError` will now be raised. When being used with Rails + the error message will include information on how to create a database: + `rake db:create`. Supported adapters: postgresql, mysql, mysql2, sqlite3 - Updating the id of a `belongs_to` object with the id of a new object will - also keep the count accurate. + *Richard Schneeman* - *John Wang* +* Do not raise `'can not touch on a new record object'` exception on destroying + already destroyed `belongs_to` association with `touch: true` option. -* Referencing join tables implicitly was deprecated. There is a - possibility that these deprecation warnings are shown even if you - don't make use of that feature. You can now disable the feature entirely. - Fixes #9712. + Fixes #13445. Example: - # in your configuration - config.active_record.disable_implicit_join_references = true + # Given Comment has belongs_to :post, touch: true + comment.post.destroy + comment.destroy # no longer raises an error - # or directly - ActiveRecord::Base.disable_implicit_join_references = true + *Paul Nikitochkin* - *Yves Senn* +* Fix a bug when assigning an array containing string numbers to a + PostgreSQL integer array column. -* The `:distinct` option for `Relation#count` is deprecated. You - should use `Relation#distinct` instead. + Fixes #13444. Example: - # Before - Post.select(:author_name).count(distinct: true) - - # After - Post.select(:author_name).distinct.count - - *Yves Senn* - -* Rename `Relation#uniq` to `Relation#distinct`. `#uniq` is still - available as an alias but we encourage to use `#distinct` instead. - Also `Relation#uniq_value` is aliased to `Relation#distinct_value`, - this is a temporary solution and you should migrate to `distinct_value`. - - *Yves Senn* - -* Fix quoting for sqlite migrations using `copy_table_contents` with binary - columns. + # Given Book#ratings is of type :integer, array: true + Book.new(ratings: [1, 2]) # worked before + Book.new(ratings: ['1', '2']) # now works as well - These would fail with "SQLite3::SQLException: unrecognized token" because - the column was not being passed to `quote` so the data was not quoted - correctly. + *Damien Mathieu* - *Matthew M. Boedicker* +* Improve the default select when `from` is used. -* Promotes `change_column_null` to the migrations API. This macro sets/removes - `NOT NULL` constraints, and accepts an optional argument to replace existing - `NULL`s if needed. The adapters for SQLite, MySQL, PostgreSQL, and (at least) - Oracle, already implement this method. + Previously, if you did something like Topic.from(:temp_topics), it + would generate SQL like: - *Xavier Noria* + SELECT topics.* FROM temp_topics; -* Uniqueness validation allows you to pass `:conditions` to limit - the constraint lookup. + Which is will cause an error since there's not a topics table to select + from. - Example: + Now the default if you use from is just `*`: - validates_uniqueness_of :title, conditions: -> { where('approved = ?', true) } + SELECT * FROM temp_topics; - *Mattias Pfeiffer + Yves Senn* + *Cody Cutrer* -* `connection` is deprecated as an instance method. - This allows end-users to have a `connection` method on their models - without clashing with Active Record internals. +* Fix `PostgreSQL` insert to properly extract table name from multiline string SQL. - *Ben Moss* + Previously, executing an insert SQL in `PostgreSQL` with a command like this: -* When copying migrations, preserve their magic comments and content encoding. + insert into articles( + number) + values( + 5152 + ) - *OZAWA Sakuro* + would not work because the adapter was unable to extract the correct `articles` + table name. -* Fix `subclass_from_attrs` when `eager_load` is false. It cannot find - subclass because all classes are loaded automatically when it needs. + *Kuldeep Aggarwal* - *Dmitry Vorotilin* +* `Relation` no longer has mutator methods like `#map!` and `#delete_if`. Convert + to an `Array` by calling `#to_a` before using these methods. -* When `:name` option is provided to `remove_index`, use it if there is no - index by the conventional name. + It intends to prevent odd bugs and confusion in code that call mutator + methods directly on the `Relation`. - For example, previously if an index was removed like so - `remove_index :values, column: :value, name: 'a_different_name'` - the generated SQL would not contain the specified index name, - and hence the migration would fail. - Fixes #8858. + Example: - *Ezekiel Smithburg* + # Instead of this + Author.where(name: 'Hank Moody').compact! -* Created block to by-pass the prepared statement bindings. - This will allow to compose fragments of large SQL statements to - avoid multiple round-trips between Ruby and the DB. + # Now you have to do this + authors = Author.where(name: 'Hank Moody').to_a + authors.compact! - Example: + *Lauro Caetano* - sql = Post.connection.unprepared_statement do - Post.first.comments.to_sql - end +* Better support for `where()` conditions that use a `belongs_to` + association name. - *Cédric Fabianski* + Using the name of an association in `where` previously worked only + if the value was a single `ActiveRecord::Base` object. e.g. -* Change the semantics of combining scopes to be the same as combining - class methods which return scopes. For example: + Post.where(author: Author.first) - class User < ActiveRecord::Base - scope :active, -> { where state: 'active' } - scope :inactive, -> { where state: 'inactive' } - end + Any other values, including `nil`, would cause invalid SQL to be + generated. This change supports arguments in the `where` query + conditions where the key is a `belongs_to` association name and the + value is `nil`, an `Array` of `ActiveRecord::Base` objects, or an + `ActiveRecord::Relation` object. class Post < ActiveRecord::Base - def self.active - where state: 'active' - end - - def self.inactive - where state: 'inactive' - end + belongs_to :author end - ### BEFORE ### - - User.where(state: 'active').where(state: 'inactive') - # => SELECT * FROM users WHERE state = 'active' AND state = 'inactive' - - User.active.inactive - # => SELECT * FROM users WHERE state = 'inactive' + `nil` value finds records where the association is not set: - Post.active.inactive - # => SELECT * FROM posts WHERE state = 'active' AND state = 'inactive' + Post.where(author: nil) + # SELECT "posts".* FROM "posts" WHERE "posts"."author_id" IS NULL - ### AFTER ### + `Array` values find records where the association foreign key + matches the ids of the passed ActiveRecord models, resulting + in the same query as `Post.where(author_id: [1,2])`: - User.active.inactive - # => SELECT * FROM posts WHERE state = 'active' AND state = 'inactive' + authors_array = [Author.find(1), Author.find(2)] + Post.where(author: authors_array) + # SELECT "posts".* FROM "posts" WHERE "posts"."author_id" IN (1, 2) - Before this change, invoking a scope would merge it into the current - scope and return the result. `Relation#merge` applies "last where - wins" logic to de-duplicate the conditions, but this lead to - confusing and inconsistent behaviour. This fixes that. - - If you really do want the "last where wins" logic, you can opt-in to - it like so: - - User.active.merge(User.inactive) - - Fixes #7365. - - *Neeraj Singh* and *Jon Leighton* - -* Expand `#cache_key` to consult all relevant updated timestamps. - - Previously only `updated_at` column was checked, now it will - consult other columns that received updated timestamps on save, - such as `updated_on`. When multiple columns are present it will - use the most recent timestamp. - Fixes #9033. - - *Brendon Murphy* - -* Throw `NotImplementedError` when trying to instantiate `ActiveRecord::Base` or an abstract class. - - *Aaron Weiner* - -* Warn when `rake db:structure:dump` with a MySQL database and - `mysqldump` is not in the PATH or fails. - Fixes #9518. - - *Yves Senn* + `ActiveRecord::Relation` values find records using the same + query as `Post.where(author_id: Author.where(last_name: "Emde"))` -* Remove `connection#structure_dump`, which is no longer used. *Yves Senn* + Post.where(author: Author.where(last_name: "Emde")) + # SELECT "posts".* FROM "posts" + # WHERE "posts"."author_id" IN ( + # SELECT "authors"."id" FROM "authors" + # WHERE "authors"."last_name" = 'Emde') -* Make it possible to execute migrations without a transaction even - if the database adapter supports DDL transactions. - Fixes #9483. + Polymorphic `belongs_to` associations will continue to be handled + appropriately, with the polymorphic `association_type` field added + to the query to match the base class of the value. This feature + previously only worked when the value was a single `ActveRecord::Base`. - Example: - - class ChangeEnum < ActiveRecord::Migration - disable_ddl_transaction! - - def up - execute "ALTER TYPE model_size ADD VALUE 'new_value'" - end + class Post < ActiveRecord::Base + belongs_to :author, polymorphic: true end - *Yves Senn* - -* Assigning "0.0" to a nullable numeric column does not make it dirty. - Fixes #9034. + Post.where(author: Author.where(last_name: "Emde")) + # Generates a query similar to: + Post.where(author_id: Author.where(last_name: "Emde"), author_type: "Author") - Example: + *Martin Emde* - product = Product.create price: 0.0 - product.price = '0.0' - product.changed? # => false (this used to return true) - product.changes # => {} (this used to return { price: [0.0, 0.0] }) +* Respect temporary option when dropping tables with MySQL. - *Yves Senn* + Normal DROP TABLE also works, but commits the transaction. -* Added functionality to unscope relations in a relations chain. For - instance, if you are passed in a chain of relations as follows: + drop_table :temporary_table, temporary: true - User.where(name: "John").order('id DESC') + *Cody Cutrer* - but you want to get rid of order, then this feature allows you to do: +* Add option to create tables from a query. - User.where(name: "John").order('id DESC').unscope(:order) - == User.where(name: "John") + create_table(:long_query, temporary: true, + as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id") - The .unscope() function is more general than the .except() method because - .except() only works on the relation it is acting on. However, .unscope() - works for any relation in the entire relation chain. + Generates: - *John Wang* + CREATE TEMPORARY TABLE long_query AS + SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id -* PostgreSQL timestamp with time zone (timestamptz) datatype now returns a - ActiveSupport::TimeWithZone instance instead of a string + *Cody Cutrer* - *Troy Kruthoff* +* `db:test:clone` and `db:test:prepare` must load Rails environment. -* The `#append` method for collection associations behaves like`<<`. - `#prepend` is not defined and `<<` or `#append` should be used. - Fixes #7364. + `db:test:clone` and `db:test:prepare` use `ActiveRecord::Base`. configurations, + so we need to load the Rails environment, otherwise the config wont be in place. - *Yves Senn* + *arthurnn* -* Added support for creating a table via Rails migration generator. - For example, +* Use the right column to type cast grouped calculations with custom expressions. - rails g migration create_books title:string content:text + Fixes #13230. - will generate a migration that creates a table called books with - the listed attributes, without creating a model. + Example: - *Sammy Larbi* + # Before + Account.group(:firm_name).sum('0.01 * credit_limit') + # => { '37signals' => '0.5' } -* Fix bug that raises the wrong exception when the exception handled by PostgreSQL adapter - doesn't respond to `#result`. - Fixes #8617. + # After + Account.group(:firm_name).sum('0.01 * credit_limit') + # => { '37signals' => 0.5 } - *kennyj* + *Paul Nikitochkin* -* Support PostgreSQL specific column types when using `change_table`. - Fixes #9480. +* Polymorphic `belongs_to` associations with the `touch: true` option set update the timestamps of + the old and new owner correctly when moved between owners of different types. Example: - change_table :authors do |t| - t.hstore :books - t.json :metadata + class Rating < ActiveRecord::Base + belongs_to :rateable, polymorphic: true, touch: true end - *Yves Senn* - -* Revert 408227d9c5ed7d, 'quote numeric'. This introduced some regressions. - - *Steve Klabnik* + rating = Rating.create rateable: Song.find(1) + rating.update_attributes rateable: Book.find(2) # => timestamps of Song(1) and Book(2) are updated -* Fix calculation of `db_runtime` property in - `ActiveRecord::Railties::ControllerRuntime#cleanup_view_runtime`. - Previously, after raising `ActionView::MissingTemplate`, `db_runtime` was - not populated. - Fixes #9215. + *Severin Schoepke* - *Igor Fedoronchuk* +* Improve formatting of migration exception messages: make them easier to read + with line breaks before/after, and improve the error for pending migrations. -* Do not try to touch invalid (and thus not persisted) parent record - for a `belongs_to :parent, touch: true` association + *John Bachir* - *Olek Janiszewski* - -* Fix when performing an ordered join query. The bug only - affected queries where the order was given with a symbol. - Fixes #9275. +* Fix `last` with `offset` to return the proper record instead of always the last one. Example: - # This will expand the order :name to "authors".name. - Author.joins(:books).where('books.published = 1').order(:name) - - -## Rails 4.0.0.beta1 (February 25, 2013) ## - -* Fix overriding of attributes by `default_scope` on `ActiveRecord::Base#dup`. - - *Hiroshige UMINO* + Model.offset(4).last + # => returns the 4th record from the end. -* Update queries now use prepared statements. + Fixes #7441. - *Olli Rissanen* + *kostya*, *Lauro Caetano* -* Fixing issue #8345. Now throwing an error when one attempts to touch a - new object that has not yet been persisted. For instance: +* `type_to_sql` returns a `String` for unmapped columns. This fixes an error + when using unmapped array types in PG Example: - ball = Ball.new - ball.touch :updated_at # => raises error + change_colum :table, :column, :bigint, array: true - It is not until the ball object has been persisted that it can be touched. - This follows the behavior of update_column. + Fixes #13146. - *John Wang* + *Jens Fahnenbruck*, *Yves Senn* -* Preloading ordered `has_many :through` associations no longer applies - invalid ordering to the `:through` association. - Fixes #8663. +* Fix `QueryCache` to work with nested blocks, so that it will only clear the existing cache + after leaving the outer block instead of clearing it right after the inner block is finished. - *Yves Senn* + *Vipul A M* -* The auto explain feature has been removed. This feature was - activated by configuring `config.active_record.auto_explain_threshold_in_seconds`. - The configuration option was deprecated and has no more effect. +* The ERB in fixture files is no longer evaluated in the context of the main + object. Helper methods used by multiple fixtures should be defined on the + class object returned by `ActiveRecord::FixtureSet.context_class`. - You can still use `ActiveRecord::Relation#explain` to see the EXPLAIN output for - any given relation. + *Victor Costan* - *Yves Senn* +* Previously, the `has_one` macro incorrectly accepted the `counter_cache` + option, but never actually supported it. Now it will raise an `ArgumentError` + when using `has_one` with `counter_cache`. -* The `:on` option for `after_commit` and `after_rollback` now - accepts an Array of actions. - Fixes #988. + *Godfrey Chan* - Example: +* Implement `rename_index` natively for MySQL >= 5.7. - after_commit :update_cache on: [:create, :update] + *Cody Cutrer* - *Yves Senn* +* Fix bug when validating the uniqueness of an aliased attribute. -* Rename related indexes on `rename_table` and `rename_column`. This - does not affect indexes with custom names. + Fixes #12402. - *Yves Senn* + *Lauro Caetano* -* Prevent the creation of indices with too long names, which cause - internal operations to fail (sqlite3 adapter only). The method - `allowed_index_name_length` defines the length limit enforced by - rails. It's value defaults to `index_name_length` but can vary per adapter. - Fixes #8264. +* Update counter cache on a `has_many` relationship regardless of default scope. - *Yves Senn* + Fix #12952. -* Fixing issue #776. + *Uku Taht* - Memory bloat in transactions is handled by having the transaction hold only - the AR objects which it absolutely needs to know about. These are the AR - objects with callbacks (they need to be updated as soon as something in the - transaction occurs). +* `rename_index` adds the new index before removing the old one. This allows to + rename indexes on columns with a foreign key and prevents the following error: - All other AR objects can be updated lazily by keeping a reference to a - TransactionState object. If an AR object gets inside a transaction, then - the transaction will add its TransactionState to the AR object. When the - user makes a call to some attribute on an AR object (which has no - callbacks) associated with a transaction, the AR object will call the - sync_with_transaction_state method and make sure it is up to date with the - transaction. After it has synced with the transaction state, the AR object - will return the attribute that was requested. + Cannot drop index 'index_engines_on_car_id': needed in a foreign key constraint - Most of the logic in the changes are used to handle multiple transactions, - in which case the AR object has to recursively follow parent pointers of - TransactionState objects. + *Cody Cutrer*, *Yves Senn* - *John Wang* +* Raise `ActiveRecord::RecordNotDestroyed` when a replaced child marked with `dependent: destroy` fails to be destroyed. -* Descriptive error message when the necessary AR adapter gem was not found. - Fixes #7313. + Fix #12812 - *Yves Senn* + *Brian Thomas Storti* -* Active Record now raises an error when blank arguments are passed to query - methods for which blank arguments do not make sense. +* Fix validation on uniqueness of empty association. - Example: + *Evgeny Li* - Post.includes() # => raises error +* Make `ActiveRecord::Relation#unscope` affect relations it is merged in to. - *John Wang* - -* Simplified type casting code for timezone aware attributes to use the - `in_time_zone` method if it is available. This introduces a subtle change - of behavior when using `Date` instances as they are directly converted to - `ActiveSupport::TimeWithZone` instances without first being converted to - `Time` instances. For example: - - # Rails 3.2 behavior - >> Date.today.to_time.in_time_zone - => Wed, 13 Feb 2013 07:00:00 UTC +00:00 - - # Rails 4.0 behavior - >> Date.today.in_time_zone - => Wed, 13 Feb 2013 00:00:00 UTC +00:00 - - On the plus side it now behaves the same whether you pass a `String` date - or an actual `Date` instance. For example: - - # Rails 3.2 behavior - >> Date.civil(2013, 2, 13).to_time.in_time_zone - => Wed, 13 Feb 2013 07:00:00 UTC +00:00 - >> Time.zone.parse("2013-02-13") - => Wed, 13 Feb 2013 00:00:00 UTC +00:00 - - # Rails 4.0 behavior - >> Date.civil(2013, 2, 13).in_time_zone - => Wed, 13 Feb 2013 00:00:00 UTC +00:00 - >> "2013-02-13".in_time_zone - => Wed, 13 Feb 2013 00:00:00 UTC +00:00 + *Jon Leighton* - If you need the old behavior you can convert the dates to times manually. - For example: +* Use strings to represent non-string `order_values`. - >> Post.new(created_at: Date.today).created_at - => Wed, 13 Feb 2013 00:00:00 UTC +00:00 + *Yves Senn* - >> Post.new(created_at: Date.today.to_time).created_at - => Wed, 13 Feb 2013 07:00:00 UTC +00:00 +* Checks to see if the record contains the foreign key to set the inverse automatically. - *Andrew White* + *Edo Balvers* -* Preloading `has_many :through` associations with conditions won't - cache the `:through` association. This will prevent invalid - subsets to be cached. - Fixes #8423. +* Added `ActiveRecord::Base.to_param` for convenient "pretty" URLs derived from a model's attribute or method. Example: - class User - has_many :posts - has_many :recent_comments, -> { where('created_at > ?', 1.week.ago) }, :through => :posts - end - - a_user = User.includes(:recent_comments).first - - # This is preloaded. - a_user.recent_comments - - # This is not preloaded, fetched now. - a_user.posts - - *Yves Senn* - -* Don't run `after_commit` callbacks when creating through an association - if saving the record fails. - - *James Miller* - -* Allow store accessors to be overridden like other attribute methods, e.g.: - class User < ActiveRecord::Base - store :settings, accessors: [ :color, :homepage ], coder: JSON - - def color - super || 'red' - end + to_param :name end - *Sergey Nartimov* + user = User.find_by(name: 'Fancy Pants') + user.id # => 123 + user.to_param # => "123-fancy-pants" + + *Javan Makhmali* -* Quote numeric values being compared to non-numeric columns. Otherwise, - in some database, the string column values will be coerced to a numeric - allowing 0, 0.0 or false to match any string starting with a non-digit. +* Added `ActiveRecord::Base.no_touching`, which allows ignoring touch on models. Example: - App.where(apikey: 0) # => SELECT * FROM users WHERE apikey = '0' + Post.no_touching do + Post.first.touch + end - *Dylan Smith* + *Sam Stephenson*, *Damien Mathieu* -* Schema dumper supports dumping the enabled database extensions to `schema.rb` - (currently only supported by PostgreSQL). +* Prevent the counter cache from being decremented twice when destroying + a record on a `has_many :through` association. - *Justin George* + Fixes #11079. -* The database adapters now converts the options passed thought `DATABASE_URL` - environment variable to the proper Ruby types before using. For example, SQLite requires - that the timeout value is an integer, and PostgreSQL requires that the - prepared_statements option is a boolean. These now work as expected: + *Dmitry Dedov* - Example: +* Unify boolean type casting for `MysqlAdapter` and `Mysql2Adapter`. + `type_cast` will return `1` for `true` and `0` for `false`. - DATABASE_URL=sqlite3://localhost/test_db?timeout=500 - DATABASE_URL=postgresql://localhost/test_db?prepared_statements=false + Fixes #11119. - *Aaron Stone + Rafael Mendonça França* + *Adam Williams*, *Yves Senn* -* `Relation#merge` now only overwrites where values on the LHS of the - merge. Consider: +* Fix bug where `has_one` association record update result in crash, when replaced with itself. - left = Person.where(age: [13, 14, 15]) - right = Person.where(age: [13, 14]).where(age: [14, 15]) + Fixes #12834. - `left` results in the following SQL: + *Denis Redozubov*, *Sergio Cambra* - WHERE age IN (13, 14, 15) +* Log bind variables after they are type casted. This makes it more + transparent what values are actually sent to the database. - `right` results in the following SQL: + irb(main):002:0> Event.find("im-no-integer") + # Before: ... WHERE "events"."id" = $1 LIMIT 1 [["id", "im-no-integer"]] + # After: ... WHERE "events"."id" = $1 LIMIT 1 [["id", 0]] - WHERE age IN (13, 14) AND age IN (14, 15) + *Yves Senn* - Previously, `left.merge(right)` would result in all but the last - condition being removed: +* Fix uninitialized constant `TransactionState` error when `Marshall.load` is used on an Active Record result. - WHERE age IN (14, 15) + Fixes #12790. - Now it results in the LHS condition(s) for `age` being removed, but - the RHS remains as it is: + *Jason Ayre* - WHERE age IN (13, 14) AND age IN (14, 15) +* `.unscope` now removes conditions specified in `default_scope`. *Jon Leighton* -* Fix handling of dirty time zone aware attributes +* Added `ActiveRecord::QueryMethods#rewhere` which will overwrite an existing, named where condition. - Previously, when `time_zone_aware_attributes` were enabled, after - changing a datetime or timestamp attribute and then changing it back - to the original value, `changed_attributes` still tracked the - attribute as changed. This caused `[attribute]_changed?` and - `changed?` methods to return true incorrectly. - - Example: - - in_time_zone 'Paris' do - order = Order.new - original_time = Time.local(2012, 10, 10) - order.shipped_at = original_time - order.save - order.changed? # => false - - # changing value - order.shipped_at = Time.local(2013, 1, 1) - order.changed? # => true + Examples: - # reverting to original value - order.shipped_at = original_time - order.changed? # => false, used to return true - end + Post.where(trashed: true).where(trashed: false) #=> WHERE `trashed` = 1 AND `trashed` = 0 + Post.where(trashed: true).rewhere(trashed: false) #=> WHERE `trashed` = 0 + Post.where(active: true).where(trashed: true).rewhere(trashed: false) #=> WHERE `active` = 1 AND `trashed` = 0 - *Lilibeth De La Cruz* + *DHH* -* When `#count` is used in conjunction with `#uniq` we perform `count(:distinct => true)`. - Fixes #6865. +* Extend `ActiveRecord::Base#cache_key` to take an optional list of timestamp attributes of which the highest will be used. Example: - relation.uniq.count # => SELECT COUNT(DISTINCT *) + # last_reviewed_at will be used, if that's more recent than updated_at, or vice versa + Person.find(5).cache_key(:updated_at, :last_reviewed_at) - *Yves Senn + Kaspar Schiess* + *DHH* -* PostgreSQL ranges type support. Includes: int4range, int8range, - numrange, tsrange, tstzrange, daterange - - Ranges can be created with inclusive and exclusive bounds. +* Added `ActiveRecord::Base#enum` for declaring enum attributes where the values map to integers in the database, but can be queried by name. Example: - create_table :Room do |t| - t.daterange :availability + class Conversation < ActiveRecord::Base + enum status: [:active, :archived] end - Room.create(availability: (Date.today..Float::INFINITY)) - Room.first.availability # => Wed, 19 Sep 2012..Infinity - - One thing to note: Range class does not support exclusive lower - bound. - - *Alexander Grebennik* + Conversation::STATUS # => { active: 0, archived: 1 } -* Added a state instance variable to each transaction. Will allow other objects - to know whether a transaction has been committed or rolled back. + # conversation.update! status: 0 + conversation.active! + conversation.active? # => true + conversation.status # => "active" - *John Wang* + # conversation.update! status: 1 + conversation.archived! + conversation.archived? # => true + conversation.status # => "archived" -* Collection associations `#empty?` always respects built records. - Fixes #8879. + # conversation.update! status: 1 + conversation.status = :archived - Example: + *DHH* - widget = Widget.new - widget.things.build - widget.things.empty? # => false +* `ActiveRecord::Base#attribute_for_inspect` now truncates long arrays (more than 10 elements). - *Yves Senn* - -* Support for PostgreSQL's `ltree` data type. - - *Rob Worley* - -* Fix undefined method `to_i` when calling `new` on a scope that uses an - Array; Fix FloatDomainError when setting integer column to NaN. - Fixes #8718, #8734, #8757. - - *Jason Stirk + Tristan Harward* - -* Rename `update_attributes` to `update`, keep `update_attributes` as an alias for `update` method. - This is a soft-deprecation for `update_attributes`, although it will still work without any - deprecation message in 4.0 is recommended to start using `update` since `update_attributes` will be - deprecated and removed in future versions of Rails. - - *Amparo Luna + Guillermo Iguaran* - -* `after_commit` and `after_rollback` now validate the `:on` option and raise an `ArgumentError` - if it is not one of `:create`, `:destroy` or `:update` - - *Pascal Friederich* - -* Improve ways to write `change` migrations, making the old `up` & `down` methods no longer necessary. + *Jan Bernacki* - * The methods `drop_table` and `remove_column` are now reversible, as long as the necessary information is given. - The method `remove_column` used to accept multiple column names; instead use `remove_columns` (which is not reversible). - The method `change_table` is also reversible, as long as its block doesn't call `remove`, `change` or `change_default` +* Allow for the name of the `schema_migrations` table to be configured. - * New method `reversible` makes it possible to specify code to be run when migrating up or down. - See the [Guide on Migration](https://github.com/rails/rails/blob/master/guides/source/migrations.md#using-the-reversible-method) + *Jerad Phelps* - * New method `revert` will revert a whole migration or the given block. - If migrating down, the given migration / block is run normally. - See the [Guide on Migration](https://github.com/rails/rails/blob/master/guides/source/migrations.md#reverting-previous-migrations) +* Do not add to scope includes values from through associations. + Fixed bug when providing `includes` in through association scope, and fetching targets. - Attempting to revert the methods `execute`, `remove_columns` and `change_column` will now - raise an `IrreversibleMigration` instead of actually executing them without any output. + Example: - *Marc-André Lafortune* + class Vendor < ActiveRecord::Base + has_many :relationships, -> { includes(:user) } + has_many :users, through: :relationships + end -* Serialized attributes can be serialized in integer columns. - Fixes #8575. + vendor = Vendor.first - *Rafael Mendonça França* + # Before -* Keep index names when using `alter_table` with sqlite3. - Fixes #3489. + vendor.users.to_a # => Raises exception: not found `:user` for `User` - *Yves Senn* + # After -* Add ability for PostgreSQL adapter to disable user triggers in `disable_referential_integrity`. - Fixes #5523. + vendor.users.to_a # => No exception is raised - *Gary S. Weaver* + Fixes #12242, #9517, #10240. -* Added support for `validates_uniqueness_of` in PostgreSQL array columns. - Fixes #8075. + *Paul Nikitochkin* - *Pedro Padron* +* Type cast json values on write, so that the value is consistent + with reading from the database. -* Allow int4range and int8range columns to be created in PostgreSQL and properly convert to/from database. + Example: - *Alexey Vasiliev aka leopard* + x = JsonDataType.new tags: {"string" => "foo", :symbol => :bar} -* Do not log the binding values for binary columns. + # Before: + x.tags # => {"string" => "foo", :symbol => :bar} - *Matthew M. Boedicker* + # After: + x.tags # => {"string" => "foo", "symbol" => "bar"} -* Fix counter cache columns not updated when replacing `has_many :through` - associations. + *Severin Schoepke* - *Matthew Robertson* +* `ActiveRecord::Store` works together with PG `hstore` columns. -* Recognize migrations placed in directories containing numbers and 'rb'. - Fixes #8492. + Fixes #12452. *Yves Senn* -* Add `ActiveRecord::Base.cache_timestamp_format` class attribute to control - the format of the timestamp value in the cache key. Defaults to `:nsec`. - Fixes #8195. +* Fix bug where `ActiveRecord::Store` used a global `Hash` to keep track of + all registered `stored_attributes`. Now every subclass of + `ActiveRecord::Base` has it's own `Hash`. - *Rafael Mendonça França* - -* Session variables can be set for the `mysql`, `mysql2`, and `postgresql` adapters - in the `variables: <hash>` parameter in `config/database.yml`. The key-value pairs of this - hash will be sent in a `SET key = value` query on new database connections. See also: - http://dev.mysql.com/doc/refman/5.0/en/set-statement.html - http://www.postgresql.org/docs/8.3/static/sql-set.html - - *Aaron Stone* - -* Allow `Relation#where` with no arguments to be chained with new `not` query method. - - Example: - - Developer.where.not(name: 'Aaron') + *Yves Senn* - *Akira Matsuda* +* Save `has_one` association when primary key is manually set. -* Unscope `update_column(s)` query to ignore default scope. + Fixes #12302. - When applying `default_scope` to a class with a where clause, using - `update_column(s)` could generate a query that would not properly update - the record due to the where clause from the `default_scope` being applied - to the update query. + *Lauro Caetano* - class User < ActiveRecord::Base - default_scope -> { where(active: true) } - end +* Allow any version of BCrypt when using `has_secure_password`. - user = User.first - user.active = false - user.save! + *Mike Perham* - user.update_column(:active, true) # => false +* Sub-query generated for `Relation` passed as array condition did not take in account + bind values and have invalid syntax. - In this situation we want to skip the default_scope clause and just - update the record based on the primary key. With this change: + Generate sub-query with inline bind values. - user.update_column(:active, true) # => true + Fixes #12586. - Fixes #8436. + *Paul Nikitochkin* - *Carlos Antonio da Silva* +* Fix a bug where rake db:structure:load crashed when the path contained + spaces. -* SQLite adapter no longer corrupts binary data if the data contains `%00`. + *Kevin Mook* - *Chris Feist* +* `ActiveRecord::QueryMethods#unscope` unscopes negative equality -* Fix performance problem with `primary_key` method in PostgreSQL adapter when having many schemas. - Uses `pg_constraint` table instead of `pg_depend` table which has many records in general. - Fixes #8414. + Allows you to call `#unscope` on a relation with negative equality + operators, i.e. `Arel::Nodes::NotIn` and `Arel::Nodes::NotEqual` that have + been generated through the use of `where.not`. - *kennyj* + *Eric Hankins* -* Do not instantiate intermediate Active Record objects when eager loading. - These records caused `after_find` to run more than expected. - Fixes #3313. +* Raise an exception when model without primary key calls `.find_with_ids`. - *Yves Senn* + *Shimpei Makimoto* -* Add STI support to init and building associations. - Allows you to do `BaseClass.new(type: "SubClass")` as well as - `parent.children.build(type: "SubClass")` or `parent.build_child` - to initialize an STI subclass. Ensures that the class name is a - valid class and that it is in the ancestors of the super class - that the association is expecting. +* Make `Relation#empty?` use `exists?` instead of `count`. - *Jason Rush* + *Szymon Nowak* -* Observers was extracted from Active Record as `rails-observers` gem. +* `rake db:structure:dump` no longer crashes when the port was specified as `Fixnum`. - *Rafael Mendonça França* + *Kenta Okamoto* -* Ensure that associations take a symbol argument. *Steve Klabnik* +* `NullRelation#pluck` takes a list of columns -* Fix dirty attribute checks for `TimeZoneConversion` with nil and blank - datetime attributes. Setting a nil datetime to a blank string should not - result in a change being flagged. - Fixes #8310. + The method signature in `NullRelation` was updated to mimic that in + `Calculations`. - *Alisdair McDiarmid* + *Derek Prior* -* Prevent mass assignment to the type column of polymorphic associations when using `build` - Fixes #8265. +* `scope_chain` should not be mutated for other reflections. - *Yves Senn* + Currently `scope_chain` uses same array for building different + `scope_chain` for different associations. During processing + these arrays are sometimes mutated and because of in-place + mutation the changed `scope_chain` impacts other reflections. -* Deprecate calling `Relation#sum` with a block. To perform a calculation over - the array result of the relation, use `to_a.sum(&block)`. + Fix is to dup the value before adding to the `scope_chain`. - *Carlos Antonio da Silva* + Fixes #3882. -* Fix PostgreSQL adapter to handle BC timestamps correctly + *Neeraj Singh* - HistoryEvent.create!(name: "something", occured_at: Date.new(0) - 5.years) +* Prevent the inversed association from being reloaded on save. - *Bogdan Gusiev* + Fixes #9499. -* When running migrations on PostgreSQL, the `:limit` option for `binary` and `text` columns is silently dropped. - Previously, these migrations caused sql exceptions, because PostgreSQL doesn't support limits on these types. + *Dmitry Polushkin* - *Victor Costan* +* Generate subquery for `Relation` if it passed as array condition for `where` + method. -* Don't change STI type when calling `ActiveRecord::Base#becomes`. - Add `ActiveRecord::Base#becomes!` with the previous behavior. + Example: - See #3023 for more information. + # Before + Blog.where('id in (?)', Blog.where(id: 1)) + # => SELECT "blogs".* FROM "blogs" WHERE "blogs"."id" = 1 + # => SELECT "blogs".* FROM "blogs" WHERE (id IN (1)) - *Thomas Hollstegge* + # After + Blog.where('id in (?)', Blog.where(id: 1).select(:id)) + # => SELECT "blogs".* FROM "blogs" + # WHERE "blogs"."id" IN (SELECT "blogs"."id" FROM "blogs" WHERE "blogs"."id" = 1) -* `rename_index` can be used inside a `change_table` block. + Fixes #12415. - change_table :accounts do |t| - t.rename_index :user_id, :account_id - end + *Paul Nikitochkin* - *Jarek Radosz* +* For missed association exception message + which is raised in `ActiveRecord::Associations::Preloader` class + added owner record class name in order to simplify to find problem code. -* `#pluck` can be used on a relation with `select` clause. Fix #7551 + *Paul Nikitochkin* - Example: +* `has_and_belongs_to_many` is now transparently implemented in terms of + `has_many :through`. Behavior should remain the same, if not, it is a bug. - Topic.select([:approved, :id]).order(:id).pluck(:id) +* `create_savepoint`, `rollback_to_savepoint` and `release_savepoint` accept + a savepoint name. *Yves Senn* -* Do not create useless database transaction when building `has_one` association. - - Example: - - User.has_one :profile - User.new.build_profile - - *Bogdan Gusiev* - -* `:counter_cache` option for `has_many` associations to support custom named counter caches. - Fixes #7993. +* Make `next_migration_number` accessible for third party generators. *Yves Senn* -* Deprecate the possibility to pass a string as third argument of `add_index`. - Pass `unique: true` instead. - - add_index(:users, :organization_id, unique: true) +* Objects instantiated using a null relationship will now retain the + attributes of the where clause. - *Rafael Mendonça França* + Fixes #11676, #11675, #11376. -* Raise an `ArgumentError` when passing an invalid option to `add_index`. + *Paul Nikitochkin*, *Peter Brown*, *Nthalk* - *Rafael Mendonça França* +* Fixed `ActiveRecord::Associations::CollectionAssociation#find` + when using `has_many` association with `:inverse_of` and finding an array of one element, + it should return an array of one element too. -* Fix `find_in_batches` crashing when IDs are strings and start option is not specified. + *arthurnn* - *Alexis Bernard* +* Callbacks on has_many should access the in memory parent if a inverse_of is set. -* `AR::Base#attributes_before_type_cast` now returns unserialized values for serialized attributes. + *arthurnn* - *Nikita Afanasenko* +* `ActiveRecord::ConnectionAdapters.string_to_time` respects + string with timezone (e.g. Wed, 04 Sep 2013 20:30:00 JST). -* Use query cache/uncache when using `DATABASE_URL`. - Fixes #6951. + Fixes #12278. *kennyj* -* Fix bug where `update_columns` and `update_column` would not let you update the primary key column. - - *Henrik Nyh* +* Calling `update_attributes` will now throw an `ArgumentError` whenever it + gets a `nil` argument. More specifically, it will throw an error if the + argument that it gets passed does not respond to to `stringify_keys`. -* The `create_table` method raises an `ArgumentError` when the primary key column is redefined. - Fixes #6378. - - *Yves Senn* - -* `ActiveRecord::AttributeMethods#[]` raises `ActiveModel::MissingAttributeError` - error if the given attribute is missing. Fixes #5433. + Example: - class Person < ActiveRecord::Base - belongs_to :company - end + @my_comment.update_attributes(nil) # => raises ArgumentError - # Before: - person = Person.select('id').first - person[:name] # => nil - person.name # => ActiveModel::MissingAttributeError: missing_attribute: name - person[:company_id] # => nil - person.company # => nil + *John Wang* - # After: - person = Person.select('id').first - person[:name] # => ActiveModel::MissingAttributeError: missing_attribute: name - person.name # => ActiveModel::MissingAttributeError: missing_attribute: name - person[:company_id] # => ActiveModel::MissingAttributeError: missing_attribute: company_id - person.company # => ActiveModel::MissingAttributeError: missing_attribute: company_id +* Deprecate `quoted_locking_column` method, which isn't used anywhere. - *Francesco Rodriguez* + *kennyj* -* Small binary fields use the `VARBINARY` MySQL type, instead of `TINYBLOB`. +* Migration dump UUID default functions to schema.rb. - *Victor Costan* + Fixes #10751. -* Decode URI encoded attributes on database connection URLs. + *kennyj* - *Shawn Veader* +* Fixed a bug in `ActiveRecord::Associations::CollectionAssociation#find_by_scan` + when using `has_many` association with `:inverse_of` option and UUID primary key. -* Add `find_or_create_by`, `find_or_create_by!` and - `find_or_initialize_by` methods to `Relation`. + Fixes #10450. - These are similar to the `first_or_create` family of methods, but - the behaviour when a record is created is slightly different: + *kennyj* - User.where(first_name: 'Penélope').first_or_create +* Fix: joins association, with defined in the scope block constraints by using several + where constraints and at least of them is not `Arel::Nodes::Equality`, + generates invalid SQL expression. - will execute: + Fixes #11963. - User.where(first_name: 'Penélope').create + *Paul Nikitochkin* - Causing all the `create` callbacks to execute within the context of - the scope. This could affect queries that occur within callbacks. +* `CollectionAssociation#first`/`#last` (e.g. `has_many`) use a `LIMIT`ed + query to fetch results rather than loading the entire collection. - User.find_or_create_by(first_name: 'Penélope') + *Lann Martin* - will execute: +* Make possible to run SQLite rake tasks without the `Rails` constant defined. - User.create(first_name: 'Penélope') + *Damien Mathieu* - Which obviously does not affect the scoping of queries within - callbacks. +* Allow Relation#from to accept other relations with bind values. - The `find_or_create_by` version also reads better, frankly. + *Ryan Wallace* - If you need to add extra attributes during create, you can do one of: +* Fix inserts with prepared statements disabled. - User.create_with(active: true).find_or_create_by(first_name: 'Jon') - User.find_or_create_by(first_name: 'Jon') { |u| u.active = true } + Fixes #12023. - The `first_or_create` family of methods have been nodoc'ed in favour - of this API. They may be deprecated in the future but their - implementation is very small and it's probably not worth putting users - through lots of annoying deprecation warnings. + *Rafael Mendonça França* - *Jon Leighton* +* Setting a has_one association on a new record no longer causes an empty + transaction. -* Fix bug with presence validation of associations. Would incorrectly add duplicated errors - when the association was blank. Bug introduced in 1fab518c6a75dac5773654646eb724a59741bc13. + *Dylan Thacker-Smith* - *Scott Willson* +* Fix `AR::Relation#merge` sometimes failing to preserve `readonly(false)` flag. -* Fix bug where sum(expression) returns string '0' for no matching records. - Fixes #7439 + *thedarkone* - *Tim Macfarlane* +* Re-use `order` argument pre-processing for `reorder`. -* PostgreSQL adapter correctly fetches default values when using multiple schemas and domains in a db. Fixes #7914 + *Paul Nikitochkin* - *Arturo Pie* +* Fix PredicateBuilder so polymorphic association keys in `where` clause can + accept objects other than direct descendants of `ActiveRecord::Base` (decorated + models, for example). -* Learn ActiveRecord::QueryMethods#order work with hash arguments + *Mikhail Dieterle* - When symbol or hash passed we convert it to Arel::Nodes::Ordering. - If we pass invalid direction(like name: :DeSc) ActiveRecord::QueryMethods#order will raise an exception +* PostgreSQL adapter recognizes negative money values formatted with + parentheses (eg. `($1.25) # => -1.25`)). + Fixes #11899. - User.order(:name, email: :desc) - # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC + *Yves Senn* - *Tima Maslyuchenko* +* Stop interpreting SQL 'string' columns as :string type because there is no + common STRING datatype in SQL. -* Rename `ActiveRecord::Fixtures` class to `ActiveRecord::FixtureSet`. - Instances of this class normally hold a collection of fixtures (records) - loaded either from a single YAML file, or from a file and a folder - with the same name. This change make the class name singular and makes - the class easier to distinguish from the modules like - `ActiveRecord::TestFixtures`, which operates on multiple fixture sets, - or `DelegatingFixtures`, `::Fixtures`, etc., - and from the class `ActiveRecord::Fixture`, which corresponds to a single - fixture. + *Ben Woosley* - *Alexey Muranov* +* `ActiveRecord::FinderMethods#exists?` returns `true`/`false` in all cases. -* The postgres adapter now supports tables with capital letters. - Fixes #5920. + *Xavier Noria* - *Yves Senn* +* Assign inet/cidr attribute with `nil` value for invalid address. -* `CollectionAssociation#count` returns `0` without querying if the - parent record is not persisted. + Example: - Before: + record = User.new + record.logged_in_from_ip # is type of an inet or a cidr - person.pets.count - # SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" IS NULL - # => 0 + # Before: + record.logged_in_from_ip = 'bad ip address' # raise exception - After: + # After: + record.logged_in_from_ip = 'bad ip address' # do not raise exception + record.logged_in_from_ip # => nil + record.logged_in_from_ip_before_type_cast # => 'bad ip address' - person.pets.count - # fires without sql query - # => 0 + *Paul Nikitochkin* - *Francesco Rodriguez* +* `add_to_target` now accepts a second optional `skip_callbacks` argument -* Fix `reset_counters` crashing on `has_many :through` associations. - Fixes #7822. + If truthy, it will skip the :before_add and :after_add callbacks. - *lulalala* + *Ben Woosley* -* Support for partial inserts. +* Fix interactions between `:before_add` callbacks and nested attributes + assignment of `has_many` associations, when the association was not + yet loaded: - When inserting new records, only the fields which have been changed - from the defaults will actually be included in the INSERT statement. - The other fields will be populated by the database. + - A `:before_add` callback was being called when a nested attributes + assignment assigned to an existing record. - This is more efficient, and also means that it will be safe to - remove database columns without getting subsequent errors in running - app processes (so long as the code in those processes doesn't - contain any references to the removed column). + - Nested Attributes assignment did not affect the record in the + association target when a `:before_add` callback triggered the + loading of the association - The `partial_updates` configuration option is now renamed to - `partial_writes` to reflect the fact that it now impacts both inserts - and updates. + *Jörg Schray* - *Jon Leighton* +* Allow enable_extension migration method to be revertible. -* Allow before and after validations to take an array of lifecycle events + *Eric Tipton* - *John Foley* +* Type cast hstore values on write, so that the value is consistent + with reading from the database. -* Support for specifying transaction isolation level + Example: - If your database supports setting the isolation level for a transaction, you can set - it like so: + x = Hstore.new tags: {"bool" => true, "number" => 5} - Post.transaction(isolation: :serializable) do - # ... - end + # Before: + x.tags # => {"bool" => true, "number" => 5} - Valid isolation levels are: + # After: + x.tags # => {"bool" => "true", "number" => "5"} - * `:read_uncommitted` - * `:read_committed` - * `:repeatable_read` - * `:serializable` + *Yves Senn* , *Severin Schoepke* - You should consult the documentation for your database to understand the - semantics of these different levels: +* Fix multidimensional PG arrays containing non-string items. - * http://www.postgresql.org/docs/9.1/static/transaction-iso.html - * https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html + *Yves Senn* - An `ActiveRecord::TransactionIsolationError` will be raised if: +* Fixes bug when using includes combined with select, the select statement was overwritten. - * The adapter does not support setting the isolation level - * You are joining an existing open transaction - * You are creating a nested (savepoint) transaction + Fixes #11773. - The mysql, mysql2 and postgresql adapters support setting the transaction - isolation level. However, support is disabled for mysql versions below 5, - because they are affected by a bug (http://bugs.mysql.com/bug.php?id=39170) - which means the isolation level gets persisted outside the transaction. + *Edo Balvers* - *Jon Leighton* +* Load fixtures from linked folders. -* `ActiveModel::ForbiddenAttributesProtection` is included by default - in Active Record models. Check the docs of `ActiveModel::ForbiddenAttributesProtection` - for more details. + *Kassio Borges* - *Guillermo Iguaran* +* Create a directory for sqlite3 file if not present on the system. -* Remove integration between Active Record and - `ActiveModel::MassAssignmentSecurity`, `protected_attributes` gem - should be added to use `attr_accessible`/`attr_protected`. Mass - assignment options has been removed from all the AR methods that - used it (ex. `AR::Base.new`, `AR::Base.create`, `AR::Base#update_attributes`, etc). + *Richard Schneeman* - *Guillermo Iguaran* +* Removed redundant override of `xml` column definition for PG, + in order to use `xml` column type instead of `text`. -* Fix the return of querying with an empty hash. - Fixes #6971. + *Paul Nikitochkin*, *Michael Nikitochkin* - User.where(token: {}) +* Revert `ActiveRecord::Relation#order` change that make new order + prepend the old one. Before: - #=> SELECT * FROM users; + User.order("name asc").order("created_at desc") + # SELECT * FROM users ORDER BY created_at desc, name asc After: - #=> SELECT * FROM users WHERE 1=0; - - *Damien Mathieu* - -* Fix creation of through association models when using `collection=[]` - on a `has_many :through` association from an unsaved model. - Fixes #7661. - - *Ernie Miller* - -* Explain only normal CRUD sql (select / update / insert / delete). - Fix problem that explains unexplainable sql. - Closes #7544 #6458. - - *kennyj* - -* You can now override the generated accessor methods for stored attributes - and reuse the original behavior with `read_store_attribute` and `write_store_attribute`, - which are counterparts to `read_attribute` and `write_attribute`. - - *Matt Jones* - -* Accept `belongs_to` (including polymorphic) association keys in queries. - - The following queries are now equivalent: - - Post.where(author: author) - Post.where(author_id: author) - - PriceEstimate.where(estimate_of: treasure) - PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure) - - *Peter Brown* - -* Use native `mysqldump` command instead of `structure_dump` method - when dumping the database structure to a sql file. Fixes #5547. - - *kennyj* - -* PostgreSQL inet and cidr types are converted to `IPAddr` objects. - - *Dan McClain* + User.order("name asc").order("created_at desc") + # SELECT * FROM users ORDER BY name asc, created_at desc -* PostgreSQL array type support. Any datatype can be used to create an - array column, with full migration and schema dumper support. + This also affects order defined in `default_scope` or any kind of associations. - To declare an array column, use the following syntax: +* Add ability to define how a class is converted to Arel predicates. + For example, adding a very vendor specific regex implementation: - create_table :table_with_arrays do |t| - t.integer :int_array, array: true - # integer[] - t.integer :int_array, array: true, length: 2 - # smallint[] - t.string :string_array, array: true, length: 30 - # char varying(30)[] + regex_handler = proc do |column, value| + Arel::Nodes::InfixOperation.new('~', column, value.source) end + ActiveRecord::PredicateBuilder.register_handler(Regexp, regex_handler) - This respects any other migration detail (limits, defaults, etc). - Active Record will serialize and deserialize the array columns on - their way to and from the database. - - One thing to note: PostgreSQL does not enforce any limits on the - number of elements, and any array can be multi-dimensional. Any - array that is multi-dimensional must be rectangular (each sub array - must have the same number of elements as its siblings). + *Sean Griffin & @joannecheng* - If the `pg_array_parser` gem is available, it will be used when - parsing PostgreSQL's array representation. +* Don't allow `quote_value` to be called without a column. - *Dan McClain* + Some adapters require column information to do their job properly. + By enforcing the provision of the column for this internal method + we ensure that those using adapters that require column information + will always get the proper behavior. -* Attribute predicate methods, such as `article.title?`, will now raise - `ActiveModel::MissingAttributeError` if the attribute being queried for - truthiness was not read from the database, instead of just returning `false`. + *Ben Woosley* - *Ernie Miller* +* When using optimistic locking, `update` was not passing the column to `quote_value` + to allow the connection adapter to properly determine how to quote the value. This was + affecting certain databases that use specific column types. -* `ActiveRecord::SchemaDumper` uses Ruby 1.9 style hash, which means that the - schema.rb file will be generated using this new syntax from now on. + Fixes #6763. - *Konstantin Shabanov* + *Alfred Wong* -* Map interval with precision to string datatype in PostgreSQL. Fixes #7518. +* rescue from all exceptions in `ConnectionManagement#call` - *Yves Senn* - -* Fix eagerly loading associations without primary keys. Fixes #4976. + Fixes #11497. - *Kelley Reynolds* + As `ActiveRecord::ConnectionAdapters::ConnectionManagement` middleware does + not rescue from Exception (but only from StandardError), the Connection + Pool quickly runs out of connections when multiple erroneous Requests come + in right after each other. -* Rails now raise an exception when you're trying to run a migration that has an invalid - file name. Only lower case letters, numbers, and '_' are allowed in migration's file name. - Please see #7419 for more details. + Rescuing from all exceptions and not just StandardError, fixes this + behaviour. - *Jan Bernacki* - -* Fix bug when calling `store_accessor` multiple times. - Fixes #7532. - - *Matt Jones* - -* Fix store attributes that show the changes incorrectly. - Fixes #7532. - - *Matt Jones* - -* Fix `ActiveRecord::Relation#pluck` when columns or tables are reserved words. - - *Ian Lesperance* - -* Allow JSON columns to be created in PostgreSQL and properly encoded/decoded. - to/from database. - - *Dickson S. Guedes* - -* Fix time column type casting for invalid time string values to correctly return `nil`. + *Vipul A M* - *Adam Meehan* +* `change_column` for PostgreSQL adapter respects the `:array` option. -* Allow to pass Symbol or Proc into `:limit` option of #accepts_nested_attributes_for. + *Yves Senn* - *Mikhail Dieterle* +* Remove deprecation warning from `attribute_missing` for attributes that are columns. -* ActiveRecord::SessionStore has been extracted from Active Record as `activerecord-session_store` - gem. Please read the `README.md` file on the gem for the usage. + *Arun Agrawal* - *Prem Sichanugrist* +* Remove extra decrement of transaction deep level. -* Fix `reset_counters` when there are multiple `belongs_to` association with the - same foreign key and one of them have a counter cache. - Fixes #5200. + Fixes #4566. - *Dave Desrochers* + *Paul Nikitochkin* -* `serialized_attributes` and `_attr_readonly` become class method only. Instance reader methods are deprecated. +* Reset @column_defaults when assigning `locking_column`. + We had a potential problem. For example: - *kennyj* + class Post < ActiveRecord::Base + self.column_defaults # if we call this unintentionally before setting locking_column ... + self.locking_column = 'my_locking_column' + end -* Round usec when comparing timestamp attributes in the dirty tracking. - Fixes #6975. + Post.column_defaults["my_locking_column"] + => nil # expected value is 0 ! *kennyj* -* Use inversed parent for first and last child of `has_many` association. - - *Ravil Bayramgalin* +* Remove extra select and update queries on save/touch/destroy ActiveRecord model + with belongs to reflection with option `touch: true`. -* Fix `Column.microseconds` and `Column.fast_string_to_time` to avoid converting - timestamp seconds to a float, since it occasionally results in inaccuracies - with microsecond-precision times. Fixes #7352. + Fixes #11288. - *Ari Pollak* + *Paul Nikitochkin* -* Fix AR#dup to nullify the validation errors in the dup'ed object. Previously the original - and the dup'ed object shared the same errors. +* Remove deprecated nil-passing to the following `SchemaCache` methods: + `primary_keys`, `tables`, `columns` and `columns_hash`. - *Christian Seiler* + *Yves Senn* -* Raise `ArgumentError` if list of attributes to change is empty in `update_all`. +* Remove deprecated block filter from `ActiveRecord::Migrator#migrate`. - *Roman Shatsov* + *Yves Senn* -* Fix AR#create to return an unsaved record when AR::RecordInvalid is - raised. Fixes #3217. +* Remove deprecated String constructor from `ActiveRecord::Migrator`. - *Dave Yeu* + *Yves Senn* -* Fixed table name prefix that is generated in engines for namespaced models. +* Remove deprecated `scope` use without passing a callable object. - *Wojciech Wnętrzak* + *Arun Agrawal* -* Make sure `:environment` task is executed before `db:schema:load` or `db:structure:load`. - Fixes #4772. +* Remove deprecated `transaction_joinable=` in favor of `begin_transaction` + with `:joinable` option. - *Seamus Abshere* + *Arun Agrawal* -* Allow Relation#merge to take a proc. +* Remove deprecated `decrement_open_transactions`. - This was requested by DHH to allow creating of one's own custom - association macros. + *Arun Agrawal* - For example: +* Remove deprecated `increment_open_transactions`. - module Commentable - def has_many_comments(extra) - has_many :comments, -> { where(:foo).merge(extra) } - end - end + *Arun Agrawal* - class Post < ActiveRecord::Base - extend Commentable - has_many_comments -> { where(:bar) } - end +* Remove deprecated `PostgreSQLAdapter#outside_transaction?` + method. You can use `#transaction_open?` instead. - *Jon Leighton* + *Yves Senn* -* Add CollectionProxy#scope. +* Remove deprecated `ActiveRecord::Fixtures.find_table_name` in favor of + `ActiveRecord::Fixtures.default_fixture_model_name`. - This can be used to get a Relation from an association. + *Vipul A M* - Previously we had a #scoped method, but we're deprecating that for - AR::Base, so it doesn't make sense to have it here. +* Removed deprecated `columns_for_remove` from `SchemaStatements`. - This was requested by DHH, to facilitate code like this: + *Neeraj Singh* - Project.scope.order('created_at DESC').page(current_page).tagged_with(@tag).limit(5).scoping do - @topics = @project.topics.scope - @todolists = @project.todolists.scope - @attachments = @project.attachments.scope - @documents = @project.documents.scope - end +* Remove deprecated `SchemaStatements#distinct`. - *Jon Leighton* + *Francesco Rodriguez* -* Add `Relation#load`. +* Move deprecated `ActiveRecord::TestCase` into the rails test + suite. The class is no longer public and is only used for internal + Rails tests. - This method explicitly loads the records and then returns `self`. + *Yves Senn* - Rather than deciding between "do I want an array or a relation?", - most people are actually asking themselves "do I want to eager load - or lazy load?" Therefore, this method provides a way to explicitly - eager-load without having to switch from a `Relation` to an array. +* Removed support for deprecated option `:restrict` for `:dependent` + in associations. - Example: + *Neeraj Singh* - @posts = Post.where(published: true).load +* Removed support for deprecated `delete_sql` in associations. - *Jon Leighton* + *Neeraj Singh* -* `Relation#order`: make new order prepend old one. +* Removed support for deprecated `insert_sql` in associations. - User.order("name asc").order("created_at desc") - # SELECT * FROM users ORDER BY created_at desc, name asc + *Neeraj Singh* - This also affects order defined in `default_scope` or any kind of associations. +* Removed support for deprecated `finder_sql` in associations. - *Bogdan Gusiev* + *Neeraj Singh* -* `Model.all` now returns an `ActiveRecord::Relation`, rather than an - array of records. Use `Relation#to_a` if you really want an array. +* Support array as root element in JSON fields. - In some specific cases, this may cause breakage when upgrading. - However in most cases the `ActiveRecord::Relation` will just act as a - lazy-loaded array and there will be no problems. + *Alexey Noskov & Francesco Rodriguez* - Note that calling `Model.all` with options (e.g. - `Model.all(conditions: '...')` was already deprecated, but it will - still return an array in order to make the transition easier. +* Removed support for deprecated `counter_sql` in associations. - `Model.scoped` is deprecated in favour of `Model.all`. + *Neeraj Singh* - `Relation#all` still returns an array, but is deprecated (since it - would serve no purpose if we made it return a `Relation`). +* Do not invoke callbacks when `delete_all` is called on collection. - *Jon Leighton* + Method `delete_all` should not be invoking callbacks and this + feature was deprecated in Rails 4.0. This is being removed. + `delete_all` will continue to honor the `:dependent` option. However + if `:dependent` value is `:destroy` then the `:delete_all` deletion + strategy for that collection will be applied. -* `:finder_sql` and `:counter_sql` options on collection associations - are deprecated. Please transition to using scopes. + User can also force a deletion strategy by passing parameter to + `delete_all`. For example you can do `@post.comments.delete_all(:nullify)`. - *Jon Leighton* + *Neeraj Singh* -* `:insert_sql` and `:delete_sql` options on `has_and_belongs_to_many` - associations are deprecated. Please transition to using `has_many - :through`. +* Calling default_scope without a proc will now raise `ArgumentError`. - *Jon Leighton* + *Neeraj Singh* -* Added `#update_columns` method which updates the attributes from - the passed-in hash without calling save, hence skipping validations and - callbacks. `ActiveRecordError` will be raised when called on new objects - or when at least one of the attributes is marked as read only. +* Removed deprecated method `type_cast_code` from Column. - post.attributes # => {"id"=>2, "title"=>"My title", "body"=>"My content", "author"=>"Peter"} - post.update_columns(title: 'New title', author: 'Sebastian') # => true - post.attributes # => {"id"=>2, "title"=>"New title", "body"=>"My content", "author"=>"Sebastian"} + *Neeraj Singh* - *Sebastian Martinez + Rafael Mendonça França* +* Removed deprecated options `delete_sql` and `insert_sql` from HABTM + association. -* The migration generator now creates a join table with (commented) indexes every time - the migration name contains the word `join_table`: + Removed deprecated options `finder_sql` and `counter_sql` from + collection association. - rails g migration create_join_table_for_artists_and_musics artist_id:index music_id + *Neeraj Singh* - *Aleksey Magusev* +* Remove deprecated `ActiveRecord::Base#connection` method. + Make sure to access it via the class. -* Add `add_reference` and `remove_reference` schema statements. Aliases, `add_belongs_to` - and `remove_belongs_to` are acceptable. References are reversible. + *Yves Senn* - Examples: +* Remove deprecation warning for `auto_explain_threshold_in_seconds`. - # Create a user_id column - add_reference(:products, :user) - # Create a supplier_id, supplier_type columns and appropriate index - add_reference(:products, :supplier, polymorphic: true, index: true) - # Remove polymorphic reference - remove_reference(:products, :supplier, polymorphic: true) + *Yves Senn* - *Aleksey Magusev* +* Remove deprecated `:distinct` option from `Relation#count`. -* Add `:default` and `:null` options to `column_exists?`. + *Yves Senn* - column_exists?(:testings, :taggable_id, :integer, null: false) - column_exists?(:testings, :taggable_type, :string, default: 'Photo') +* Removed deprecated methods `partial_updates`, `partial_updates?` and + `partial_updates=`. - *Aleksey Magusev* + *Neeraj Singh* -* `ActiveRecord::Relation#inspect` now makes it clear that you are - dealing with a `Relation` object rather than an array:. +* Removed deprecated method `scoped`. - User.where(age: 30).inspect - # => <ActiveRecord::Relation [#<User ...>, #<User ...>, ...]> + *Neeraj Singh* - User.where(age: 30).to_a.inspect - # => [#<User ...>, #<User ...>] +* Removed deprecated method `default_scopes?`. - The number of records displayed will be limited to 10. + *Neeraj Singh* - *Brian Cardarella, Jon Leighton & Damien Mathieu* +* Remove implicit join references that were deprecated in 4.0. -* Add `collation` and `ctype` support to PostgreSQL. These are available for PostgreSQL 8.4 or later. Example: - development: - adapter: postgresql - host: localhost - database: rails_development - username: foo - password: bar - encoding: UTF8 - collation: ja_JP.UTF8 - ctype: ja_JP.UTF8 - - *kennyj* - -* Changed `validates_presence_of` on an association so that children objects - do not validate as being present if they are marked for destruction. This - prevents you from saving the parent successfully and thus putting the parent - in an invalid state. - - *Nick Monje & Brent Wheeldon* + # before with implicit joins + Comment.where('posts.author_id' => 7) -* `FinderMethods#exists?` now returns `false` with the `false` argument. + # after + Comment.references(:posts).where('posts.author_id' => 7) - *Egor Lynko* + *Yves Senn* -* Added support for specifying the precision of a timestamp in the PostgreSQL - adapter. So, instead of having to incorrectly specify the precision using the - `:limit` option, you may use `:precision`, as intended. For example, in a migration: +* Apply default scope when joining associations. For example: - def change - create_table :foobars do |t| - t.timestamps precision: 0 - end + class Post < ActiveRecord::Base + default_scope -> { where published: true } end - *Tony Schneider* - -* Allow `ActiveRecord::Relation#pluck` to accept multiple columns. Returns an - array of arrays containing the typecasted values: - - Person.pluck(:id, :name) - # SELECT people.id, people.name FROM people - # [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] - - *Jeroen van Ingen & Carlos Antonio da Silva* - -* Improve the derivation of HABTM join table name to take account of nesting. - It now takes the table names of the two models, sorts them lexically and - then joins them, stripping any common prefix from the second table name. - - Some examples: - - Top level models (Category <=> Product) - Old: categories_products - New: categories_products - - Top level models with a global table_name_prefix (Category <=> Product) - Old: site_categories_products - New: site_categories_products - - Nested models in a module without a table_name_prefix method (Admin::Category <=> Admin::Product) - Old: categories_products - New: categories_products - - Nested models in a module with a table_name_prefix method (Admin::Category <=> Admin::Product) - Old: categories_products - New: admin_categories_products - - Nested models in a parent model (Catalog::Category <=> Catalog::Product) - Old: categories_products - New: catalog_categories_products - - Nested models in different parent models (Catalog::Category <=> Content::Page) - Old: categories_pages - New: catalog_categories_content_pages - - *Andrew White* - -* Move HABTM validity checks to `ActiveRecord::Reflection`. One side effect of - this is to move when the exceptions are raised from the point of declaration - to when the association is built. This is consistent with other association - validity checks. + class Comment + belongs_to :post + end - *Andrew White* + When calling `Comment.joins(:post)`, we expect to receive only + comments on published posts, since that is the default scope for + posts. -* Added `stored_attributes` hash which contains the attributes stored using - `ActiveRecord::Store`. This allows you to retrieve the list of attributes - you've defined. + Before this change, the default scope from `Post` was not applied, + so we'd get comments on unpublished posts. - class User < ActiveRecord::Base - store :settings, accessors: [:color, :homepage] - end + *Jon Leighton* - User.stored_attributes[:settings] # [:color, :homepage] +* Remove `activerecord-deprecated_finders` as a dependency. - *Joost Baaij & Carlos Antonio da Silva* + *Łukasz Strzałkowski* -* PostgreSQL default log level is now 'warning', to bypass the noisy notice - messages. You can change the log level using the `min_messages` option - available in your config/database.yml. +* Remove Oracle / Sqlserver / Firebird database tasks that were deprecated in 4.0. *kennyj* -* Add uuid datatype support to PostgreSQL adapter. - - *Konstantin Shabanov* - -* Added `ActiveRecord::Migration.check_pending!` that raises an error if - migrations are pending. - - *Richard Schneeman* - -* Added `#destroy!` which acts like `#destroy` but will raise an - `ActiveRecord::RecordNotDestroyed` exception instead of returning `false`. - - *Marc-André Lafortune* +* `find_each` now returns an `Enumerator` when called without a block, so that it + can be chained with other `Enumerable` methods. -* Added support to `CollectionAssociation#delete` for passing `fixnum` - or `string` values as record ids. This finds the records responding - to the `id` and executes delete on them. + *Ben Woosley* - class Person < ActiveRecord::Base - has_many :pets - end +* `ActiveRecord::Result.each` now returns an `Enumerator` when called without + a block, so that it can be chained with other `Enumerable` methods. - person.pets.delete("1") # => [#<Pet id: 1>] - person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>] + *Ben Woosley* - *Francesco Rodriguez* +* Flatten merged join_values before building the joins. -* Deprecated most of the 'dynamic finder' methods. All dynamic methods - except for `find_by_...` and `find_by_...!` are deprecated. Here's - how you can rewrite the code: + While joining_values special treatment is given to string values. + By flattening the array it ensures that string values are detected + as strings and not arrays. - * `find_all_by_...` can be rewritten using `where(...)` - * `find_last_by_...` can be rewritten using `where(...).last` - * `scoped_by_...` can be rewritten using `where(...)` - * `find_or_initialize_by_...` can be rewritten using - `where(...).first_or_initialize` - * `find_or_create_by_...` can be rewritten using - `find_or_create_by(...)` or where(...).first_or_create` - * `find_or_create_by_...!` can be rewritten using - `find_or_create_by!(...) or `where(...).first_or_create!` + Fixes #10669. - The implementation of the deprecated dynamic finders has been moved - to the `activerecord-deprecated_finders` gem. See below for details. + *Neeraj Singh and iwiznia* - *Jon Leighton* +* Do not load all child records for inverse case. -* Deprecated the old-style hash based finder API. This means that - methods which previously accepted "finder options" no longer do. For - example this: + currently `post.comments.find(Comment.first.id)` would load all + comments for the given post to set the inverse association. - Post.find(:all, conditions: { comments_count: 10 }, limit: 5) + This has a huge performance penalty. Because if post has 100k + records and all these 100k records would be loaded in memory + even though the comment id was supplied. - Should be rewritten in the new style which has existed since Rails 3: + Fix is to use in-memory records only if loaded? is true. Otherwise + load the records using full sql. - Post.where(comments_count: 10).limit(5) + Fixes #10509. - Note that as an interim step, it is possible to rewrite the above as: + *Neeraj Singh* - Post.all.merge(where: { comments_count: 10 }, limit: 5) +* `inspect` on Active Record model classes does not initiate a + new connection. This means that calling `inspect`, when the + database is missing, will no longer raise an exception. + Fixes #10936. - This could save you a lot of work if there is a lot of old-style - finder usage in your application. + Example: - `Relation#merge` now accepts a hash of - options, but they must be identical to the names of the equivalent - finder method. These are mostly identical to the old-style finder - option names, except in the following cases: + Author.inspect # => "Author(no database connection)" - * `:conditions` becomes `:where`. - * `:include` becomes `:includes`. + *Yves Senn* - The code to implement the deprecated features has been moved out to the - `activerecord-deprecated_finders` gem. This gem is a dependency of Active - Record in Rails 4.0, so the interface works out of the box. It will no - longer be a dependency from Rails 4.1 (you'll need to add it to the - `Gemfile` in 4.1), and will be maintained until Rails 5.0. +* Handle single quotes in PostgreSQL default column values. + Fixes #10881. - *Jon Leighton* + *Dylan Markow* -* It's not possible anymore to destroy a model marked as read only. +* Log the sql that is actually sent to the database. - *Johannes Barre* + If I have a query that produces sql + `WHERE "users"."name" = 'a b'` then in the log all the + whitespace is being squeezed. So the sql that is printed in the + log is `WHERE "users"."name" = 'a b'`. -* Added ability to ActiveRecord::Relation#from to accept other ActiveRecord::Relation objects. + Do not squeeze whitespace out of sql queries. Fixes #10982. - Record.from(subquery) - Record.from(subquery, :a) + *Neeraj Singh* - *Radoslav Stankov* +* Fixture setup no longer depends on `ActiveRecord::Base.configurations`. + This is relevant when `ENV["DATABASE_URL"]` is used in place of a `database.yml`. -* Added custom coders support for ActiveRecord::Store. Now you can set - your custom coder like this: + *Yves Senn* - store :settings, accessors: [ :color, :homepage ], coder: JSON +* Fix mysql2 adapter raises the correct exception when executing a query on a + closed connection. - *Andrey Voronkov* + *Yves Senn* -* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by - default to avoid silent data loss. This can be disabled by specifying - `strict: false` in your `database.yml`. +* Ambiguous reflections are on :through relationships are no longer supported. + For example, you need to change this: - *Michael Pearson* + class Author < ActiveRecord::Base + has_many :posts + has_many :taggings, through: :posts + end -* Added default order to `first` to assure consistent results among - different database engines. Introduced `take` as a replacement to - the old behavior of `first`. + class Post < ActiveRecord::Base + has_one :tagging + has_many :taggings + end - *Marcelo Silveira* + class Tagging < ActiveRecord::Base + end -* Added an `:index` option to automatically create indexes for references - and belongs_to statements in migrations. + To this: - The `references` and `belongs_to` methods now support an `index` - option that receives either a boolean value or an options hash - that is identical to options available to the add_index method: + class Author < ActiveRecord::Base + has_many :posts + has_many :taggings, through: :posts, source: :tagging + end - create_table :messages do |t| - t.references :person, index: true - end + class Post < ActiveRecord::Base + has_one :tagging + has_many :taggings + end - Is the same as: + class Tagging < ActiveRecord::Base + end - create_table :messages do |t| - t.references :person - end - add_index :messages, :person_id + *Aaron Patterson* - Generators have also been updated to use the new syntax. +* Remove column restrictions for `count`, let the database raise if the SQL is + invalid. The previous behavior was untested and surprising for the user. + Fixes #5554. - *Joshua Wood* + Example: -* Added `#find_by` and `#find_by!` to mirror the functionality - provided by dynamic finders in a way that allows dynamic input more - easily: + User.select("name, username").count + # Before => SELECT count(*) FROM users + # After => ActiveRecord::StatementInvalid - Post.find_by name: 'Spartacus', rating: 4 - Post.find_by "published_at < ?", 2.weeks.ago - Post.find_by! name: 'Spartacus' + # you can still use `count(:all)` to perform a query unrelated to the + # selected columns + User.select("name, username").count(:all) # => SELECT count(*) FROM users - *Jon Leighton* + *Yves Senn* -* Added ActiveRecord::Base#slice to return a hash of the given methods with - their names as keys and returned values as values. +* Rails now automatically detects inverse associations. If you do not set the + `:inverse_of` option on the association, then Active Record will guess the + inverse association based on heuristics. - *Guillermo Iguaran* + Note that automatic inverse detection only works on `has_many`, `has_one`, + and `belongs_to` associations. Extra options on the associations will + also prevent the association's inverse from being found automatically. -* Deprecate eager-evaluated scopes. + The automatic guessing of the inverse association uses a heuristic based + on the name of the class, so it may not work for all associations, + especially the ones with non-standard names. - Don't use this: + You can turn off the automatic detection of inverse associations by setting + the `:inverse_of` option to `false` like so: - scope :red, where(color: 'red') - default_scope where(color: 'red') + class Taggable < ActiveRecord::Base + belongs_to :tag, inverse_of: false + end - Use this: + *John Wang* - scope :red, -> { where(color: 'red') } - default_scope { where(color: 'red') } +* Fix `add_column` with `array` option when using PostgreSQL. Fixes #10432 - The former has numerous issues. It is a common newbie gotcha to do - the following: + *Adam Anderson* - scope :recent, where(published_at: Time.now - 2.weeks) +* Usage of `implicit_readonly` is being removed`. Please use `readonly` method + explicitly to mark records as `readonly. + Fixes #10615. - Or a more subtle variant: + Example: - scope :recent, -> { where(published_at: Time.now - 2.weeks) } - scope :recent_red, recent.where(color: 'red') + user = User.joins(:todos).select("users.*, todos.title as todos_title").readonly(true).first + user.todos_title = 'clean pet' + user.save! # will raise error - Eager scopes are also very complex to implement within Active - Record, and there are still bugs. For example, the following does - not do what you expect: + *Yves Senn* - scope :remove_conditions, except(:where) - where(...).remove_conditions # => still has conditions +* Fix the `:primary_key` option for `has_many` associations. + Fixes #10693. - *Jon Leighton* + *Yves Senn* -* Remove IdentityMap +* Fix bug where tiny types are incorrectly coerced as boolean when the length is more than 1. - IdentityMap has never graduated to be an "enabled-by-default" feature, due - to some inconsistencies with associations, as described in this commit: + Fixes #10620. - https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6 + *Aaron Patterson* - Hence the removal from the codebase, until such issues are fixed. +* Also support extensions in PostgreSQL 9.1. This feature has been supported since 9.1. - *Carlos Antonio da Silva* + *kennyj* -* Added the schema cache dump feature. +* Deprecate `ConnectionAdapters::SchemaStatements#distinct`, + as it is no longer used by internals. - `Schema cache dump` feature was implemented. This feature can dump/load internal state of `SchemaCache` instance - because we want to boot rails more quickly when we have many models. + *Ben Woosley* - Usage notes: +* Fix pending migrations error when loading schema and `ActiveRecord::Base.table_name_prefix` + is not blank. - 1) execute rake task. - RAILS_ENV=production bundle exec rake db:schema:cache:dump - => generate db/schema_cache.dump + Call `assume_migrated_upto_version` on connection to prevent it from first + being picked up in `method_missing`. - 2) add config.active_record.use_schema_cache_dump = true in config/production.rb. BTW, true is default. + In the base class, `Migration`, `method_missing` expects the argument to be a + table name, and calls `proper_table_name` on the arguments before sending to + `connection`. If `table_name_prefix` or `table_name_suffix` is used, the schema + version changes to `prefix_version_suffix`, breaking `rake test:prepare`. - 3) boot rails. - RAILS_ENV=production bundle exec rails server - => use db/schema_cache.dump + Fixes #10411. - 4) If you remove clear dumped cache, execute rake task. - RAILS_ENV=production bundle exec rake db:schema:cache:clear - => remove db/schema_cache.dump + *Kyle Stevens* - *kennyj* +* Method `read_attribute_before_type_cast` should accept input as symbol. -* Added support for partial indices to PostgreSQL adapter. + *Neeraj Singh* - The `add_index` method now supports a `where` option that receives a - string with the partial index criteria. +* Confirm a record has not already been destroyed before decrementing counter cache. - add_index(:accounts, :code, where: 'active') + *Ben Tucker* - generates +* Fixed a bug in `ActiveRecord#sanitize_sql_hash_for_conditions` in which + `self.class` is an argument to `PredicateBuilder#build_from_hash` + causing `PredicateBuilder` to call non-existent method + `Class#reflect_on_association`. - CREATE INDEX index_accounts_on_code ON accounts(code) WHERE active + *Zach Ohlgren* - *Marcelo Silveira* +* While removing index if column option is missing then raise IrreversibleMigration exception. -* Implemented `ActiveRecord::Relation#none` method. + Following code should raise `IrreversibleMigration`. But the code was + failing since options is an array and not a hash. - The `none` method returns a chainable relation with zero records - (an instance of the NullRelation class). + def change + change_table :users do |t| + t.remove_index [:name, :email] + end + end - Any subsequent condition chained to the returned relation will continue - generating an empty relation and will not fire any query to the database. + Fix was to check if the options is a Hash before operating on it. - *Juanjo Bazán* + Fixes #10419. -* Added the `ActiveRecord::NullRelation` class implementing the null - object pattern for the Relation class. + *Neeraj Singh* - *Juanjo Bazán* +* Do not overwrite manually built records during one-to-one nested attribute assignment -* Added new `dependent: :restrict_with_error` option. This will add - an error to the model, rather than raising an exception. + For one-to-one nested associations, if you build the new (in-memory) + child object yourself before assignment, then the NestedAttributes + module will not overwrite it, e.g.: - The `:restrict` option is renamed to `:restrict_with_exception` to - make this distinction explicit. + class Member < ActiveRecord::Base + has_one :avatar + accepts_nested_attributes_for :avatar - *Manoj Kumar & Jon Leighton* + def avatar + super || build_avatar(width: 200) + end + end -* Added `create_join_table` migration helper to create HABTM join tables. + member = Member.new + member.avatar_attributes = {icon: 'sad'} + member.avatar.width # => 200 - create_join_table :products, :categories - # => - # create_table :categories_products, id: false do |td| - # td.integer :product_id, null: false - # td.integer :category_id, null: false - # end + *Olek Janiszewski* - *Rafael Mendonça França* +* fixes bug introduced by #3329. Now, when autosaving associations, + deletions happen before inserts and saves. This prevents a 'duplicate + unique value' database error that would occur if a record being created had + the same value on a unique indexed field as that of a record being destroyed. -* The primary key is always initialized in the @attributes hash to `nil` (unless - another value has been specified). + *Johnny Holton* - *Aaron Paterson* +* Handle aliased attributes in ActiveRecord::Relation. -* In previous releases, the following would generate a single query with - an `OUTER JOIN comments`, rather than two separate queries: + When using symbol keys, ActiveRecord will now translate aliased attribute names to the actual column name used in the database: - Post.includes(:comments) - .where("comments.name = 'foo'") + With the model - This behaviour relies on matching SQL string, which is an inherently - flawed idea unless we write an SQL parser, which we do not wish to - do. + class Topic + alias_attribute :heading, :title + end - Therefore, it is now deprecated. + The call - To avoid deprecation warnings and for future compatibility, you must - explicitly state which tables you reference, when using SQL snippets: + Topic.where(heading: 'The First Topic') - Post.includes(:comments) - .where("comments.name = 'foo'") - .references(:comments) + should yield the same result as - Note that you do not need to explicitly specify references in the - following cases, as they can be automatically inferred: + Topic.where(title: 'The First Topic') - Post.includes(:comments).where(comments: { name: 'foo' }) - Post.includes(:comments).where('comments.name' => 'foo') - Post.includes(:comments).order('comments.name') + This also applies to ActiveRecord::Relation::Calculations calls such as `Model.sum(:aliased)` and `Model.pluck(:aliased)`. - You do not need to worry about this unless you are doing eager - loading. Basically, don't worry unless you see a deprecation warning - or (in future releases) an SQL error due to a missing JOIN. + This will not work with SQL fragment strings like `Model.sum('DISTINCT aliased')`. - *Jon Leighton* + *Godfrey Chan* -* Support for the `schema_info` table has been dropped. Please - switch to `schema_migrations`. +* Mute `psql` output when running rake db:schema:load. - *Aaron Patterson* + *Godfrey Chan* -* Connections *must* be closed at the end of a thread. If not, your - connection pool can fill and an exception will be raised. +* Trigger a save on `has_one association=(associate)` when the associate contents have changed. - *Aaron Patterson* + Fix #8856. -* PostgreSQL hstore records can be created. + *Chris Thompson* - *Aaron Patterson* +* Abort a rake task when missing db/structure.sql like `db:schema:load` task. -* PostgreSQL hstore types are automatically deserialized from the database. + *kennyj* - *Aaron Patterson* +* rake:db:test:prepare falls back to original environment after execution. + *Slava Markevich* -Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/activerecord/CHANGELOG.md) for previous changes. +Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/activerecord/CHANGELOG.md) for previous changes. |