0

我们default_scope的 User 类有一个将用户限制为一组公司:

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.lastUser.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,它是。如果我什至将 sql 复制到一个where语句中,它的计算结果是正确的。

User.where("SELECT  1 AS one FROM `users`  WHERE `companies`.`id` IN (4) AND `users`.`id` = 66668 LIMIT 1")

这让我觉得有一个评估顺序,default_scope并且exists?以某种方式调用 before default_scope

如果我打电话:

User.includes(:companies).where(companies: { id: [4] }).exists?(55557)

作品。这就是default_scope正在做的事情,所以我知道default_scope范围没有失败。

4

2 回答 2

1

老实说,我不知道,但在我看来,它就像直接exists?建立一个关系并决定丢弃该includes子句,因为exists?它决定它不需要加载其他对象。这发生在这个方法调用中。而链式 exists?已经通过建立更早的关系(其中includesget 转换为 a joins)正确计算了它。

也许不是一个错误,但可能是另一个奇怪的添加到列表中default_scope

可能最好的解决方案是在您实际需要完整记录时includes将其default_scope变为实际joins并手动调用。includes(因为您实际上并不需要它们进行exists?通话)

另一种可能性是同时链接includesjoinsdefault_scope我不知道这对arel计算有什么影响,尽管我很怀疑。可能或可能不工作。

或者,如果你真的希望它整体保持不变,你可以做一些疯狂的事情,比如:

def self.exists?(args)
  self.scoped.exists?(args)
end

这将基本上建立一个具有默认范围的关系,然后调用已经执行了->魔法的exists?那个建立的关系。includesjoins

于 2015-04-13T21:50:11.920 回答
0

试试这个

User.exists?(id: 55557)
于 2015-04-13T20:30:53.800 回答