ActiveRecord:如何在使用left_join时取消对default_scope的作用域?

时间:2019-05-14 23:01:29

标签: ruby-on-rails join activerecord ruby-on-rails-5 left-join

假设我有一个模型Person。该Person有许多Posts。帖子具有默认范围,以排除所有软删除的条目。软删除表示属性deleted_at不是nil

class Person < ActiveRecord::Base

  has_many :posts

end

class Post < ActiveRecord::Base

  belongs_to :person
  default_scope { where(:deleted_at => nil) }

end

我现在要查询所有拥有至少一个职位的人员,并且我还希望包括软删除的职位-所以我希望默认范围不适用。使用

Person.left_joins(:posts).where.not(posts: { id: nil })

仍然应用默认范围并在此SQL中生成结果:

SELECT `persons`.* FROM `persons` LEFT OUTER JOIN `posts` ON `posts`.`person_id` = `persons`.`id` AND `posts`.`deleted_at` IS NULL WHERE `posts`.`id` IS NOT NULL

解决此问题的一种优雅方法是什么?

2 个答案:

答案 0 :(得分:0)

使用unscoped方法删除所有以前的作用域。

Person.unscoped.left_join(....

https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-unscoped

编辑:我误解了默认范围在哪里,我认为您可以取消关联的范围:

has_many :posts, -> { unscoped }

https://guides.rubyonrails.org/association_basics.html#scopes-for-has-many

默认情况下,这应该取消关联的作用域。虽然不是100%肯定!希望对您有所帮助。

答案 1 :(得分:0)

我在Rails 5中尝试过这种方法,并且可以正常工作:

has_many :posts, -> { unscope( where: : deleted_at) }