我们的User类上有一个default_scope
,它将用户限制为一组公司:
class User < ActiveRecord::Base
default_scope do
c_ids = Authorization.current_company_ids
includes(:companies).where(companies: { id: c_ids })
end
has_many :company_users
has_many :companies, through: company_users
end
class CompanyUser < ActiveRecord::Base
belongs_to :user
belongs_to :company
validates_uniqueness_of :company_id, scope: :user_id
end
class Company < ActiveRecord::Base
has_many :company_users
has_many :users, through: company_users
end
按预期调用User.last
或User.find_by_email('mhayes@widgetworks.com')
或User.find(55557)
所有工作和范围。
调用User.exists?(id)
会引发一个奇怪的错误:
Mysql2::Error: Unknown column 'companies.id' in 'where clause': SELECT 1 AS one FROM `users` WHERE `companies`.`id` IN (4) AND `users`.`id` = 55557 LIMIT 1
基本上,如果我收到此消息,则表示companies
不是User
上的列,而是where
。如果我甚至将sql复制到User.where("SELECT 1 AS one FROM `users` WHERE `companies`.`id` IN (4) AND `users`.`id` = 66668 LIMIT 1")
语句中,它会正确评估。
default_scope
这让我觉得exists?
有一个评估顺序,default_scope
之前会以某种方式调用User.includes(:companies).where(companies: { id: [4] }).exists?(55557)
。
如果我打电话:
default_scope
作品。这就是default_scope
正在做的事情,所以我知道{{1}}范围没有失败。
答案 0 :(得分:1)
老实说,我不知道,但我认为exists?
直接构建 relation 并决定抛出includes
子句,因为exists?
决定它不需要加载其他对象。这发生在this method call。而链式 exists?
已经通过构建早期的关系(其中includes
转换为joins
)正确计算了它
也许不是一个错误,但可能是另一个奇怪的事情,用default_scope
添加到列表中。
最好的解决方案可能是将includes
中的default_scope
变为实际joins
,并在实际需要完整记录时手动调用includes
。 (因为exists?
通话实际上并不需要它们)
另一种可能性是在includes
中链接joins
和default_scope
。我不知道这对arel
计算有什么影响,尽管我对此表示怀疑。 五月或五月不起作用。
或者如果你真的希望它保持整体相同,你可以做一些疯狂的事情:
def self.exists?(args)
self.scoped.exists?(args)
end
这将基本上构建一个具有默认范围的 relation ,然后在已经执行exists?
的已构建关系上调用includes
- &gt ; joins
魔法。
答案 1 :(得分:0)
试试这个
User.exists?(id: 55557)