Reputation: 310
I am building a Order management system. I recently posted a problem about adding a order to a customer. It seems that i have fixed it for 99%. if i look in my terminal it first finds the current customer ID and then creates a new order. The following result is.
Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1 [["id", 111]]
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "orders" ("customer_id", "created_at", "updated_at") VALUES (?, ?, ?) [["customer_id", 111], ["created_at", "2015-11-12 13:28:21.185604"], ["updated_at", "2015-11-12 13:28:21.185604"]]
(8.2ms) commit transaction
But the problem is, it doesn't add the params. I did this intentionally just to check if my syntax would execute the following sql statement. But once i add params i get a common error "param is missing or the value is empty: order"
Here is my code:
def createorders
@customer = Customer.find(params[:id]) #find current id??
#current_user = Order.find(params[:id])
@orders = @customer.orders.new(order_params)
if @orders.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
#If save fails, redisplay the form so user can fix problems
render('new') #het zit in de new.html template
end
end
private
def order_params
#same as using "params[:subject]", expect that it:
# - raises an error if :subject is not present
# - allows listed attributes to be mass-assigned
params.require(:order).permit(:pakket, :verstuurt)
end
end
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for(:order, :url=> {:action => 'createorders'}) do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
ActionController::ParameterMissing in OrderController#createorders param is missing or the value is empty: order
Extracted source (around line #107): 105 106 107 108 109 110 def order_params params.require(:order).permit(:pakket, :verstuurt) end end
Started GET "/order/createorders?id=111" for ::1 at 2015-11-13 11:58:30 +0100 Processing by OrderController#createorders as HTML
Parameters: {"id"=>"111"} Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1 [["id", 111]] Completed 400 Bad Request in 5ms (ActiveRecord: 0.2ms)ActionController::ParameterMissing (param is missing or the value is empty: order): app/controllers/order_controller.rb:107:in
order_params' app/controllers/order_controller.rb:44:in
createorders'Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb
(8.3ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.6ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.3ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (68.2ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.4ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.4ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.4ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.4ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (60.3ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.3ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.5ms) Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (124.2ms)
Thank you stackoverflow for showing me support. I am new with ruby, and i understand i am making noob mistakes. So pointing out flaws are welcome!
Upvotes: 0
Views: 2573
Reputation: 2743
I was ignoring your minor, non-fatal issues earlier while I was focused on locating the major issue, but I'll include them now that the major issue is apparent.
First, I'll discuss Rails naming conventions a little bit. You have two models, which are named Customer
and Order
. You've used the singular form of the noun for these, which is good. Each instance of a model is one thing, so it should be singular. Your controller for the Order
model actions, however, should be named with the plural form, so it should be called OrdersController
. This is because it controls the actions related to all of your orders. This leads us to your createorders
action, which would make a little more sense if it were named createorder
, since it only creates one Order
. Actually, though, the convention is to name that action create
. The action is in your OrdersController
, so we already assume that it deals with an Order
instance. (When you have Rails automatically generate REST-ful routes for a model's controller with the resources
function, it assumes you have an action named create
.) Lastly, in your create
method, the new Order
instance that will be referenced in your view should be called @order
instead of @orders
, since it contains only one Order
.
Now things get a little more complicated. Your param is missing
error means exactly that. The parameters for the new Order
instance are missing. The request to the server that is producing that error is a GET
request that has only one parameter, which you're providing in your URL with ?id=111
. Your form's data is not being submitted to the server with that GET
request. You should be doing a POST
request to create a new Order
. I'm going to avoid further exploration (and speculation without seeing your full code) regarding why things aren't working right now and I'll just suggest some key adjustments. It's turning in to a bit a puzzle to figure out how your app works without seeing all of the pieces.
In routes.rb, you should have this line:
resources :customers, :orders
I've made minimal changes to the view you provided, which I assume is called show.html.erb and is in your app/views/customers folder:
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for @order do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<%= f.hidden_field :customer_id %>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is the necessary code from customers_controller.rb to support it:
def show
customer = Customer.find params[:id]
@order = customer.orders.new
end
Notice, in the view, the parameter for form_for
is the instance that was created in the controller. Also, I've added a hidden field to submit the customer_id
with the new Order
data.
Finally, your create
action in orders_controller.rb might look like this:
def create
@order = Order.new(order_params)
if @order.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
render 'customers/show'
end
end
And your order_params
method should be changed to include the customer_id
parameter:
def order_params
params.require(:order).permit(:pakket, :verstuurt, :customer_id)
end
Notice that on a failed save
, the action renders customers/show
, because this is the page that they were on where the save failed. This will allow Rails to re-populate the form (in the same context) with the data that was present during the failed submission.
Upvotes: 0