Program Club

Rails3에서 관련 관계에 범위가 지정되지 않은 것을 사용하는 방법은 무엇입니까?

proclub 2020. 11. 26. 20:10
반응형

Rails3에서 관련 관계에 범위가 지정되지 않은 것을 사용하는 방법은 무엇입니까?


정보 보안 제약으로 인해 제품에 대한 기본 범위가 있습니다.

class Product < ActiveRecord::Base
  has_many :photos

  default_scope where('visible = 1')
end

그러나 내 관련 사진 모델에서는 보이지 않아야하는 제품도 찾아야합니다.

class Photo < ActiveRecord::Base
  belongs_to :product
end

my_photo.product

다른 경우 에는 default_scope를 우회하기 위해 unscoped사용할 수 있습니다 Product.unscoped.find_by_title('abc'). 하나:

레코드 연결을 사용할 때 범위를 제거하는 방법은 무엇입니까?

my_photo.unscoped.productmy_photo에는라는 메서드가 없으므로 의미가 없습니다 unscoped. 둘 다 이미 nil 일 수 있으므로 my_photo.product.unscoped의미 가 없습니다 my_photo.product.


오. 나는 속았다. 다음은 작동하지 않을 것이라고 생각했지만 ... 작동합니다.

Product.unscoped do
  my_photo.product
end

default_scope우회되어야 하는 모델에서 범위가 지정되지 않음을 호출 해야합니다.

또한 상속은 존중되어야합니다. 당신이있는 경우 class InsuranceProduct < Productclass FinancialProduct < Producta와 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의 또 다른 특징이라고 생각합니다.


또 다른 옵션은 getter 메서드를 재정의하고 super 범위를 해제하는 것입니다.

class Photo < ActiveRecord::Base
  belongs_to :product

  def product
    Product.unscoped{ super }
  end
end

범위를 지정하지 않아야하는 관련 모델이 하나있는 동일한 상황에 직면했지만 거의 모든 경우에 기본 범위가 필요했습니다. 두 개 이상의 위치에서 연결 게터를 사용하는 경우 범위가 지정되지 않은 추가 호출을 절약 할 수 있습니다.


나는 아마도 파티에 조금 늦었지만 얼마 전에 나는 같은 상황에 처해 있었고 이것을 쉽게 할 수있는 gem을 썼습니다 : unscoped_associations .

Usage:

belongs_to :user, unscoped: true

Support for:

  • belongs_to
  • has_one
  • has_many

Polymorphic associations are also supported.


If you need for a specific association to always be unscoped, you can unscope it when defining the association:

belongs_to :product, -> { unscope(where: :visible) }

For some reason, the specific where key wasn't loading correctly for me, so I just unscoped the entire where, which is another option that happens to work out in my case:

belongs_to :product, -> { unscope(:where) }

The other answers are worth looking at too, but this is another option for Rails 4.1+.


In Rails 4 you can use the association with an explicit unscope of the undesirable filter i.e. my_photo.product.unscope(where: :visible)


It's not on the main topic but on your problem with ActiveRecord#becomes: We (hopefully) fixed it with an initializer

 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

https://gist.github.com/2478161


New answer

This question should help you figure out how to bypass the default where clause for your association.

It's worth repeating though that if you're regularly having to avoid a scope then it probably should be a default. Create a visible non-default scope and use that explicitly in your associations.

참고URL : https://stackoverflow.com/questions/4758145/how-to-use-unscoped-on-associated-relations-in-rails3

반응형