ROR- Can't use Find in 1-many ratio

In Ruby on rails, our model includes orders and payments. There is 1-lot relationship between order and payments. In the order model, we specify: has_many: payments ,: as =>: payable And the payment record has a payable_id, which is set to order.id.

In the report, I want to select all payments belonging to orders of a certain type. With: payments = Payment.find (: all ,: conditions => conditions) and adding 'payable.type = "a"' to conditions doesn't work. It seems that ActiveRecord does not evolve this into the correct join operator (payable_id = order.id and orders.type = 'a'). I cannot use explicit SQL here as the condition contains other things that were inserted there earlier in the code. Thanks, Raffi Lipkin

+1


a source to share


3 answers


The terms offer is incorrect.

You indicate that Order

has_many :payments, :as => :payable

      

This tells me that a Payment

belongs_to :payable, :polymorphic => true

      

This means that the table payments

has two comment columns: payable_id

and payable_type

. It also means that it payments

can be applied not only to Orders

, but also to other models ( CreditCardBalances

who knows).

If you want to request payments of a specific type, i.e. belonging to any instance of a specific class, you need to query the field payments.payable_type

. This works great:

Payment.find(:all, :conditions => "payable_type = 'Order'")

      

Here's a gist that shows what I did to test it out. The created models are configured as described above.



Don't forget that you can extract this into named scopes if it's easier:

named_scope :on_orders, :conditions => "payable_type = 'Order'"

      

That makes him

Payment.on_orders

      

Or dynamically:

named_scope :on, lambda { |type| { :conditions => "payable_type = '#{type.to_s}'" } }

      

Which then does it

Payment.on(Order) # or Payment.on(CreditCardBalance) or Payment.on("Order")

      

+2


a source


Try to include and reference the actual table id name in the condition, rather than the association alias:



find(:include => "payments", :conditions => ["payment.type = ?", "x"]

      

+1


a source


You specify the type of payment. If they are fairly static, would you consider using unidirectional inheritance (STI) to subclass different types of payments? Then Rails does all the magic to filter by type.

eg.

class CreditCardPayment < Payment
...
end

      

You don't even need to exhibit different behavior in the beginning; however, you will probably find it really useful to have different data and polymorphic behavior in relation to payments.

0


a source







All Articles