Полиморфная ассоциация Rails Неинициализированная Постоянная Ошибка
Работал над отладкой в течение нескольких часов и до сих пор не могу найти решение. Когда я отправляю запрос PUT, который вызывает @action.save в методе обновления моего контроллера транзакций, мой журнал сервера выплевывает:
NameError - uninitialized constant Transaction::Respondable:
Базовая соответствующая схема: у пользователей и организаций могут быть запросы, у запросов могут быть транзакции, а у пользователей и организаций также могут быть транзакции. Различие заключается в том, что транзакция существует между Лицом / Организацией 1, который инициализирует запрос, и Лицом / Организацией 2, который отвечает на запрос. Другими словами, Транзакция принадлежит как Запросу (и через запрос Пользователь / Организация 1), так и Пользователю / Организации 2. Сейчас я просто ищу пользователей, поэтому пока не буду включать код об Организациях, поскольку еще не реализовано. Вот соответствующий код:
Схема:
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 относится к запросу (также полиморфному, поскольку он также может быть получен из предложения, но пока не имеет значения). Ответственный относится к Пользователю.
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
Пользовательская схема не имеет значения, поскольку она не содержит ссылок на другие таблицы (has_many только отношения).
А вот и мои модели:
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
И Контроллер транзакций:
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
Самое странное в этом заключается в том, что в Rails Controller такие вызовы, как User.first.responded_transactions или Transaction.first.respondable, работают. Тем не менее, кажется, что что-то, связанное с ответом, терпит неудачу где-то... Любая помощь будет принята с благодарностью
1 ответ
Проблема заключается в вашей проверке. Попробуйте проверить ваши полиморфные столбцы индивидуально. Позволь мне показать тебе:
validates(
:respondable_id,
uniqueness: {
scope: [:respondable_type, :listable_id, :listable_type],
message: "You've already initialized a transaction on this item"
}
)