#ruby-on-rails #view #routes #controller
Вопрос:
У меня есть Payment
, Client
и PaymentTransactions
модель. Я пытаюсь показать все PaymentTransactions
для данного Client
, но контроллер возвращает пустой массив.
Маршрут, которым я пользуюсь, чтобы добраться туда, таков /api/v1/clients/:id/payment_transactions
Это мой файл маршрутов:
Rails.application.routes.draw do
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :payments, only: [ :index ]
resources :clients, only: [ :index ]
resources :clients, only: [:show] do
resources :payment_transactions, only: [:index]
end
end
end
end
Рельсовые пути:
Uri Pattern /api/v1/clients/:client_id/payment_transactions
Controller#Action api/v1/payment_transactions#index {:format=>:json}
Это мои модели:
class Payment < ApplicationRecord
belongs_to :client, optional: true, dependent: :destroy
has_many :payment_transactions, dependent: :destroy
end
class Client < ApplicationRecord
has_one :payment, dependent: :destroy
has_many :payment_transactions, through: :payment, dependent: :destroy
end
class PaymentTransaction < ApplicationRecord
belongs_to :payment, optional: true
has_one :client, through: :payment
end
А это мой контроллер:
class Api::V1::PaymentTransactionsController < Api::V1::BaseController
before_action :set_client
def index
@transactions = PaymentTransaction.where(client: @client)
end
private
def set_client
@client = Client.find(params[:client_id])
end
end
Я могу сделать PaymentTransaction.client
и получить Клиента, связанного с этой платежной операцией. Я также могу сделать все, Client.payment_transactions
чтобы получить все транзакции для данного Клиента.
Однако, сделав звонок на /api/v1/clients/1/payment_transactions
возврат []
.
Редактировать:
Изменение действия контроллера @transactions = PaymentTransaction.where(client_id: @client.id)
, приведшее к
ActionView::Template::Error (PG::UndefinedColumn: ERROR: column payment_transactions.client_id does not exist
LINE 1: ...transactions".* FROM "payment_transactions" WHERE "payment_t...
^
):
1: json.array! @transactions do |transaction|
2: json.extract! transaction, :id, :payment_id, :transaction_identification, :amount, :status
3: end
Комментарии:
1. Просто сделай
@transactions = Payment transaction.where(client_id: @client.id)
или@transactions = @client.payment_transactions
2. Спасибо! @Maxence. Последнее сработало. Первый из них привел к ошибке, которую я добавил в операцию.
3. Моя ошибка. Модель PaymentTransaction не имеет столбца client_id. Последнее должно сработать.
Ответ №1:
where
Метод ActiveRecord ожидает, что его входные данные будут столбцами в вызываемой модели, поэтому вы не можете использовать его для фильтрации по промежуточным ассоциациям. Вместо этого вы можете вызвать определенное payment_transaction
asosciation непосредственно из @client
объекта.
def index
@transactions = @client.payment_transactions
end
Примечание сбоку:
Использование ассоциации напрямую имеет дополнительное преимущество, позволяющее вам загружать записи позже, на случай, если вам когда-либо понадобится перечислить клиентов вместе с их платежными транзакциями. например
Client.all.includes(:payment_transactions)
Использование a where
не сделает это легко выполнимым.
Комментарии:
1. Спасибо! @Абдулазиз