Rails: избавление от общих ошибок валидации "X is invalid" - PullRequest
8 голосов
/ 01 июня 2010

У меня есть форма регистрации, в которой есть вложенные ассоциации / атрибуты, как бы вы их ни называли.

Моя иерархия такова:

class User < ActiveRecord::Base
  acts_as_authentic
  belongs_to :user_role, :polymorphic => true
end

class Customer < ActiveRecord::Base
  has_one :user, :as => :user_role, :dependent => :destroy
  accepts_nested_attributes_for :user, :allow_destroy => true
  validates_associated :user
end

class Employee < ActiveRecord::Base
  has_one :user, :as => :user_role, :dependent => :destroy
  accepts_nested_attributes_for :user, :allow_destroy => true
  validates_associated :user
end

У меня есть кое-что для проверки в этих классах. Моя проблема заключается в том, что если я пытаюсь создать и Customer (или Employee и т. Д.) С пустой формой, я получаю все ошибки проверки, которые я должен получить, а также некоторые общие ошибки, такие как «Пользователь недействителен» и «Клиент недействителен», если я выполняю итерацию по ошибки я получаю что-то вроде:

user.login can't be blank
User is invalid
customer.whatever is blah blah blah...etc
customer.some_other_error etc etc

Поскольку во вложенной модели User есть хотя бы одно недопустимое поле, в список ошибок добавляется дополнительное сообщение «X is invalid». Это сбивает с толку моего клиента, и поэтому мне интересно, есть ли быстрый способ сделать это вместо того, чтобы самостоятельно разбирать ошибки.

Ответы [ 2 ]

6 голосов
/ 14 сентября 2010

Салил ответил почти правильно, но он никогда не делал это на 100% Вот правильный способ сделать это:

def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %{ person }.include?(err.first) }

    # recollect the field names and retitlize them
    # this was I won't be getting 'user.person.first_name' and instead I'll get
    # 'First name'
    filtered_errors.collect{ |err|
      if err[0] =~ /(.+\.)?(.+)$/
        err[0] = $2.titleize
      end
      err
    }

    # reset the errors collection and repopulate it with the filtered errors.
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end
3 голосов
/ 01 июня 2010

Использование после проверки метод

  def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %w{ user User  }.include?(err.first) }
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end

EDITED

Примечание: -

Добавьте в следующем списке, если это пользователь или пользователь. Вы можете добавить несколько, если у вас есть несколько ассоциаций, разделенных пробелом.

%w{ User user }.include?(err.first) #### This piece of code from the above method has logic which reject the errors which won't be useful to the end user
...