Programing

Rails 4의 has_many 'conditions'옵션과 동일한 것은 무엇입니까?

crosscheck 2020. 11. 7. 09:01
반응형

Rails 4의 has_many 'conditions'옵션과 동일한 것은 무엇입니까?


누군가가 Rails 4에서 다음 줄을 수행하는 동등한 방법이 무엇인지 말해 줄 수 있습니까?

has_many :friends, :through => :friendships, :conditions => "status = 'accepted'", :order => :first_name

다음을 시도했습니다.

has_many :friends, -> { where status: 'accepted' }, :through => :friendships , :order => :first_name

하지만 다음과 같은 오류가 발생합니다.

Invalid mix of scope block and deprecated finder options on ActiveRecord association: User.has_many :friends

두 번째 인수 여야합니다.

class Customer < ActiveRecord::Base
  has_many :orders, -> { where processed: true }
end

http://edgeguides.rubyonrails.org/association_basics.html#scopes-for-has-many

업데이트에 대한 응답 :

블록 안에 주문을 넣으십시오.

has_many :friends, -> { where(friendship: {status: 'accepted'}).order('first_name DESC') }, :through => :friendships

여기에있는 다른 답변은 기술적으로 정확하지만 캡슐화를 위반합니다. 사용자 모델은 알지 못한다 우정 모델이라는 열이 status, 그리고 같은 특정 값을 가질 수 있습니다 accepted.

예를 들어 Rails 4의 Enums를 활용하기 위해 변경하기로 결정한 경우 UserFriendship 모델을 모두 변경해야합니다 . 이로 인해 캡슐화 유지가 피하는 버그가 발생할 수 있습니다.

Friendship 모델 에서 범위를 노출합니다 .

scope :accepted, -> { where(status: :accepted) }

나는 그 다음에이 범위를 사용하는 것이 사용자 로부터 어떠한 구현 세부 정보를 숨기고, 모델 사용자 .

has_many :friendships, -> { Friendship.accepted }
has_many :friends, through: :friendships

# Or...

has_many :friends, -> { Friendship.accepted }, through: :friendships

더 나아가 범위를 accepted_friendships더 명확하게 바꿀 수 있습니다 .

has_many :accepted_friendships, -> { Friendship.accepted }
has_many :friends, through: :accepted_friendships

이제 각 모델에 구현 세부 정보를 성공적으로 캡슐화했습니다. 변경 사항이있을 경우 한 곳에서만 변경할 수 있으므로 유지 관리가 줄어들고 견고성이 향상됩니다.


Mohamad의 대답의 Rails 3.2 버전은 다음과 같습니다.

class Friend < ActiveRecord::Base
  has_many :friendships, :order => :first_name

  has_many :friends, :through => :friendships,
           :conditions => proc { Friendship.accepted.where_ast }

  has_many :pending_friends, :through => :friendships,
           class_name => Friend,
           :conditions => proc { Friendship.pending.where_ast }
end

class Friendship < ActiveRecord::Base
  scope :status, ->(status) { where(:status => status) }
  scope :accepted, -> { status('accepted') }
  scope :pending, -> { where(arel_table[:status].not_eq('accepted')) } 
end

메모:

  • where_ast 조건이 작동하는 데 필요한 AREL 노드를 반환하므로 중요합니다.
  • 에 전달 된 시저 내에서 :conditions, self항상 모델의 인스턴스가 아닌 (예를 들면 협회가 다른 쿼리와 합병하는 경우)
  • 범위 및 연관 내에서 원시 SQL을 사용하면 테이블 이름의 네임 스페이스와 관련된 문제가 발생할 수 있습니다. AREL을 사용하십시오.

Rails 4.1 (제 경우)에서 작업하려면 다음을 입력해야합니다.

has_many :friends, -> { where(friendships: { status: 'accepted' }) }, through: :friendships

우정에 대한 S에 유의하십시오. 데이터베이스 이름을 직접 참조합니다.


has_many :friends, -> { where(status: 'accepted').order('frist_name')}, through: :friendships

또는

has_many :friends, -> { where(status: 'accepted').order(:frist_name)}, through: :friendships

참고 URL : https://stackoverflow.com/questions/20307874/what-is-the-equivalent-of-the-has-many-conditions-option-in-rails-4

반응형