Проверка нескольких состояний в Rails - PullRequest
7 голосов
/ 28 мая 2009

Я работаю над приложением Rails, в которое существующие пользователи могут приглашать дополнительных участников. Проблема в том, что модель User существует в разных состояниях, и в этих разных состояниях требуются разные наборы информации.

Например, Джон является участником сайта и приглашает Мэри. Джон вводит имя и адрес электронной почты Мэри, в базе данных для Мэри создается запись пользователя и отправляется приглашение по электронной почте. Однако после присоединения требуемый набор данных изменяется, и мы требуем, чтобы она ввела дополнительную информацию (например, пароль).

Я все еще изучаю Ruby on Rails и не вижу способа справиться с этим, используя стандартные методы проверки validates_presence_of, validates_format_of и т. Д. Кто-нибудь может указать мне правильное направление

Ответы [ 2 ]

9 голосов
/ 28 мая 2009

Проще всего использовать :if следующим образом:

class User < ActiveRecord::Base
  validate_presence_of :name
  validate_presence_of :age, :if => Proc.new { |user| user.signup_step >= 2 }
  # ... etc
end

или

class User < ActiveRecord::Base
  validate_presence_of :name
  validate_presence_of :age, :if => :registering?

  def registering?
    signup_step >= 2
  end
end

Вы также можете использовать метод validate для определения любой сложной пользовательской логики. Например:

class User < ActiveRecord::Base
  validate :has_name_and_email_after_invitation
  validate :has_complete_profile_after_registration

  def has_name_and_email_after_invitation
    if ... # determine if we're creating an invitation
      # step 1 validation logic here
    end
  end

  def has_complete_profile_after_registration
    if ... # determine if we're registering a new user
      # step 2 validation logic here
    end
  end 
end

(В приведенном выше примере вы могли бы фактически определить правила проверки в has_name_and_email_after_invitation с помощью обычных вызовов validates_xxx_of, поскольку они также должны применяться на шаге 2, но использование двух методов для отдельных шагов дает вам максимальную гибкость. )

5 голосов
/ 16 сентября 2009

И, для DRYin'up вашего кода, вы можете использовать with_options, например:

class Example < ActiveRecord::Base
  [...]
  def registering?
    signup_step >= 2
  end
  with_options(:if => :registering?) do |c|
    c.validates_presence_of :name
  end

  with_options(:unless => :registering?) do |c|
    c.validates_presence_of :contact_details
  end
  [...]
end

Узнайте больше о with_options здесь:

http://apidock.com/rails/v2.3.2/Object/with_options

Есть даже скринкаст от RailsCasts:

http://railscasts.com/episodes/42-with-options

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...