简体   繁体   中英

RoR 3 Creating an Invoice app - How do I create the form for a HABTM invoice/products association?

I'm attempting to make an invoice application. Here are my models which are related to my question:

UPDATE: Model information has changed due to recent suggestions

Invoice  
> id  
> created_at  
> sales_person_id

LineItem
> id  
> invoice_id  
> item_id  
> qty_commit (inventory only)  
> qty_sold  
> price (because prices change)  
> ...etc

Item
> barcode  
> name  
> price
> ...etc

Invoice has_many items, :through => :line_items . Ditto for Item. What I want to do is that when I create a new invoice, I'd like the form to be populated with all available Items. The only time I don't want all items to be populated is when I'm viewing the invoice (so only items which exist in the LineItems table should be retrieved). Currently - and obviously - a new Invoice has no items. How do I get them listed when there is nothing currently in the collection, and how do I populate the form? Also I'd like all products to be available when creation fails (along with what the user selected through the form).

UPDATE: I can create items through the controller via the following:

@invoice = Invoice.new
# Populate the invoice with all products so that they can be selected
Item.where("stock > ?", 0).each do |i|
@invoice.items.new(i.attributes)
end

This is of course my crude attempt at doing what I want. Visually it works out great, but as predicted my form id's and such are not playing well when I actually attempt to save the model.

LineItem(#37338684) expected, got Array(#2250012)

An example of the form:

# f is form_for
<% @invoice.items.group_by{|p| p.category}.each do |category, products| %>

<%= category.name %>

<%= f.fields_for :line_items do |line_item| %>
<% for p in products %>

<%= line_item.hidden_field :tax_included, :value => p.tax_included %>
<%= p.name %>
$<%= p.price %>

<% end %>
<% end %>
<% end %>

First of all, if you explicitly want to have a join model with additional attributes in it, you should use has_many :through instead of has_and_belongs_to_many . See the RoR Guide to the differences of the two.

Second, there is no single solution for what you want to reach. I see there two typical usages, depending on the mass of possible instances, one is better than the other:

  1. Use radio buttons to select (and deselect) where a relation should be created or deleted. See the railscast #165 how to do part of that.
  2. You could use select menus with a button to add a relation. See railscast #88 . The added relation could be shown in a list, with a delete button nearby.
  3. Use token fields (see railscast #258 ) to autocomplete multiple entries in one single text entry field.

In all the situations, you normally have to check at the end, if

  • a relation should be deleted
  • kept
  • or created

I hope some of the ideas may show you the right solution for your problem.


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM