Rails用户私信功能点击发消息按钮报路由缺失id参数错误如何解决
问题原因
- 你调用的
conversation_path是Rails REST路由默认的详情页路由,对应ConversationsController的show动作,要求必须传会话的id参数,你传的sender_id和recipient_id自然会触发缺少id的报错 - 你需要的其实是触发create动作创建/匹配已有会话,应该用对应create动作的复数路由
conversations_path,同时指定POST请求方法 - 另外要确认你的
config/routes.rb里已经配置了会话的路由规则,示例配置如下:resources :conversations, only: [:index, :create] do resources :messages, only: [:index, :create] end
修复步骤
- 修改视图里的"Message me!"按钮的link_to代码:
<%= link_to "Message me!", conversations_path(conversation: {sender_id: current_user.id, recipient_id: user.id}), method: :post %>
这里调整了3个核心点:
- 把单数
conversation_path改成复数conversations_path,对应create路由 - 加了
method: :post指定用POST请求触发create动作 - 把参数套在
conversation对象里,匹配你controller里conversation_params的强校验要求
- 可选优化(推荐)
你现在index方法里查全量会话再过滤当前用户的,效率很低,可以给Conversation模型加作用域:
# app/models/conversation.rb scope :for_user, ->(user_id) { where("sender_id = ? OR recipient_id = ?", user_id, user_id) } belongs_to :sender, class_name: "User" belongs_to :recipient, class_name: "User"
然后controller的index方法改成:
def index @users = User.where.not(id: current_user.id) # 直接过滤掉当前用户,不用在视图里判断 @conversations = Conversation.for_user(current_user.id) end
视图里也不需要手动写User.find查询收件人,直接调用关联即可:
<% recipient = conversation.sender_id == current_user.id ? conversation.recipient : conversation.sender %>
避免触发N+1查询问题。
内容的提问来源于stack exchange,提问作者prstsb
相关产品推荐
相关产品推荐

