如何在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 < Productclass FinancialProduct < Productdefault_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

 结束

https://gist.github.com/2478161

新的答案

这个问题应该帮助你弄清楚如何绕过你的关联的默认where子句。

值得重复的是,如果你经常不得不避免一个范围,那么它可能应该是一个默认值。 创build一个visible非默认范围,并在关联中明确使用它。