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

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

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

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

Ruby on Rails 6

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

Q&A

解決済

1回答

1108閲覧

(DM機能)トークルームに相手のユーザー情報を表示したい

nyanko-meshi

総合スコア13

Ruby

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

Ruby on Rails 6

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

0グッド

0クリップ

投稿2021/11/10 10:00

編集2021/11/10 10:39

前提・実現したいこと

こちらの記事を参考に、RailsアプリにDM機能を実装しています。
RailsでややこしいDM機能を1万字でくわしく解説してみた

上記の記事では、トークルーム(rooms/show.html.erb)に、

  • ログイン中ユーザーのユーザー情報
  • トーク相手のユーザー情報

を、それぞれ表示していますが、
「トーク相手のユーザー情報だけ」を表示するように変更したいです。

該当のソースコード

rooms_controller.rb

ruby

1 # GET /rooms/:id 2 def show 3 @room = Room.find(params[:id]) 4 if Entry.where(user_id: current_user.id,room_id: @room.id).present? 5 @messages = @room.messages 6 @message = Message.new 7 @entries = @room.entries 8 else 9 redirect_back(fallback_location: root_path) 10 end 11 end

rooms/show.html.erb

<% @entries.each do |e| %> <div class="user-name"> <strong> <%= image_tag e.user.avatar, class:"user-image" %> <a class="rooms-user-link" href="/users/<%= e.user.id %>"> <%= e.user.name %>さん </a> </strong> </div> <% end %>

試したこと

上記のeachを用いたコードでは、entriesテーブルから取得したデータに対してusersテーブルのアソシエーションが機能しているので、
下記変更後のコードでも、entriesテーブルからwhereメソッドで条件を指定して取得してきたデータに対してuserのアソシエーションを用いてみると、機能しませんでした。

この違いはどこにあるのでしょうか?

> e = Entry.first Entry Load (0.4ms) SELECT "entries".* FROM "entries" ORDER BY "entries"."id" ASC LIMIT ? [["LIMIT", 1]] => #<Entry id: 1, user_id: 1, room_id: 1, created_at: "2021-11-10 03:32:52", updated_at: "2021-11-10 03:32:52"> > e.user User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] => #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2021-10-27 03:52:05", updated_at: "2021-10-27 03:52:05", password_digest: [FILTERED], remember_digest: nil, admin: true, activation_digest: "$2a$12$a5wBerQmUiR2bPbf8YZr.OgpSI8U/OSV9CuMUtkMipQ...", activated: true, activated_at: "2021-10-27 03:52:04", reset_digest: nil, reset_sent_at: nil> > ee = Entry.where(room_id: 1).where.not(user_id: 1) Entry Load (0.4ms) SELECT "entries".* FROM "entries" WHERE "entries"."room_id" = ? AND "entries"."user_id" != ? LIMIT ? [["room_id", 1], ["user_id", 1], ["LIMIT", 11]] => #<ActiveRecord::Relation [#<Entry id: 2, user_id: 4, room_id: 1, created_at: "2021-11-10 03:32:52", updated_at: "2021-11-10 03:32:52">]> > ee.user Traceback (most recent call last): 1: from (irb):55 Entry Load (0.3ms) SELECT "entries".* FROM "entries" WHERE "entries"."room_id" = ? AND "entries"."user_id" != ? LIMIT ? [["room_id", 1], ["user_id", 1], ["LIMIT", 11]] NoMethodError (undefined method `user' for #<Entry::ActiveRecord_Relation:0x00007fa0e4d473f8>)

####改変後のコード
rooms_controller.rb

ruby

1 # GET /rooms/:id 2 def show 3 @room = Room.find(params[:id]) 4 if Entry.where(user_id: current_user.id, room_id: @room.id).present? 5 @messages = @room.messages 6 @message = Message.new 7 # 以下2行を追加 8 @partner_entry = Entry.where(room_id: @room.id).where.not(user_id: current_user.id) 9 @user = @partner_entry.user 10 else 11 redirect_back(fallback_location: root_path) 12 end 13 end

rooms/show.html.erb
※ 画像の表示箇所はgravatorに変更しています。

erb

1<h4 class="rooms-title">ダイレクトメッセージを送る</h4> 2<div class="user-name"> 3 <strong> 4 <%= gravatar_for @user, class:"user-image" %> 5 <a class="rooms-user-link" href="/users/<%= @user.id %>"> 6 <%= @user.name %>さん 7 </a> 8 </strong> 9</div> 10 11<%# 以下略 %>

発生している問題・エラーメッセージ

NoMethodError in RoomsController#show undefined method `user' for #<Entry::ActiveRecord_Relation:0x00007fa367fd4348> Did you mean? super

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

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

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

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

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

guest

回答1

0

ベストアンサー

e は単一のオブジェクトです。
ee は配列みたいなやつです。@partner_entry も配列みたいなやつです。

単一のオブジェクトに対しては関連を決定できますが配列みたいなやつではできません。
なので以下のように単一のオブジェクトをひとつ取り出して user を呼ぶ必要があります。

ruby

1ee.first.user 2 3# 配列みたいなやつなので本当は @partner_entries という名前がふさわしい 4@partner_entry.first.user

find や find_by は単一のオブジェクトを返します。
where は配列みたいなやつを返します。

投稿2021/11/12 00:05

neko_daisuki

総合スコア2090

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

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

nyanko-meshi

2021/11/12 02:50

非常に分かりやすかったです! おかげさまでアプリの方も正常に動作しました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問