aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/CHANGELOG.md
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/CHANGELOG.md')
-rw-r--r--activerecord/CHANGELOG.md2198
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.