Reputation: 1758
In my app I have model PurchaseOrder and PurchaseOrderList. When I create a purchase order it updates both tables purchase_orders and purchase_order_lists with a nested form.
Now I want to be able to add a button update stock on purchase_orders/show. When I click this button a new record will be created on table stockdiaries with same products, units and prices as on the purchase order.
The logic is that first I create a purchase order and then I click the button to update stock when goods are received.
The best I came up with is to create this method on PurchaseOrders controller:
def update_stock
@purchase_order_list = PurchaseOrderList.where(PURCHASE_ORDER: params[:ID])
@stockdiary = Stockdiary.create(PRODUCT: @purchase_order_list.PRODUCT, UNITS: @purchase_order_list.UNITS, PRICEBUY: @purchase_order_list.PRICEBUY)
flash[:notice] = "Stock updated successfully."
redirect_to(:action => 'show', :ID => @purchase_order.ID)
end
and in my purchase_orders/show:
<%= link_to "Update Stock", { controller: :purchase_orders, action: :update_stock, ID: @purchase_order.ID} %>
but it raises error
undefined method `PRODUCT' for
#<PurchaseOrderList::ActiveRecord_Relation:0x007f1efeff4898>
But there is a column PRODUCT on purchase_order_lists table.
Note that I included in the method only columns that are common to purchase_order_lists and stockdiaries as others (as id or status) are not concerned on this question. Columns names are capital as I'm building the app on existing db.
What is the correct way to create a stockdiary from a purchase order?
Upvotes: 0
Views: 1128
Reputation: 3282
Updated
Rails is returning an an ActiveRecord Relation from this query:
@purchase_order_list = PurchaseOrderList.where(PURCHASE_ORDER: params[:ID])
This is because you used where
, so ActiveRecord returns a relation that could potentially have multiple records in it. If you only want one record, or even if you know that there will only be one record then you should use find_by
So you can either do:
# change where to find_by
@purchase_order_list = PurchaseOrderList.find_by(PURCHASE_ORDER: params[:ID])
# and then this will work
@stockdiary = Stockdiary.create(PRODUCT: @purchase_order_list.PRODUCT, UNITS: @purchase_order_list.UNITS, PRICEBUY: @purchase_order_list.PRICEBUY)
OR... If you want where
or there might be multiple records, then you can loop:
@purchase_order_list = PurchaseOrderList.where(PURCHASE_ORDER: params[:ID])
# and then loop through you potentially multiple records in @purchase_order_list
@purchase_order_list.each do |po|
@stockdiary = Stockdiary.create(PRODUCT: po.PRODUCT, UNITS: po.UNITS, PRICEBUY: po.PRICEBUY)
end
or use first
:
@stockdiary = Stockdiary.create(PRODUCT: @purchase_order_list.first.PRODUCT, UNITS: @purchase_order_list.first.UNITS, PRICEBUY: @purchase_order_list.first.PRICEBUY)
Usually this means you didn't place accepts_nested_attributes_for in the PurchaseOrder model.
PurchaseOrder
class PurchaseOrder
accepts_nested_attributes_for :purchase_order_list
end
Upvotes: 1