Reputation: 185
I have an Index view that lists orders in a collection. Each order has a status. I want to be able to update the status of an order from the Index page, AJAX style.
Not sure why the ID is NULL when trying to update the record.
index.html.erb
<h1>Recent Orders</h1>
<section class="order-results">
<ol class="list-group">
<%= render partial: 'pf_order', collection: @pf_orders %>
</ol>
</section>
_pf_orders.html.erb
<%= form_for(pf_order, url: update_receiver_status_path(pf_order)) do |f| %>
<%= f.select :receiver_status, options_for_select(receiver_statuses, f.object.receiver_status), {include_blank: true}, {class: 'form-control'} %>
<% end %>
pf_orders_controller.rb
def index
@pf_orders = PfOrder.all
end
def update_receiver_status
@status = PfOrder.find_by(id: params[:id])
@status.update_attributes(pf_order_params)
end
pf_orders.coffee
jQuery ($) ->
$(document).ready ->
$("#pf_order_receiver_status").bind 'change', ->
$.ajax
type: 'PATCH'
url: 'pf_orders/update_receiver_status'
data: 'pf_order[receiver_status]=' + $('#pf_order_receiver_status').val()
routes.rb
patch 'pf_orders/update_receiver_status', as: 'update_receiver_status'
LOGS
Started PATCH "/pf_orders/update_receiver_status" for 127.0.0.1 at 2016-10-01 17:36:11 -0400
Processing by PfOrdersController#update_receiver_status as */*
Parameters: {"pf_order"=>{"receiver_status"=>"Completed"}}
PfOrder Load (1.0ms) SELECT "pf_orders".* FROM "pf_orders" WHERE "pf_orders"."id" IS NULL LIMIT $1 [["LIMIT", 1]]
Completed 500 Internal Server Error in 4ms (ActiveRecord: 1.0ms)
NoMethodError (undefined method `update_attributes' for nil:NilClass):
Upvotes: 0
Views: 229
Reputation: 185
Here's how I got this to work correctly:
pf_orders_controller.rb
def update_receiver_status
@pf_order = PfOrder.find(params[:id])
if @pf_order.update_attributes(pf_order_params)
render json: @pf_order.as_json, status: :ok
else
render json: {pf_order: @pf_order.errors, status: :unprocessable_entity}
end
end
def pf_order_params
params.fetch(:pf_order, {}).permit(:sequence_number, :message_guid, :hl7_document, :download, :post_status_code, :patient_id, :receiver_status)
end
_pf_order.html.erb
Got rid of the form_for
<%= label :receiver_status, 'Status:' %>
<%= select_tag :receiver_status,
options_for_select(receiver_statuses, pf_order[:receiver_status]),
onchange: "$.post('#{update_receiver_status_pf_order_path(pf_order)}',
{'_method':'patch', 'pf_order[receiver_status]':this.value} );",
class: 'form-control' %>
I removed the jQuery from pf_orders.coffee
routes.rb
resources :pf_orders do
patch :update_receiver_status, on: :member
end
Thanks to Alexandre Angelim for the correct route and pointing me in the right direction.
Upvotes: 1
Reputation: 6753
You're not submitting the order's id anywhere. You can verify that in your logs
Parameters: {"pf_order"=>{"receiver_status"=>"Completed"}}
.
If you'd like to stick with RESTful routes(and I strongly believe you should), you're request should go to /pf_orders/:id/update_receiver_status
.
You can change your route to:
patch 'pf_orders/:id/update_receiver_status', as: 'update_receiver_status'
or just add a custom route to your pf_orders resources:
resources :pf_orders do
patch :update_receiver_status, on: :member
end
The last thing to do is retrieve the order's id in your javascript. That will already be reflected in your form's action URL, so it's easier to retrieve it from there.
jQuery ($) ->
$(document).ready ->
$("#pf_order_receiver_status").bind 'change', ->
$.ajax
type: 'PATCH'
url: $('#pf_order_receiver_status').closest('form').attr('action')
data: 'pf_order[receiver_status]=' + $('#pf_order_receiver_status').val()
Upvotes: 1