2016-01-31 8 views
0

Я пытаюсь справиться с ситуацией, когда пользователь вошел данные неправильно, поэтому у меня есть путь, который следует примерно:Как добавить ошибки перед обновлением атрибутов?

class Thing < AR 
    before_validation :byebug_hook 
    def byebug_hook 
    byebug 
    end 
end 

thing = Thing.find x 
thing.errors.add(:foo, "bad foo") 
# Check byebug here, and errors added 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end 

byebug for byebug_hook> errors.messages #=> {} 

Первоначально я думал, что, возможно, модель работает свои валидаций и перезапись те Я добавил, но, как вы можете видеть, даже когда я добавляю до крючка ошибки отсутствуют, и я не уверен, что вызывает его

АКТУАЛЬНОЕ РЕШЕНИЕ Итак, @SteveTurczyn был прав, что ошибки должны были произойти в определенное место, в этом случае объект обслуживания, указанный в моем контроллере

Изменение я сделал был

class Thing < AR 
validate :includes_builder_added_errors 
    def builder_added_errors 
     @builder_added_errors ||= Hash.new { |hash, key| hash[key] = [] } 
    end 

    def includes_builder_added_errors 
    builder_added_errors.each {|k, v| errors.set(k, v) } 
    end 
end 

and in the builder object 
thing = Thing.find x 
# to my thinking this mirrors the `errors.add` syntax better 
thing.builder_added_errors[:foo].push("bad foo") if unshown_code_does_stuff? 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end 
+0

Я думаю, что в вашей попытке сделать ваш фрагмент кода кратким вы сделали это трудно следовать. В любом случае, я думаю, вы найдете ответ на свои вопросы [здесь] (http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations) – Iwnnay

ответ

1

update_attributes проверит модель ... это включает в себя удаление всех существующих ошибок, а затем запуская никаких before_validation обратных вызовов. По этой причине никогда не возникает ошибок на pont в before_validation

Если вы хотите добавить ошибки в "нормальные" ошибки проверки, вам будет лучше, если вы сделаете это как настраиваемый метод проверки в модели.

class Thing < ActiveRecord::Base 
    validate :add_foo_error 

    def add_foo_error 
    errors.add(:foo, "bad foo") 
    end 
end 

Если вы хотите, чтобы некоторые валидация происходит только в некоторых контроллерах или условий, вы можете сделать это путем установки attr_accessor значения на модели, и установив значение, прежде чем запускать валидаций непосредственно (?: Допустим) или косвенно (: update,: save).

class Thing < ActiveRecord::Base 
    attr_accessor :check_foo 
    validate :add_foo_error 

    def add_foo_error 
    errors.add(:foo, "bad foo") if check_foo 
    end 
end 

В контроллере ...

thing = Thing.find x 
thing.check_foo = true 
if thing.update_attributes(params) 
    DelayedJobThatDoesntLikeFoo.perform 
else 
    flash.now.errors = #... 
end