将通知添加到 RoR 消息收件箱系统
Add notification to RoR messaging inbox system
我有一个带有实习消息系统的 rails 应用程序。用户可以向其他用户发送消息。示例:用户 1 发送消息,用户 2 可以回复,反之亦然。
一切正常。但我想用通知功能升级这个系统。我想要通知类型:
1) 在导航栏上
2) 邮寄
问题:我不知道我该怎么做。
你能帮帮我吗?
对话table
class CreateConversations < ActiveRecord::Migration
def change
create_table :conversations do |t|
t.integer :sender_id
t.integer :recipient_id
t.timestamps
end
end
end
消息table。在这段代码中,我有一个布尔值:read。我认为解决方案可以在这里。你怎么看这个?
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.text :body
t.references :conversation, index: true
t.references :user, index: true
t.boolean :read, :default => false
t.timestamps
end
end
end
conversation.rb
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
Message.rb
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
conversations_controller.rb
class ConversationsController < ApplicationController
before_action :authenticate_user!
# GET /conversations
# GET /conversations.json
def index
@users = User.all
# Restrict to conversations with at least one message and sort by last updated
@conversations = Conversation.joins(:messages).uniq.order('updated_at DESC')
end
# POST /conversations
# POST /conversations.json
def create
if Conversation.between(params[:conversation][:sender_id], params[:conversation][:recipient_id]).present?
@conversation = Conversation.between(params[:conversation][:sender_id], params[:conversation][:recipient_id]).first
else
@conversation = Conversation.create!(conversation_params)
end
redirect_to conversation_messages_path(@conversation)
end
private
# Use callbacks to share common setup or constraints between actions.
def conversation_params
params.require(:conversation).permit(:sender_id, :recipient_id)
end
end
messages_controller.rb
class MessagesController < ApplicationController
before_action do
@conversation = Conversation.find(params[:conversation_id])
end
def index
@messages = @conversation.messages
if @messages.length > 10
@over_ten = true
@messages = @messages[-10..-1]
end
if params[:m]
@over_ten = false
@messages = @conversation.messages
end
if @messages.last
if @messages.last.user_id != current_user.id
@messages.last.read = true;
end
end
@message = @conversation.messages.new
end
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
end
/conversations/index.html.erb
<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.recipient_id == current_user.id %>
<% if conversation.sender_id == current_user.id %>
<% recipient = User.find(conversation.recipient_id) %>
<% else %>
<% recipient = User.find(conversation.sender_id) %>
<% end %>
Conversation avec <%= link_to recipient.prenom, 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.prenom %> <%= button_to 'Message me', conversations_path(conversation: { sender_id: current_user.id, recipient_id: user.id }), class: 'btn btn-primary m-t' %>
</div>
<% end %>
<% end %>
</div>
</div>
messages/index.html.erb
<% if @over_ten %>
<%= link_to 'Show Previous', "?m=all" %>
<% end %>
<div class="ui segment">
<% @messages.each do |message| %>
<% if message.body %>
<% user = User.find(message.user_id) %>
<div class="item">
<div class="content">
<div class="header"><strong><div class="imageavatarmessage"><%= image_tag user.avatar(:thumb), class:"imageavatarmessage" %></div><%= user.prenom %></strong> <%= message.message_time %></div>
<div class="list">
<div class="item">
<i class="right triangle icon"></i>
<%= message.body %>
</div>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
<%= form_for [@conversation, @message], html: {class: "ui reply form"} do |f| %>
<div class=”field”>
<%= f.text_area :body, class: "form-control" %>
</div>
<%= f.text_field :user_id, value: current_user.id, type: "hidden" %>
<div>
<%= f.submit "Add Reply", class: "ui blue labeled submit icon button" %>
</div>
<% end %>
我建议您通过本教程来构建漂亮的通知系统
https://www.devwalks.com/lets-build-instagram-part-6-notifications/
基本上,您必须创建新模型,设置与您的 Message
模型的依赖关系并集成到控制器
邮件通知就更简单了。
只需创建新的邮件程序并在 messages_controller
中的创建操作中触发它
def create
@message = @conversation.messages.new(message_params)
if @message.save
SendMessageMailer.new_message(@message).deliver_later
redirect_to conversation_messages_path(@conversation)
end
end
编辑:
要创建邮件程序,您应该这样做:
rails g mailer SendMessage
转到 /app/mailers/send_message_mailer.rb 并添加动作,与控制器类型相同的建筑物
def new_message(message)
@message = message
mail(to: @message.user.email, subject: 'Hey! Here is what you missed')
end
此外,创建一个视图(电子邮件模板)并使用 erb 代码进行编码
app/views/send_message_mailer/new_message.html.erb
我不会深入探讨这个问题,我想你可以弄清楚如何传递间隔(假设用户在线或已阅读消息时不发送)并与 receiver/sender 用户
再一次,Mailer 只是同一类型的控制器。您可以根据需要传递任意数量的参数,并在邮件控制器和视图中使用模型嵌套
邮寄者
def new_message(message, sender, receiver)
end
控制器
SendMessageMailer.new_message(@message, @message.user, params[:receiver]).deliver_later
我有一个带有实习消息系统的 rails 应用程序。用户可以向其他用户发送消息。示例:用户 1 发送消息,用户 2 可以回复,反之亦然。
一切正常。但我想用通知功能升级这个系统。我想要通知类型:
1) 在导航栏上 2) 邮寄
问题:我不知道我该怎么做。
你能帮帮我吗?
对话table
class CreateConversations < ActiveRecord::Migration
def change
create_table :conversations do |t|
t.integer :sender_id
t.integer :recipient_id
t.timestamps
end
end
end
消息table。在这段代码中,我有一个布尔值:read。我认为解决方案可以在这里。你怎么看这个?
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.text :body
t.references :conversation, index: true
t.references :user, index: true
t.boolean :read, :default => false
t.timestamps
end
end
end
conversation.rb
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
Message.rb
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
conversations_controller.rb
class ConversationsController < ApplicationController
before_action :authenticate_user!
# GET /conversations
# GET /conversations.json
def index
@users = User.all
# Restrict to conversations with at least one message and sort by last updated
@conversations = Conversation.joins(:messages).uniq.order('updated_at DESC')
end
# POST /conversations
# POST /conversations.json
def create
if Conversation.between(params[:conversation][:sender_id], params[:conversation][:recipient_id]).present?
@conversation = Conversation.between(params[:conversation][:sender_id], params[:conversation][:recipient_id]).first
else
@conversation = Conversation.create!(conversation_params)
end
redirect_to conversation_messages_path(@conversation)
end
private
# Use callbacks to share common setup or constraints between actions.
def conversation_params
params.require(:conversation).permit(:sender_id, :recipient_id)
end
end
messages_controller.rb
class MessagesController < ApplicationController
before_action do
@conversation = Conversation.find(params[:conversation_id])
end
def index
@messages = @conversation.messages
if @messages.length > 10
@over_ten = true
@messages = @messages[-10..-1]
end
if params[:m]
@over_ten = false
@messages = @conversation.messages
end
if @messages.last
if @messages.last.user_id != current_user.id
@messages.last.read = true;
end
end
@message = @conversation.messages.new
end
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
end
/conversations/index.html.erb
<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.recipient_id == current_user.id %>
<% if conversation.sender_id == current_user.id %>
<% recipient = User.find(conversation.recipient_id) %>
<% else %>
<% recipient = User.find(conversation.sender_id) %>
<% end %>
Conversation avec <%= link_to recipient.prenom, 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.prenom %> <%= button_to 'Message me', conversations_path(conversation: { sender_id: current_user.id, recipient_id: user.id }), class: 'btn btn-primary m-t' %>
</div>
<% end %>
<% end %>
</div>
</div>
messages/index.html.erb
<% if @over_ten %>
<%= link_to 'Show Previous', "?m=all" %>
<% end %>
<div class="ui segment">
<% @messages.each do |message| %>
<% if message.body %>
<% user = User.find(message.user_id) %>
<div class="item">
<div class="content">
<div class="header"><strong><div class="imageavatarmessage"><%= image_tag user.avatar(:thumb), class:"imageavatarmessage" %></div><%= user.prenom %></strong> <%= message.message_time %></div>
<div class="list">
<div class="item">
<i class="right triangle icon"></i>
<%= message.body %>
</div>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
<%= form_for [@conversation, @message], html: {class: "ui reply form"} do |f| %>
<div class=”field”>
<%= f.text_area :body, class: "form-control" %>
</div>
<%= f.text_field :user_id, value: current_user.id, type: "hidden" %>
<div>
<%= f.submit "Add Reply", class: "ui blue labeled submit icon button" %>
</div>
<% end %>
我建议您通过本教程来构建漂亮的通知系统 https://www.devwalks.com/lets-build-instagram-part-6-notifications/
基本上,您必须创建新模型,设置与您的 Message
模型的依赖关系并集成到控制器
邮件通知就更简单了。
只需创建新的邮件程序并在 messages_controller
def create
@message = @conversation.messages.new(message_params)
if @message.save
SendMessageMailer.new_message(@message).deliver_later
redirect_to conversation_messages_path(@conversation)
end
end
编辑: 要创建邮件程序,您应该这样做:
rails g mailer SendMessage
转到 /app/mailers/send_message_mailer.rb 并添加动作,与控制器类型相同的建筑物
def new_message(message)
@message = message
mail(to: @message.user.email, subject: 'Hey! Here is what you missed')
end
此外,创建一个视图(电子邮件模板)并使用 erb 代码进行编码
app/views/send_message_mailer/new_message.html.erb
我不会深入探讨这个问题,我想你可以弄清楚如何传递间隔(假设用户在线或已阅读消息时不发送)并与 receiver/sender 用户
再一次,Mailer 只是同一类型的控制器。您可以根据需要传递任意数量的参数,并在邮件控制器和视图中使用模型嵌套
邮寄者
def new_message(message, sender, receiver)
end
控制器
SendMessageMailer.new_message(@message, @message.user, params[:receiver]).deliver_later