Techioz Blog

Rails accepts_nested_attributes_for が渡されたレコードを関連付けることができません (または検索できません)

概要

アタッチメント モデル (この場合、チームに関連付けられたロゴに使用されます) は、チームに関連付ける前にデータベースに保存されます。これを行うのは、クライアント側で S3 アップロードを行うためです。そのため、S3 キーを生成し、それをデータベース内の別のモデルに関連付ける前に確認する必要があります。

チーム モデルは次のようにアタッチメント クラスを参照します。

Class Team < ApplicationRecord
 has_many :logos, as: :attachable, class_name: "Attachment", dependent: :destroy, after_add: :cache_logo_url, inverse_of: :attachable
 accepts_nested_attributes_for :logos, allow_destroy: true
end

アタッチメント クラスは、次のようにポリモーフィック アタッチ可能オブジェクトを参照します。

class Attachment < ApplicationRecord
  belongs_to :attachable, polymorphic: true, optional: true
end

コントローラーでは、ネストされた属性を受け入れます。

class Api::V1::TeamsController < Api::V1::BaseController
  def update
    @team = Team.find(params[:id])
    authorize @team

    if @team.update(params)
      render status: :no_content
    else
      validation_error(@team.errors)
    end
  end

  private
  def team_params
    params.require(:team).permit(
      :name, 
      logos_attributes: [:id, :_destroy]
    )
  end
end

しかし、PUT を実行すると、次のようになります。

基本的に、ID 1021 の添付ファイルにアタッチ可能ファイルが設定されていないため、Rails はその添付ファイルを見つけることができません。

私が望んでいるのは、Rails が ID (および ID のみ) に基づいて添付ファイルを検索し、それをチームに関連付けることです。

この場合、ネストされた属性をどのように受け入れるかについて、明らかな何かが欠けているのでしょうか?

解決策

もう少し情報を待っていますが、それまでは次のようにパラメータを渡したいと思うかもしれません。

params: {"teams"=>{logo_ids[1,2,3]}} 

Rails はモデルに has_many と accepts_nested_attributes_for があるため、logo_id の受け渡しを理解する必要があります。

Rails はこれらのコンテキストで …_id を理解します。したがって、コンソールで次のように言うことができるはずです。

@team.logo_ids = [1,2,3]

そして、それらのロゴを検索し、保存時に添付しようとします。 @team.logo_ids を呼び出すこともでき、添付されたロゴ ID の配列が返されます。