Ruby:仅当至少存在1个子项时才创建父项

时间:2013-05-14 03:50:01

标签: ruby-on-rails ruby oop validation inheritance

我和维修之间有亲子关系。 RepairItems。

修复必须至少保存1个RepairItem。我已经创建了一个嵌套(简单)表单来创建一个Repair并显示3个空白repair_items。

我正在尝试确定如何确保修复至少输入了1个repair_item以允许用户保存修复。否则,我需要提示用户在输入至少1个repair_item之前无法保存修复..

有人能指出我正确的方向进行验证,以便用户无法在没有输入修复项目的情况下保存修复吗?感谢

class Repair < ActiveRecord::Base
attr_accessible :repair_id, :repairer_id, :fault_num, :vehicle_id, :date_reported, :date_closed, :hours_open, :mileage_open, :reported_to, :reported_by,
   :repair_items_attributes

   belongs_to :vehicle
   belongs_to :repairer

   has_many :repair_items, :dependent => :destroy

   validates_presence_of :vehicle_id
   validates_associated :repair_items

   accepts_nested_attributes_for :repair_items, :reject_if => lambda { |a| a[:repair_type_id].blank? }, :allow_destroy => true

end

class RepairItem < ActiveRecord::Base
attr_accessible :repair_id, :problem, :solution, :repair_type_id, :priority, :repairer_id, :invoice, :cost, :tax,
 :item_state_id, :mileage_closed, :hours_closed, :date_closed

   belongs_to :repair
   belongs_to :repairer
   belongs_to :repair_type
   belongs_to :item_state

   #validates_presence_of :repair_id
   validates_presence_of :repair_type_id   

   scope :open, where(:item_state_id => 1)
   scope :monitor, where(:item_state_id=> 2)
   scope :deferred, where(:item_state_id => 3)
   scope :closed, where(:item_state_id => 4)
   scope :cancelled, where(:item_state_id => 5)

end

class RepairsController < ApplicationController

    before_filter :authorise
    layout :resolve_layout

def index
    #status = 1
    @repairItems = RepairItem.open
end

def monitor
    #status = 2
    @repairItems = RepairItem.monitor
end

def deferred
    #status = 3
    @repairItems = RepairItem.deferred
end

def closed
    #status = 4
    @repairItems = RepairItem.closed
end

def cancelled
    #status = 5
    @repairItems = RepairItem.cancelled
end

def new
    @repair = Repair.new
    3.times { @repair.repair_items.build }
end

def create
    # Instantiate a new object using form parameters
    @repair = Repair.new(params[:repair])

    # Save the object
if @repair.save
    # If the save suceeds, redirect to the list action

    redirect_to(repairs_path, :notice => 'Repair Created.')

else
  # If the save fails, redisplay the form so user can fix problems
  render :action => :new
end

end

<%= simple_form_for( @repair, :defaults => { :disabled => @current_user.read_only, :input_html => { :class => "span10" } }) do |f| %> 

<fieldset>      
  <!-- This will display some text in red at the top of the form telling the user -->
  <%= f.error_notification %>
  <div class="st-row-fluid">

    <div class="span2">
      <%= f.association :vehicle, label_method: :fleet_num, value_method: :id, include_blank: true, label: 'Vehicle'%>
    <p>Current Kms</p>
    <p>Current Hours</p>
    <p class="muted">Warranty Expires</p>
    <p class="muted">Contract Maintenance</p>

  </div>

      <div class="span2">
        <%= f.input :date_reported, :as => :date_picker, :input_html => { :class => "span10 st-datepicker"} %>
        <%= f.input :mileage_open, :label => "Km/Miles" %>
        <%= f.input :hours_open %>
      </div>
    <div class="span2">
      <%= f.input :fault_num %>
      <%= f.input :reported_to %>
      <%= f.input :reported_by %>
    </div>

  </div>

<div class="row-fluid">
  <h4> Items</h4>
  <%= f.simple_fields_for :repair_items do |p| %>
     <table class="table table-condensed">
        <tr>
           <%= render "repair_items", :p => p %>
       </tr>
    </table>
  <% end %>
</div>  


    <%= f.error :base %>
    <div class="st-form-actions">
       <% if @current_user.read_only == false %>
        <%= f.submit nil, :class => 'btn btn-success pull-right' %>
       <% end %>
      <%= link_to 'Cancel', repairs_path, :class => 'btn btn-danger pull-right' %>
    </div>
</fieldset>
  <% end %>

部分

<td><%= p.association :repair_type, label_method: :repair_type_label, value_method: :id, include_blank: true, label: 'Repair Type'%></td>
<td><%= p.input :problem %></td>
<td><%= p.input :solution %></td>
<td><%= p.input :priority %></td>
<td><%= p.association :repairer, label_method: :rep_name, value_method: :id, include_blank: true, label: 'Repairer'%></td>
</tr>
<tr>
<td><%= p.input :invoice %></td>
<td><%= p.input :cost %></td>
<td><%= p.input :tax %></td>
<td><%= p.input :date_closed, :as => :date_picker, :input_html => { :class => "span10 st-datepicker"} %></td>
<td><%= p.input :mileage_closed, :label => "Km/Miles" %></td>
<td><%= p.input :hours_closed %></td>
<td><%= p.association :item_state, label_method: :state_label, value_method: :id, label: 'Status', :default => 1 %></td>

1 个答案:

答案 0 :(得分:0)

在修复中使用validates_associated :repair_items来验证修复项目。操作必须使用repair.RepairItem.build构造修复项目,以便在尝试保存修复之前将项目与修复相关联。修复是在修复项目之前构建的,但repair_items将阻止相关修复的保存。