Передача параметров кросс-области в Rails 3

Я пытаюсь запросить базу данных, которая использует соединение, чтобы найти пользователей, которым требуется предупреждение. Мой запрос отлично работает в модели, для которой он написан, а также работает в области видимости, когда передаваемый параметр является явным. Однако, когда я передаю параметр как переменную, он не работает. Вот мой код:

class Alert < ActiveRecord::Base
  belongs_to :user
  attr_accessible :first_alert, :second_alert, :third_alert, :user_id
  def self.find_users_to_alert(time)
    where(:third_alert => time)
  end
  scope :alerter, find_users_to_alert (here is where i want to pass param)
end

class User < ActiveRecord::Base
  has_many :alerts
  attr_accessor :password
  attr_accessible :name, :email, :password, :password_confirmation

  scope :alerts_to_be_sent, joins(:alerts) & Alert.alerter
end

Ошибка, которую я получаю, - это неопределенная локальная переменная или метод NameError. Но я бы подумал о передаче значения переменной в консоли рельсов, например:

User.alerts_to_be_sent(5)

было бы хорошо. Помощь будет оценена спасибо.


person Hugs    schedule 08.02.2012    source источник


Ответы (2)


Из Руководства по интерфейсу запросов Active Record:

Использование метода класса является предпочтительным способом принятия аргументов для областей. Эти методы по-прежнему будут доступны для объектов ассоциации [...]

Вместо этого напишите методы класса:

class Alert < ActiveRecord::Base
  def self.alerter(t)
    find_users_to_alert(t)
  end
end

def User < ActiveRecord::Base
  def self.alerts_to_be_sent(t)
    joins(:alerts) & Alert.alerter(t)
  end
end
person mu is too short    schedule 08.02.2012
comment
спасибо, вы избавили меня от многих разочарований. Мне вообще не нужно было использовать прицел. Комбинированные методы класса работали хорошо. - person Hugs; 09.02.2012

Я думаю, вы ищете синтаксис области лямбда

scope :alerter, lambda { |number| find_users_to_alert(number) }
scope :alerts_to_be_sent, lambda { |number| joins(:alerts) & Alert.alerter(number) }
person Bradley Priest    schedule 08.02.2012
comment
Это тоже сработает, но методы класса являются предпочтительным способом, но предпочтения различаются. - person mu is too short; 09.02.2012
comment
Да, лично я сделал бы область alerts_to_be_sent методом класса из-за ее сложности, но иногда краткость областей действия кажется мне более приятной. Опять же, это вопрос предпочтений. - person Bradley Priest; 09.02.2012
comment
Обратите внимание, почему они предпочтительнее - область действия может быть объединена в цепочку и т. д. - например, current_user.products.available я не думаю, что вы можете реализовать availableкак метод класса здесь. - person DavidC; 30.01.2013
comment
class Product; def self.available; self.where(available: true); end; end можно полностью связать - person Bradley Priest; 30.01.2013