Been working on debugging this for a few hours and still can't find the solution. When I send a PUT request that calls @transaction.save in the update method of my Transaction Controller, my server log spits out:
NameError - uninitialized constant Transaction::Respondable:
Basic relevant schema is both Users and Organizations can have Requests, Requests can have Transactions, and both Users and Organizations can also have Transactions. The differentiation is that the transaction exists between Person/Organization 1, who initializes the request and Person/Organization 2, who responds to the request. In other words, a Transaction belongs to both a Request (and through a request User/Orgnization 1) and User/Organization 2. I'm just looking for now at Users, so I won't include code about Organizations for now since it's not yet implemented. Here's the relevant code:
Schema:
create_table "transactions", force: true do |t|
t.string "name", null: false
t.string "description", null: false
t.integer "listable_id", null: false
t.string "listable_type", null: false
t.integer "respondable_id", null: false
t.string "respondable_type", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
listable refers to the Request (also polymorphic, since it can also come from an Offer, but irrelevant for now). respondable refers to the User.
create_table "requests", force: true do |t|
t.string "name", null: false
t.string "description", null: false
t.integer "requestable_id", null: false
t.string "requestable_type", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
User schema is irrelevant since it contains no links to other tables (only relationships are has_many).
And here are my models:
class User < ActiveRecord::Base
...
has_many :requests, as: :requestable, dependent: :destroy
has_many :responded_transactions, class_name: 'Transaction', as: :respondable, dependent: :destroy
has_many :listed_transactions, through: :requests, source: :transactions
...
end
class Request < ActiveRecord::Base
validates :name, :description, :requestable, presence: true
has_many :transactions, as: :listable, dependent: :destroy
belongs_to :requestable, polymorphic: true
def relevant_transaction(user)
self.transactions.where('respondable_id = ?', user.id).first
end
end
class Transaction < ActiveRecord::Base
validates :name, :description, :listable, :respondable, presence: true
validates :respondable, uniqueness: { scope: :listable, message: 'You have already initialized a transaction on this item' }
belongs_to :listable, polymorphic: true
belongs_to :respondable, polymorphic: true
before_validation :set_name_and_description
private
def set_name_and_description
self.name = listable.name
self.description = listable.description
end
end
And the TransactionsController:
module Api
class TransactionsController < ApplicationController
def create
@transaction = current_user.responded_transactions.new(transaction_params)
if @transaction.save
render :show, status: :created
else
render json: @transaction.errors.full_messages, status: :unprocessable_entity
end
end
def update
@transaction = Transaction.find(params[:id])
if @transaction.save
render :show, status: :saved
else
render json: @transaction.errors.full_messages, status: :unprocessable_entity
end
end
private
def transaction_params
params.require(:transaction).permit(:listable_id, :listable_type)
end
end
end
The weirdest thing about this is that in the Rails Controller, making calls like User.first.responded_transactions or Transaction.first.respondable work. Yet it seems like something related to respondable is failing somewhere... Any help would be greatly appreciated!
The problem lies in your validation. Try validating your polymorphic columns individually. Let me show you:
validates(
:respondable_id,
uniqueness: {
scope: [:respondable_type, :listable_id, :listable_type],
message: "You've already initialized a transaction on this item"
}
)