Reputation: 18109
I'm trying to setup simple_form
for a product/cart scenario, but a little differently than the typical scenario. My display needs to list ALL available products and have a qty input for each. When saved, the cart_items should store cart_id
, product_id
, and qty
only for those items which have a qty provided. If it's blank or zero, it should not be added to cart_items
Cart:
class Cart < ApplicationRecord
has_many :cart_items
has_many :products, through: :cart_items
accepts_nested_attributes_for :cart_items
end
Cart Items:
class CartItem < ApplicationRecord
belongs_to :cart
belongs_to :product
end
Products:
class Products < ApplicationRecord
has_many :cart_items
has_many :carts, through: :cart_items
end
I'm trying to have my form display such as:
[ x ] (Qty) Product Name
[ x ] (Qty) Product Name
[ x ] (Qty) Product Name
[ x ] (Qty) Product Name
I'm not sure how to get the extra field for qty using f.association :cart_items, collection: Products.all()
, and I tried this:
<%= f.simple_fields_for :cart_items do |fa| %>
<%= fa.association :product, as: :select %>
<%= fa.input :qty %>
<% end %>
But that only displays existing associations, and also displays the product in a select list whereas I'd like to just list out all products and display their associated qty.
Is there a nice and pretty "Rails-y" way of doing this that I'm overlooking, or do I need to do some more manual manipulation in my controller and views? I'm using Rails 5.
Upvotes: 0
Views: 471
Reputation:
I suspect that there is no special "Rails-y" way, or I am not aware of it. I think that you will have to loop over all your products and build cart_items for the missing ones before simple_fields_for tag. If a cart item with a product already exists then just show it; otherwise, build it first and then show.
You will also have to add rejection of cart_items in case of missing qty. Something like this:
accepts_nested_attributes_for :cart_items, reject_if: lambda { |ci| ci[:qty].blank? || ci[:qty].zero? }
This should do the trick.
Upvotes: 1