Reputation: 126
I am trying to achieve polymorphic behaviour in my rails application.
I have 3 models
:
Transaction has a Party(either customer or supplier).
I have created a model Party
as concern
when I am trying to save or update I receive this error.
The models are as follows:
party.rb
module Party
extend ActiveSupport::Concern
included do
has_many :transactions, :as => :party
end
end
customer.rb
class Customer < ApplicationRecord
include Party
....
end
supplier.rb
class Supplier < ApplicationRecord
include Party
....
end
transaction.rb
class Transaction < ApplicationRecord
belongs_to :party, polymorphic: true
....
end
When hit save the params received at server are
Parameters: {"authenticity_token"=>"....", "transaction"=>{"party"=>"4", ...}, "commit"=>"Update Transaction", "id"=>"2"}
Hope someone can figure out the issue. Thanks for your time.
Here is the transactions schemea.
create_table "transactions", force: :cascade do |t|
t.date "date"
t.string "transaction_type"
t.integer "supplier_id"
t.integer "customer_id"
t.string "party_type", null: false
t.bigint "party_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["party_type", "party_id"], name: "index_transactions_on_party_type_and_party_id"
end
Upvotes: 2
Views: 1410
Reputation: 1
There is problem with params, it contains "party" => "4", for polymorphic association you can have one of the following:
"transaction"=>{"party_type" => "Customer", "party_id" => "4", ... }
"transaction"=>{"party" => <Customer OR supplier object>, ... }
Rails will try transactioin.party.class.primary_key
to find out primary_key column, in above case it will get String
for transaction.party.class
and hence it will raise NoMethodError (undefined method
primary_key' for String:Class)`.
You can try assigning transaction.party = "4"
in rails console, you will get same error.
Upvotes: 0
Reputation: 11
According to what you exposed here, this issue is caused by the params sent. You need to make sure that "party_id" holds the polymorphic resource id and "party_type" either "customer" or "supplier". Also as you are using rails' polymorphic behaviour, "supplier_id" and "party_id" columns are no longer relevant.
Upvotes: 1
Reputation: 101
If you want to achieve Polymorphism using Party you will have to change the code as the following:
Your code treat party as a module which does not implement primary_key method as the activerecord use it to build the associations on create or update.
Upvotes: 1
Reputation: 371
Can you add transactions table schema in question?
I am assuming that the transactions table has party_id
and party_type
.
So if the columns are present then you need check view so that in params controller should receive like "transaction"=>{"party_id"=>"4", "party_type"=>"custmer"...}
Upvotes: 2