aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/association_scope.rb
Commit message (Collapse)AuthorAgeFilesLines
* Correct through associations using scopesSean Griffin2015-06-301-0/+1
| | | | | | | | | | | | | | | | | | | | | | The changes introduced to through associations in c80487eb were quite interesting. Changing `relation.merge!(scope)` to `relation = relation.merge(scope)` should in theory never cause any changes in behavior. The subtle breakage led to a surprising conclusion. The old code wasn't doing anything! Since `merge!` calls `instance_exec` when given a proc, and most scopes will look something like `has_many :foos, -> { where(foo: :bar) }`, if we're not capturing the return value, it's a no-op. However, removing the `merge` causes `unscope` to break. While we're merging in the rest of the chain elsewhere, we were never merging in `unscope` values, causing a breakage on associations where a default scope was being unscoped in an association scope (yuk!). This is subtly related to #20722, since it appears we were previously relying on this mutability. Fixes #20721. Fixes #20727.
* Go through normal `where` logic in `AssociationScope`Sean Griffin2015-01-261-51/+31
| | | | | | | | | | | | This removes the need to duplicate much of the logic in `WhereClause` and `PredicateBuilder`, simplifies the code, removes the need for the connection adapter to be continuously passed around, and removes one place that cares about the internal representation of `bind_values` Part of the larger refactoring to change how binds are represented internally [Sean Griffin & anthonynavarre]
* Remove all references to `where_values` in association codeSean Griffin2015-01-251-2/+1
|
* Remove references to `:bind` in `except`Sean Griffin2015-01-251-1/+1
| | | | Bind values are no longer a thing, so this is unnecessary.
* Cleanup methods, missing spacing and missing nodocseileencodes2015-01-021-19/+20
| | | | | | | | | | Add missing nodoc's Change `assoc_klass` argument name to `association_klass` Change `prev_reflection` argument name to `previous_reflection` Change `prev` to `previous_reflection` in `#get_chain` Switch use of `refl` and `reflection` in `#get_chain` so main parameter is not abbreviated. Add missing space in `#add_constraints`
* Move `#type_caster` to alias tracker initializeeileencodes2015-01-021-1/+1
| | | | | This moves the `#type_caster` from the `aliased_table_for` and into the initialize of the `alias_tracker`.
* Add `#all_includes` method to reflectionseileencodes2015-01-021-1/+3
| | | | | `yield` instead of relying on checking if the reflection is equal to the `chain_head`.
* Initialze `#alias_tracker` with base table nameeileencodes2015-01-021-1/+0
| | | | | | | Instead of initializing an empty connection use the base table name instead. Split up and refactor `#create` to be 2 methods `#create` and `#create_with_joins`. Removes the need to update the count by 1 on initialzing a JoinDependency.
* Move `alias_candiate` into `AbstractReflection`eileencodes2015-01-021-9/+7
| | | | | | This moves `alias_candidate` out of the `ReflectionProxy` and into the `AbstractReflection` so it is shared by all reflections. Change `alias_name` to a method and and remove assignment in `#get_chain`.
* Pass `connection` rather than `alias_tracker`eileencodes2015-01-021-4/+4
| | | | | | | | | After the refactorings we're only using the connection and not the alias tracker anymore. This builds on commit 18019. Reuse the already available `@connection` to reduce the surface area of the alias tracker's API. We can then remove the `attr_reader` because the connection is already available.
* Assign the `#alias_name` to each reflectioneileencodes2015-01-021-11/+12
| | | | This makes the `#alias_name` more functional.
* Clean up / refactor new reflection classeseileencodes2015-01-021-50/+1
| | | | | | Move `RuntimeReflection` and `PolymorphicReflect` into Reflection. This allows the methods to inherit from `ThroughReflection` and DRY up the methods by removing duplicates.
* Refactor `#get_chain` iteration to a linked listeileencodes2015-01-021-14/+21
| | | | | | The linked list lets us use a loop in `#add_constraints` and completely remove the need for indexing the iteration becasue we have access to the next item in the chain.
* Refactor `#get_chain` to remove need for `#construct_tables`eileencodes2015-01-021-14/+11
| | | | | | By concatnating the `ReflectionProxy` with the `chain` we remove the need for `#construct_tables` because the `chain` is now in the correct order (order of the chain DOES matter).
* Move `#alias_name` to `ReflectionProxy` classeileencodes2015-01-021-10/+23
| | | | | Putting the `#alias_name` into ReflectionProxy means we don't have to cache the `#alias_name` globally anymore - it's not cached per query.
* Clean up assignments in `#add_constraints`eileencodes2015-01-021-8/+3
| | | | | | `is_first_chain`, `items` and `klass` are no longer beneficial and can be called directly instead of via their assignments - because they are each only used once.
* Refactor construct_tables methodeileencodes2015-01-021-36/+10
| | | | | Move method structure into reflection classes for accessibly on each reflection rather than by traversing the chain.
* Add RuntimeReflection for recursive access to chaineileencodes2015-01-021-3/+54
| | | | | | | The `RuntimeReflection` class allows the reflection to be accessed at runtime - then we always know which reflection we are accessing in the chain. The `#get_chain` method then allows us to recursively access the chain through the `RuntimeReflection`.
* Add PolymorphicReflection and constraints methodeileencodes2015-01-021-3/+4
| | | | | | `#constraints` builds a flattened version of `scope_chain` to allow it to be accessible without requiring an index when iterating over the `scope_chain`
* Pass a type caster when aliasing tables for joinsSean Griffin2014-12-291-1/+2
|
* Pass connection rather than alias_trackereileencodes2014-12-131-16/+17
| | | | | | | | | Because we're only using the `connection` so passing the entire tracker isn't unnecessary. Eventually only the `connection` will be passed to `add_constraints` with later refactoring but curretly that's not possible because of `construct_tables` method.
* Remove the unused second argument to `substitute_at`Sean Griffin2014-11-171-2/+1
| | | | Oh hey, we got to remove some code because of that!
* Merge pull request #16801 from ↵Rafael Mendonça França2014-09-041-5/+1
|\ | | | | | | | | eileencodes/refactor-scope_chain-on-through-refelction-to-eliminate-branch-in-eval_scope Always add lambda to scope chain to eliminate branch in eval_scope
| * Always add lambda to scope chain to eliminate branch in eval_scopeeileencodes2014-09-041-5/+1
| | | | | | | | | | | | We convert all other scopes to lambda's so it makes sense that we should always returns a lambda on a ThroughReflection as well. This eliminates the need to check if the scope is a Relation.
* | Follup to PR #16762eileencodes2014-09-041-4/+4
|/ | | | | | | | Remove chain from parameters, it's no longer needed since chain and i are being passed via next_reflection Change name of `reflection` to `owner_reflection` because of shadow variable warning. The last reflection will always be the owner.
* get rid of shadowing warning when running tests AR and railtie tests.Yves Senn2014-09-041-2/+2
| | | | | | | | Warning looked like this: ``` /Users/senny/Projects/rails/activerecord/lib/active_record/associations/association_scope.rb:142: warning: shadowing outer local variable - reflection ```
* Break conditional branches into separate methodseileencodes2014-09-011-35/+52
| | | | | | | | | | | | | | | | | | This breaks the two branches of the `if reflection.last` and `else` to clearer see where the two methods can be refactored. Eventually we hope to remove the need for these separated methods altogether. Move the first branch outside the loop This code doesn't need to be in the loop because it it always affects the last chain. `get_bind_values` and `add_constraints` must match in this context because `get_bind_values` is the caching of `add_constraints` Use each_cons to remove need for `chain[i + 1]` The `chain[i + 1]` is confusing because it's not immediately obvious what it's trying to achieve. The use of `each_cons` makes it clear we need to get the `next_reflection`.
* Remove to_s from reflection.type in add_constraintseileencodes2014-08-181-2/+2
| | | | | | | The instance var is already saved as a string in the initialization method of AssociationReflection. See https://github.com/rails/rails/blob/master/activerecord/lib/active_record/reflection.rb#L273
* begin refactoring add_constraints by moving join keyseileencodes2014-06-101-12/+3
| | | | | | | | | | | | | | add_constraints is complicated and difficult to read. This is the beginning of a long process of refactoring this code. First step: moved the join keys out of AssociationScope and into reflection. We then don't need to call `reflection` because now reflection is `self`. `foreign_key` must be named something else because reflection already has a `foreign_key` method and when passed into `JoinKeys` it was getting the wrong assignment. `reflection_foreign_key` seemed to be an appropriate name. I also named `key` `reflection_key` to match `reflection_foreign_key`.
* fix polymorphic? method and reuse iteileencodes2014-06-021-1/+1
| | | | | | Fix polymorphic to check for `options[:polymorphic]` instead of `options.key? :polymorphic` and then reuse the method `polymorphic?` method instead of constantly checking the same `options[:polymorphic]`.
* Refactor AssociationScope#get_bind_valuesEric Chahin2014-05-051-8/+1
| | | | Added #join_id_for(owner) to reflection to avoid accessing the source_macro
* cache scope building on associationsAaron Patterson2014-04-141-6/+49
| | | | SQL statements for querying associations are now cached
* Merge branch 'master' into adequaterecordAaron Patterson2014-02-171-31/+56
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * master: (311 commits) Add a missing changelog entry for #13981 and #14035 Revert "Fixed plugin_generator test" implements new option :month_format_string for date select helpers [Closes #13618] add factory methods for empty alias trackers guarantee a list in the alias tracker so we can remove a conditional stop exposing table_joins make most parameters to the AliasTracker required make a singleton for AssociationScope pass the association and connection to the scope method pass the tracker down the stack and construct it in the scope method clean up add_constraints signature remove the reflection delegate remove klass delegator remove railties changes. fixes #14054 remove chain delegate remove scope_chain delegate Add verb to sanitization note fix path shown in mailer's templates updated Travis build status image url fix guide active_support_core_extensions. add Note to String#indent [ci skip] ... Conflicts: activerecord/lib/active_record/associations/join_dependency.rb activerecord/test/cases/associations/association_scope_test.rb
| * add factory methods for empty alias trackersAaron Patterson2014-02-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we know the alias tracker is empty, we can create one that doesn't use a hash with default block for counting. ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') ActiveRecord::Schema.define do create_table :posts, force: true do |t| t.integer :comments_count end create_table :comments, force: true do |t| t.integer :post_id end end class Post < ActiveRecord::Base; has_many :comments; end class Comment < ActiveRecord::Base; belongs_to :post, counter_cache: true; end 10.times { Comment.create!(post: Post.create!) } record = Post.first association_name = :comments Benchmark.ips do |x| reflection = record.class.reflect_on_association(association_name) association = reflection.association_class.new(record, reflection) x.report('assoc') do reflection.association_class.new(record, reflection) end x.report('reader') do association.reader;nil end x.report('combined') do reflection.association_class.new(record, reflection).reader;nil end end [aaron@higgins rails (tracker)]$ TEST=ips bundle exec ruby ../1bb5456b5e035343df9d/gistfile1.rb -- create_table(:posts, {:force=>true}) -> 0.0062s -- create_table(:comments, {:force=>true}) -> 0.0003s Calculating ------------------------------------- assoc 833 i/100ms reader 28703 i/100ms combined 839 i/100ms ------------------------------------------------- assoc 9010.3 (±3.8%) i/s - 44982 in 5.000022s reader 3214523.4 (±5.5%) i/s - 16016274 in 5.001136s combined 8841.0 (±5.8%) i/s - 44467 in 5.049269s [aaron@higgins rails (tracker)]$ TEST=ips bundle exec ruby ../1bb5456b5e035343df9d/gistfile1.rb -- create_table(:posts, {:force=>true}) -> 0.0060s -- create_table(:comments, {:force=>true}) -> 0.0003s Calculating ------------------------------------- assoc 888 i/100ms reader 29217 i/100ms combined 900 i/100ms ------------------------------------------------- assoc 9674.3 (±3.3%) i/s - 48840 in 5.054022s reader 2988474.8 (±6.9%) i/s - 14842236 in 4.998230s combined 9674.0 (±3.1%) i/s - 48600 in 5.028694s
| * guarantee a list in the alias tracker so we can remove a conditionalAaron Patterson2014-02-141-1/+1
| |
| * make a singleton for AssociationScopeAaron Patterson2014-02-141-0/+6
| | | | | | | | | | AssociationScope no longer maintains state, so we're safe to keep a singleton and save on GC time
| * pass the association and connection to the scope methodAaron Patterson2014-02-141-8/+2
| |
| * pass the tracker down the stack and construct it in the scope methodAaron Patterson2014-02-141-18/+18
| |
| * clean up add_constraints signatureAaron Patterson2014-02-141-8/+9
| |
| * remove the reflection delegateAaron Patterson2014-02-141-15/+14
| |
| * remove klass delegatorAaron Patterson2014-02-141-10/+11
| |
| * remove chain delegateAaron Patterson2014-02-141-5/+6
| |
| * remove scope_chain delegateAaron Patterson2014-02-141-3/+3
| |
| * remove more delegate methodsAaron Patterson2014-02-131-7/+9
| |
| * :scissors: whitespaceAaron Patterson2014-02-131-1/+0
| |
| * rm delegate methods that are not actually usedAaron Patterson2014-02-131-2/+2
| |
| * JoinHelper is never reused, so there is no need to separateAaron Patterson2014-02-131-5/+25
| |
| * this class depends on JoinHelper, so we should require itAaron Patterson2014-01-311-0/+2
| |
* | Merge branch 'master' into set_bindsAaron Patterson2014-01-111-18/+12
|\| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * master: (2794 commits) doc, API example on how to use `Model#exists?` with multiple IDs. [ci skip] Restore DATABASE_URL even if it's nil in connection_handler test [ci skip] - error_messages_for has been deprecated since 2.3.8 - lets reduce any confusion for users Ensure Active Record connection consistency Revert "ask the fixture set for the sql statements" Check `respond_to` before delegation due to: https://github.com/ruby/ruby/commit/d781caaf313b8649948c107bba277e5ad7307314 Adding Hash#compact and Hash#compact! methods MySQL version 4.1 was EOL on December 31, 2009 We should at least recommend modern versions of MySQL to users. clear cache on body close so that cache remains during rendering add a more restricted codepath for templates fixes #13390 refactor generator tests to use block form of Tempfile Fix typo [ci skip] Move finish_template as the last public method in the generator Minor typos fix [ci skip] make `change_column_null` reversible. Closes #13576. create/drop test and development databases only if RAILS_ENV is nil Revert "Speedup String#to" typo fix in test name. [ci skip]. `core_ext/string/access.rb` test what we are documenting. Fix typo in image_tag documentation ... Conflicts: activerecord/lib/active_record/associations/join_dependency/join_association.rb activerecord/lib/active_record/relation/query_methods.rb
| * Skip `include_values` from through associations chains for building target scopePaul Nikitochkin2013-10-271-2/+6
| | | | | | | | Fixes: #12242, #9517, #10240