在Ruby on rails中,我们的模型包括订单和付款。 订单和付款之间存在一对多的关系。 在订单模型中,我们指定: has_many:payments,:as => :应付 付款记录的payment_id设置为order.id。
在报告中,我想选择属于给定类型订单的所有付款。 使用: payments = Payment.find(:all,:conditions =>条件) 并在条件中添加'payable.type =“a”'不起作用。 似乎ActiveRecord没有将它开发成正确的连接语句(payable_id = order.id和orders.type ='a')。 我不能在这里使用显式SQL,因为条件包含在代码中较早插入的其他内容。 谢谢, Raffi Lipkin
答案 0 :(得分:2)
您的条件条款错误。
您声明Order
has_many :payments, :as => :payable
这告诉我Payment
belongs_to :payable, :polymorphic => true
这意味着payments
表格有两列注释:payable_id
和payable_type
。这也意味着Payments
不仅可以应用于Orders
,还可以应用于其他模型(CreditCardBalances
,谁知道)。
如果要查询特定类型的付款,即属于特定类的任何实例,则需要查询字段payments.payable_type
。这很好用:
Payment.find(:all, :conditions => "payable_type = 'Order'")
Here's a gist显示了我为测试此操作所做的工作。创建的模型如上所述进行设置。
不要忘记,如果更容易,可以将其提取到命名范围中:
named_scope :on_orders, :conditions => "payable_type = 'Order'"
使它成为
Payment.on_orders
或动态:
named_scope :on, lambda { |type| { :conditions => "payable_type = '#{type.to_s}'" } }
然后才能成功
Payment.on(Order) # or Payment.on(CreditCardBalance) or Payment.on("Order")
答案 1 :(得分:1)
尝试在条件中倾斜并引用实际的表ID名称,而不是关联别名:
find(:include => "payments", :conditions => ["payment.type = ?", "x"]
答案 2 :(得分:0)
你提到'付款方式'。如果它们是相当静态的,您是否考虑使用单表继承(STI)来子类化不同的支付类型?然后Rails会做所有魔术来过滤类型。
E.g。
class CreditCardPayment < Payment
...
end
它最初甚至不需要表现出不同的行为;但是你可能会发现,在付款方面有不同的数据和多态行为是非常有用的。