前提・実現したいこと
解決したいこと:親モデルに紐づく子モデルを一括編集をしたい
Railsで一括編集する機能を開発しています。
一括で編集する際に、unknown attribute '39' for It.. エラーが出て編集できません。
StrongParameter周辺に問題があるのはわかるのですが、どのようにすればよいかわかりません。
足りない情報があれば指摘していただけると助かりますm(_ _)m
###問題が発生するまでの流れ・手順
一括で編集するボタンを押した時
エラーメッセージ
ソースコード
app/views/its/new.html.erb
<%= form_with model: @its, url: its_path, local: true do |form| %> <% @its.collection.each do |it| %> <%= fields_for 'its[]', it do |field| %> <%= field.label :situation %> <%= field.text_field :situation, class: 'form-field' %> <br> <%= field.label :behavior %> <%= field.text_field :behavior, class: 'form-field' %> <% end %> <% end %> <%= form.submit %> <%= link_to '戻る', it_path(current_user) %> <% end %>
app/views/its/edit.html.erb
<%= form_with model: @its, url: it_path, method: :patch, local: true do |form| %> <% @its.each do |it| %> <%= fields_for 'its[]', it do |field| %> <%= field.label :situation %> <%= field.text_field :situation, class: 'form-field', required: true %> <br> <%= field.label :behavior %> <%= field.text_field :behavior, class: 'form-field', required: true %> <% end %> <% end %> <%= form.submit '一括編集'%> <%= link_to '戻る', it_path(current_user) %> <% end %>
app/views/its/show.html.erb
<% @user.its.each do |it| %> <div class="wrapper"> <div class="column"> <h1><%= simple_format(it.situation) %></h1> </div> <div class="column"> <h1><%= simple_format(it.behavior) %></h1> </div> </div> <% end %> <%= link_to(content_tag(:i, '', class: "fas fa-trash-alt fa-3x faa-horizontal animated-hover fa-pull-right", style: "color: rgb(80,80,80);"), it_path, method: :delete, data: {confirm: "本当に削除しますか?"}) %> <%= link_to(content_tag(:i, '', class: "fas fa-edit fa-3x faa-vertical animated-hover fa-pull-right", style: "color: rgb(80,80,80);"), edit_it_path ) %>
app/models/user.rb
#== Schema Information # id :bigint not null, primary key # admin :boolean default(FALSE) # email :string(255) # name :string(255) # password_digest :string(255) # remember_digest :string(255) # created_at :datetime not null # updated_at :datetime not null # # Indexes # # index_users_on_email (email) UNIQUE # class User < ApplicationRecord has_many :its, dependent: :destroy end
app/models/it.rb
# == Schema Information # # Table name: its # # id :bigint not null, primary key # behavior :text(65535) # situation :text(65535) # created_at :datetime not null # updated_at :datetime not null # user_id :bigint # # Indexes # # index_its_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (user_id => users.id) # class It < ApplicationRecord belongs_to :user end
app/models/its_collection.rb
# Itのコレクションモデル class ItCollection include ActiveModel::Conversion extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::AttributeMethods include ActiveModel::Validations IT_NUM = 3 # 同時にitを作成する数 attr_accessor :collection # 初期化メソッド def initialize(current_user, attributes = []) if attributes.present? self.collection = attributes.map do |value| It.new( user_id: current_user.id, situation: value['situation'], behavior: value['behavior'] ) end else self.collection = IT_NUM.times.map { It.new } end end # レコードが存在するか確認するメソッド def persisted? false end # コレクションをDBに保存するメソッド def save is_success = true ActiveRecord::Base.transaction do collection.each do |result| # バリデーションを全てかけたいからsave!ではなくsaveを使用 is_success = false unless result.save end # バリデーションエラーがあった時は例外を発生させてロールバックさせる raise ActiveRecord::RecordInvalid unless is_success end rescue p 'エラー' ensure return is_success end end
app/controllers/its_controller.rb
class ItsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] before_action :correct_user, only: :destroy skip_before_action :verify_authenticity_token def show @user = User.find(params[:id]) @its = @user.its end def new @its = ItCollection.new(current_user) end def create @its = ItCollection.new(current_user, its_params) if @its.save flash[:success] = '成功しました!' redirect_to it_path(current_user) else render 'new' end end def destroy @it.destroy flash[:danger] = "#{@its.situation}削除しました!" redirect_to request.referrer || root_url end def edit @its = current_user.its end def update @its = current_user.its if @its.update(its_params) flash[:success] = "編集しました!" redirect_to it_path(current_user) else render 'its/edit' end end private def its_params params.slice(:its).permit(its: [:situation, :behavior]).require(:its) end def correct_user @it = current_user.its.find_by(id: params[:id]) redirect_to root_url if @it.nil? end end
app/helpers/sessions_helpers.rb
module SessionsHelper # 渡されたユーザーでログインする def log_in(user) session[:user_id] = user.id end # ユーザーのセッションを永続的にする def remember(user) user.remember cookies.permanent.signed[:user_id] = user.id cookies.permanent[:remember_token] = user.remember_token end # 記憶トークンcookieに対応するユーザーを返す def current_user if (user_id = session[:user_id]) @current_user ||= User.find_by(id: user_id) elsif (user_id = cookies.signed[:user_id]) user = User.find_by(id: user_id) if user && user.authenticated?(cookies[:remember_token]) log_in user @current_user = user end end end # 渡されたユーザーがログイン済みユーザーであればtrueを返す def current_user?(user) user == current_user end # ユーザーがログインしていればtrue、その他ならfalseを返す def logged_in? !current_user.nil? end # 永続的セッションを破棄する def forget(user) user.forget cookies.delete(:user_id) cookies.delete(:remember_token) end # 現在のユーザーをログアウトする def log_out forget(current_user) session.delete(:user_id) @current_user = nil end end
ログ
web_1 | Started PATCH "/its/8" for 172.19.0.1 at 2020-09-11 05:52:21 +0000 web_1 | Cannot render console from 172.19.0.1! Allowed networks: 172.18.0.1, 127.0.0.0/127.255.255.255, ::1 web_1 | Processing by ItsController#update as HTML web_1 | Parameters: {"utf8"=>"✓", "authenticity_token"=>"/MDK5kbE0pqSh6uHKcWA==", "its"=>{"39"=>{"situation"=>"Situation1", "behavior"=>"Behavior1"}, "40"=>{"situation"=>"Situation4", "behavior"=>"Behavior4"}, "41"=>{"situation"=>"Situation8", "behavior"=>"Behavior8"}}, "commit"=>"一括編集", "id"=>"8"} web_1 | User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 8 LIMIT 1 web_1 | It Load (0.4ms) SELECT `its`.* FROM `its` WHERE `its`.`user_id` = 8 ORDER BY `its`.`created_at` DESC web_1 | (0.2ms) BEGIN web_1 | (0.2ms) ROLLBACK web_1 | Completed 500 Internal Server Error in 112ms (ActiveRecord: 3.2ms) web_1 | ActiveModel::UnknownAttributeError - unknown attribute '39' for It.: web_1 | app/controllers/its_controller.rb:44:in `update'
環境
rails: 5.2.3 ruby: 2.5.7
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/11 00:02
2020/09/11 01:20 編集
2020/09/11 05:03
2020/09/11 06:02 編集
2020/09/11 08:14