Hello, tell me how to determine the relationship, depending on the attribute of the model? The User model has a pay_currency attribute, which can be 'real' or 'bitcoin'. There are 2 engines (Tbitcoin, Tstripe) each of which has the same payment table.

You need to find a way to create a payment from the user, send it to the desired engine automatically.

# Пример создания payments User.create(pay_currency: 'real').payments.create # => Tstripe::Payments 

Sample code for ideas

 class User < ActiveRecord::Base has_many :payments, ~> { where "pay_currency = 'real'" } , class_name: Tstripe::Payment, foreign_key: :uid has_many :payments, ~> { where "pay_currency = 'bitcoin'" } ,class_name: Tbitcoin::Payment, foreign_key: :uid end 

In what direction to think to implement such dynamics?

  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

1 answer 1

First, make different names for these associations, otherwise they will overlap each other and you will be a great bang:

 has_many :stripe_payments, class_name: Tstripe::Payment, foreign_key: :uid has_many :bitcoin_payments, class_name: Tbitcoin::Payment, foreign_key: :uid 

And then just make a choice of one of two associations. There are a whole bunch of ways.


You can make a method in User that accepts a payment method and returns one of the two associations (you need to catch cases when a non-existing method is obtained).

You can make a "payment creator", one of the parameters of which is the payment method, and it will choose the association inside.

You can simply place them in different controllers and refer not to "general" payments , but only to specific ones.

Choose any.

  • IMHO the second method is preferable. In the case of the first a lot of inaccurate code, and more difficult to maintain. - anoam
  • @anoam I'd rather choose the third. The choice of the payment engine in this case is being shipped to some kind of otfonarny parameter, the controller could well be this parameter. And bred by inheritance, if necessary. - D-side
  • Many thanks for the answer, the power of ROR development is the solution of one problem in thousands of ways)), for the solution I chose 1 method (with a slight change), it turned out that the emulation type has_many, which was distributed from the condition of what kind of extension to use). If someone needs this implementation example - Alex