3

假设一个模型捕获了一个验证错误,通常这是由控制器处理的,但是模型可以自动处理它吗?

实际上,我想uid为每个生成一个唯一的 id Note,模型如下所示:

class Note < ActiveRecord::Base
  validates_uniqueness_of :uid
  # ... some code to generate uid on after_initialize
end

我得到的最接近的是:

class Note < ActiveRecord::Base
  validates_uniqueness_of :uid
  # ... some code to generate uid on after_initialize

  after_rollback :repair

  protected

  def repair
    if self.errors[:uid].size > 0
      self.uid = generate_uid
    end
    self.save # Try again
  end
end

我的解决方案的一些直接问题:(1)模型实例仍然有控制器可以看到的错误,我不确定如何清除错误。(2)修复方法是递归的。

4

2 回答 2

2

虽然我确信有一种方法可以捕获和处理模型中的错误(也许after_validation回调可能有用),但也许您可以通过确保uid您在创建它时生成的唯一性来避免这种情况下的问题。

Ryan Bates 提供了这种在 RailsCast 中生成唯一令牌的方法

def generate_token(column)
  begin
    self[column] = SecureRandom.urlsafe_base64
  end while User.exists?(column => self[column])
end

使用before_create回调,即before_create { generate_token(:uid) },每个模型将有一个唯一的 id。

综上所述,@Beerlington 提出了一个关于 UUID 的非常好的观点。

更新:请注意,给定的方法预计将在User模型中定义。对于您的示例,您希望将其更改为...while Note.exists?....

于 2012-09-24T18:10:04.193 回答
0

我会使用一个真正的 UUID,它保证是唯一的,并且不会给你的模型增加开销。在模型中进行唯一性验证会增加一些开销,因为它必须访问数据库才能确定是否存在某些东西,而且它甚至还不能保证。

查看这个 Ruby 项目以生成 UUID:https ://github.com/assaf/uuid/

于 2012-09-24T18:03:19.953 回答