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

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

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

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

Ruby on Rails

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

Q&A

解決済

2回答

408閲覧

Rails showアクションでのコントローラー側の設定がうまくいきません

muraishi

総合スコア17

Ruby

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

Ruby on Rails

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

0グッド

1クリップ

投稿2020/02/18 05:48

showアクションにて、URLに表示されているidを
@timetable = User.find_by_id(params[:id])でurlのidを取得しつつ、viewのほうには
Timetableテーブルの値を表示したいです。

viewを表示するにはログインユーザーのidを渡してあげないとroot_pathに飛ばされるようになっています。

うまいやり方が思いつきません。よろしくお願いいたします。

DB

1timetablesテーブルにあるカラム 2id, user_id, user_name, date, hour, minute 3 4 5Usersテーブルにあるカラム 6id, name 7

TimetableController

1class TimetablesController < ApplicationController 2 before_action :logged_in_timetable, only: [:edit, :update, :show] 3 before_action :correct_timetable, only: [:edit, :update, :show] 4 before_action :set_timetable, only: [:destroy] 5 6 def timetable_index 7 @timetables = Timetable.all 8 9 @times0900 = Timetable.where(hour: "9", minute: "00") 10 @times0930 = Timetable.where(hour: "9", minute: "30") 11 @times1000 = Timetable.where(hour: "10", minute: "00") 12 @times1030 = Timetable.where(hour: "10", minute: "30") 13 @times1100 = Timetable.where(hour: "11", minute: "00") 14 @times1130 = Timetable.where(hour: "11", minute: "30") 15 @times1200 = Timetable.where(hour: "12", minute: "00") 16 @times1230 = Timetable.where(hour: "12", minute: "30") 17 @times1500 = Timetable.where(hour: "15", minute: "00") 18 @times1530 = Timetable.where(hour: "15", minute: "30") 19 @times1600 = Timetable.where(hour: "16", minute: "00") 20 @times1630 = Timetable.where(hour: "16", minute: "30") 21 @times1700 = Timetable.where(hour: "17", minute: "00") 22 @times1730 = Timetable.where(hour: "17", minute: "30") 23 @times1800 = Timetable.where(hour: "18", minute: "00") 24 @times1830 = Timetable.where(hour: "18", minute: "30") 25 @times1900 = Timetable.where(hour: "19", minute: "00") 26 @times1930 = Timetable.where(hour: "19", minute: "30") 27 end 28 29 def new 30 @timetable = Timetable.new 31 end 32 33 def create 34 @timetable = Timetable.new(user_id: current_user.id, user_name: current_user.name, date: timetable_params[:date], hour: timetable_params[:hour], minute: timetable_params[:minute]) 35 if @timetable.save 36 flash[:success] = "ご予約ありがとうございます" 37 redirect_to root_path 38 else 39 flash[:success] = "申し訳ございません。予約を受け付けられませんでした" 40 redirect_to root_path 41 end 42 end 43 44 def show 45 @timetable = User.find_by_id(params[:id]) 46 end 47//本当はshowアクションの中を 48//@timetable = Timetable.find_by_id(params[:id])としたいのですが、(params[:id])ではUrlに表示されているidを取得するため、Userテーブルのidとは一致しません。 49 50//もし、@timetable = Timetable.find_by_id(params[:id])みたいな感じでTimetabeslテーブルからidカラムではなくuser_idカラムをとることができればこの問題は解決すると思うのですが。。。 51 52// viewにtimetablesのuser_name, date, hour, minuteを表示したいです。 53 54 55 def edit 56 @timetable = Timetable.find(params[:id]) 57 58 @times0900 = Timetable.where(hour: "9", minute: "00") 59 @times0930 = Timetable.where(hour: "9", minute: "30") 60 @times1000 = Timetable.where(hour: "10", minute: "00") 61 @times1030 = Timetable.where(hour: "10", minute: "30") 62 @times1100 = Timetable.where(hour: "11", minute: "00") 63 @times1130 = Timetable.where(hour: "11", minute: "30") 64 @times1200 = Timetable.where(hour: "12", minute: "00") 65 @times1230 = Timetable.where(hour: "12", minute: "30") 66 @times1500 = Timetable.where(hour: "15", minute: "00") 67 @times1530 = Timetable.where(hour: "15", minute: "30") 68 @times1600 = Timetable.where(hour: "16", minute: "00") 69 @times1630 = Timetable.where(hour: "16", minute: "30") 70 @times1700 = Timetable.where(hour: "17", minute: "00") 71 @times1730 = Timetable.where(hour: "17", minute: "30") 72 @times1800 = Timetable.where(hour: "18", minute: "00") 73 @times1830 = Timetable.where(hour: "18", minute: "30") 74 @times1900 = Timetable.where(hour: "19", minute: "00") 75 @times1930 = Timetable.where(hour: "19", minute: "30") 76 end 77 78 def update 79 @timetable = Timetable.find(params[:id]) 80 if @timetable.update_attributes(timetable_params) 81 flash[:success] = "予約時間を変更しました。" 82 redirect_to timetable_path(current_user) 83 else 84 flash[:danger] = "予約を受け付けられませんでした。" 85 render 'edit' 86 87 end 88 end 89 90 def destroy 91 @timetable.destroy 92 flash[:success] = "予約が取り消されました。" 93 redirect_to root_path 94 end 95 96 private 97 def timetable_params 98 params.require(:timetable).permit(:user_id, :user_name, :date, :hour, :minute) 99 end 100 101 def logged_in_timetable 102 unless logged_in? 103 flash[:danger] = "Please log in." 104 redirect_to login_url 105 end 106 end 107 108 def correct_timetable 109 @timetable = User.find(params[:id]) 110 redirect_to(root_url) unless @timetable == current_user 111 112 end 113 114 def set_timetable 115 @timetable = Timetable.find(params[:id]) 116 end 117end 118

view

1<% if @timetable.nil? %> 2 <h1>予約が存在しません</h1> 3 <% else %> 4 <h1><%= @timetable.user_name %>さんの次の予約は<h1> 5 <h3><%= @timetable.date %>日の<%= @timetable.hour %>時<%= @timetable.minute %>時からです</h3> 6 <%= link_to "予約時間を変更する", edit_timetable_path(current_user) %> 7 <%= link_to "予約を取り消す", @timetable, method: :delete, data: { confirm: "予約を消去します。よろしですか?"} %> 8<% end %>

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

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

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

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

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

guest

回答2

0

ものすご〜〜〜〜〜〜〜〜〜〜〜く違和感あります。
new,create,edit, では @timetable = Timetable.なにがし なのに
なぜ show は @timetable = User.なにがし なのでしょう???
showに渡ってくるparams[:id]はUserのidですかTimetableのidですか?

載っているviewがshowのものだとすると、ここの@timetableはUserでなくTimetableを期待している様にみえます。

追記
def new が受け取る params[:id] が user.id であるなら
おそらく、user has many timetables でしょうから、timetable を特定することが出来ません。
def show を呼ぶ view を見せていただけますか? 
脊髄反射では、それは showしたい timetableのidだと思うのです
urlに表示されているidってuser_idですか?

monoliaさんへの18 17:35のコメントで「なぜidで値を取ってこれるのにuser_idだと値をとれないのでしょうか。。。」とありますが
id でとる場合は timetableひとつ、user_id でとる場合は(というかwhereでですが)TimetableのRelation(配列みたいなもの)なので
undefined method `user_name' for #<Timetable::ActiveRecord_Relation:
となります。

showのときにUserのidにこだわるのはなんでしょう?

試みに

def show @timetable = Timetable.find_by_id(params[:id]) end

で試してください。望みの結果になるかどうか

投稿2020/02/18 06:58

編集2020/02/18 08:43
winterboum

総合スコア23401

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

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

muraishi

2020/02/18 07:20

変な書き方をしてすみません。 @timetable = User.find_by_id(params[:id])としたのはurlに表示されているidとログインしているユーザーのidを一致させるためにUserを使いました。 @timetableに入れたいのはTimetable.find_by_id(ログインしているユーザーのuser_id)です。 これをうまく実現できる方法はありますか?
maisumakun

2020/02/18 08:39

> @timetableに入れたいのはTimetable.find_by_id(ログインしているユーザーのuser_id)です。 えっと、user_idが入っている列は、timetables.idでしょうか?それとも、timetables.user_idでしょうか?
muraishi

2020/02/18 11:31

これが、showを呼ぶviewだと思います <% if logged_in? %> <li><%= link_to "予約表", timetable_path(user_id: current_user) %></li>←ここです! <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">アカウント<b class="caret"></b></a> <ul class="dropdown-menu"> <li><%= link_to "アカウント情報", current_user %></li> <li><%= link_to "アカウント編集", edit_user_path(current_user) %></li> <li><%= link_to "コンタクト", contact_path %></li> <li class="divider"></li> <li><%= link_to "ログアウト", logout_path, method: :delete %></li> </ul> </li> <% end %> Urlに表示されているidはuser_idではないと思います。Userテーブルのidだと思います。 Timetablesテーブルが持っているカラムはid, user_id, user_name, date, hour, minuteです。 Usersテーブルにあるカラムはid, nameです。 ユーザーはshowに入る時Userテーブルにある、idが必要です。(自分のidを渡さないとrootに戻されます。)しかし、@timetableにUser.find_by_id(params[:id])を入れてもview側で引っ張れる情報はUsersテーブルのidとnameカラムだけです。Timetablesテーブルのuser_nameやdateなどは引っ張ってこれません。 そこでTimetablesテーブルにあるuser_idカラムはUsersテーブルのidカラムと紐づいているので(同じ値です)、@timetable = Timetable.find_by_id(タイムテーブルのuser_idカラム) としてあげることができれば @timetable = User.find_by_id(params[:id]) と同じ働きをし、尚且つその後viewで Timetablesテーブルのuser_nameカラム や dateカラムを引っ張ってこれると思います。 なので @timetable にはUserテーブルにあるidと同じ値の,user_id(Timetablesテーブル)を入れたいのです。 説明がうまくいかずすみません
muraishi

2020/02/18 11:32

maisumakunさん、 ごめんなさい。質問の意味がよくわかりませんでした。 もう少し詳しくお願いできますか? すみません!
winterboum

2020/02/18 11:39

確かにuserのidを渡してますね。 でも、何のために? Taimetableのidをわたしても、そのtimetableにuser_idがあるのですから、Userは特定できます。 user id を渡すことによって、どのtimetableなのか、がわからなくなってしまうのでshow出来ません。 そこは timetableのidを渡して Timetable.find(params[:id])としてみてください。 showのviewは@timetableがtimetableである前提で書かれています。
winterboum

2020/02/18 11:45

それに、 渡すのがcurrent_userなら渡さなくてもcurrent_userは取れます
muraishi

2020/02/18 12:33

def show @timetable = Timetable.where(user_id: params[:id]).first end とりあえず、こうすることでエラーなく動くようになりました。 User の idを渡しているのは試行錯誤の末、そうなったはずなのですが、今となってはよく覚えていません。すみません。
guest

0

ベストアンサー

devise使ってそうで、かつ、showはログインしている人の専用ページだと想像しました。

controller

1def show 2 @timetable = User.find_by_id(current_user.id) 3end 4

これでいけないですかね?

投稿2020/02/18 06:22

編集2020/02/18 06:23
mongolia

総合スコア133

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

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

muraishi

2020/02/18 07:11

ありがとうございます! deviseは使っていなくて、rails tutorial と同じ方法を使っています。 showはログインしている人の専用ページなので、他のユーザーはアクセスできないです。 viewで表示したいのはTimetablesテーブルの値なので @timetable = Timetable.find_by_id(params[:id])とできれば良いのですが、 こうしてしまうと、Timetableのidを検索するのでUserテーブルのidと同じにならないとおもいます(@timetableに入れたいのは今ログインしているユーザーの「id」ではなく、「user_id」です) 説明が下手ですみません(/ _ ; ) @timetable = User.find_by_id(current_user.id)だと以下のエラーがでます NoMethodError in Timetables#show Showing /home/ec2-user/environment/portfolio/app/views/timetables/show.html.erb where line #4 raised: undefined method `user_name' for #<User:0x00007fe8f8843878> Extracted source (around line #4): 2 3 4 5 6 7 <h1>予約が存在しません</h1> <% else %> <h1><%= @timetable.user_name %>さんの次の予約は<h1> <h3><%= @timetable.date %>日の<%= @timetable.hour %>時<%= @timetable.minute %>時からです</h3> <%= link_to "予約時間を変更する", edit_timetable_path(current_user) %> <%= link_to "予約を取り消す", @timetable, method: :delete, data: { confirm: "予約を消去します。よろしですか?"} %> Rails.root: /home/ec2-user/environment/portfolio Application Trace | Framework Trace | Full Trace app/views/timetables/show.html.erb:4:in `_app_views_timetables_show_html_erb___1378983249258843218_70319289275300' Request Parameters: {"id"=>"1"} Toggle session dump Toggle env dump Response Headers: None
mongolia

2020/02/18 07:23

1.showへのリンクを変更 ```view link_to 'showページへ', timetable_path(user_id: ユーザーID) ``` 2.コントローラー変更 ```controller def show @timetable = User.find_by_id(hoge_params[:user_id]) end private def hoge_params params.permit(:user_id) end ``` こんなでありましょうか。
muraishi

2020/02/18 07:42

私の説明が下手でほうとうに申し訳ないです。 @timetable に入れたいのは現在ログインしている Userテーブルのid ではなく Timetableのuser_id です。 @timetable = Timetablesテーブルのuser_id とするにはどうすれば良いでしょうか?
mongolia

2020/02/18 07:51

見当違いな回答ばかりで恐縮です。 先程のソースのUser.find_by_idをTimetable.find_by_idに変えても欲しいデータが取れないですか? 例 def show @timetable = Timetable.find_by_id(hoge_params[:user_id]) end
muraishi

2020/02/18 08:12

試しにviewに書いてあるif文を消してみたのですが、まだnilになっているみたいです。 NoMethodError in Timetables#show Showing /home/ec2-user/environment/portfolio/app/views/timetables/show.html.erb where line #2 raised: undefined method `user_name' for nil:NilClass Extracted source (around line #2): 1 2 3 4 5 <h1><%= @timetable.user_name %>さんの次の予約は<h1> <h3><%= @timetable.date %>日の<%= @timetable.hour %>時<%= @timetable.minute %>時からです</h3> <%= link_to "予約時間を変更する", edit_timetable_path(current_user) %> <%= link_to "予約を取り消す", @timetable, method: :delete, data: { confirm: "予約を消去します。よろしですか?"} %> Rails.root: /home/ec2-user/environment/portfolio Application Trace | Framework Trace | Full Trace app/views/timetables/show.html.erb:2:in `_app_views_timetables_show_html_erb___1378983249258843218_70319292990500' Request Parameters: {"id"=>"1"} Toggle session dump Toggle env dump Response Headers: None 確認なのですが、 1.showへのリンクを変更 ```view link_to 'showページへ', timetable_path(user_id: ユーザーID) ``` timetable_path(user_id: ユーザーID) これは timetable_path(current_user)で大丈夫ですか? --sessions_helper-- def current_user if session[:user_id] @current_user ||= User.find_by(id: session[:user_id]) end end
mongolia

2020/02/18 08:20

>timetable_path(user_id: ユーザーID) >これは >timetable_path(current_user)で大丈夫ですか? こんな感じでどうでしょうか。 link_to 'showページへ', timetable_path(user_id: current_user)
muraishi

2020/02/18 08:35

エラーが出てしまいます。 NoMethodError in Timetables#show Showing /home/ec2-user/environment/portfolio/app/views/timetables/show.html.erb where line #2 raised: undefined method `user_name' for nil:NilClass Extracted source (around line #2): 1 2 3 4 5 <h1><%= @timetable.user_name %>さんの次の予約は<h1> <h3><%= @timetable.date %>日の<%= @timetable.hour %>時<%= @timetable.minute %>時からです</h3> <%= link_to "予約時間を変更する", edit_timetable_path(current_user) %> <%= link_to "予約を取り消す", @timetable, method: :delete, data: { confirm: "予約を消去します。よろしですか?"} %> Rails.root: /home/ec2-user/environment/portfolio Application Trace | Framework Trace | Full Trace app/views/timetables/show.html.erb:2:in `_app_views_timetables_show_html_erb___1378983249258843218_70319289778020' Request Parameters: {"user_id"=>"1", "id"=>"1"} Toggle session dump Toggle env dump Response Headers: None 例えば @timetable = Timetable.find_by_id(5) みたいな感じでidを指定してあげるとうまく表示されるのですが、 @timetable = Timetable.where(user_id: "1") だと同じような下記のエラーになってしまいます。 なぜidで値を取ってこれるのにuser_idだと値をとれないのでしょうか。。。 NoMethodError in Timetables#show Showing /home/ec2-user/environment/portfolio/app/views/timetables/show.html.erb where line #2 raised: undefined method `user_name' for #<Timetable::ActiveRecord_Relation:0x00007fe8f8119980> Extracted source (around line #2): 1 2 3 4 5 <h1><%= @timetable.user_name %>さんの次の予約は<h1> <h3><%= @timetable.date %>日の<%= @timetable.hour %>時<%= @timetable.minute %>時からです</h3> <%= link_to "予約時間を変更する", edit_timetable_path(current_user) %> <%= link_to "予約を取り消す", @timetable, method: :delete, data: { confirm: "予約を消去します。よろしですか?"} %> Rails.root: /home/ec2-user/environment/portfolio Application Trace | Framework Trace | Full Trace app/views/timetables/show.html.erb:2:in `_app_views_timetables_show_html_erb___1378983249258843218_70319286804240' Request Parameters: {"user_id"=>"1", "id"=>"1"} Toggle session dump Toggle env dump Response Headers: None
mongolia

2020/02/18 08:50

整理したいこと 1. >@timetable = Timetable.find_by_id(5) timetablesテーブルのid=5であるデータを取得します。取得できるのは1件だけ。 2.>@timetable = Timetable.where(user_id: "1") timetablesテーブルのuser_id=1であるデータを取得します。取得できるのは複数件。 今回は2がやりたいことですか? 質問したいこと1 >@timetable = Timetable.where(user_id: "1") >だと同じような下記のエラーになってしまいます。 > >なぜidで値を取ってこれるのにuser_idだと値をとれないのでしょうか。。。 timetablesにuser_id=1であるデータはありますか? データが存在する場合、 @timetable = Timetable.where(user_id: "1").first ではどうでしょうか。
muraishi

2020/02/18 11:03

>整理したいこと >1. >@timetable = Timetable.find_by_id(5) >timetablesテーブルのid=5であるデータを取得します。取得できるのは1件だけ。 >2.>@timetable = Timetable.where(user_id: "1") >timetablesテーブルのuser_id=1であるデータを取得します。取得できるのは複数件。 >今回は2がやりたいことですか? 今回やりたいことは、@timetableの中に、ログインしているユーザーのuser_idを入れることです。(Timetablesテーブル) >timetablesにuser_id=1であるデータはありますか? >データが存在する場合、 >@timetable = Timetable.where(user_id: "1").first >ではどうでしょうか。 おお、.firstを付けたらちゃんと表示されました! すごいです!
muraishi

2020/02/18 12:22

def show @timetable = Timetable.where(user_id: params[:id]).first end とすることでTimetablesテーブルのuser_idを渡すことができました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問