#ruby-on-rails-3 #parent-child #nested-forms
#ruby-on-rails-3 #родитель-потомок #вложенные формы
Вопрос:
Я создаю приложение для выставления счетов в rails3, у меня возникает путаница, когда дело доходит до создания счета.
один счет может содержать один или несколько элементов
'bill' has many 'items'
'item' belongs to 'bill'
мое требование заключается в следующем
Я должен иметь возможность создавать новый счет и добавлять в него элементы (можно добавить любое количество элементов)
моя проблема в том
1 — чтобы сохранить элементы в таблице bill_details, я должен сначала сгенерировать bill_id, каков наилучший способ сгенерировать этот идентификатор счета.
2 — каков наилучший способ реализовать подобный сценарий
3 — могу ли я получить какую-либо помощь от вложенных форм rails
Спасибо
приветствую sameera
Ответ №1:
В этом сценарии следует использовать полиморфную ассоциацию. Вот что вы можете сделать для достижения этого:
в файле модели bill.rb #:
class Bill < ActiveRecord::Base
has_many :items # establish association with items!
# to save items in bill only if they are there!
accepts_nested_attributes_for :items, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end
в файле item.rb # model :
class Item < ActiveRecord::Base
belongs_to :bill # establish association with bill!
end
В вашем bills_controller.rb создайте обычные действия: index, new, create, show, edit, update, delete
для действия обновления:
def update
@bill = Bill.find(params[:id])
respond_to do |format|
if @bill.update_attributes(params[:bill])
format.html { redirect_to(@bill, :notice => 'Bill was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @bill.errors, :status => :unprocessable_entity }
end
end
end
и вам не нужно беспокоиться о создании какого-либо действия / метода в вашем items_controller.rb, просто создайте частичный _form.html.erb в view / Items /_form.html.erb и поместите это:
<%= form.fields_for :items do |item_form| %>
<div class="field">
<%= tag_form.label :name, 'Item:' %>
<%= tag_form.text_field :name %>
</div>
<div class="field">
<%= tag_form.label :quantity, 'Quantity:' %>
<%= tag_form.text_field :quantity %>
</div>
<% unless item_form.object.nil? || item_form.object.new_record? %>
<div class="field">
<%= tag_form.label :_destroy, 'Remove:' %>
<%= tag_form.check_box :_destroy %>
</div>
<% end %>
<% end %>
Теперь вы должны вызвать это из вашего view / bills /_form.html.erb:
<% @bill.tags.build %>
<%= form_for(@bill) do |bill_form| %>
<% if @bill.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(@bill.errors.count, "error") %> prohibited this bill from being saved:</h2>
<ul>
<% @bill.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= bill_form.label :name %><br />
<%= bill_form.text_field :name %>
</div>
<h2>Items</h2>
<%= render :partial => 'items/form',
:locals => {:form => bill_form} %>
<div class="actions">
<%= bill_form.submit %>
</div>
<% end %>
Просмотр / Счета / new.html.erb:
<h1>New Bill</h1>
<%= render 'form' %>
<%= link_to 'Back', bills_path %>
Просмотр / Счета / редактирование.html.erb:
<h1>Editing Bill</h1>
<%= render 'form' %>
<%= link_to 'Show', @bill %> |
<%= link_to 'Back', bills_path %>
С уважением,
Сурья