是否可以结合with_options和:if for conditional validations?

时间:2012-08-14 15:52:08

标签: ruby validation activerecord

我正在尝试使用with_options将管理员用户的条件验证分组。 对用户名唯一性的第二次验证最终会覆盖with_options条件。

有更好的方法吗?或者我应该忘记with_options并写两个单独的语句?

with_options :if => Proc.new { |user| user.admin? } do |admin|
  admin.validates :email, :presence => true
  admin.validates :username, :uniqueness => true, :if => Proc.new { |user| user.category == "customized_username" }
end

3 个答案:

答案 0 :(得分:1)

如果您只有这两个验证,我不认为放弃with_options块并直接为每个验证添加条件是个坏主意:

admin.validates :email, :presence => true, :if => Proc.new { |user| user.admin? }
admin.validates :username, :uniqueness => true, :if => Proc.new { |user| user.admin? && user.category == "customized_username" }

您可能想要考虑的另一件事是单表继承(STI),而不是使用布尔字段。如果您发现自己在应用程序中进行user.admin?,我会建议您这样做。使用STI,您将拥有常规用户和管理员用户,并且每个用户可以为每个类包含不同的逻辑。您需要做的唯一真正的改变就是改变您的管理员和管理员。字段到"键入"并使它成为一个字符串:

class User < ActiveRecord::Base
end

class AdminUser < User
  validates :email, :presence => true
  validates :username, :uniqueness => true, :if => Proc.new { |user| user.category == "customized_username" }
end

答案 1 :(得分:0)

你应该使用两行,但是,使用方法比在Proc。

中重复相同的逻辑更清晰
validates :email, :presence => true, :if => :admin?
validates :username, :uniqueness => true, :if => [:admin?, :custom_user?]

def custom_user?
   category == "customized_username"
end

答案 2 :(得分:0)

改为使用unless

with_options :unless => Proc.new { |user| !user.admin? } do |admin|
  admin.validates :email, :presence => true
  admin.validates :username, :uniqueness => true, :if => Proc.new { |user| user.category == "customized_username" }
end