缺少必需参数 - rails

时间:2013-10-21 22:44:42

标签: ruby-on-rails devise strong-parameters

我有这些相关的控制器型号:

class VendorsController < ApplicationController

  def vendor_params
      params.require(:vendor).permit(:id, :name, :address, :image, :latitude, :longitude)
  end

  def create
      vendor = Vendor.create(vendor_params)
      flash[:success] = "Vendor Created"
      redirect_to vendors_mgmt_path
  end

end

当我尝试创建新的供应商对象时,出现以下错误:

Required parameter missing: vendor

这是我的表格:

<%= form_tag({controller: "vendors", action: "create"}, method: "post", multipart: true) do %>
<%= text_field_tag :name, "Store Name" %>
<%= text_field_tag :address, "Store Address" %>
<%= file_field_tag :image %>
<%= submit_tag "Save", class: "btn btn-success" %>
<% end %>

我对供应商表的迁移:

class CreateVendors < ActiveRecord::Migration
  def change
    create_table :vendors do |t|

    t.string :name
    t.string :address
    t.float :latitude
    t.float :longitude
    t.string :image

    t.timestamps
    end
  end
end

有没有人看到我可能会收到此错误的线索?我不明白:vendor本身是如何参数...任何帮助都非常感谢。提前谢谢!

以下是我更新的表格:

<%= form_for @vendor, multipart: true do |f| %>
<%= f.text_field :name, "Store Name" %>
<%= f.text_field :address, "Store Address" %>
<%= f.file_field :image %>
<%= f.submit "Save", class: "btn btn-success" %>
<% end %>

虽然我没有收到此错误:

undefined method `merge' for "Store Name":String

从我的搜索开始,听起来像rails方法merge只适用于哈希,而不是字符串。我不确定为什么它会尝试合并这个,除非我的表单没有正确创建哈希?

我的新动作:

def new
    @vendors = Vendor.all
    @vendor = Vendor.new
end

服务器日志

Started GET "/vendors/new" for 127.0.0.1 at 2013-10-23 08:04:04 -0700
Processing by VendorsController#new as HTML
  Vendor Load (0.3ms)  SELECT "vendors".* FROM "vendors" 
Rendered vendors/new.html.erb within layouts/application (2.0ms)
Completed 500 Internal Server Error in 18ms

ActionView::Template::Error (undefined method `merge' for "Store Name":String):
    5: <h4>New Vendor Form</h4>
    6: 
    7: <%= form_for @vendor, multipart: true do |f| %>
    8: <%= f.text_field :name, "Store Name" %>
    9: <%= f.text_field :address, "Store Address" %>
    10: <%= f.file_field :image %>
    11: <%= f.submit "Save", class: "btn btn-success" %>
  app/views/vendors/new.html.erb:8:in `block in _app_views_vendors_new_html_erb__2593637676836103609_2161482240'
  app/views/vendors/new.html.erb:7:in `_app_views_vendors_new_html_erb__2593637676836103609_2161482240'


  Rendered /Users/******/.rvm/gems/ruby-2.0.0-p195/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.8ms)
  Rendered /Users/******/.rvm/gems/ruby-2.0.0-p195/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.4ms)
  Rendered /Users/******/.rvm/gems/ruby-2.0.0-p195/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (11.9ms)

3 个答案:

答案 0 :(得分:3)

问题是您没有正确使用form_for发送参数。你直接使用form_tagtext_field_tag等,你应该只在特定情况下这样做,因为这将绕过很多Rails的内置功能。您无需指定值,因为它会自动填充@vendor中的内容。您可以制作标签来标记每个字段,如下例所示:

<%= form_for @vendor, html: {multipart: true} do |f| %>
  <%= f.label :name, "Store Name" %>
  <%= f.text_field :name %>
  <%= f.label :address, "Store Address" %>
  <%= f.text_field :address %>
  <%= f.file_field :image %>
  <%= f.submit "Save", class: "btn btn-success" %>
<% end %>

new操作中,请确保实例化一个空Vendor对象,以便它知道将表单发送到提交时的控制器/操作。

如果您不想使用标签标记字段,可以使用html5 placeholder属性来提供字段提示:

<%= f.text_field :name, placeholder: "Store Name" %>

答案 1 :(得分:2)

你的问题在这里:

<%= form_tag({controller: "vendors", action: "create"}, method: "post", multipart: true) do %>

具体来说,当您在Rails中使用strong params“需要”参数时,它基本上期望params hash以这种方式构建:

params{"vendor" => {"name":sdfadsf, "address": 23423}}

只有在new.html.erb视图中使用form_for @vendor时才能实现这一点,因为这是Rails如何定义params散列的初始值。您的应用正在做的是将params哈希设置为:

params{"name": 234234, "address: 234324}

<强>解决方案

new.html.erb 表单中,只需使用以下代码:

<%= form_for @vendor, method: "post", multipart: true) do %>
    <%= text_field_tag :name, "Store Name" %>
    <%= text_field_tag :address, "Store Address" %>
    <%= file_field_tag :image %>
    <%= submit_tag "Save", class: "btn btn-success" %>
<% end %>

答案 2 :(得分:0)

除非我错过了一些不是很明显的东西 -

params.require(:vendor)

您指定params必须包含:vendor。只需删除此条款,例如

def vendor_params
  params.permit(:id, :name, :address, :image, :latitude, :longitude)
end

如果您的参数嵌套在:vendor下方,则.require(:vendor)会有意义。查看开发日志以查看传入参数(如果您仍然遇到问题,请在此处分享)。