Опрос отношений в ARel - PullRequest
       3

Опрос отношений в ARel

1 голос
/ 27 апреля 2011

Я делаю что-то вроде этого:

@invoices = Invoice.order(:due_date)
@invoices = @invoices.where(:invoiced => true)

Теперь я хочу отфильтровать счета по идентификатору связанной модели (мне нужны только счета, в которых идентификатор владельца проекта счета соответствует определенному идентификатору). На данный момент я делаю это:

owner_id = #get owner_id somehow
@invoices = @invoices.find_all do |invoice|
  invoice.project.owner_id == owner_id
end

Конечно, это немного грязно, и я делаю это в контроллере, что я бы предпочел не делать. Кроме того, это разрушает весь смысл ARel. Я не могу понять, как сделать выше, используя предложение ARel where, хотя. Есть идеи?

Я не могу просто поместить все это в метод класса, потому что order и where используются для других путей кода, и мне пришлось бы дублировать их для этого особого случая (что не правильно ).

Редактировать: Глядя на этот связанный вопрос похоже, мне может понадобиться использовать MetaWhere , чтобы сделать это чисто. Мысли

Edit2: Я пошел с ответом fl00r , добавив область к Счету:

#invoice.rb
scope :academic, lambda {
  academic_id = #get academic_id somehow
  joins(:project).where(:projects => { :owner_id => academic_id })
}

Я также добавил области действия для invoiced и not_invoiced, так что теперь я могу сделать @invoices.invoiced.academic в моем контроллере, что намного чище.

1 Ответ

3 голосов
/ 27 апреля 2011
@invoices = Invoice.order(:due_date).joins(:project).
  where(:invoiced => true, :projects => {:owner_id => owner_id})
# you can also uniq the list
@invoices.uniq!

UPD

Также вы можете пойти другим путем

@owner = Owner.find_some
@invoices = @owner.projects.include(:invoices).map(&:invoices).flatten

Или даже немного рефакторинг:

class Owner < AR::Base
  has_many :projects
  has_many :invoices, :through => :projects
end

@invoices = @owner.invoices
...