2017年1月23日 星期一

MailBox

參考網站 https://medium.com/@danamulder/tutorial-create-a-simple-messaging-system-on-rails-d9b94b0fbca1#.yi0myzbcv
自己練習過後的筆記
先從model開始,因為是要做mailbox,所以需要下面三個表單
  1. user <- user資料
  2. message <-所有訊息
  3. conversation <- 記錄哪些人和哪些人有建立過對話
一個user會有好幾個對話,一段對話會包含很多條message,而message則會隸屬於某段對話和使用者
class Conversation < ActiveRecord::Base
  belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
  belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User'

  has_many :messages, dependent: :destroy

  validates_uniqueness_of :sender_id, :scope => :recipient_id

  scope :between, -> (sender_id,recipient_id) do
    where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id)
  end

end
上面建立了一個between scope,是為了之後方便確認某兩位使用者之間有沒有建立過對話
最前面兩個belongs_to是為了方便可以查到sender或是recipient的使用者資料,因為從sender_id或是recipient_id沒有辦法自動對應到關聯model,所以需要在後面指定class_name: ‘User’,然後直接寫明foreign_key
class Message < ActiveRecord::Base
  belongs_to :conversation
  belongs_to :user
  validates_presence_of :body, :conversation_id, :user_id

  def message_time
    created_at.strftime("%m/%d/%y at %l:%M %p")
  end
end
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :messages
  has_many :conversations
end

conversation index
<div class=”ui segment”>
  <h3>Mailbox</h3>
    <div class=”ui list”>
      <div class=”item”>
        <% @conversations.each do |conversation| %>
          <% if conversation.sender_id == current_user.id || conversation.receiver_id == current_user.id %>
            <% if conversation.sender_id == current_user.id %>
              <% recipient = User.find(conversation.receiver_id) %>
            <% else %>
              <% recipient = User.find(conversation.sender_id) %>
            <% end %>
            <%= link_to recipient.first_name,   conversation_messages_path(conversation)%>
          <% end %>
        <% end %>
      </div>
   </div>
  </div>

<div class=”ui segment”>
  <h3>All Users</h3>
    <div class=”ui list”>
      <% @users.each do |user| %>
        <% if user.id != current_user.id %>
          <div class=”item”>
            <%= user.first_name %> <%= link_to ‘Message me!’, conversations_path(sender_id: current_user.id, receiver_id: user.id), method: ‘post’%>
          </div>
        <% end %>
      <% end %>
    </div>
</div>
mailbox的首頁,controller裡面已經定義好@users和@conversations會撈出所有的使用者和目前所有的對話,然後view在顯示出目前使用者相關的對話,以及可以send訊息的link,點下會連到conversation的create action
  def create
        if Conversation.between(params[:sender_id],params[:recipient_id]).present?
      @conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
    else
      @conversation = Conversation.create!(conversation_params)
    end
    redirect_to conversation_messages_path(@conversation)
  end
會先判斷這兩個使用者之間有沒有已存在的對話,有則把舊的撈出來,沒有就create,之後的動作會交給message controller
  def new
    @message = @conversation.messages.new
  end

  def create
    @message = @conversation.messages.new(message_params)
    if @message.save
      redirect_to conversation_messages_path(@conversation)
    end
  end

private
  def message_params
    params.require(:message).permit(:body, :user_id)
  end
Written with StackEdit.

沒有留言:

張貼留言