解決したいこと:userモデルに紐づくstepモデルを一括保存をしたい
Railsで一括保存する機能を開発しています。
モデルを一括登録する手順を参考にしてやってみましたが
どのようにすれば一括保存をすることができますか?
色々試しましたがどうしても解決できませんでした。
足りない情報があれば指摘していただけると助かりますm(_ _)m
問題が発生するまでの流れ・手順
new.html.erbでフォームに入力して登録ボタンを押した時
※追記(最新の情報に修正)
app/views/steps/new.html.erb
<%= form_with model: @steps, url: steps_path, local: true do |form| %> <% @steps.collection.each do |step| %> <%= fields_for 'steps[]', step do |field| %> <%= field.label :step_name %> <%= field.text_field :step_name, class: 'form-field' %> <br> <% end %> <% end %> <%= form.submit %> <%= link_to '戻る', step_path(current_user) %> <% end %>
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 :steps, dependent: :destroy end
app/models/step.rb
# == Schema Information # # Table name: steps # # id :bigint not null, primary key # goal :string(255) # step_day :date # step_name :text(65535) # step_time :integer # created_at :datetime not null # updated_at :datetime not null # user_id :bigint # # Indexes # # index_steps_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (user_id => users.id) # class Step < ApplicationRecord belongs_to :user end
app/models/steps_collection.rb
# Stepのコレクションモデル class StepCollection include ActiveModel::Conversion extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::AttributeMethods include ActiveModel::Validations STEP_NUM = 3 # 同時にstepを作成する数 attr_accessor :collection # 初期化メソッド def initialize(current_user,attributes = []) if attributes.present? self.collection = attributes.map do |value| # 修正 Step.new( user_id: value['current_user.id'], step_name: value['step_name'] ) end else self.collection = STEP_NUM.times.map { Step.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/steps_controller.rb
class StepsController < ApplicationController def new @steps = StepCollection.new(current_user) end def create @steps = StepCollection.new(current_user, step_params) if @steps.save flash[:success] = '成功しました!' redirect_to step_path(current_user) else render 'new' end end private def step_params params.require(:steps) 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 # 記憶したURL (もしくはデフォルト値) にリダイレクト(フレンドリーフォワーディング) def redirect_back_or(default) redirect_to(session[:forwarding_url] || default) session.delete(:forwarding_url) end # アクセスしようとしたURLを覚えておく def store_location session[:forwarding_url] = request.original_url if request.get? end end
ログ
Started POST "/steps" for 172.19.0.1 at 2020-09-01 13:31:37 +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 StepsController#create as HTML web_1 | Parameters: {"utf8"=>"✓", "authenticity_token"=>"pZy8W+7yYOGz+BNc8CfWRJW+rBlkVX1ctV5OS7DWHFCe6FTD4ixvm97mVTw0kJ9v3naRHGnFREDo/r+2aM/x5Q==", "steps"=>[{"step_name"=>"step"}, {"step_name"=>"step1"}, {"step_name"=>"step2"}], "commit"=>"登録する"} web_1 | User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 8 LIMIT 1 web_1 | (0.3ms) BEGIN web_1 | (0.3ms) ROLLBACK web_1 | "エラー" web_1 | Rendering steps/new.html.erb within layouts/application web_1 | Rendered steps/_form.html.erb (2.3ms) web_1 | Rendered steps/new.html.erb within layouts/application (14.7ms) web_1 | Rendered layouts/_shim.html.erb (0.4ms) web_1 | Rendered layouts/_head.html.erb (441.1ms) web_1 | Rendered layouts/_header.html.erb (2.3ms) web_1 | Rendered layouts/_flash_messages.html.erb (0.4ms) web_1 | Rendered layouts/_footer.html.erb (2.0ms) web_1 | Completed 200 OK in 644ms (Views: 563.5ms | ActiveRecord: 3.0ms)
環境
rails: 5.2.3 ruby: 2.5.7
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/02 08:49 編集
2020/09/01 04:12
2020/09/01 04:18
2020/09/01 10:27 編集
2020/09/01 10:32
2020/09/01 11:16
2020/09/01 12:13
2020/09/01 12:28
2020/09/01 13:17 編集
2020/09/01 13:19
2020/09/02 08:48 編集
2020/09/01 20:52
2020/09/02 09:03
2020/09/03 10:24