aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation.rb
Commit message (Collapse)AuthorAgeFilesLines
* Refactor `bind_attribute` to expand an association to actual attributeRyuta Kamizono2019-01-111-0/+5
|
* #create_or_find_by/!: add more tests and fix docs (#34653)Bogdan2018-12-081-2/+2
| | | | | | | | * `#create_or_find_by/!`: add more tests * Fix docs of `create_or_find_by` This method uses `find_by!` internally.
* Move UPDATE/DELETE with JOIN handling to the Arel sideRyuta Kamizono2018-10-031-26/+12
|
* Handle UPDATE/DELETE with OFFSET in ArelRyuta Kamizono2018-10-011-2/+4
|
* Handle DELETE with LIMIT in ArelRyuta Kamizono2018-09-301-1/+4
| | | | | | | | | | | | | | | | | | MySQL supports DELETE with LIMIT and ORDER BY. https://dev.mysql.com/doc/refman/8.0/en/delete.html Before: ``` Post Destroy (1.0ms) DELETE FROM `posts` WHERE `posts`.`id` IN (SELECT `id` FROM (SELECT `posts`.`id` FROM `posts` WHERE `posts`.`author_id` = ? ORDER BY `posts`.`id` ASC LIMIT ?) __active_record_temp) [["author_id", 1], ["LIMIT", 1]] ``` After: ``` Post Destroy (0.4ms) DELETE FROM `posts` WHERE `posts`.`author_id` = ? ORDER BY `posts`.`id` ASC LIMIT ? [["author_id", 1], ["LIMIT", 1]] ```
* Extract `Arel.arel_node?` helper methodRyuta Kamizono2018-09-281-1/+1
|
* Make `update_counters` preparableRyuta Kamizono2018-09-281-9/+14
| | | | | | | | | | | | | | | | Before: ``` Topic Update All (0.4ms) UPDATE `topics` SET `topics`.`replies_count` = COALESCE(`topics`.`replies_count`, 0) + 1, `topics`.`updated_at` = '2018-09-27 18:34:05.068774' WHERE `topics`.`id` = ? [["id", 7]] ``` After: ``` Topic Update All (0.4ms) UPDATE `topics` SET `topics`.`replies_count` = COALESCE(`topics`.`replies_count`, 0) + ?, `topics`.`updated_at` = ? WHERE `topics`.`id` = ? [["replies_count", 1], ["updated_at", 2018-09-27 18:55:05 UTC], ["id", 7]] ```
* Make `update_all` preparableRyuta Kamizono2018-09-281-2/+14
| | | | | | | | | | | | | | Before: ``` Pet Update All (0.8ms) UPDATE `pets` LEFT OUTER JOIN `toys` ON `toys`.`pet_id` = `pets`.`pet_id` SET `pets`.`name` = 'Bob' WHERE `toys`.`name` = ? [["name", "Bone"]] ``` After: ``` Pet Update All (1.1ms) UPDATE `pets` LEFT OUTER JOIN `toys` ON `toys`.`pet_id` = `pets`.`pet_id` SET `pets`.`name` = ? WHERE `toys`.`name` = ? [["name", "Bob"], ["name", "Bone"]] ```
* Use table name qualified column name for update countersRyuta Kamizono2018-09-161-9/+7
| | | | | | | | | MySQL supports JOINs to UPDATE, so if column name isn't qualified by table name, it would cause an ambiguous error: ``` Mysql2::Error: Column 'integer' in field list is ambiguous: UPDATE `pets` INNER JOIN `toys` ON `toys`.`pet_id` = `pets`.`pet_id` SET `integer` = COALESCE(`integer`, 0) + 1 WHERE `toys`.`name` = ? ```
* Refactor object creation from relation to avoid pushing scope attributesRyuta Kamizono2018-09-111-24/+3
| | | | | | Pushing scope attributes was added at d4007d5 for fixing inheritance object creation. But it was not a better fix, since we could just pull that on demand in `Inheritance` module.
* Move `scoping` handling into klass level from relationRyuta Kamizono2018-09-111-4/+1
| | | | | I'd like to use this `scoping` handling on klass level to address unwanted internal scoping issues.
* Fixes #33610Darwin D Wu2018-09-111-7/+18
| | | | | | | | | | | | In order to avoid double assignments of nested_attributes for `has_many` relations during record initialization, nested_attributes in `create_with` should not be passed into `klass.new` and have them populate during `initialize_internals_callback` with scope attributes. However, `create_with` keys should always have precedence over where clauses, so if there are same keys in both `create_with` and `where_values_hash`, the value in `create_with` should be the one that's used.
* Just delegate `update` with ids on a relation to `klass.update`Ryuta Kamizono2018-08-311-2/+6
| | | | | | | | | | | | This restores an ability that `update` with ids on a relation which is described at https://github.com/rails/rails/issues/33470#issuecomment-411203013. I personally think that the `update` with two arguments on a relation is not a designed feature, since that is totally not using a relation state, and also is not documented. But removing any feature should not be suddenly happened in a stable version even if that is not documented.
* Avoid extra scoping when using `Relation#update`Ryuta Kamizono2018-07-311-0/+4
| | | | | | | | | | | | | | Since 9ac7dd4, class level `update`, `destroy`, and `delete` were placed in the `Persistence` module as class methods. But `Relation#update` without passing ids which was introduced at #11898 is not a class method, and it was caused the extra scoping regression #33470. I moved the relation method back into the `Relation` to fix the regression. Fixes #33470.
* Extract `Relation#bind_attribute` for internal useRyuta Kamizono2018-07-301-0/+6
| | | | To make it easier to construct boundable predicate.
* Extract `Relation#update_counters` for internal useRyuta Kamizono2018-07-301-0/+18
| | | | | | The target object for counter cache is not always determined by the primary key value on the model. I'd like to extract `update_couters` onto the `Relation` for the internal use.
* Rails guides are now served over httpsPaul McMahon2018-07-241-1/+1
| | | | | http links will be redirected to the https version, but still better to just directly link to the https version.
* Avoid extra scoping in delegating to klass methods in the `scope` blockRyuta Kamizono2018-07-191-2/+2
| | | | | | | | | | Since #29301, delegating to klass methods in the `scope` block would cause extra scoping by the receiver itself. The extra scoping would always override intermediate scoping like `unscoped` and caused the regression #33387. To keep the original scoping behavior, should avoid the extra scoping in the `scope` block. Fixes #33387.
* Ensure to calculate column aliases after all table aliases are constructedRyuta Kamizono2018-06-191-11/+11
| | | | | | | | | | | | | | | | | Currently, column aliases which is used for eager loading are calculated before constructing all table aliases in FROM clause. `JoinDependency#join_constraints` constructs table aliases for `joins` first, and then always re-constructs table aliases for eager loading. If both `joins` and eager loading are given a same table association, the re-construction would cause the discrepancy between column aliases and table aliases. To avoid the discrepancy, the column aliases should be calculated after all table aliases are constructed. Fixes #30603.
* Fix `touch` option to behave consistently with `Persistence#touch` methodRyuta Kamizono2018-06-181-4/+1
| | | | | | | | | | | | | | | | `touch` option was added to `increment!` (#27660) and `update_counters` (#26995). But that option behaves inconsistently with `Persistence#touch` method. If `touch` option is passed attribute names, it won't update update_at/on attributes unlike `Persistence#touch` method. Due to changed from `Persistence#touch` to `increment!` with `touch` option, #31405 has a regression that `counter_cache` with `touch` option which is passed attribute names won't update update_at/on attributes. I think that the inconsistency is not intended. To get back consistency, ensure that `touch` option updates update_at/on attributes.
* Fix typo in the `touch_all` doc [ci skip]Ryuta Kamizono2018-04-211-4/+4
|
* Merge pull request #31513 from fatkodima/relation-touch_allRafael França2018-04-201-0/+37
|\ | | | | Add `touch_all` method to `ActiveRecord::Relation`
| * Add `touch_all` method to `ActiveRecord::Relation`fatkodima2018-04-131-0/+37
| |
* | Don't expose `Relation#preload_associations` in the docRyuta Kamizono2018-04-201-1/+1
|/ | | | | | | The extracted method is used for `CollectionCacheAssociationLoading`, still not public API. [ci skip]
* don't check for immutability when setting skip_preloading as it doesn't ↵Lachlan Sylvester2018-04-121-2/+3
| | | | effect the arel and the arel may already be generated by fresh_when
* Deprecate accessibility of private/protected class methods in named scopeRyuta Kamizono2018-03-301-0/+2
|
* Bring back private class methods accessibility in named scopeRyuta Kamizono2018-03-271-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The receiver in a scope was changed from `klass` to `relation` itself for all scopes (named scope, default_scope, and association scope) behaves consistently. In addition. Before 5.2, if both an AR model class and a Relation instance have same named methods (e.g. `arel_attribute`, `predicate_builder`, etc), named scope doesn't respect relation instance information. For example: ```ruby class Post < ActiveRecord::Base has_many :comments1, class_name: "RecentComment1" has_many :comments2, class_name: "RecentComment2" end class RecentComment1 < ActiveRecord::Base self.table_name = "comments" default_scope { where(arel_attribute(:created_at).gteq(2.weeks.ago)) } end class RecentComment2 < ActiveRecord::Base self.table_name = "comments" default_scope { recent_updated } scope :recent_updated, -> { where(arel_attribute(:updated_at).gteq(2.weeks.ago)) } end ``` If eager loading `Post.eager_load(:comments1, :comments2).to_a`, `:comments1` (default_scope) respects aliased table name, but `:comments2` (using named scope) may not work correctly since named scope doesn't respect relation instance information. See also 801ccab. But this is a breaking change between releases without deprecation. I decided to bring back private class methods accessibility in named scope. Fixes #31740. Fixes #32331.
* Only preload misses on multifetch cacheLachlan Sylvester2018-03-061-8/+13
|
* Add #create_or_find_by to lean on unique constraints (#31989)David Heinemeier Hansson2018-02-141-12/+42
| | | Add #create_or_find_by to lean on unique constraints
* Rdoc formatting fix: <b> instead of MD-style asterisksT.J. Schuck2018-02-141-1/+1
| | | | [ci skip]
* Avoid passing unnecessary arguments to relationDaniel Colson2018-01-241-1/+1
| | | | | | | | | | | | Most of the time the table and predicate_builder passed to Relation.new are exactly the arel_table and predicate builder of the given klass. This uses klass.arel_table and klass.predicate_builder as the defaults, so we don't have to pass them in most cases. This does change the signaure of both Relation and AssocationRelation. Are we ok with that?
* Use `apply_join_dependency` instead of meaningless named ↵Ryuta Kamizono2018-01-111-2/+2
| | | | | | | | | | `find_with_associations` `find_with_associations` is meaningless name in this point since it just contain `construct_join_dependency` and `apply_join_dependency`, does not contain finding anything. If `apply_join_dependency` returns `relation` and `join_dependency` then `find_with_associations` is no longer needed.
* Using subselect for `delete_all` with `limit` or `offset`Ryuta Kamizono2017-12-191-4/+4
| | | | | | 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.
* Using subselect generated by the connection adapter for `update_all` with ↵Ryuta Kamizono2017-12-191-1/+1
| | | | | | | | | | | `offset` Most RDBMS (except SQLite) requires subselect for UPDATE with OFFSET, but Arel doesn't support executable subselect generation for MySQL's UPDATE yet. We need to use the subselect generated by the connection adapter for now, it works well. Fixes #30148.
* Fix inheritance object creation from relationRyuta Kamizono2017-12-131-8/+18
| | | | | | | | | | We need to pass scope attributes to `klass.new` to detect subclass. Otherwise `subclass_from_attributes` can't detect subclass which is had in scope attributes. Fixes #18062. Closes #18227. Closes #30720.
* Make `sanitize_sql_` methods publicyuuji.yaginuma2017-12-131-1/+1
| | | | | | | | Currently, sanitize methods are private. So need `send` to use from outside class. However, sometimes want to use sanitize methods from outside Class when want to generate SQL including multiple tables like search. In order to avoid using `send` in such a case, changed methods to public.
* Revert "Merge pull request #31006 from ↵eileencodes2017-11-261-1/+0
| | | | | | | | | | | rails/kamipo/ordinal_methods_should_respect_loaded_records" This reverts commit 0f79ab91150b4cdb6c018530978a3395962c7a02, reversing changes made to d575f7f2e737739302a0e8210d01c10f5d4e2c35. This PR philosophically conflicts with #30800 and Matthew thinks we should hold off merging this until we find concensus. Reverting since we're about to cut a release for 5.2.
* Merge pull request #31006 from ↵Eileen M. Uchitelle2017-11-251-0/+1
|\ | | | | | | | | rails/kamipo/ordinal_methods_should_respect_loaded_records Ordinal methods should respect loaded records
| * Ordinal methods should respect loaded recordsRyuta Kamizono2017-10-281-0/+1
| | | | | | | | | | | | We should reset partially loaded `@offsets` cache when latest records has loaded because the cache has been staled and it may not be consistent with latest records.
* | Avoid creating extra `relation` and `build_arel` in `_create_record` and ↵Ryuta Kamizono2017-11-171-61/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `_update_record` (#29999) Currently `_create_record` and `_update_record` in `Persistence` are creating extra `unscoped` and calling `build_arel` in the relation. But `compile_insert` and `compile_update` can be done without those expensive operation for `SelectManager` creation. So I moved the implementation to `Persistence` to avoid creating extra relation and refactored to avoid calling `build_arel`. https://gist.github.com/kamipo/8ed73d760112cfa5f6263c9413633419 Before: ``` Warming up -------------------------------------- _update_record 150.000 i/100ms Calculating ------------------------------------- _update_record 1.548k (±12.3%) i/s - 7.650k in 5.042603s ``` After: ``` Warming up -------------------------------------- _update_record 201.000 i/100ms Calculating ------------------------------------- _update_record 2.002k (±12.8%) i/s - 9.849k in 5.027681s ``` 30% faster for STI classes.
* | Consolidate duplicated `to_ary`/`to_a` definitions in `Relation` and ↵Ryuta Kamizono2017-11-101-1/+2
| | | | | | | | `CollectionProxy`
* | Ensure `apply_join_dependency` for `update_all` and `delete_all` if ↵Ryuta Kamizono2017-11-061-0/+10
|/ | | | | | | | | | eager-loading is needed If a relation has eager-loading values, `count` and `exists?` works properly, but `update_all` and `delete_all` doesn't work due to missing `apply_join_dependency`. It should be applied to work consistently. Fixes #28863.
* Joined tables in association scope doesn't use the same aliases with the ↵Ryuta Kamizono2017-10-091-1/+2
| | | | | | | | | parent relation's aliases Building association scope in join dependency should respect the parent relation's aliases to avoid using the same alias name more than once. Fixes #30681.
* Decouple building `AliasTracker` from `JoinDependency`Ryuta Kamizono2017-10-081-0/+4
| | | | | This is preparation to respect parent relation's alias tracking for fixing #30681.
* Merge pull request #30619 from ↵Eileen M. Uchitelle2017-09-201-4/+4
|\ | | | | | | | | jagthedrummer/jeremy/instrumentation-payload-names Update payload names for `sql.active_record` instrumentation to be more descriptive.
| * Update payload names for `sql.active_record` to be more descriptive.Jeremy Green2017-09-201-4/+4
| | | | | | | | Fixes #30586.
* | Place class level `update`, `destroy`, and `delete` in ↵Ryuta Kamizono2017-09-181-94/+0
|/ | | | | | | | | | `Persistence::ClassMethods` The docs are obviously for class level `update`, `destroy`, and `delete`. It should be placed in `Persistence::ClassMethods` rather than `Relation`. And also, these methods are not dependent on relation. So it is not needed to delegate to `all` (plus, `klass.find` is faster than `relation.find`).
* Remove unused explicit delegation to `klass` in `relation`Ryuta Kamizono2017-09-141-1/+1
| | | | | | | It is only used `primary_key` and `connection` in the internal, so it is not needed to delegate others to `klass` explicitly. This doesn't change public behavior because `relation` will delegate missing method to `klass`.
* Should work inverse association when eager loadingRyuta Kamizono2017-08-251-2/+14
| | | | | | | This regression was caused by caa178c1. The block for `set_inverse_instance` should also be passed to join dependency. Fixes #30402.
* Restore `to_sql` to return only SQL (#29945)Ryuta Kamizono2017-08-181-2/+1
| | | | Because `to_sql` is public API. I introduced `to_sql_and_binds` internal API to return SQL and binds.