-
Notifications
You must be signed in to change notification settings - Fork 40
Open
Description
Hi folks! Thanks for your work on this gem.
QueryObject is a commonly used pattern in RoR community, and I noticed that everyone is re-implementing it similarly.
All realizations I saw were mostly designed to be used in ActiveRecord scopes definition:
class User < ApplicationRecord
scope :active, Users::ActiveQuery
endUsing query objects in this way has quite unpleasant and hidden behavior – if you try to create some subqueries on User model inside of query object – it will be scoped to the "current" scope.
I've briefly described the problem itself here.
Also there are some instructions how to reproduce the issue with this gem:
# rails new pattern-gem-test && cd pattern-gem-test
# bundle add rails-patterns
# rails g model User name:string terminated:boolean manager_id:integer
# rails db:migrate
# app/models/user.rb
class User < ApplicationRecord
belongs_to :manager, class_name: 'User', optional: true
scope :with_terminated_manager, Users::WithTerminatedManagerQuery
end
# app/models/users/with_terminated_manager_query.rb
class Users::WithTerminatedManagerQuery < Patterns::Query
queries User
def query
relation.where(manager: User.where(terminated: true))
end
end
# Then by executing the scope this query:
User.where(name: 'Galalthius').with_terminated_manager
# SELECT "users".*
# FROM "users"
# WHERE "users"."name" = 'Galathius' <---------- name condition
# AND "users"."manager_id" IN
# (SELECT "users"."id"
# FROM "users"
# WHERE "users"."name" = 'Galathius' <---------- name condition
# AND "users"."terminated" = TRUE)So far I found the only workaround for this, is simply define scopes using lambdas, although this reduces readability:
scope :with_terminated_manager, -> { Users::WithTerminatedManagerQuery.new(self).call }Metadata
Metadata
Assignees
Labels
No labels