4

I'm trying to use with_options to group my conditional validations together for admin users. The second validation for username uniqueness ends up overriding the with_options condition.

Is there a better way to do this? Or should I just forget about with_options and write two separate statements?

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
4

3 回答 3

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,您将拥有普通用户和管理员用户,并且每个用户都可以为每个类包含不同的逻辑。您需要进行的唯一真正更改是将“admin”字段更改为“type”并将其设为字符串:

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
于 2012-12-14T09:18:12.020 回答
0

您应该使用两行代码,但是,有方法比在 Proc 中重复相同的逻辑更简洁。

validates :email, :presence => true, :if => :admin?
validates :username, :uniqueness => true, :if => [:admin?, :custom_user?]

def custom_user?
   category == "customized_username"
end
于 2014-11-07T01:01:18.533 回答
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
于 2019-08-15T14:05:00.213 回答