2014-11-02 3 views
0

В моей модели у меня есть некоторые валидации, как это:Установить поле в присваивателе

validates :text, presence: true, unless: :skip_fehler 

я установил skip_fehler для конкретного экземпляра в моем контроллере:

@user.create(skip_fehler: params['skip_fehler'], text: .. 

Bascially мой код работал, когда я был в моей модели:

attr_accessor :skip_fehler 

Единственная проблема, я заметил, что когда @user.skip_fehler был установлен в "". Проверка также была пропущена.

Я хочу, чтобы избежать такого поведения Так я пытался изменить accessor к reader:

attr_reader :skip_fehler 

И я написал свой собственный метод установки:

def skip_fehler=(value) 
    if value && value != "" 
     self.skip_fehler = true 
    else 
     self.skip_fehler = false 
    end 
    end 

Но теперь, я получаю эту Ошибка: stack level too deep

Я полагаю, потому что в пределах skip_fehler=(value) я звоню self.skip_fehler = true!

Как мне изменить код? Итак, когда skip_fehler установлен в контроллер на "", его набор равен false в модели? Thanks

ответ

0

Попробуйте использовать write_attribute вместо назначения. Таким образом, значение записывается во внутреннее представление атрибутов напрямую.

write_attribute(:skip_fehler, value) 
1

Вы можете написать:

attr_reader :skip_fehler 

def skip_fehler=(value) 
    @skip_fehler = value.present? 
end 

Это работа, потому что attr_reader :skip_fehler ярлык для:

def skip_fehler 
    @skip_fehler 
end 

и value.present? делает то же самое, чем !value.nil? && value != ""

0

Рельсы валидаторы принять Procs для: if и: if parameters. Это означает, что вы можете объявить валидатор как это:

validates :text, 
    presence: true, 
    unless: Proc.new { |model| model.skip_fehler.present? } 

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

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