查询 ARel 中的关系

发布于 2024-11-03 14:02:35 字数 1283 浏览 4 评论 0原文

我正在做这样的事情:

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

现在,我想按相关模型的 id 过滤发票(我只需要发票项目所有者的 id 与某个 id 匹配的发票)。目前我正在这样做:

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

当然,这有点混乱,而且我是在控制器中做的,我宁愿不这样做。而且,它破坏了 ARel 的全部意义。不过,我无法弄清楚如何使用 ARel where 子句执行上述操作。有什么想法吗?

我不能将所有这些都放入一个类方法中,因为 orderwhere 用于其他代码路径,并且我必须为这个特殊的复制它们情况(这是不对的)。

编辑:看看这个相关问题,看起来我可能需要使用 MetaWhere 来干净地完成此操作。想法?

编辑2:我选择了fl00r的答案,添加发票的范围:

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

我还添加了 invoicednot_invoiced 的范围,所以我现在可以这样做我的控制器中的 @invoices.invoiced.academic ,这更加干净。

I'm doing something like this:

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

Now, I want to filter the invoices by the id of a related model (I need only the invoices where the id of the invoice's project's owner matches a certain id). At the moment I'm doing this:

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

Of course, this is a bit messy, and I'm doing it in the controller, which I'd rather not do. Also, it breaks down the whole point of ARel. I can't work out how to do the above using an ARel where clause though. Any ideas?

I can't just put this all into a class method, because the order and where are used for other code paths, and I'd have to duplicate them for this special case (which ain't right).

Edit: Looking at this related question it looks like I may need to use MetaWhere to do this cleanly. Thoughts?

Edit2: I went with fl00r's answer, adding a scope to Invoice:

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

I also added scopes for invoiced and not_invoiced, so I can now do @invoices.invoiced.academic in my controller, which is much cleaner.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清音悠歌 2024-11-10 14:02:35
@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
@invoices = Invoice.order(:due_date).joins(:project).
  where(:invoiced => true, :projects => {:owner_id => owner_id})
# you can also uniq the list
@invoices.uniq!

UPD

Also you can go another way

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

Or even refactor a little:

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

@invoices = @owner.invoices
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文