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

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

ただいまの
回答率

88.78%

railsでユーザー同士のメッセージ機能を付けたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,999

yoshimitsu41

score 34

タイトル通りですがrailsでユーザー同士のメッセージ機能の実装に関してです。
モデルは

  • userモデル
  • roomモデル
  • messageモデル
    の3つで対応しようと考えています。

userモデルのカラム

  • id
  • email
  • password
  • nickname

user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_one :profile
  has_many :messages
  acts_as_followable # フォロワー機能
  acts_as_follower   # フォロー機能
end

roomモデルのカラム

  • id
  • user_id
  • second_user_id
    のカラムがあります。
    user_idが送信した人で
    second_user_idが受信した人
    にしようと思っています。

room.rb

class Room < ActiveRecord::Base
  belongs_to :user
  belongs_to :second_user, class_name: 'User'
  has_many :messages
end

messageモデルのカラム

  • id
  • text
  • room_id
  • user_id
    があります。

message.rb

class Message < ActiveRecord::Base
  belongs_to :room
  belongs_to :user
end

user/show.html.erb

                <h3>メッセージを送る</h3>
                    <%= form_tag('/messages', method: :post,) do %>
                      <div class="form-group">
                        <textarea class="form-control" rows="5" name="text"></textarea>
                      </div>
                      <button type="submit" class="btn btn-primary btn-lg btn-block">送信</button>
                    <% end %>


submitをクリックすると・・・
roomが新しく作成されて送信者のIDと受信者のIDがroomsテーブルに追加されるようにしたい。
messagesテーブルにtextとroom_idとuser_idが追加されるようにしたい。

controller/messages_controller.rb

  def create
    #以下はルームモデルに追加する
    @user = User.find(params[:id])
    binding.pry
    room = Room.new(user_id: current_user.id,second_user_id: user.id )
    room.save
    #以下はメッセージモデルに追加する
    Message.create(text: message_params[:text],user_id: current_user.id,room_id: room.id)
    redirect_to user_path(current_user.id)
  end

  private
  def message_params
    params.permit(:text)
  end

routes.rb

  Rails.application.routes.draw do
  #devise_for :users
  devise_for :users do
    member do
      get :follow
      get :unfollow
    end
  end
    root 'homes#index' #root_path
    get 'flow' => 'flows#index'
    resources :messages
    resources :profiles
    resources :rooms
    resources :users do
      member do
        put :follow
        put :unfollow
      end
    end
  end

上記の内容で登録[submit]すると下記のようなエラーが出ます。
イメージ説明

受信した側のID(second_user_id)が取得できていないのですが
どのようにして取得すればよろしいでしょうか?

ご指摘・ご教授お願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

                <h3>メッセージを送る</h3>
                    <%= form_tag('/messages', method: :post,) do %>
                      <div class="form-group">
                        <textarea class="form-control" rows="5" name="text"></textarea>
<input id="user_id" name="user_id" type="hidden" value="<%=@user.id%>"><input>

                      </div>
                      <button type="submit" class="btn btn-primary btn-lg btn-block">送信</button>
                    <% end %>


controller

def create
    #以下はルームモデルに追加する
    @user = User.find(params[:user_id])
    binding.pry
    room = Room.new(user_id: current_user.id,second_user_id: user.id )
    room.save
    #以下はメッセージモデルに追加する
    Message.create(text: message_params[:text],user_id: current_user.id,room_id: room.id)
    redirect_to user_path(current_user.id)
  end
 def message_params
    params.permit(:user_id,:text)
  end

で動くと思いますが

どうでしょう

ちなみに
roomモデルがあることから
チャットのようなものを作りたいのかなと
思いますが、Railsの普通の機能でチャットを作ると
実際に運用すると、すごく重くて使い物にならないと思いますよ
ActionCableとRedisを使って実装してください

rails5でやるときは
rails5
で結構簡単にできますが
rails4だと結構大変です。
rails4
上記サイトをみても最初からつまづくと思うので
一応ヒントとして

#Gemfile
gem 'actioncable', github: 'rails/actioncable',branch: 'archive'


としてみてください

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/25 20:59 編集

    何度もすみません。。。

    routes.rbを

    resources :users do
    resources :rooms do
    resources :messages
    end
    member do
    put :follow
    put :unfollow
    end
    end

    のように変更してネストさせると

    <%= form_tag('/messages/', method: :post,) do %>
    <div class="form-group">
    <textarea class="form-control" rows="5" name="text"></textarea>
    <input id="user_id" name="user_id" type="hidden" value="<%= @user.id %>" />
    </div>
    <button type="submit" class="btn btn-primary btn-lg btn-block">送信</button>
    <% end %>

    のsubmitをクリックするとルーティングエラーがでます。
    rake routesが

    user_room_messages GET /users/:user_id/rooms/:room_id/messages(.:format) messages#index
    POST /users/:user_id/rooms/:room_id/messages(.:format) messages#create
    new_user_room_message GET /users/:user_id/rooms/:room_id/messages/new(.:format) messages#new
    edit_user_room_message GET /users/:user_id/rooms/:room_id/messages/:id/edit(.:format) messages#edit
    user_room_message GET /users/:user_id/rooms/:room_id/messages/:id(.:format) messages#show
    PATCH /users/:user_id/rooms/:room_id/messages/:id(.:format) messages#update
    PUT /users/:user_id/rooms/:room_id/messages/:id(.:format) messages#update
    DELETE /users/:user_id/rooms/:room_id/messages/:id(.:format) messages#destroy

    です。
    submitしたらroomが新しく作成されるようにしたいのですが

    <%= form_tag('/messages', method: :post,) do %>

    はどのように記述すれば改善されますでしょうか?

    キャンセル

  • 2017/04/25 22:46 編集

    なぜ、そのようにネストしたいのですか?そうするとメッセージを見るのに、いちいちユーザーとルームを指定しないといけません。ユーザーのメッセージ一覧を見たかったり、ルームごとに見たり出来ませんが…。もう一度どうしたいかを紙に書くなどして整理して新たに質問をし直してはいかがでしょう?

    キャンセル

  • 2017/04/27 16:31

    おっしゃるとおりでした。。。ご指摘ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る