I am creating an inventory system, in which I have the following 2 models:
Model Product
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :name
t.float :price
t.integer :weight
t.string :unity
t.timestamps
end
end
end
Inventory Transactions Model This registers the amount of items to enter or leave the inventory for each product, for this I have added a boolean field, which will determine the type of transaction, whether it is purchase or sale
class CreateInventoryTransactions < ActiveRecord::Migration[5.2]
def change
create_table :inventory_transactions do |t|
t.string :invoice
t.integer :product_id
t.integer :quantity
t.boolean :transaction_type
t.timestamps
end
end
end
In this case I have made a purchase transaction of 100 items of the same product, but when trying to print that data of that product in the loop, it generates an error, and obviously since that product has many purchase transactions or sale, how could I print the sum of purchase or sale transactions within the loop, for each product?
<% @products.each do |product| %>
<tr>
<td>-</td>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= product.weight %></td>
<td><%= product.unity %></td>
<td><%= product.inventory_transactions.quantity %></td>
</tr>
<% end %>
Avoiding the error of:undefined method 'quantity' for #<InventoryTransaction::ActiveRecord_Associations_CollectionProxy:0x007fdc3d68c038>
The problem is that you are calling the method
quantity
on a collection, not on an objectProduct
.What you have to do is first add the amounts of each transaction and then show them; for instance:
Although you can use it like this directly in your view, I recommend extracting that logic and adding it in the model
Product
:And in your view you can call the new method:
You could add a (private) method in your model to add the values of
quantity
for eachtransaction_type
and then use it in your current method to get the difference; for instance:As an exercise to improve this code, you might consider using scopes on the model
InventoryTransaction
to avoid usingwhere
within the modelProduct
.