Search code examples
ruby-on-railsassociationshas-manypolymorphic-associations

Rails Unknown attribute error, but attribute does exist


I'm getting the error unknown attribute id when I run

@user.payments.create(payment_params)

I know this means I need a user_id in my payments table. But I'm using polymorphic associations (perhaps incorrectly?) and my payments table has a payee_id and a payer_id (for each "type" of user). In the above method the @user instance is a payer.

Here are the payment and user models:

class Payment < ActiveRecord::Base
  belongs_to :payee, :class_name => 'User', :foreign_key => 'payee_id'
  belongs_to :payer, :class_name => 'User', :foreign_key => 'payer_id'
end

class User < ActiveRecord::Base
  has_many :payments
end

And the create action in the payment controller:

def create
  @user = User.find_or_create_by(user_params)
  @payment = @user.payments.create(payment_params)
end

The polymorphic associations are confusing me. How can I correct this error?


Solution

  • This is not a polymorphic association. You have to define relations correctly to get the payments you need to get. From the code i understand that this is kind of loan application.

    The user in the above model does not have a single type of payment. There are two types of payments, the ones user gets money for, lets say incoming_payments and the one which user has to give money outgoing_payments. The relation should be defined like

    class Payment < ActiveRecord::Base
      belongs_to :payee, :class_name => 'User', :foreign_key => 'payee_id'
      belongs_to :payer, :class_name => 'User', :foreign_key => 'payer_id'
    end
    
    
    class User < ActiveRecord::Base
      has_many :incoming_payments, :class_name => 'Payment', :foreign_key => 'payee_id'
      has_many :outgoing_payments, :class_name => 'Payment', :foreign_key => 'payer_id'
    end
    

    So if the user you are querying payments for is a payer then you should call user.outgoing_payements and if the user is a lender then you should call user.incoming_payments