Вопрос

У меня есть несколько моделей, для которых необходимо задать специальные условия поиска.Например, если у меня есть модель контактов, каждый раз, когда вызывается 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

Это тоже отлично работает, однако я хочу, чтобы оно было СУХИМ.Теперь у меня есть несколько разных моделей, в которых я хочу использовать такую ​​функцию.Как лучше всего это сделать?

Когда вы ответите, пожалуйста, включите код, который поможет нашему разуму понять метапрограммирование Ruby-fu.

(Я использую Rails v2.1)

Это было полезно?

Решение

Вы не сообщаете нам, какую версию рельсов вы используете [отредактируйте - она ​​находится на рельсах 2.1, поэтому следующий совет полностью работоспособен], но я бы рекомендовал вам использовать следующую форму вместо перегрузки find себя:

account.contacts.find(...) 

это автоматически перенесет поиск в область, в которую включено предложение пользователя (поскольку у вас есть account_id, я предполагаю, что у вас есть учетная запись где-то рядом)

Я предлагаю вам проверить следующие ресурсы по областям действия.

Другие советы

Совет Джина здравый.Предположим, что ваши модели выглядят так:

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