Reputation: 3383
I have these relevant controller models:
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
When I try to create a new vendor object, I get the following error:
Required parameter missing: vendor
Here is my form:
<%= 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 %>
And my migration for the Vendor table:
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
Does anyone see a clue as to why I might be getting this error? I don't understand how :vendor
itself is a parameter... Any help is much appreciated. Thanks in advance!
Here is my updated form:
<%= 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 %>
I'm not getting this error though:
undefined method `merge' for "Store Name":String
From the searching I've done, it sounds like the rails method merge
only works on hashes, not strings. I'm not sure why it would be trying to merge this though unless my form isn't creating a hash properly?
My new action:
def new
@vendors = Vendor.all
@vendor = Vendor.new
end
Server Logs
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)
Upvotes: 1
Views: 3666
Reputation: 16120
The problem is that you aren't sending your params using form_for
correctly. You're directly using form_tag
, text_field_tag
, etc which you should only do under specific circumstances because this will circumvent much of Rails' built-in functionality. You don't need to specify a value because that automatically gets populated by what's in @vendor
. You can make labels to label each field as in this example:
<%= 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 %>
In your new
action make sure you instantiate an empty Vendor
object so it knows what controller/action to send the form off to when it gets submitted.
If you don't want to use labels to label the fields you can use the html5 placeholder
attribute to give a field hint instead:
<%= f.text_field :name, placeholder: "Store Name" %>
Upvotes: 3
Reputation: 76784
Your problem is here:
<%= form_tag({controller: "vendors", action: "create"}, method: "post", multipart: true) do %>
Specifically, when you "require" params using strong params
in Rails, it basically expects the params hash to be structured this way:
params{"vendor" => {"name":sdfadsf, "address": 23423}}
This can only be achieved if you use form_for @vendor
in your new.html.erb view, as this is how Rails defines that initial value to the params hash. What your app is doing is setting the params hash as this:
params{"name": 234234, "address: 234324}
Solution
In your new.html.erb
form, just use this code:
<%= 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 %>
Upvotes: 2
Reputation: 2750
Unless I've missed something that is not immediately obvious--
params.require(:vendor)
You are specifying that params must contain :vendor. Just remove this clause, e.g.
def vendor_params
params.permit(:id, :name, :address, :image, :latitude, :longitude)
end
If your parameters were nested beneath :vendor
then the .require(:vendor)
would make sense. Take a look at your development log to see the incoming parameters (share them here if you're still having trouble).
Upvotes: 0