Ruby & Ruby on Rails « Валидация. Проверка существования пользователя.

Как правильно валидировать наличие пользователя в БД? Т.е. я хочу чтобы пользователи могли отправлять личные сообщения только существующим пользователям. Отправителя и получателя храню в виде id пользователя.

Модель
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .ruby.geshi_code {font-family:monospace;} .ruby.geshi_code .imp {font-weight: bold; color: red;} .ruby.geshi_code .kw1 {color:#9966CC; font-weight:bold;} .ruby.geshi_code .kw2 {color:#0000FF; font-weight:bold;} .ruby.geshi_code .kw3 {color:#CC0066; font-weight:bold;} .ruby.geshi_code .kw4 {color:#CC00FF; font-weight:bold;} .ruby.geshi_code .co1 {color:#008000; font-style:italic;} .ruby.geshi_code .coMULTI {color:#000080; font-style:italic;} .ruby.geshi_code .es0 {color:#000099;} .ruby.geshi_code .br0 {color:#006600; font-weight:bold;} .ruby.geshi_code .sy0 {color:#006600; font-weight:bold;} .ruby.geshi_code .st0 {color:#996600;} .ruby.geshi_code .nu0 {color:#006666;} .ruby.geshi_code .me1 {color:#9900CC;} .ruby.geshi_code .re0 {color:#ff6633; font-weight:bold;} .ruby.geshi_code .re1 {color:#0066ff; font-weight:bold;} .ruby.geshi_code .re2 {color:#6666ff; font-weight:bold;} .ruby.geshi_code .re3 {color:#ff3333; font-weight:bold;} .ruby.geshi_code span.xtra { display:block; }

# encoding: utf-8
class Message < ActiveRecord::Base
  attr_accessible :subject, :body, :receiver_name
 
  belongs_to :user
  belongs_to :receiver, :class_name => 'User'

  validates :receiver_name, :receiver => true
 
  # Getter
  def receiver_name
    receiver_id ? User.find_by_id(receiver_id).username.to_s : nil
  end
 
  # Setter
  def receiver_name=(name)
    self.receiver_id = User.find_by_username(name).id
  end
end
 


Валидатор
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .ruby.geshi_code {font-family:monospace;} .ruby.geshi_code .imp {font-weight: bold; color: red;} .ruby.geshi_code .kw1 {color:#9966CC; font-weight:bold;} .ruby.geshi_code .kw2 {color:#0000FF; font-weight:bold;} .ruby.geshi_code .kw3 {color:#CC0066; font-weight:bold;} .ruby.geshi_code .kw4 {color:#CC00FF; font-weight:bold;} .ruby.geshi_code .co1 {color:#008000; font-style:italic;} .ruby.geshi_code .coMULTI {color:#000080; font-style:italic;} .ruby.geshi_code .es0 {color:#000099;} .ruby.geshi_code .br0 {color:#006600; font-weight:bold;} .ruby.geshi_code .sy0 {color:#006600; font-weight:bold;} .ruby.geshi_code .st0 {color:#996600;} .ruby.geshi_code .nu0 {color:#006666;} .ruby.geshi_code .me1 {color:#9900CC;} .ruby.geshi_code .re0 {color:#ff6633; font-weight:bold;} .ruby.geshi_code .re1 {color:#0066ff; font-weight:bold;} .ruby.geshi_code .re2 {color:#6666ff; font-weight:bold;} .ruby.geshi_code .re3 {color:#ff3333; font-weight:bold;} .ruby.geshi_code span.xtra { display:block; }

# encoding: utf-8
class ReceiverValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if User.find_by_username(value).blank?
      record.errors[attribute] << (options[:message] || "не существует")
    end
  end
end
 

1 ответов


Может кому-то будет полезно... Теперь если пользователя не существует, выдается ошибка валидации и сообщение не отправляется. Только один недочет, имя пользователя сбрасывается, если оно было не валидным.

Модель


# encoding: utf-8
class Message < ActiveRecord::Base
  attr_accessible :subject, :body, :receiver_name
 
  belongs_to :user
  belongs_to :receiver, :class_name => 'User'
 
  #validates :receiver_name, :presence => true
  validates :receiver_name, :receiver_username => true
 
  # Getter
  def receiver_name
    if receiver_id
      User.find_by_id(receiver_id).username.to_s
    end
  end
 
  # Setter
  def receiver_name=(name)
    if User.exists?(:username => name)
      self.receiver_id = User.find_by_username(name).id
    end
  end
end
 

Валидатор

# encoding: utf-8
class ReceiverUsernameValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    unless User.exists?(:username => value)
      object.errors.add(attribute, 'Пользователь не существует')
    end
  end
end