首页 > 解决方案 > Rails ActionController::ParameterMissing(参数丢失或值为空

问题描述

我使用指南作为从头开始创建消息传递系统的起点。我不得不修改这些来处理 和 之间的User消息AdminUser。出于某种原因,每当我现在尝试通过在我的视图中单击以下链接来创建新对话时:

<li><%= link_to admin.email, conversations_path(sendable_id: current_user.id, recipientable_id: admin.id), method: :post %></li>

我遇到错误:

ActionController::ParameterMissing(参数丢失或值为空:conversation 你的意思是?控制器authentity_token action recipientable_id):

参数是:

=> #<ActionController::Parameters {"_method"=>"post", "authenticity_token"=>"pHmi9kWBLSc5QSJUPQxfNsqSR1fqWCSCBqEVgRMljhgrxB9g4M0ClsdEi2hBLCTjrLLl774T-mnyK8m40LFhNA", "recipientable_id"=>"1", "sendable_id"=>"2", "controller"=>"conversations", "action"=>"create"} permitted: false>

我被定向到控制器中的 params.permit 行:

class ConversationsController < BaseController
  def index
    @users = User.all
    @admins = AdminUser.all
    @conversations = Conversation.all
  end

  def create
    @conversation = if Conversation.between(params[:sendable_id], params[:recipientable_id]).present?
                      Conversation.between(params[:sendable_id], params[:recipientable_id]).first
                    else
                      Conversation.create!(conversation_params)
                    end

    redirect_to conversation_messages_path(@conversation)
  end

  private

  def conversation_params
    params.require(:conversation).permit(:sendable_id, :recipientable_id)
  end
end

如果我删除require(:conversation)我会得到一个错误:

验证失败:Sendable 必须存在,Recipientable 必须存在

楷模:

class User < ApplicationRecord
  has_many :conversations, as: :sendable
  has_many :conversations, as: :recipientable
end


class AdminUser < ApplicationRecord
  has_many :conversations, as: :sendable
  has_many :conversations, as: :recipientable
end

class Conversation < ApplicationRecord
  belongs_to :sendable, polymorphic: true
  belongs_to :recipientable, polymorphic: true
  has_many :messages, dependent: :destroy

  validates :sendable_id, uniqueness: { scope: :recipientable_id }
end

class Message < ApplicationRecord
  belongs_to :conversation
  belongs_to :messageable, polymorphic: true

  validates_presence_of :body
end

架构:

create_table "conversations", force: :cascade do |t|
    t.string "sendable_type"
    t.bigint "sendable_id"
    t.string "recipientable_type"
    t.bigint "recipientable_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["recipientable_type", "recipientable_id"], name: "index_conversations_on_recipientable"
    t.index ["sendable_type", "sendable_id"], name: "index_conversations_on_sendable"
  end

标签: ruby-on-railsruby

解决方案


你需要帮助 Rails 了解你引用了哪些多态模型;如果您只提供 id 则失败,因为 Rails 还需要多态类型(请记住:类型是强制性的,因此 Rails 可以链接到实际表。在您的情况下,有两种可能的类型 User 和 AdminUser)

只需提供多态类型并将它们添加到conversation_params方法中。通过查看您的代码,我猜这就是您所追求的:

<li><%= link_to admin.email, conversations_path(sendable_id: current_user.id, sendable_type: 'User', recipientable_id: admin.id, recipientable_type: 'AdminUser'), method: :post %></li>

推荐阅读