由于信息安全限制,我在产品上有默认范围。
class Product < ActiveRecord::Base
has_many :photos
default_scope where('visible = 1')
end
然而,在我的相关照片模型中,我还必须找到不应该看到的产品。
class Photo < ActiveRecord::Base
belongs_to :product
end
my_photo.product
在其他情况下,我可以使用unscoped来绕过default_scope,例如在Product.unscoped.find_by_title('abc')
。但是:
如何在使用记录关联时删除范围?
my_photo.unscoped.product
没有意义,因为my_photo没有名为unscoped
的方法。 my_photo.product.unscoped
也没有意义,因为my_photo.product
可能已经是零。
答案 0 :(得分:61)
喔。我骗了自己。以为以下方法不起作用......但确实如此:
Product.unscoped do
my_photo.product
end
请注意,您必须使用应绕过的default_scope
在模型上调用unscoped。
此外,必须尊重继承。如果class InsuranceProduct < Product
中有class FinancialProduct < Product
和default_scope
以及Product
,则以下两种组合都可以使用:
InsuranceProduct.unscoped do
my_record.insurance_products
end
FinancialProduct.unscoped do
my_record.financial_products
end
Product.unscoped do
my_record.products
end
但是,以下无效,但范围在Product
中定义:
Product.unscoped do
my_record.financial_products
end
我猜这是Ruby / Rails中STI的另一个怪癖。
答案 1 :(得分:50)
另一个选择是覆盖getter方法和unscope super:
class Photo < ActiveRecord::Base
belongs_to :product
def product
Product.unscoped{ super }
end
end
我遇到了一个相同的情况,我有一个相关的模型需要无范围,但在几乎所有其他情况下,它需要默认范围。如果您在多个地方使用关联吸气器,这应该可以节省额外的无范围调用。
答案 2 :(得分:24)
我可能有点迟到了,但不久前我发现自己处于相同的状况,我写了一个宝石来轻松做到这一点:unscoped_associations。
用法:
belongs_to :user, unscoped: true
支持:
也支持多态关联。
答案 3 :(得分:7)
如果您需要一个特定的关联以始终未展开,您可以在定义关联时取消它:
belongs_to :product, -> { unscope(where: :visible) }
由于某些原因,我没有正确加载特定的where
密钥,所以我只是解开了整个where
,这是我的情况下碰巧遇到的另一种选择:
belongs_to :product, -> { unscope(:where) }
其他答案也值得一看,但这是Rails 4.1 +的另一个选择。
答案 4 :(得分:5)
在Rails 4中,您可以使用与不受欢迎的过滤器的明确不合作关联,即my_photo.product.unscope(where: :visible)
答案 5 :(得分:1)
这不是关于主题,而是关于ActiveRecord#的问题变成:我们(希望)用初始化器修复它
class ActiveRecord::Base def becomes_with_association_cache(klass) became = becomes_without_association_cache(klass) became.instance_variable_set("@association_cache", @association_cache) became end alias_method_chain :becomes, :association_cache end
答案 6 :(得分:0)
This question应该帮助您弄清楚如何绕过关联的默认where子句。
值得重复的是,如果你经常不得不避开范围那么它可能应该是默认值。创建一个visible
非默认范围,并在您的关联中明确使用它。