2010-02-08 44 views
0

我遇到了我的rails自定義驗證問題。使用多模型表單的Rails自定義驗證

def validates_hsp_program(*attr_names) 
    options = attr_names.extract_options! 
    regex = '^(' 
    err = '' 
    $CetConfig.program.each do |key, val| 
     regex << val.to_s << '|' 
     err << $CetConfig.program_prefix + " " + val.to_s + ", " 
    end 

    regex.chomp!('|') 
    regex << ')$' 
    regex = Regexp.new(regex) 

    validates_each attr_names do | record, attr_name, value | 
    exit 1 
     unless value.nil? or value =~ regex 
     record.errors.add(attr_name, 'must be one of ' + err.chomp(", ")); 
     end 
    end 

    end 

問題是,出於調試目的,我添加了退出1,因爲我沒有得到該字段的無效日期的錯誤消息。但是,它永遠不會退出。這是我在所有其他自定義驗證器中所做的同樣的事情。我能看到的唯一區別是這是多模式表單的第二個模型,其他所有模型都在第一個模型上......我做錯了什麼?

我的模型

class ProfileProgram < ActiveRecord::Base 
    set_table_name "profile_program" 
    set_primary_key "STUDENT_ID" 
    belongs_to :profile_core, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID" 

    validates_presence_of :program 
    validates_hsp_program :program 
end 

從我的控制器行動

def create 
    @pc = ProfileCore.new(params[:profile_core]) 
    @pp = ProfileProgram.new(params[:profile_program]) 

    @pc.student_type = $CetConfig.student_type.application 
    @pc.AGENT_ID = current_agents_staff.AGENT_ID 

    year = @pc.contract.to_s 

    case @pp.program 
    when 10 then 
     sd = year + '-09-01' 
     ed = year + '-06-30' 
    when 51 then 
     sd = year + '-08-15' 
     ed = year + '-06-30' 
    when 52 then 
     sd = year + '-01-15' 
     ed = year + '-06-30' 
    when 12 then 
     sd = year + '-01-15' 
     ed = year + '-01-14' 
    else 
     sd = nil 
     ed = nil 
    end 

    @pc.start_date = Date.parse(sd) unless sd.nil? 
    @pc.end_date = Date.parse(ed) unless ed.nil? 

    @pc.program_status = $CetConfig.student_status.apply 

    if @pc.valid? and @pp.valid? 
    ProfileCore.transaction do 
     @pc.save! 
     @pp.save! 
    end 
    redirect_to(students_path(@pc.STUDENT_ID)) 
    else 
    render :action => 'new' 
    end 
end 

我的觀點(element_block是,僅僅充塞的標籤和字段到右側的標籤爲DL一個幫手)

<% form_for :profile_core, @pc, :url => { :controller => 'core', :action => 'create'} do |f| %> 
    <%= error_messages_for :object => [ @pc, @pp ] %> 
    <dl> 
    <%= element_block f.label(:contract, 'Contract Year'), f.contract_year_select(:contract) %> 
    <% fields_for :profile_program do |pp| %> 
     <%= element_block pp.label(:program, 'Program'), pp.hsp_program_select(:program) %> 
    <% end %> 

    <%= element_block f.label(:passport_number, 'Passport Number'), f.text_field(:passport_number) %> 
    <%= element_block f.label(:passport_country, "Country that issued the student's passport"), f.countries_select(:passport_country) %> 
    <%= element_block f.label(:passport_expires, 'Passport Expiration Date'), f.text_field(:passport_expires, :class => 'datepicker') %> 
    <%= element_block f.label(:last_name, 'Last Name (as on passport)'), f.text_field(:last_name) %> 
    <%= element_block f.label(:first_name, 'First Name (as on passport)'), f.text_field(:first_name) %> 
    <%= element_block f.label(:middle_name, 'Middle Name (as on passport)'), f.text_field(:middle_name) %> 
    <%= element_block f.label(:other_names, 'Other Names'), f.text_field(:other_names) %> 
    <%= element_block f.label(:residence_street_address, 'Street Address'), f.text_field(:residence_street_address) %> 
    <%= element_block f.label(:residence_city, 'City'), f.text_field(:residence_city) %> 
    <%= element_block f.label(:residence_province, 'Province'), f.text_field(:residence_province) %> 
    <%= element_block f.label(:residence, 'Country'), f.text_field(:residence) %> 
    <%= element_block f.label(:residence_postal_code, 'Postal Code'), f.text_field(:residence_postal_code) %> 
    <%= element_block f.label(:birthdate, 'Date of Birth'), f.text_field(:birthdate, :class => 'datepicker', :id => "student_birth_date") %> 
    <%= element_block f.label(:citizenship, 'Country of Citizenship'), f.countries_select(:citizenship) %> 
    <%= element_block f.label(:birth_city, 'Birth City'), f.text_field(:birth_city) %> 
    <%= element_block f.label(:nationality, 'Nationality'), f.countries_select(:nationality) %> 
    <%= element_block f.label(:gender, 'Gender'), f.gender_select(:gender) %> 
    <%= element_block f.label(:email, 'Email'), f.text_field(:email) %> 
    <%= element_block f.label(:desires_esl, 'Does the student wish to participate in CLEP?'), f.bool_yes_no_select(:desires_esl) %> 
    <%= element_block f.label(:may_pay_tuiton, 'Willing to pay tuition'), f.yes_no_select(:may_pay_tuition) %> 
    </dl> 
    <div class="submit"><%= submit_tag("Proceed to Step Two") %></div> 
<% end %> 

回答

1

這是我結束了照顧它accepts_nested_attributes_for

主要模式。 (替換爲省略號無關代碼)

class ProfileCore < ActiveRecord::Base 
    set_table_name "profile_core" 
    set_primary_key "STUDENT_ID" 
    belongs_to :agents_profile, :primary_key => "AGENT_ID", :foreign_key => "AGENT_ID" 
    has_one :profile_program, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID" 

    accepts_nested_attributes_for :profile_program 
... 
end 

二次模型

class ProfileProgram < ActiveRecord::Base 
    set_table_name "profile_program" 
    set_primary_key "STUDENT_ID" 
    belongs_to :profile_core, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID" 

    validates_presence_of :program 
    validates_hsp_program :program 
end 

在控制器新的動作。 (創建,是無關緊要的)

def new 
    @pc = ProfileCore.new 
    @pp = @pc.build_profile_program 
end 

查看

<% form_for @pc, :url => { :controller => 'core', :action => 'create'} do |f| %> 
    <%= f.error_messages %> 
    <dl> 
    <%= element_block f.label(:contract, 'Contract Year'), f.contract_year_select(:contract) %> 
    <% f.fields_for :profile_program do |pp| %> 
     <%= element_block pp.label(:program, 'Program'), pp.hsp_program_select(:program) %> 
    <% end %> 
    <%= element_block f.label(:passport_number, 'Passport Number'), f.text_field(:passport_number) %> 
... 
<% end %>