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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

766閲覧

【Ruby on Rails】messages controllerにgroup_idが正しく送られない。

kumamin

総合スコア12

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2020/07/19 03:19

編集2020/07/19 05:08

前提・実現したいこと

今Ruby on Railsで、チャット画面を実装しています。

具体的には、チャットをしたいユーザーの投稿一覧ページにある「トークルーム」というボタンをクリックすると、そのユーザーとログイン中のユーザーが1対1で話せるようなチャット画面を作りたいです。

前提として、指定したユーザーとログイン中のユーザーのまとまりのことを"group"と定義し、チャットの中身を"message"と定義しています。
また、ユーザーの投稿一覧ページのビューを**"posts_g/show.html.haml", 遷移先のチャット画面を"messages/index.html.haml**"としています。

もし2人組のgroupがまだできていなかったらgroupsコントローラーのcreateアクションに行き、groupが作成されたら messagesコントローラーのindexアクションに飛ぶように設定しています。
もしすでにgroupが作成されていたら、createアクションを経由せずにmessages#indexに飛ばせたいです。

実装中にエラーが発生したので、解決方法を教えていただけないでしょうか?

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

エラーメッセージは以下の通りです。

ActiveRecord::RecordNotFound in MessagesController#index Couldn't find Group with 'id'=[36]

イメージ説明

問題は、posts_g/show.html.hamlで送った"group_id"が、messagesコントローラーに正しく渡されていないことです。
ターミナルを見ると、posts_g/show.html.hamlが表示されるまでは正しく送られているのに、messagesコントローラーに飛ぶと"group_id"が変わってしまうんです。
今回の場合だと、本当の"group_id"は26なのに、36に変わってしまっています。

該当のソースコード

app/views/posts_g/show.html.haml

ruby

1.Wrapper 2 .Title 3 = "#{@user.name}さんのページ" 4 .Profile 5 = attachment_image_tag @user, :profile_image, fallback: "no-image.jpg", class: "Profile__Image" 6 .Profile__Content 7 .Profile__Content__Name_btns 8 .Name 9 = @user.name 10 .White_btns 11 - if @group.empty? 12 = link_to "トークルーム", "/groups/#{@user.id}/create", class: "White_btns__Btn" 13 - else 14 = link_to "トークルーム", "/groups/#{@group.ids}/messages", class: "White_btns__Btn" 15 .Profile__Content__Text.Text 16 = simple_format(@user.profile) 17

app/controllers/posts_g_controller.rb

ruby

1class PostsGController < ApplicationController 2 before_action :set_post, only: [:edit] 3 before_action :move_to_index, except: [:index] 4 5 def show 6 @user = User.find(params[:id]) 7 @posts = @user.post_gs 8 @posts_g = current_user.post_gs 9 10 groups = @user.groups.pluck(:id) 11 group = GroupUser.where(group_id: groups) 12 @group = group.where(user_id: current_user.id) 13 end 14 15 private 16 def post_params 17 params.require(:post_g).permit(:region, :datetime, :content, :charge).merge(user_id: current_user.id) 18 end 19 20 def set_post 21 @post = PostG.find(params[:id]) 22 end 23 24 def move_to_index 25 redirect_to action: :index unless user_signed_in? 26 end 27end

app/controllers/groups_controller.rb

ruby

1class GroupsController < ApplicationController 2 3 def create 4 group = Group.create 5 group_user = GroupUser.create(group_id: group.id, user_id: current_user.id) 6 @user = User.find(params[:id]) 7 group_user = GroupUser.create(group_id: group.id, user_id: user.id) 8 redirect_to posts_g_path(@user.id) 9 end 10 11 private 12 def group_params 13 params.permit(:id, user_ids: []) 14 end 15 16end

app/controllers/messages_controller.rb

ruby

1class MessagesController < ApplicationController 2 before_action :set_group 3 4 def index 5 end 6 7 def create 8 @message = Message.new 9 redirect_to group_path(@message.group_id) 10 end 11 12 def show 13 @user = User.find(params[:id]) 14 end 15 16 private 17 18 def message_params 19 params.require(:message).permit(:text, :image).merge(user_id: current_user.id) 20 end 21 22 def set_group 23 @group = Group.find(params[:group_id]) 24 end 25end

config/routes.rb

ruby

1Rails.application.routes.draw do 2 devise_for :users 3 devise_scope :user do 4 get '/users/sign_out' => 'devise/sessions#destroy' 5 end 6 7 root "home#index" 8 resources :users 9 resources :posts_g 10 11 resources :groups, only: :show do 12 resources :messages, only: [:index, :create] 13 end 14 15 get '/groups/:id/create', to: 'groups#create' 16end

app/models/group.rb

ruby

1class Group < ApplicationRecord 2 has_many :group_users 3 has_many :users, through: :group_users 4 has_many :messages 5end

app/models/message.rb

ruby

1class Message < ApplicationRecord 2 belongs_to :group 3 belongs_to :user 4 5 validates :text, presence: true, unless: :image? 6end

試したこと

・トークルームのボタンのリンク先である"/groups/#{@group.ids}/messages"をPrefixで書いてみたり、"@group.ids"を"@group", 書いたりしましたが変わりませんでした。また、"@group.id"と書き換えたら別のエラーが出ました。
・messages#indexのルーティングにidが含まれていないのではないか?と思ったのですが、rails routesで確認したら含まれていました。
・messagesコントローラーの"set_group"のparamsの書き方も[:id]と書き換えてみたりしたんですがそれもダメでした。

補足情報(FW/ツールのバージョンなど)

ブラウザで表示されるトークルームのURLは以下の通りです。
http://localhost:3000/groups/[36]/messages

データベースはPostgresQL12を使っています。
一応ルーティングと、サーバーを立ち上げたターミナルの画像も載せておきます。

ターミナル(rails routesの結果)
イメージ説明

ターミナル(rails sの結果)
イメージ説明

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

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

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

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

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

Cojiro

2020/07/19 04:39

トークルームのリンクのURLはブラウザで確認するとどうなっていますか?
Cojiro

2020/07/19 06:56

コントローラーで26を受け取りたいなら、 まずはそのURLの[36]が26にならないといけないですね。 []も変ですね。 showアクションのこの記述が問題かと思います。 @group = group.where(user_id: current_user.id) ここで、group_idが26のものを取得できるようにすればいいと思います。 トライしてみてください。 ここでは単一のインスタンスを返すのが望ましいので、findやfind_byを使うといいでしょう。
kumamin

2020/07/19 08:35

findやfind_byに書き換えてもエラーは解決できなかったのですが、showアクションを見直してみたところ、確かにその部分の記述が間違っていました。 36という数字はgroupのIDではなく、group_userという中間テーブルのIDだったため、IDが一致しなかったということでした。 ただそこを直しても別のエラーが発生してしまったので、また別のところで質問させていただこうと思います。 この度はご回答、ありがとうございました!!
guest

回答1

0

自己解決

app/controllers/posts_g_controller.rbのshowアクション内の記述が間違っていました。
上記で定義した@groupではgroupのデータではなく、group_userという中間テーブルのデータが取り出されており、group_userのIDがビューに送られていたためIDが一致していなかったということでした。

以下が修正後のコードです。
▼app/controllers/posts_g_controller.rb

ruby

1 def show 2 @user = User.find(params[:id]) 3 @posts = @user.post_gs 4 @posts_g = current_user.post_gs 5 6 groups = @user.groups.pluck(:id) 7 group_users = GroupUser.where(group_id: groups) 8 group_user = group_users.where(user_id: current_user.id) 9 @group_id = group_user.pluck(:group_id) 10 end

▼app/views/posts_g/show.html.haml

ruby

1= link_to "トークルーム", "/groups/#{@group_id}/messages", class: "White_btns__Btn"

投稿2020/07/19 08:43

kumamin

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問