2015-01-17 4 views
1

У меня есть поле даты, которое не является обязательным. Я использую Chronic для форматирования строки ввода пользователя в действительный формат рельсов для поля даты. Если Chronic не может выполнить синтаксический анализ даты, я хотел бы поднять ошибку, отображая представление редактирования с соответствующим сообщением об ошибке и исходным значением ввода. В настоящее время обновление выполнено успешно, если введена неверная дата, но ничего не обновляется для поля service_date.Как добавить сообщение об ошибке при использовании виртуального атрибута

new.html.erb

<%= f.text_field :service_date_text %> 

bill.rb

require 'chronic' 

class Bill < ActiveRecord::Base 

    def service_date_text 
    service_date.try(:strftime, "%m/%d/%Y") 
    end 

    def service_date_text=(date) 
    if date.present? 
     if Chronic.parse(date) 
     self.service_date = Chronic.parse(date) 
     else 
     self.errors.add(:service_date_text, "invalid date format hello.") 
     end 
    else 
     self.service_date = '' 
    end 
    end 
end 

bills_controller.rb

def update 
    @bill = current_account.bills.find(params[:id]) 
    if @bill.update_attributes(bill_params) 
     redirect_to @bill, notice: 'Bill has been successfully updated.' 
    else 
     render :edit 
    end 
    end 

    private 

    def bill_params 
    params.require(:bill).permit(:description, :notes, :po_number, :service_date_text) 
    end 
+0

Вы просматривали пользовательские валидаторы в ActiveRecord? http://guides.rubyonrails.org/active_record_validations.html#custom-validators – davidkovsky

ответ

2

errors очищается всякий раз, когда вы запускаете valid?, который update_attributes делает.

Пример:

irb(main):001:0> album = Album.new 
=> #<Album id: nil, name: nil, release_date: nil, rating: nil, genre_id: nil, 
artist_id: nil, created_at: nil, updated_at: nil> 

irb(main):004:0> album.errors.add :artist, "You've selected Justin Bieber (!!!)" 
=> ["You've selected Justin Bieber (!!!)"] 

irb(main):006:0> album.errors.messages 
=> {:artist=>["You've selected Justin Bieber (!!!)"]} 

irb(main):007:0> album.valid? 
=> true 

irb(main):008:0> album.errors.messages 
=> {} 

Не злоупотребляет сеттера, используйте соответствующие валидации. Например (не тестировались):

require 'chronic' 

    class Bill < ActiveRecord::Base 
    validate :service_date_validation 

    def service_date_text 
     service_date.try(:strftime, "%m/%d/%Y") 
    end 

    def service_date_text=(date) 
     if date.present? 
     if Chronic.parse(date) 
      self.service_date = Chronic.parse(date) 
     else 
      self.service_date = false 
     end 
     else 
     self.service_date = '' 
     end 
    end 


    private 

     def service_date_validation 
     if self.service_date == false 
      self.errors.add(:service_date_text, "invalid date format hello.") 
     end 
     end 
    end 

... Есть также некоторые драгоценные камни, которые обеспечивают даты валидации, такие как:

... а также некоторые другие ...

+0

Установка service_date в false - это недостающая часть для меня. Я пытался установить service_date на входное значение, которое Chronic не смог проанализировать. Мысль о том, что при рендеринге я бы показал ошибку и исходное значение ввода. Также приятно объяснять, когда должны быть установлены ошибки. Спасибо за помощь. – Steve

0

Держу пари, вопрос в том, что Rails не ожидает сеттер методы для добавления ошибок. Я бы сделал service_date_text просто attr_accessor, а затем вызвал метод проверки, который устанавливает service_date или добавляет ошибку.

attr_accessor :service_date_text 

validate :service_date_text_format 

private 

def service_date_text_format 
    return unless service_date_text # or self.service_date ||= '' and then return 
    if date = Chronic.parse(date) 
    self.service_date = date 
    else 
    errors.add(:service_date, 'invalid format') 
    end 
end 
+0

Я обновился до 'self.errors.add (: service_date,« недопустимый формат даты. »)', но при этом не возникало ошибок при обновлении. – Steve

+0

Думаю, сейчас я понимаю вашу проблему. Надеюсь, обновление поможет. – evanbikes

Смежные вопросы