【问题标题】:Rails Pass A Parameter To Conditional ValidationRails 将参数传递给条件验证
【发布时间】:2012-10-10 17:31:53
【问题描述】:

我正在从电子表格文档中导入大量学生数据。每行学生数据将代表一个新用户,但是,存在导入现有学生的可能性,我想相应地绕过一些用户验证,例如用户名唯一性,以便我可以为新记录和现有记录建立关联,但前提是它们被导入同一所学校。

到目前为止,我的用户模型中有以下验证设置:

user.rb

validates_uniqueness_of :username, :unless => :not_unique_to_school?

def not_unique_to_school?
  user = find_by_username(self.username)
  user.present? && user.school_id == 6
end

现在我将如何用我在控制器中可以访问的值替换那个 6?教师将是处理导入的人,他们会将学生导入他们的学校,所以我通常会运行 current_user.school_id 来检索我希望他们导入的学校 ID,但我无权访问 current_user我的模型中的助手。

我不担心重复用户名,因为我将在不同的步骤中处理它,这只是初步验证。


编辑

简化的学校和用户模型:

user.rb

class User < ActiveRecord::Base    

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :username, 
                  :first_name, :last_name, :school_id, :roles_mask

  belongs_to :school

  validates_presence_of :username, :on => :create, :message => "can't be blank"
  validates_uniqueness_of :username, :unless => :unique_to_school?

  def unique_to_school?
    user = find_by_username(self.username)
    user.present? && user.school_id == 6
  end 

  def find_by_username(username)
    User.where(:username => username).first
  end     

end

school.rb

class School < ActiveRecord::Base
  attr_accessible :country_id, :name, :state_id

  has_many :users    

end

【问题讨论】:

  • 你能发布你的整个用户模型和学校模型吗?
  • 你的控制器也可能有用。
  • 相信我,你不想要我的整个用户和学校模型,那里有很多不相关的复杂性。

标签: ruby-on-rails-3 validation activerecord


【解决方案1】:

我会在你的 School 模型中添加一个方法:

def student_named?(name)
  self.users.where(:username => name).any?
end

然后在您的验证中:

def not_unique_to_school?
  self.school.student_named?(self.username)
end

【讨论】:

  • 这会在结果重定向中为我生成Unknown key: username。我无法确定它是来自 School 模型还是来自 User 模型。
  • 抱歉,.find 应该是.where,试试修改后的代码。
  • 现在很好用,感谢您的快速响应。我希望其他用户没有删除他的答案,因为这对我也有一些小的修改。
  • 对不起,但我可能已经跳过了这一点,因为我认为它最初是有效的,但似乎并非如此。现在查看代码,没有什么可以区分学生被添加到的当前学校和 not_unique_to_school 中的self.school?方法。事实上,如果你正在测试一个孩子的父母是否包含孩子,那不是总是返回 true 吗?如果您想了解我的意思,我有一个有效的验证,其他用户已在不久后发布并删除。
【解决方案2】:

这就是最终对我有用的东西:

validate :user_cant_be_duplicate_in_other_schools  

def user_cant_be_duplicate_in_other_schools
    errors.add(:username, :taken) if User.count(:conditions => ["school_id != ? AND username = ?", self.school_id, self.username]) > 0
end  

与测试用户是否属于特定学校不同,我们测试的是是否不属于特定学校。我没有想出这个答案,另一位用户将此作为答案发布,但不久后出于未知原因将其删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-23
    • 2018-06-03
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多