Juan Pablo Ugas Juan Pablo Ugas - 5 months ago 15
Ajax Question

Rails 4 Unprocessable Entity Error when making ajax post

I am trying to build an ajax object and I am getting a funny error...

Here are my nested form fields

<%= f.fields_for :order_item do |ff| %>
<div class="col-md-4">
<%= ff.hidden_field :quote_id, value: @quote.id %>
<%= ff.collection_select :category_id, Category.order(:name), :id, :name, include_blank: "Select Category", hide_label: true %>
</div>
<div class="col-md-6">
<%= ff.grouped_collection_select :product_id, Category.order(:name), :products, :name, :id, :name, include_blank: true, hide_label: true %>
</div>
<div class="col-md-2">
<%= ff.submit "Add Item", class:"btn-u btn-u-blue pull-right", id:"add_item" %>
</div>
<% end %>


Here is my quote.js.coffee where I am making my ajax call

$('form').on 'click', '#add_item', (e) ->
e.preventDefault()
product = $('#quote_order_item_product_id :selected').val()
quote = $('#quote_order_item_quote_id').val()
console.log(product)
console.log(quote)
$.ajax '/order_items',
type: 'POST'
dataType: 'json'
data: { order_item: { product_id: product, quote_id: quote } }
success:(data) ->
alert data.id
return false
error: (jqXHR, textStatus, errorThrown) ->
alert textStatus
return false


Here is my controller (params accepts
product_id
and
quote_id
)

def create
@order_item = OrderItem.new(order_item_params)
respond_to do |format|
if @order_item.save
format.json { render :show, status: :created, location: @order_item }
else
format.json { render json: @order_item.errors, status: :unprocessable_entity }
end
end
end


Here is my order_item model as requested

belongs_to :quote
belongs_to :product
# validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
before_save :set_quantity
before_save :set_unit_price

def total_price
unit_price * quantity
end

def set_unit_price
product = Product.find(self.product_id)
self.unit_price = product.price
end

def set_quantity
if quantity.nil?
self.quantity = 1
end
end

private
def product_present
if product_id.nil?
errors.add(:product, "is not valid or is not active.")
end
end

def quote_present
if quote_num.nil?
errors.add(:quote, "is not a valid quote.")
end
end

def finalize
self[:unit_price] = unit_price
self[:total_price] = quantity * self[:unit_price]
end
end


Here is my route

resources :order_items, only: [:create, :update, :destroy]


I've also tried to make the data being posted in this format

data: { product_id: product, quote_id: quote }

Answer

It seems that you have some validations in place, so you cannot save an empty object.

You are always trying to save an empty object because you are not initialising it with params from the request.

To keep to the rails convention send the params in the format you tried:

order_item: { product_id: product, quote_id: quote }

Then in your controller change your code to this

def create
 @order_item = OrderItem.new(order_item_params)
 respond_to do |format|
  if @order_item.save
    format.json { render :show, status: :created, location: @order_item }
  else
    format.json { render json: @order_item.errors, status: :unprocessable_entity }
  end
 end
end

private

def order_item_params
params.require(:order_item).permit(:product_id, :quote_id)
end

Your problem was with this line @order_item = OrderItem.new which needed arguments (in rails it is advised to whitelist them hence the other method).

P.S. If it is still not working, please provide your validations for OrderItem model.

Comments