質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

Q&A

解決済

1回答

621閲覧

マイページからcreate済のチェック内容の編集に直接遷移させたい

Mo.mi

総合スコア4

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

ルーティング

ルーティングとは、TCP/IPネットワークにおいて、目的のホストまでパケットを送る為のパス選定のプロセスを言います。

0グッド

0クリップ

投稿2021/12/14 14:57

前提・実現したいこと

お世話になります。

ruby(rails)でマイページ機能を作っており、課題の提出状況をチェックして登録、その後追加提出したらチェック内容を更新するという実装を行いたいです。
初めて登録する(new-create)まではできたのですが、編集の実装について2種類の方法で試しているのですが、どちらもエラーが出てしまいます。
idを適切に指定するにはどのように記述すればよいでしょうか。
なお、アソシエーションをhas_oneで組んでいて、current_userはquestionを0or1持っている状態にしたいです。

よろしくお願いします。

試した方法1

マイページに貼るlink_toはnewアクションに遷移するもの1つにし、newアクションの中でcurrent_userがquestionテーブルを持っていなければそのままnewアクションの処理を、持っている場合はeditアクションに進むように実装しようと思いました。

発生している問題・エラーメッセージ
ActionView::Template::Error (undefined method `id' for nil:NilClass): 3: </div> 4: <div class="questions"> 5: 6: <%= form_with model:@question, url: user_question_path(current_user.id, @question.id),local: true do |f|%> 7: <div class="volume"> 8: 9: app/views/questions/edit.html.erb:6 app/controllers/questions_controller.rb:6:in `new'
該当のソースコード

ruby

1class QuestionsController < ApplicationController 2 def new 3 if current_user.question == nil 4 @question = Question.new 5 else 6 render :edit 7 end 8 end 9 10 def create 11 @question = Question.create!(question_params) 12 redirect_to edit_user_question_path(@question.user, @question) 13 end 14 15 def edit 16 @question = Question.find(params[:id]) 17 end 18 19 def update 20 @question = Question.find(params[:id]) 21 @question.update(question_params) 22 redirect_to edit_user_question_path(@question.user, @question) 23 end 24 25 26 private 27 28 def question_params 29 params.require(:question).permit(:q1, :q2, :q3).merge(user_id: current_user.id) 30 end 31 32end

ruby

1class UsersController < ApplicationController 2 def index 3 if user_signed_in? 4 @code = current_user.code 5 #略 6 end 7 end 8 9 def show 10 #略 11 end 12end

↓users/index.html.erb(マイページ)

ruby

1<main class="main"> 2 <div class="inner"> 3 <% if user_signed_in? %> 4 #略 5 <div class ="menu"> 6 <div class ="item"> 7 <%= link_to "メソッド問題", new_user_question_path(current_user) %> 8 </div> 9 </div> 10 <% end %> 11 </div> 12 13</main>

↓questions/new.html.erb

ruby

1<div> 2メソッド問題 3</div> 4<div class="questions"> 5 <%= form_with model:@question, url: user_questions_path,local: true do |f|%> 6 7 <div class="volume"> 8 <div class="question"> 9 <div class="method"> 10 <%= link_to "①", "#", target: :_blank, rel: "noopener noreferrer" %> 11 </div> 12 <div class="check"> 13 <%= f.check_box :q1 %> 14 </div> 15 </div> 16 <div class="question"> 17 <div class="method"> 18 <%= link_to "②", "#", target: :_blank, rel: "noopener noreferrer" %> 19 </div> 20 <div class="check"> 21 <%= f.check_box :q2 %> 22 </div> 23 </div> 24 <div class="question"> 25 <div class="method"> 26 <%= link_to "③", "#", target: :_blank, rel: "noopener noreferrer" %> 27 </div> 28 <div class="check"> 29 <%= f.check_box :q3 %> 30 </div> 31 </div> 32 </div> 33 34 <div class="actions"> 35 <%= f.submit "送信する", class: :form__btn %> 36 </div> 37 <% end %> 38</div>

↓questions/edit.html.erb

ruby

1<div> 2メソッド問題(更新用) 3</div> 4<div class="questions"> 5 6 <%= form_with model:@question, url: user_question_path(current_user.id, @question.id),local: true do |f|%> 7 <div class="volume"> 8 <div class="question"> 9 <div class="method"> 10 <%= link_to "①", "#", target: :_blank, rel: "noopener noreferrer" %> 11 </div> 12 <div class="check"> 13 <%= f.check_box :q1 %> 14 </div> 15 </div> 16 <div class="question"> 17 <div class="method"> 18 <%= link_to "②", "#", target: :_blank, rel: "noopener noreferrer" %> 19 </div> 20 <div class="check"> 21 <%= f.check_box :q2 %> 22 </div> 23 </div> 24 <div class="question"> 25 <div class="method"> 26 <%= link_to "③", "#", target: :_blank, rel: "noopener noreferrer" %> 27 </div> 28 <div class="check"> 29 <%= f.check_box :q3 %> 30 </div> 31 </div> 32 </div> 33 34 <div class="actions"> 35 <%= f.submit "送信する", class: :form__btn %> 36 </div> 37 <% end %> 38</div>

↓ルーティング

ruby

1Rails.application.routes.draw do 2 devise_for :users 3 root to: "users#index" 4 resources :users, only: [:index, :show] do 5 resources :questions, only: [:new, :create, :edit, :update] 6 end 7end

↓userモデル

ruby

1class User < ApplicationRecord 2 devise :database_authenticatable, :registerable, 3 :recoverable, :rememberable, :validatable 4 5 validates :name, presence: true 6 validates :code, presence: true 7 validates :password, presence: true 8 9 has_one :actor 10 has_one :question 11 12end

↓questionモデル

ruby

1class Question < ApplicationRecord 2 belongs_to :user 3end

試した方法2

マイページで条件分岐をして、current_userがquestionテーブルを持っていなければnewアクションへのリンクが、持っている場合はeditアクションへのリンクが表示されるように実装しようと思いました。
このeditアクションへのリンクに必要なquestion_idをどう書けば指定できるかがわからずエラーを出してしまいます。
下記は苦肉の策で@questionをallで指定して、マイページが表示できないエラーは解除したもののeditアクションに進む時に結局エラーが出てしまっている時の状態です。

発生している問題・エラーメッセージ
ActiveRecord::RecordNotFound (Couldn't find Question with 'id'=#<Question::ActiveRecord_Relation:0x00007fddaf7fa000>):
該当のソースコード

ruby

1class QuestionsController < ApplicationController 2 def new 3 @question = Question.new 4 end 5 6 def create 7 @question = Question.create!(question_params) 8 redirect_to edit_user_question_path(@question.user, @question) 9 end 10 11 def edit 12 @question = Question.find(params[:id]) 13 end 14 15 def update 16 @question = Question.find(params[:id]) 17 @question.update(question_params) 18 redirect_to edit_user_question_path(@question.user, @question) 19 end 20 21 22 private 23 24 def question_params 25 params.require(:question).permit(:q1, :q2, :q3).merge(user_id: current_user.id) 26 end 27 28end

ruby

1class UsersController < ApplicationController 2 def index 3 if user_signed_in? 4 @code = current_user.code 5 #略 6 @question = Question.all 7 end 8 end 9 10 def show 11 #略 12 end 13end

↓users/index.html.erb(マイページ)

ruby

1<main class="main"> 2 <div class="inner"> 3 <% if user_signed_in? %> 4 #略 5 <div class ="menu"> 6 <div class ="item"> 7 <% if current_user.question == nil %> 8 <%= link_to "メソッド問題", new_user_question_path(current_user) %> 9 <% else %> 10 <%= link_to "メソッド問題(更新)", edit_user_question_path(current_user, @question) %> 11 <% end %> 12 </div> 13 </div> 14 </div> 15</main>

↓questions/new.html.erb

ruby

1<div> 2メソッド問題 3</div> 4<div class="questions"> 5 <%= form_with model:@question, url: user_questions_path,local: true do |f|%> 6 7 <div class="volume"> 8 <div class="question"> 9 <div class="method"> 10 <%= link_to "①", "#", target: :_blank, rel: "noopener noreferrer" %> 11 </div> 12 <div class="check"> 13 <%= f.check_box :q1 %> 14 </div> 15 </div> 16 <div class="question"> 17 <div class="method"> 18 <%= link_to "②", "#", target: :_blank, rel: "noopener noreferrer" %> 19 </div> 20 <div class="check"> 21 <%= f.check_box :q2 %> 22 </div> 23 </div> 24 <div class="question"> 25 <div class="method"> 26 <%= link_to "③", "#", target: :_blank, rel: "noopener noreferrer" %> 27 </div> 28 <div class="check"> 29 <%= f.check_box :q3 %> 30 </div> 31 </div> 32 </div> 33 34 <div class="actions"> 35 <%= f.submit "送信する", class: :form__btn %> 36 </div> 37 <% end %> 38</div>

↓questions/edit.html.erb

ruby

1<div> 2メソッド問題(更新用) 3</div> 4<div class="questions"> 5 6 <%= form_with model:@question, url: user_question_path(current_user.id, @question.id),local: true do |f|%> 7 <div class="volume"> 8 <div class="question"> 9 <div class="method"> 10 <%= link_to "①", "#", target: :_blank, rel: "noopener noreferrer" %> 11 </div> 12 <div class="check"> 13 <%= f.check_box :q1 %> 14 </div> 15 </div> 16 <div class="question"> 17 <div class="method"> 18 <%= link_to "②", "#", target: :_blank, rel: "noopener noreferrer" %> 19 </div> 20 <div class="check"> 21 <%= f.check_box :q2 %> 22 </div> 23 </div> 24 <div class="question"> 25 <div class="method"> 26 <%= link_to "③", "#", target: :_blank, rel: "noopener noreferrer" %> 27 </div> 28 <div class="check"> 29 <%= f.check_box :q3 %> 30 </div> 31 </div> 32 </div> 33 34 <div class="actions"> 35 <%= f.submit "送信する", class: :form__btn %> 36 </div> 37 <% end %> 38</div>

↓ルーティング

ruby

1Rails.application.routes.draw do 2 devise_for :users 3 root to: "users#index" 4 resources :users, only: [:index, :show] do 5 resources :questions, only: [:new, :create, :edit, :update] 6 end 7end

↓userモデル

ruby

1class User < ApplicationRecord 2 devise :database_authenticatable, :registerable, 3 :recoverable, :rememberable, :validatable 4 5 validates :name, presence: true 6 validates :code, presence: true 7 validates :password, presence: true 8 9 has_one :actor 10 has_one :question 11 12end

↓questionモデル

ruby

1class Question < ApplicationRecord 2 belongs_to :user 3end

補足情報

ruby 2.6.5p114
rails 6.0.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

edit に行くには、@question を設定しなければなりません。
action new にて userが持っていたらそれをなければnewをわたすのですから
@question = Question.finc_or_initalize_by(user_id: current_user.id)
としましょう。

view は new と editを分ける必要はありません。
form_with が @question が既存のものかどうかみて、update と create に振ってくれます。
ただそのためには、url: user_questions_path, は不要です。というか邪魔です。悪さするかも。
form_with model: [current_user, @question],local: true
で。

投稿2021/12/14 23:25

winterboum

総合スコア23347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mo.mi

2021/12/15 02:48

解決できました! find_or_initialize_by見つけられず初めて知れました。 また、form_withの件も非常に助かりました。ご回答の上から順に試したところ、おっしゃるとおりルーティングエラーで引っかかってしまい、form_withの記述を修正してそちらも解決しました。 ご丁寧な回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問