Description:
I’m working on a Rails application where I have a Picture model that has a nested Pictureclass model. The index (the gallery of pictures) and the show (a detail of the picture) are showing their category, tipu, and style values. The form for editing/creating also works well, but when I try to create/update a Picture record, I encounter the following error:
NoMethodError in PicturesController#update
undefined method `category_id’ for an instance of Picture
Controller
class PicturesController < ApplicationController
before_action :set_picture, only: %i[ show edit update destroy ]
def index
@pictures = Picture.where('start_date >= ?', Date.today).order(start_date: :asc)
@pictureclasses = Pictureclass.where(picture_id: @pictures.pluck(:id)).includes(:category, :ritme, :tipu)
@categories = @pictureclasses.map(&:category)
@styles = @pictureclasses.map(&:style)
@tipus = @pictureclasses.map(&:tipu)
end
def show
@pictureclasses = Pictureclass.where(picture_id: @picture.id).includes(:category, :ritme, :tipu)
@categories = @pictureclasses.map(&:category)
@styles = @pictureclasses.map(&:style)
@tipus = @pictureclasses.map(&:tipu)
end
def edit
@picture = Picture.find_by(slug: params[:id])
@picture.build_pictureclass if @picture.pictureclass.nil?
@pictureclasses = Pictureclass.where(picture_id: @picture.id).includes(:category, :ritme, :style)
end
def update
if @picture.update(picture_params)
redirect_to @picture, notice: "Picture was successfully updated."
else
render :edit, status: :unprocessable_entity
end
end
private
def set_picture
@picture = Picture.friendly.find(params[:id])
end
def picture_params
params.require(:picture).permit(:start_date, :start_time, :start_point, :title, :descripcio, :ruta_foto, :Km, :slug, :max_inscrits, :min_inscrits, :num_dies, :fi_ndies, :oberta, pictureclass_attributes: [:id, :category_id, :tipu_id, :style_id])
end
end
Models:
class Picture < ApplicationRecord
has_one :pictureclass, dependent: :destroy
accepts_nested_attributes_for :pictureclass, allow_destroy: true
has_one :category, through: :pictureclass
has_one :tipu, through: :pictureclass
has_one :style, through: :pictureclass
end
class Pictureclass < ApplicationRecord
belongs_to :category
belongs_to :style
belongs_to :tipu
belongs_to :picture
end
class Category < ApplicationRecord
has_many :pictureclasses, dependent: :destroy
has_many :pictures, through: :pictureclasses
end
class Tipu < ApplicationRecord
has_many :pictureclasses, dependent: :destroy
has_many :pictures, through: :pictureclasses
end
class Style < ApplicationRecord
has_many :pictureclasses, dependent: :destroy
has_many :pictures, through: :pictureclasses
end
Form
<%= form_with(model: @picture, class: "contents text-sm") do |form| %>
<%= form.fields_for :pictureclass do |pictureclass_form| %>
<div class="field">
<%= pictureclass_form.label :category_id %>
<%= pictureclass_form.collection_select :category_id, Category.all, :id, :name %>
</div>
<div class="field">
<%= pictureclass_form.label :tipu_id %>
<%= pictureclass_form.collection_select :tipu_id, Tipu.all, :id, :name %>
</div>
<div class="field">
<%= pictureclass_form.label :style_id %>
<%= pictureclass_form.collection_select :style_id, Style.all, :id, :name %>
</div>
<% end %>
<% end %>
Steps Taken:
- Ensured that accepts_nested_attributes_for is set up in the Picture model.
- Verified that the form is correctly structured to handle nested attributes.
- Checked that the picture_params method permits the nested attributes.
Question:
What might be causing the NoMethodError for category_id when updating a Picture record, and how can I resolve it?