Active record has_many association for one model having two types of values

泪湿孤枕 提交于 2020-01-15 08:16:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!