문제

사용자 정의 찾기 조건을 배치해야 하는 몇 가지 모델이 있습니다.예를 들어 연락처 모델이 있는 경우 Contact.find가 호출될 때마다 사용 중인 계정에만 속하는 연락처가 반환되도록 제한하고 싶습니다.

Google을 통해 이것을 찾았습니다(약간 맞춤설정했습니다).

def self.find(*args)
  with_scope(:find => { :conditions =>  "account_id = #{$account.id}" }) do
    super(*args)
  end
end

account_id가 모호한 몇 가지 경우를 제외하고는 훌륭하게 작동하므로 다음과 같이 조정했습니다.

def self.find(*args)
  with_scope(:find => { :conditions =>  "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
    super(*args)
  end
end

이것도 훌륭하게 작동하지만 DRY를 원합니다.이제 이런 종류의 기능을 사용하고 싶은 몇 가지 다른 모델이 있습니다.이를 수행하는 가장 좋은 방법은 무엇입니까?

답변하실 때 메타프로그래밍 Ruby-fu를 이해하는 데 도움이 되는 코드를 포함해 주세요.

(저는 Rails v2.1을 사용하고 있습니다)

도움이 되었습니까?

해결책

사용 중인 레일 버전이 무엇인지 알려주지 않으셨습니다. [편집 - 레일 2.1에 있으므로 다음 조언은 완전히 작동합니다], find yourself를 오버로드하는 대신 다음 형식을 사용하도록 권장합니다.

account.contacts.find(...) 

그러면 사용자 절이 포함된 범위에서 찾기가 자동으로 래핑됩니다(account_id가 있으므로 가까운 곳에 계정이 있다고 가정합니다).

범위에 대한 다음 리소스를 확인하는 것이 좋습니다.

다른 팁

Jean의 조언은 타당합니다.모델이 다음과 같다고 가정합니다.

class Contact < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :contacts
end

당신은 contacts 현재 계정을 연결하여 Contact 해당 계정으로 범위가 지정된 레코드는 다음과 같습니다.

@account.contacts

연락처 쿼리에 추가 조건을 추가하려면 find를 사용하여 조건을 지정할 수 있습니다.

@account.contacts.find(:conditions => { :activated => true })

활성화된 사용자에 대해 지속적으로 쿼리하는 경우 이를 명명된 범위로 리팩터링할 수 있습니다.

class Contact < ActiveRecord::Base
  belongs_to :account
  named_scope :activated, :conditions => { :activated => true }
end

그런 다음 다음과 같이 사용합니다.

@account.contacts.activated

문제에 대한 구체적인 답변을 제공하려면 위에서 언급한 방법을 문제의 모델에 포함될 모듈로 옮기는 것이 좋습니다.그래서 당신은

class Contact
  include NarrowFind
  ...
end

추신.SQL에서 account_id를 이스케이프하는 것을 조심하세요. 아마도 다음을 사용해야 할 것입니다. :conditions=>[".... =?", $account_id] 통사론.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top