如何使named_scope与连接表一起正常工作?
这是我的情况。我有两个表:pledges 和 pledge_transactions。当用户做出承诺时,他在承诺表中只有一行。
稍后,当需要履行承诺时,每笔付款都会记录在我的 pledge_transactions 表中。
我需要能够查询所有未完成的质押,这意味着交易表中的金额总和小于质押金额。
这是我到目前为止所得到的:
named_scope :open,
:group => 'pledges.id',
:include => :transactions,
:select => 'pledge_transactions.*',
:conditions => 'pledge_transactions.id is not null or pledge_transactions.id is null',
:having => 'sum(pledge_transactions.amount) < pledges.amount or sum(pledge_transactions.amount) is null'
您可能会问自己为什么我指定了那个多余且荒谬的条件选项。答案是,当我不强制ActiveRecord在条件中确认pledge_transactions表时,它完全忽略了它,这意味着我的having子句变得毫无意义。
我相信我遇到了 ActiveRecord 的缺点。
最终我需要能够执行以下操作:
- Pledge.open
- Pledge.open.count
- Pledge.open.find(:all, ...)
- 等。
有人对这个问题有更优雅的答案吗?请不要建议每次交易发生时增加承诺 amount_given 字段。这感觉就像是一种创可贴方法,我更喜欢在承诺创建后保持静态并计算差异。
如果我没有在这里使用 Rails,我只需创建一个视图并完成它。
谢谢!
Here's my situation. I have two tables: pledges and pledge_transactions. When a user makes a pledge, he has only a row in the pledges table.
Later when it comes time to fulfill the pledge, each payment is logged in my pledge_transactions table.
I need to be able to query all open pledges which means that the sum of the amounts in the transactions table is less than the pledged amount.
Here's what I have so far:
named_scope :open,
:group => 'pledges.id',
:include => :transactions,
:select => 'pledge_transactions.*',
:conditions => 'pledge_transactions.id is not null or pledge_transactions.id is null',
:having => 'sum(pledge_transactions.amount) < pledges.amount or sum(pledge_transactions.amount) is null'
You might be asking yourself why I have that superfluous and ridiculous conditions option specified. The answer is that when I don't force ActiveRecord to acknowledge the pledge_transactions table in the conditions, it omits it completely, which means my having clause becomes meaningless.
My belief is that I have run into a shortcoming of ActiveRecord.
Ultimately I need to be able to do the following:
- Pledge.open
- Pledge.open.count
- Pledge.open.find(:all, ...)
- etc.
Anybody have a more elegant answer to this problem? Please no suggestions of incrementing a pledges amount_given field each time a transaction occurs. That feels like a band-aid approach and I'm much more of a fan of keeping the pledge static after it is created and computing the difference.
If I weren't using Rails here, I'd just create a view and be done with it.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
:transactions
关联是如何定义的?它是否规定:class_name = 'PledgeTransaction'
(或者无论该类是什么,如果它使用set_table_name
)?您看过
:joins
参数吗?我想这可能就是您正在寻找的。当然,:conditions
看起来不太对劲。仅仅因为它是 Rails 并不意味着您不能使用视图。好的,根据它的构建方式,您可能无法更新它,但除此之外,请继续更新。您也可以在迁移中创建和删除视图:
我认为书籍/文档不会讨论这么多,因为视图的实现和支持在不同平台上存在很大差异。
How is the
:transactions
association defined? Does it stipulate:class_name = 'PledgeTransaction'
(or whatever the class is, if it usesset_table_name
)?Have you looked at the
:joins
parameter? I think it might be what you were looking for. Certainly that:conditions
thing doesn't look right.Just because it's Rails doesn't mean you can't use a view. OK, depending on the way it's constructed you may not be able to update it, but otherwise go for it. You can create and drop views in migrations, too:
I think the books/docs don't go into this much because implementation of, and support for views varies significantly across platforms.
我认为在您的条件中使用
NOT EXISTS
会得到您想要的。我假设关联在pledge_transaction
上为pledge_id
。以下是我将如何实现#open
这将允许您执行 Pledge.open、Pledge.open.count 和 Pledge.open.find_by_{whatever}。
I think using
NOT EXISTS
in your conditions will get you what you want. I'm assuming the association is on thepledge_transaction
aspledge_id
. Here's how I would implement#open
This will allow you to do Pledge.open, Pledge.open.count and Pledge.open.find_by_{what ever}.