I have an invoice controller and two model invoice and invoice_line_items and create a tax_line_items using invoice_line_item class. Below is my code :
Here is my controller code :
class InvoicesController < ApplicationController
def new
@menu = 'Income'
@page_name = 'Create new invoice'
@invoice = Invoice.new
@invoice.invoice_line_items.build
@invoice.tax_line_items.build
respond_to do |format|
format.html
format.xml { render :xml => @invoice }
end
end
end
My model for invoice:
class Invoice < ActiveRecord::Base
has_many :invoice_line_items
has_many :tax_line_items, :class_name => "InvoiceLineItem",:dependent => :destroy
accepts_nested_attributes_for :invoice_line_items, :reject_if => lambda {|a| a[:account_id].blank? } , :allow_destroy => true
accepts_nested_attributes_for :tax_line_items, :reject_if => lambda {|a| a[:account_id].blank? } , :allow_destroy => true
end
and in my forms i used :
<%= form_for(@invoice) do |f| %>
<%= render 'shared/form_error', :object => @invoice %>
<% @invoice.invoice_line_items.each_with_index do |invoice_line_item, index| %>
<%= render "invoice_line_items", :invoice_line_item => invoice_line_item, :index => index %>
<% end %>
<% @invoice.tax_line_items.each_with_index do |tax_line_item, tax_index| %>
<%= render "tax_line_items", :tax_line_item => tax_line_item, :tax_index => tax_index %>
<% end %>
<%end%>
partials :
1) invoice_line_items:
<tr id="row<%= index %>" valign="top" >
<%= hidden_field_tag "invoice[invoice_line_items_attributes][#{index}][id]",invoice_line_item.id%>
<td valign="top">
<%= select_tag "invoice[invoice_line_items_attributes][#{index}][account_id]", options_from_collection_for_select(@from_accounts, :id, :name,:selected => invoice_line_item.account_id ), :include_blank => true, :class=>"full" %>
<!-- <a href="/accounts/new?account_head_id=10" > New item</a> -->
</td>
<td><%= text_area_tag "invoice[invoice_line_items_attributes][#{index}][description]",invoice_line_item.description, :class => "full", :cols => 10, :rows=>1 %></td>
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][quantity]",invoice_line_item.quantity, :class => 'full', :id => 'quantity', :onkeydown => "return numbersOnly(event);", :size => 5, :maxlength => 25 %></td>
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][unit_rate]",invoice_line_item.unit_rate, :class => 'full', :id => 'unit_cost', :onkeydown => "return numbersOnly(event);", :size => 5, :maxlength => 20 %></td><!--Jquery code is in application.js-->
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][discount_percent]", invoice_line_item.discount_percent, :class => 'full', :id => 'discount', :onkeydown => "return numbersOnly(event);", :maxlength => 5, :size => 5%></td>
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][amount]", invoice_line_item.amount, :class => 'full', :id => 'total', :readonly => 'readonly', :size => 5%></td>
<td><%= link_to image_tag("/images/black_icon/ic_cancel.png"),{:action => :remove_line_item, :index => index}, :remote => true unless index == 0 %></td>
</tr>
and 2) tax_line_items:
<tr id="tax_row<%= tax_index %>" valign="top" >
<%= hidden_field_tag "invoice[tax_line_items_attributes][#{tax_index}][id]",tax_line_item.id%>
<%= hidden_field_tag "invoice[tax_line_items_attributes][#{tax_index}][tax]", tax_line_item.tax, :value => 1 %>
<td style="background:#EDF4FF"></td>
<td class="ta-right" style="background:#EDF4FF" colspan="2"><label>Add Tax:</label></td>
<td class="ta-right" colspan="2" style="background:#EDF4FF">
<%= select_tag "invoice[tax_line_items_attributes][#{tax_index}][account_id]", options_from_collection_for_select(@tax_accounts, :id, :name,:selected => tax_line_item.account_id ), :include_blank => true, :class=>"full" %>
<!-- <a href="/accounts/new?account_head_id=10" > New item</a> -->
</td>
<td style="background:#EDF4FF"><%= text_field_tag "invoice[tax_line_items_attributes][#{tax_index}][amount]", tax_line_item.amount, :class => 'full', :id => 'tax', :onkeydown => "return numbersOnly(event);", :size => 5%></td>
<td style="background:#EDF4FF"><%= link_to image_tag("/images/black_icon/ic_cancel.png"),{:action => :remove_tax_item, :tax_index => tax_index}, :remote => true %></td>
</tr>
I can add new line item entry easily and edit it when their is no tax item. The problem is
when their is an tax item created in any entry and later try to edit this entry then my line items row appears multiple time for example suppose i have a tax item them a new row will appear for invoice line item ans an extra row for tax line items. i think this will happen because i have used a common table for both the line items. I did this because i have to save both line items entry in same table as both accounts came from same table.
I am very thankful if anyone have the right answer.Thanks a lot
As this answer suggests, you need to add a ‘type’ column to this table to distinguish between invoice and tax items. It will remove a lot of complications from your code as Rails will do the work of identifying which record belongs to which model class from the common table.