aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/CHANGELOG.md
Commit message (Collapse)AuthorAgeFilesLines
...
* | | Merge pull request #27561 from fishbrain/count-all-in-has-many-associationRyuta Kamizono2018-01-031-0/+5
|\ \ \ | | | | | | | | | | | | Use `count(:all)` in HasManyAssociation#count_records
| * | | Use `count(:all)` in HasManyAssociation#count_recordsKlas Eskilson2017-02-071-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Calling `count` on an association can cause invalid SQL queries to be created where the `SELECT COUNT(a, b, c)` function receives multiple columns. This will cause a `StatementInvalid` exception later on. Solution: Use `count(:all)`, which generates a `SELECT COUNT(*)...` query independently of the association. This also includes a test case that, before the fix, broke.
* | | | Merge pull request #27780 from ↵Ryuta Kamizono2017-12-251-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | mikelikesbikes/fix-update-attribute-callbacks-issue save attributes changed by callbacks after update_attribute
* | | | Remove verbose_query_logs from new_framework_defaults_5_2.rbEugene Kenny2017-12-201-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The `app:update` rake task will regenerate `development.rb` so that it contains this option; that means we're currently adding it to existing apps in two places, which is unnecessary and confusing. Also: - Remove inaccurate comment about which stack frames are ignored - Clarify that the feature uses `caller_locations`, not `caller` - Remove unused return value in `extract_callstack`
* | | | Fix `count(:all)` to correctly work `distinct` with custom SELECT listRyuta Kamizono2017-12-201-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently `count(:all)` with `distinct` doesn't work correctly because SELECT list is always replaced to `*` or primary key in that case even if having custom SELECT list. And also, PostgreSQL has a limitation that ORDER BY expressions must appear in select list for SELECT DISTINCT. Therefore, we should not replace custom SELECT list when using `count(:all)` with `distinct`. Closes #31277.
* | | | Using subselect for `delete_all` with `limit` or `offset`Ryuta Kamizono2017-12-191-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | Arel doesn't support subselect generation for DELETE unlike UPDATE yet, but we already have that generation in connection adapters. We can simply use the subselect generated by that one.
* | | | Add changelog entry for e1ceb10Chris Salzberg2017-12-171-0/+5
| | | |
* | | | Log call site for all queriesOlivier Lacan2017-12-131-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This new ActiveRecord configuration option allows you to easily pinpoint what line of application code is triggering SQL queries in the development log by appending below each SQL statement log the line of Ruby code that triggered it. It’s useful with N+1 issues, and to locate stray queries. By default this new option ignores Rails and Ruby code in order to surface only callers from your application Ruby code or your gems. It is enabled on newly generated Rails 5.2 applications and can be enabled on existing Rails applications: ```ruby Rails.application.configure do # ... config.active_record.verbose_query_logs = true end ``` The `rails app:upgrade` task will also add it to `config/development.rb`. This feature purposely avoids coupling with ActiveSupport::BacktraceCleaner since ActiveRecord can be used without ActiveRecord. This decision can be reverted in the future to allow more configurable backtraces (the exclusion of gem callers for example).
* | | | Fix conflicts `counter_cache` with `touch: true` by optimistic locking.bogdanvlviv2017-12-121-0/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ``` # create_table :posts do |t| # t.integer :comments_count, default: 0 # t.integer :lock_version # t.timestamps # end class Post < ApplicationRecord end # create_table :comments do |t| # t.belongs_to :post # end class Comment < ApplicationRecord belongs_to :post, touch: true, counter_cache: true end ``` Before: ``` post = Post.create! # => begin transaction INSERT INTO "posts" ("created_at", "updated_at", "lock_version") VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0) commit transaction comment = Comment.create!(post: post) # => begin transaction INSERT INTO "comments" ("post_id") VALUES (1) UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1, "lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1 UPDATE "posts" SET "updated_at" = '2017-12-11 21:27:11.398330', "lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0 rollback transaction # => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post. Comment.take.destroy! # => begin transaction DELETE FROM "comments" WHERE "comments"."id" = 1 UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1, "lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1 UPDATE "posts" SET "updated_at" = '2017-12-11 21:42:47.785901', "lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0 rollback transaction # => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post. ``` After: ``` post = Post.create! # => begin transaction INSERT INTO "posts" ("created_at", "updated_at", "lock_version") VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0) commit transaction comment = Comment.create!(post: post) # => begin transaction INSERT INTO "comments" ("post_id") VALUES (1) UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2017-12-11 21:37:09.802642' WHERE "posts"."id" = 1 commit transaction comment.destroy! # => begin transaction DELETE FROM "comments" WHERE "comments"."id" = 1 UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2017-12-11 21:39:02.685520' WHERE "posts"."id" = 1 commit transaction ``` Fixes #31199.
* | | | Tweaks CHANGELOGs [ci skip]Ryuta Kamizono2017-12-011-2/+2
| | | |
* | | | Add support for PostgreSQL operator classes to add_indexGreg Navis2017-11-301-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add support for specifying non-default operator classes in PostgreSQL indexes. An example CREATE INDEX query that becomes possible is: CREATE INDEX users_name ON users USING gist (name gist_trgm_ops); Previously it was possible to specify the `gist` index but not the custom operator class. The `add_index` call for the above query is: add_index :users, :name, using: :gist, opclasses: {name: :gist_trgm_ops}
* | | | Merge pull request #31179 from kinnrot/scoping-reserved-namesRafael Mendonça França2017-11-281-0/+7
|\ \ \ \ | | | | | | | | | | | | | | | Scoping reserved names
| * | | | Prevent scope named same as a ActiveRecord::Relation instance method.Chen Kinnrot2017-11-281-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Due to inconsistent behavior when chaining scopes and one scope named after a Relation method Validation code added in 2 places: - scope, to prevent problematic scope names. - enum, cause it tries to auto define scope.
* | | | | Preparing for 5.2.0.beta2 releaseRafael Mendonça França2017-11-281-0/+5
|/ / / /
* | | | Preparing for 5.2.0.beta1 releaseRafael Mendonça França2017-11-271-0/+2
| | | |
* | | | Add new error class `QueryCanceled` which will be raised when canceling ↵Ryuta Kamizono2017-11-271-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | statement due to user request (#31235) This changes `StatementTimeout` to `QueryCanceled` for PostgreSQL. In MySQL, errno 1317 (`ER_QUERY_INTERRUPTED`) is only used when the query is manually cancelled. But in PostgreSQL, `QUERY_CANCELED` error code (57014) which is used `StatementTimeout` is also used when the both case. And, we can not tell which reason happened. So I decided to introduce new error class `QueryCanceled` closer to the error code name.
* | | | Rename `TransactionTimeout` to more descriptive `LockWaitTimeout` (#31223)Ryuta Kamizono2017-11-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | Since #31129, new error class `StatementTimeout` has been added. `TransactionTimeout` is caused by the timeout shorter than `StatementTimeout`, but its name is too generic. I think that it should be a name that understands the difference with `StatementTimeout`.
* | | | Fix typo s/only_up/up_only/ [ci skip]Ryuta Kamizono2017-11-151-1/+1
| | | |
* | | | Add a #populate method to migrations (#31082)Rich2017-11-141-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add a #populate method to migrations * Address rubocop issues * Rename to #up_only and use #execute in the examples intead of the model * Update CHANGELOG [Rich Daley & Rafael Mendonça França]
* | | | Merge pull request #27947 from mastahyeti/unsafe_raw_sqlMatthew Draper2017-11-141-0/+30
|\ \ \ \ | | | | | | | | | | | | | | | Disallow raw SQL in dangerous AR methods
* | | | | Properly cast input in `update_all`Sean Griffin2017-11-131-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The documentation claims that given values go through "normal AR type casting and serialization", which to me implies `serialize(cast(value))`, not just serialization. The docs were changed to use this wording in #22492. The tests I cited in that PR (which is the same test modified in this commit), is worded in a way that implies it should be using `cast` as well. It's possible that I originally meant "normal type casting" to imply just the call to `serialize`, but given that `update_all(archived: params['archived'])` seems to be pretty common, I'm inclined to make this change as long as no tests are broken from it.
* | | | | Add new error class `StatementTimeout` which will be raised when statement ↵Ryuta Kamizono2017-11-131-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | timeout exceeded (#31129) We are sometimes using The MAX_EXECUTION_TIME hint for MySQL depending on the situation. It will prevent catastrophic performance down by wrong performing queries. The new error class `StatementTimeout` will make to be easier to handle that case. https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
* | | | | Raise `TransactionTimeout` when lock wait timeout exceeded for PG adapterRyuta Kamizono2017-11-111-2/+2
|/ / / / | | | | | | | | | | | | Follow up of #30360.
* | | | Fix `bin/rails db:migrate` with specified `VERSION`bogdanvlviv2017-11-061-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | Ensure that `bin/rails db:migrate` with specified `VERSION` reverts all migrations only if `VERSION` is `0`. Raise error if target migration doesn't exist.
* | | | Remove CHANGELOG entry for PR #28681 [ci skip]Prathamesh Sonpatki2017-10-271-4/+0
| | | | | | | | | | | | | | | | | | | | - It is present in Rails 5.1.3 already. - Backport commit https://github.com/rails/rails/commit/9efa0b70a638dcfdc05b30ab530f89f2847bb9c2
* | | | Save index order :desc to schema.rb (sqlite). Fixes #30902Paul Kuruvilla2017-10-241-0/+7
| | | | | | | | | | | | | | | | | | | | Although the sqlite adapter supports index sort orders, they weren't being written to db/schema.rb.
* | | | Remove deprecated method `#sanitize_conditions`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated methd `#scope_chain`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated configuration `.error_on_ignored_order_or_limit`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated arguments from `#verify!`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated argument `name` from `#indexes`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated method `ActiveRecord::Migrator.schema_migrations_table_name`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated method `supports_primary_key?`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated method `supports_migrations?`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated methods `initialize_schema_migrations_table` and ↵Rafael Mendonça França2017-10-231-0/+4
| | | | | | | | | | | | | | | | `initialize_internal_metadata_table`
* | | | Rase when calling `lock!` in a dirty recordRafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated support to passing a class to `:class_name` on associationsRafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated argument `default` from `index_name_exists?`Rafael Mendonça França2017-10-231-0/+4
| | | |
* | | | Remove deprecated support to `quoted_id` when typecasting an Active Record ↵Rafael Mendonça França2017-10-231-0/+4
| | | | | | | | | | | | | | | | object
* | | | Fix `bin/rails db:setup` and `bin/rails db:test:prepare` create wrong ↵bogdanvlviv2017-10-151-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ar_internal_metadata's data for a test database. Before: ``` $ RAILS_ENV=test rails dbconsole > SELECT * FROM ar_internal_metadata; key|value|created_at|updated_at environment|development|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679 ``` After: ``` $ RAILS_ENV=test rails dbconsole > SELECT * FROM ar_internal_metadata; key|value|created_at|updated_at environment|test|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679 ``` Fixes #26731.
* | | | Fix longer sequence name detection for serial columns (#28339)Ryuta Kamizono2017-10-151-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We already found the longer sequence name, but we could not consider whether it was the sequence name created by serial type due to missed a max identifier length limitation. I've addressed the sequence name consideration to respect the max identifier length. Fixes #28332.
* | | | MySQL: Don't lose `auto_increment: true` in the `db/schema.rb`Ryuta Kamizono2017-10-151-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently `AUTO_INCREMENT` is implicitly used in the default primary key definition. But `AUTO_INCREMENT` is not only used for single column primary key, but also for composite primary key. In that case, `auto_increment: true` should be dumped explicitly in the `db/schema.rb`. Fixes #30894.
* | | | Fix `COUNT(DISTINCT ...)` for `GROUP BY` with `ORDER BY` and `LIMIT`Ryuta Kamizono2017-10-141-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the fix for the regression of #29848. In #29848, I've kept existing select list in the subquery for the count if ORDER BY is given. But it had accidentally affect to GROUP BY queries also. It should keep the previous behavior in that case. Fixes #30886.
* | | | Cleanup CHANGELOGs [ci skip]Ryuta Kamizono2017-10-041-11/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add missing credit * Add backticks * Fix indentation * Remove trailing spaces And some minor tweaks.
* | | | `Postgres::OID::Range` serializes to a `Range`, quote in `Quoting`Thomas Cannon2017-09-261-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PostgreSQL 9.1+ introduced range types, and Rails added support for using this datatype in ActiveRecord. However, the serialization of `PostgreSQL::OID::Range` was incomplete, because it did not properly quote the bounds that make up the range. A clear example of this is a `tsrange`. Normally, ActiveRecord quotes Date/Time objects to include the milliseconds. However, the way `PostgreSQL::OID::Range` serialized its bounds, the milliseconds were dropped. This meant that the value was incomplete and not equal to the submitted value. An example of normal timestamps vs. a `tsrange`. Note how the bounds for the range do not include their milliseconds (they were present in the ruby Range): UPDATE "iterations" SET "updated_at" = $1, "range" = $2 WHERE "iterations"."id" = $3 [["updated_at", "2017-09-23 17:07:01.304864"], ["range", "[2017-09-23 00:00:00 UTC,2017-09-23 23:59:59 UTC]"], ["id", 1234]] `PostgreSQL::OID::Range` serialized the range by interpolating a string for the range, which works for most cases, but does not work for timestamps: def serialize(value) if value.is_a?(::Range) from = type_cast_single_for_database(value.begin) to = type_cast_single_for_database(value.end) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" else super end end (byebug) from = type_cast_single_for_database(value.begin) 2010-01-01 13:30:00 UTC (byebug) to = type_cast_single_for_database(value.end) 2011-02-02 19:30:00 UTC (byebug) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" "[2010-01-01 13:30:00 UTC,2011-02-02 19:30:00 UTC)" @sgrif (the original implementer for Postgres Range support) provided some feedback about where the quoting should occur: Yeah, quoting at all is definitely wrong here. I'm not sure what I was thinking in 02579b5, but what this is doing is definitely in the wrong place. It should probably just be returning a range of subtype.serialize(value.begin) and subtype.serialize(value.end), and letting the adapter handle the rest. `Postgres::OID::Range` now returns a `Range` object, and `ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting` can now encode and quote a `Range`: def encode_range(range) "[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}" end ... encode_range(range) #=> "['2010-01-01 13:30:00.670277','2011-02-02 19:30:00.745125')" This commit includes tests to make sure the milliseconds are preserved in `tsrange` and `tstzrange` columns
* | | | Treat `Set` as an `Array` in `Relation#where`Sean Griffin2017-09-261-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I do not want to set the expectation that any enumerable object should behave this way, but this case in particular comes up frequently enough that I'm caving on this one. Fixes #30684.
* | | | Use algorithm while removing index with db:rollbackMehmet Emin İNAÇ2017-09-211-0/+6
| | | | | | | | | | | | | | | | Closes #24190
* | | | Update payload names for `sql.active_record` to be more descriptive.Jeremy Green2017-09-201-0/+7
| | | | | | | | | | | | | | | | Fixes #30586.
* | | | Added CHANGELOG for #30360 [ci skip]Prathamesh Sonpatki2017-08-281-0/+5
| | | |
* | | | Remove deprecated `#migration_keys`Ryuta Kamizono2017-08-221-0/+4
| | | |