Msencenb
Msencenb

Reputation: 5104

Rails accepts_nested_attributes_for unable to associate (or find) record passed in

Our Attachment model (in this case used for logos associated to teams) gets saved to the database before we associate it to the team. We do that because we do client side S3 uploading, so we need to generate an S3 key and confirm before we associate it with another model in the database.

The team model references the attachment class like this:

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

Attachment class references polymorphic attachable like this:

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

In the controller we accept the nested attributes:

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

But when the PUT comes across, we get this: enter image description here

Essentially, Rails can't find that attachment because the attachable is not set on attachment with id 1021.

What I want is for Rails to find the attachment based on ID (and only ID) and then associate it with the team.

Am I missing something obvious for how accepts nested attributes for should work in this case?

Upvotes: 0

Views: 57

Answers (1)

Beartech
Beartech

Reputation: 6411

Waiting on some more info, but in the meantime I think you might just want to pass the params like this:

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

Rails should understand the passing of logo_ids since it has the has_many and accepts_nested_attributes_for in the model.

Rails understands ..._ids in these contexts. So you should be able to say on the console:

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

and it will do a lookup of those logos and attempt to attach them on save. You can also call @team.logo_ids and it will return an array of the attached logo ids.

Upvotes: 0

Related Questions