yuppe0328
@yuppe0328

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

謎のNo Methodエラーが解決できない

Railsでチャット機能を作成していたところサーバーを立ててroomsコントローラーのshowアクションを動かすと、 NoMethodError Exception: undefined method `user_id' for UserRoom::ActiveRecord_AssociationRelation:0x00000000040232b8というエラーになる問題で困っています。
原因または解決策をご存知の方はいらっしゃいませんか。

ちなみに、チャット相手の情報がshowアクション動いているときに欲しくてこのような記述になっています。また、byebugを置いているポイントでコンソールを開きpartner_roomの中身を確認すると、しっかりとActiveRecord::AssociationRelation UserRoom id: 1, user_id: 1, room_id: 1, created_at: "2020-12-22 09:53:14", updated_at: "2020-12-22 09:53:14"と出ています。

以下、関係してきそうなファイルになります

show.html.erb
<h1><%= @partner.name %>さんとのチャット</h1>

<div class="chats">
<%= render "rooms/chat", chats: @chats %>
</div>
  <div class="posts">
    <%= form_with model:[@chat] do |f| %>
      <%= f.text_field :content, placeholder: "メッセージを入力して下さい" , size: 70, class:"form-text-field" %>
        <%= f.hidden_field :room_id, value: @room.id %>
          <%= f.submit "投稿",class: 'form-submit'%>
    <% end %>
  </div>
rooms_controller.rb
class RoomsController < ApplicationController

  def create
    @room = Room.create
    #フォローしている側のroom情報作成
    @user_room1 = UserRoom.create(room_id: @room.id, user_id: current_user.id)
    #フォローされている側...
    @user_room2 = UserRoom.create(params.require(:user_room).permit(:user_id, :room_id).merge(room_id: @room.id))
    #byebugで確認せよ

    redirect_to room_path(@room.id)
  end

  def show
    @room = Room.find(params[:id])
    if UserRoom.where(user_id: current_user.id, room_id: @room.id).present?
      @chats = @room.chats
      @chat = Chat.new
      @user_rooms = @room.user_rooms
      partner_room = @user_rooms.where.not(user_id: current_user.id)
      byebug
      @patner = User.find(partner_room.user_id)
    else
      redirect_back(fallback_location: users_path)
    end

  end
end

user_room.rb,user.rb,room.rb
class UserRoom < ApplicationRecord
  belongs_to :user
  belongs_to :room
end
class User < ApplicationRecord
  has_many :chats, dependent: :destroy
  has_many :user_rooms, dependent: :destroy
end

class Room < ApplicationRecord
  has_many :user_rooms
  has_many :chats
end

きちんとアソシエーションの関係も組まれているので、user_idの値を返してくれると思ったのですが、そうはならなかったみたいです。

解決法などわかる方いましたら、よろしくお願いいたします。
また、足りない情報等ございましたら、お気軽に申し付けください。

0

1Answer

partner_roomの中身を確認すると、しっかりとActiveRecord::AssociationRelation UserRoom id: 1, user_id: 1, room_id: 1, created_at: "2020-12-22 09:53:14", updated_at: "2020-12-22 09:53:14"と出ています。

とありますが、実際には

#<ActiveRecord::AssociationRelation [#<UserRoom id: 1, ...>]>

のように UserRoom が配列に入った見た目になっていませんでしたか?

partner_room は1つの UserRoom オブジェクト ではなく リレーションオブジェクトです。UserRoom が入った配列のようなものと考えてください。

.user_idUserRoom の属性ですからリレーションオブジェクトに対して呼ぶことはできません。リレーションオブジェクトの .first を呼んで、中身の UserRoom を1つ取り出してやれば解決します。

partner_room = @user_rooms.where.not(user_id: current_user.id).first
1Like

Comments

  1. @yuppe0328

    Questioner

    確かにご指摘いただいたような見た目になっておりました…
    そもそもpartner_roomがUserRoomオブジェクトを取ってきていなかったのですね!
    回答いただきありがとうございました!!

Your answer might help someone💌