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

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

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

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

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

Ruby on Rails

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

Q&A

解決済

3回答

5002閲覧

Railsのviewでの適切なデータの取り出し方

anpnt

総合スコア29

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2018/08/23 02:54

編集2018/08/23 03:58

現在作業時間を記録する機能を作っています。

テーブルは

#Userテーブル ・id ・username
#WorkingHourテーブル ・user_id ・start_time ・finish_time

を持っていて

UserテーブルのidとWorkingHourテーブルのuser_idは紐づいています。

管理者のviewで全ユーザーの作業時間を表示するために、テーブルの数に応じて増えていく表を作ってるんですが、

id名前作業時間
1ユーザー18/11 11:00〜12:00
8/11 14:00〜18:00
2ユーザー28/11 11:00〜12:00
3ユーザー38/11 11:00〜12:00
8/13 10:00〜12:00

みたいなイメージです。

このときのviewでのデータの取り出し方がわからずに苦戦しています。

まずコントローラー側では

@working_hours = WorkingHour.all @users = User.all

このように全て取り出していて

View側では

%table %thead %tr %th ID %th 名前 %th 作業時間 %tr %thead %tbody - @working_hours.each do |working_hour| - user = User.where(id:working_hour.user_id) #ここが合っているかわからない %tr %td= working_hour.user_id %td= %td= %tr %tbody %table

hamlを使っていますが、idをループで表示するところまで書いて手が止まってしまいました。
@working_hoursの1ループの中でUserテーブルのidとWorkingHourテーブルのuser_idが一致するレコードを取得して、そのusernameカラムの中身をtdに表示するにはどんな方法があるでしょうか。。。

ここが合っているかわからないと書いてあるところは、このままuser.usernameという取り出し方をするとエラーになってしまい、userとだけ書いて表示すると、ActiveRecord::Relationみたいなものが表示されます。

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

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

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

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

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

guest

回答3

0

ベストアンサー

  • user = User.where(id:working_hour.user_id) #ここが合っているかわからない

これは、whereを利用しているので、結果がおっしゃっている通りActiveRecord::Relationになります。つまり結果を配列のような形式で取得している状態です。先頭を取得するために.firstをつけてあげましょう。

つまり

- user = User.where(id: working_hour.user_id).first

のようにすれば問題が無くなると思います。

また User.where(id: 1).first このパターンは User.find(1)User.find_by(id: 1) のようにも書けます。primary_keyを指定した1レコードの取得は findfind_by を利用した方がいいです。

さらにですが、モデル側でおそらく

ruby

1class WorkingHour < ApplicationRecord 2 belongs_to :user 3 4 ... 5end

のように belongs_to :user の記述があるのでは無いでしょうか?
この場合Viewで

- user = working_hour.user

とすることでUserモデルのインスタンスを取得できるはずです。

投稿2018/08/23 05:29

kouheiszk

総合スコア213

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

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

anpnt

2018/08/26 04:28

なるほど ありがとうございます。。データ構造に対する理解があまりできていませんでした。。
guest

0

(パッと見 N+1問題 がありますが、それはおいといて、、、)

- user = User.where(id:working_hour.user_id) #ここが合っているかわからない

のとこ、

- user = User.find_by(id:working_hour.user_id)

で userの中にUserクラスのインスタンスが入ると思います。

これで

このままuser.usernameという取り出し方をするとエラーになってしまい

が解消するように思います。

投稿2018/08/23 04:49

編集2018/08/23 05:22
hoppie

総合スコア8

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

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

anpnt

2018/08/23 05:03 編集

ご回答ありがとうございます。 それだと、 (user_idが3だとして) ActiveRecord::RecordNotFound in UsersController#show Couldn't find User with 'id'={:id=>3} になってしまいました...
hoppie

2018/08/23 05:21

ごめんなさい! findじゃなくて`find_by`にするか、findのままなら`id:` を消すのが正しかったです。 編集します
anpnt

2018/08/23 05:26

わざわざありがとうございます!
guest

0

UserテーブルのidとWorkingHourテーブルのuser_idは紐づいています

見た限りだと、今のモデル設計ではuserworking_hourは一対多の関係であると思われます。
であれば、user.working_hoursのような書き方で、userに紐づくworking_hoursであれば全件取得できるはずです。

working_hoursの1ループの中でUserテーブルのidとWorkingHourテーブルのuser_idが一致するレコードを取得

ただし、working_hour.usersで時間毎のuserを取得することは、今のモデル設計ではできません。

表に示されているような、並び順はよくわかりませんが(日付順>ユーザー順>時間順?)、そのような複雑な並びにするにはもう少し複雑なモデル設計が必要になってくるのではないでしょうか?
少なくとも中間テーブルを用意してuserworking_hourを多対多の関係にする必要がありそうです。

投稿2018/08/23 03:45

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

anpnt

2018/08/23 03:59 編集

すみません、並び順については完全に日付順です。すこし書き方を間違えました。 たとえばその並び順をやめて、user順にするとどうなるでしょうか? 中間テーブルは必要なさそうですかね...? 表の例は書き直しました。 これだと単純に下に表が増えていくわけではないから余計複雑ですかね.....
退会済みユーザー

退会済みユーザー

2018/08/23 04:03

さほど複雑ではないので単純に呼び出してやればできると思いますよ。
anpnt

2018/08/23 05:26

> user.working_hoursのような書き方で、userに紐づくworking_hoursであれば全件取得できるはずです。 すみません、混乱してしまいました。。。。この場合、controller(今のまま?)とview側のループはどのようになるんでしょう....? usersの数の分だけループをする中に、userに紐づくworking_hourを取り出すループを書く...みたいなイメージですかね。
退会済みユーザー

退会済みユーザー

2018/08/23 05:32

紐づいたデータのRails特有の所得方法です。紐づけているのであればこっち方が楽じゃないですか?ってだけです。 controllerは @users を定義しておけば、view は @users.each { |user| user.working_hours } みたいな内容で、ユーザーごとの全 working_hours が取れるんじゃないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問