如何在Rails3中使用unscoped关联关系?
由于信息安全的限制,我有一个默认的产品范围。
class Product < ActiveRecord::Base has_many :photos default_scope where('visible = 1') end
然而,在我的相关照片模型中,我也必须find不应该可见的产品。
class Photo < ActiveRecord::Base belongs_to :product end my_photo.product
在其他情况下,我可以使用unscoped来绕过default_scope,例如在Product.unscoped.find_by_title('abc')
。 然而:
使用logging关联时如何删除范围?
my_photo.unscoped.product
没有意义,因为my_photo没有名为unscoped的方法。 my_photo.product.unscoped
也没有意义,因为my_photo.product
可能已经是零。
哦。 我骗了我自己。 以为以下将无法正常工作…但它确实:
Product.unscoped do my_photo.product end
请注意,您必须使用应忽略的default_scope
在模型上调用unscoped。
而且,inheritance必须得到尊重。 如果您在class InsuranceProduct < Product
具有class InsuranceProduct < Product
和class FinancialProduct < Product
和default_scope
,则以下两种组合都将起作用:
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的另一个怪癖。
另一个选项是重写getter方法和unscope super:
class Photo < ActiveRecord::Base belongs_to :product def product Product.unscoped{ super } end end
我遇到了同样的情况,我有一个关联的模型,需要不被扫描,但几乎在所有其他情况下,它需要默认范围。 如果您在多个地方使用关联获取器,这应该可以将额外的调用保存为unscoped。
我可能晚了一点,但是前一段时间我发现自己处于同样的状况,我写了一个gem来轻松做到这一点: unscoped_associations 。
用法:
belongs_to :user, unscoped: true
支持:
- 属于
- HAS_ONE
- 有很多
多态关联也被支持。
在Rails 4中,你可以使用关联的明显无用的filter,即my_photo.product.unscope(where: :visible)
如果您需要一个特定的关联总是被忽略,您可以在定义关联时对其进行取景:
belongs_to :product, -> { unscope(where: :visible) }
出于某种原因,具体where
键没有正确加载我,所以我只是无法涵盖整个where
,这是另一个选项,碰巧在我的情况下:
belongs_to :product, -> { unscope(:where) }
其他答案也值得一看,但这是Rails 4.1+的另一个select。
这不是主要的话题,但你的问题与ActiveRecord#变成:我们(希望)修复了一个初始化
类ActiveRecord :: Base def become_with_association_cache(klass) 成为= become_without_association_cache(克拉斯) become.instance_variable_set(“@ association_cache”,@association_cache) 成为 结束 alias_method_chain:变成::association_cache 结束
新的答案
这个问题应该帮助你弄清楚如何绕过你的关联的默认where子句。
值得重复的是,如果你经常不得不避免一个范围,那么它可能应该是一个默认值。 创build一个visible
非默认范围,并在关联中明确使用它。