问题
i am facing a new situation. I know someone definitely had faced these type of situation:
I have an invoices table and an invoice_line_items table. Till now every thing is going well with has_many and belongs to association. Now i want to add tax accounts in invoice items, for that i don't want to create a separate table, hence i make below changes in my invoice model :
invoice.rb:
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
#validations
validates_presence_of :invoice_line_items
validates_associated :invoice_line_items
end
invoice_line_item.rb:
class InvoiceLineItem < ActiveRecord::Base
belongs_to :invoice
end
and in my controller i did:
class InvoicesController < ApplicationController
def new
@invoice = Invoice.new
@invoice.invoice_line_items.build
@invoice.tax_line_items.create
@from_accounts = TransactionType.fetch_from_accounts(current_company.id,'sales')
@to_accounts = TransactionType.fetch_to_accounts(current_company.id, 'sales')
@tax_accounts = TransactionType.fetch_from_accounts(current_company.id, 'tax')
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @invoice }
end
end
end
in my form i did: for tax accounts
<% @invoice.invoice_line_items.each_with_index do |invoice_line_item, tax_index| %>
<%= render "tax_line_items", :invoice_line_item => invoice_line_item, :index => tax_index %>
<% end %>
and for invoice items:
<% @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 %>
and here are my partials: 1)_invoice_line_items.html.erb:
<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",:rows =>2 %></td>
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][quantity]",invoice_line_item.quantity, :class => 'amount', :id => 'quantity', :onkeydown => "return numbersOnly(event);", :size => 8, :maxlength => 25 %></td>
<td><%= text_field_tag "invoice[invoice_line_items_attributes][#{index}][unit_rate]",invoice_line_item.unit_rate, :class => 'amount', :id => 'unit_cost', :onkeydown => "return numbersOnly(event);", :size => 8, :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 => 'amount', :id => 'discount', :onkeydown => "return numbersOnly(event);", :maxlength => 5, :size => 8%></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 'Remove',{:action => :remove_line_item, :index => index}, :remote => true unless index == 0 %></td>
</tr>
2) _tax_line_items.html.erb:
<tr id="tax_row<%= tax_index %>" valign="top" >
<%= hidden_field_tag "invoice[tax_line_items_attributes][#{tax_index}][id]",invoice_line_item.id%>
<td></td>
<td colspan="2" class="ta-right"><label>Add Tax:</label></td>
<td class="ta-right" colspan="2" style="background:#EDF4FF">
<%= select_tag "invoice[invoice_line_items_attributes][#{tax_index}][account_id]", options_from_collection_for_select(@tax_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 style="background:#EDF4FF"><%= text_field_tag "invoice[invoice_line_items_attributes][#{tax_index}][amount]", invoice_line_item.amount, :class => 'full', :id => 'tax', :onkeydown => "return numbersOnly(event);", :size => 5%></td>
<td><%= link_to 'Remove',{:action => :remove_tax_item, :index => tax_index}, :remote => true %></td>
</tr>
My motto is to save both items accounts and tax accounts in invoice_line_items table's account_id column, i hope some buddy has the answer, thanks in advance
回答1:
The issue you have is @invoice.invoice_line_items
and @invoice.tax_line_items
will return the same values since they both are using the same id to join.
Seems like you could use Single Table Inheritance (you will have to scroll down to find the section in the API). Using a type column in the invoice_line_items
table, you can have model inheritance.
class InvoiceLineItem < ActiveRecord::Base
belongs_to :invoice
end
class TaxLineItem < InvoiceLineItem
belongs_to :invoice
end
then you can cleanup you associations in Invoice
class Invoice < ActiveRecord::Base
has_many :invoice_line_items
has_many :tax_line_items, :dependent => :destroy
end
回答2:
i got the solution any how i did this:
<% @invoice.tax_line_items.each_with_index do |tax_line_item, tax_index| %>
<%= render "tax_line_items", :tax_line_item => tax_line_item, :index => tax_index %>
<% end %>
and in the partial of _tax_line_items :
<tr id="tax_row<%= tax_index %>" valign="top" >
<%= hidden_field_tag "invoice[tax_line_items_attributes][#{tax_index}][id]",invoice_line_item.id%>
<td></td>
<td colspan="2" class="ta-right"><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 => invoice_line_item.account_id ), :include_blank => true, :class=>"full" %>
</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><%= link_to 'Remove',{:action => :remove_tax_item, :index => tax_index}, :remote => true %></td>
</tr>
and this is working for me....
来源:https://stackoverflow.com/questions/9907239/active-record-has-many-association-for-one-model-having-two-types-of-values