I have an invoice with some lines. A line can only belong to one invoice. This is how my schema looks like:
create_table "invoices" do |t|
end
create_table "lines" do |t|
t.integer "invoice_id"
end
And my models:
class Invoice < ActiveRecord::Base
has_many :lines
end
class Line < ActiveRecord::Base
belongs_to :invoice
end
Now, when creating (or editing) an invoice I would like to show a list with all possible lines (the lines already exist in the database) and have a check box for each line to link it with the开发者_运维百科 invoice.
I had a look at the HABTM problem but I don't think that's what I need here, the problem isn't as complex. I think the problem is me wanting to update the Unit#invoice_id while I am working on the invoice. Can I do this with a nested form or do I need a before_save callback here?
Thanks!
Have a look at Iain's answer. It's definitely the right way to go but... I prefer not to use simple_form
or formtastic
for this example to keep it as simple as possible.
I used Iain's HTML output to extract the HTML I need. This snippet is the same as Iain's answer without the need of an extra library:
<% Line.all.each do |line| %>
<%= hidden_field_tag "invoice[line_ids][]" %>
<%= check_box_tag "invoice[line_ids][]", line.id, @invoice.lines.include?(line), :id => "invoice_line_ids_#{line.id}" %>
<% end %>
PS: The Line.all
and @invoice.lines...
should be extracted to the controller and invoice model, they don't belong in the view. They are only used for brevity's sake.
A has_many association also adds the accessor line_ids
, which you can create check boxes for.
If you're using simple_form
or formtastic
it's incredibly easy:
<%= f.input :line_ids, :as => :check_boxes %>
Which will create something like this:
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_1" name="invoice[line_ids][]" type="checkbox" value="1" />
<label class="collection_check_boxes" for="invoice_line_ids_1">Line Name 1</label>
</span>
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_2" name="invoice[line_ids][]" type="checkbox" value="2" />
<label class="collection_check_boxes" for="invoice_line_ids_2">Line Name 2</label>
</span>
And that is all there is to it. No nested forms or anything else needed.
I recommend using the collection_check_boxes helper method:
<%= collection_check_boxes :invoice, :lines, @lines, :id, :name %>
or Haml:
= collection_check_boxes :invoice, :lines, @lines, :id, :name
精彩评论