Skip to content

Commit

Permalink
Add support join types in where.associated method
Browse files Browse the repository at this point in the history
  • Loading branch information
saleh-alhaddad committed Feb 17, 2024
1 parent 9b343c2 commit 7b32782
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
10 changes: 10 additions & 0 deletions activerecord/CHANGELOG.md
Expand Up @@ -3,6 +3,16 @@

*Jason Nochlin*

* Adds support to change join type in the `where.associated` method.
By default associated method use joins association, Support join type are joins, left_joins and left_outer_joins.

In this example change default join type to the `left_joins`
```ruby
Post.where.associated(join_type: :left_joins, :author)
```

*Saleh Alhaddad*

* Fix an issue where `ActiveRecord::Encryption` configurations are not ready before the loading
of Active Record models, when an application is eager loaded. As a result, encrypted attributes
could be misconfigured in some cases.
Expand Down
13 changes: 11 additions & 2 deletions activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -72,10 +72,19 @@ def not(opts, *rest)
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
# # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
# # WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
def associated(*associations)
#
# Additionally, you can change join type by one of the allowed types, joins, left_joins and left_outer_joins
# Example: Post.where.associated(join_type: :left_joins, :author)
#
def associated(*associations, join_type: :joins)
allowed_types = [:joins, :left_joins, :left_outer_joins]
unless allowed_types.include?(join_type.to_sym)
raise ArgumentError.new("An `#{join_type}` does not exist on the allowed association `#{allowed_types.join(', ')}`.")
end

associations.each do |association|
reflection = scope_association_reflection(association)
@scope.joins!(association)
@scope.send("#{join_type}!", association)
if reflection.options[:class_name]
self.not(association => { reflection.association_primary_key => nil })
else
Expand Down
7 changes: 7 additions & 0 deletions activerecord/test/cases/relation/where_chain_test.rb
Expand Up @@ -92,6 +92,13 @@ def test_associated_with_enum_extended_late
assert_equal Author.find(2), Author.order(id: :desc).joins(:reading_listing).where.associated(:reading_listing).extending(Author::NamedExtension).first
end

def test_associated_with_change_join_type
Comment.where.associated(:children, join_type: :left_joins).tap do |relation|
assert_includes relation, comments(:greetings)
assert_not_includes relation, comments(:more_greetings)
end
end

def test_missing_with_association
assert_predicate posts(:authorless).author, :blank?
assert_equal [posts(:authorless)], Post.where.missing(:author).to_a
Expand Down

0 comments on commit 7b32782

Please sign in to comment.