Rails验证问题

时间:2011-09-11 01:01:05

标签: ruby-on-rails

我有一个包含三个字段的用户模型:email,:display_name和:handle。句柄是在幕后创建的:display_name。

我正在使用以下验证:

 validates :display_name, :presence => :true, :uniqueness => { :message => "Sorry, another user has already chosen that name."}, :on => :update
  validates :email, :presence => :true, :uniqueness => { :message => "An account with that email already exists." }

我将句柄用作模型中的to_param。如果用户通过提交已经存在的display_name失败进行验证,然后尝试更改它并重新提交表单,Rails似乎使用新句柄作为电子邮件的验证 - 换句话说,它假定电子邮件没有不属于当前用户,然后对电子邮件进行验证失败。此时,Rails假定更改后的显示名称/句柄是用于查找的,并且更新操作根本无法完成,因为它无法根据新句柄找到用户。

以下是更新方法:

def update
    @user = User.find_by_handle(params[:id])
    @handle = params[:user][:display_name]
    @user.handle = @handle.parameterize
  ...
end

当验证首次在重复的电子邮件上失败时,不会发生此问题,因此我假设它是关于我编写更新方法的方式 - 也许我应该尝试在模型中设置句柄?< / p>

1 个答案:

答案 0 :(得分:2)

  

也许我应该尝试在模型中设置句柄?

^这个。

控制器不是这样做的地方。如果它是在幕后发生的模型逻辑,超出用户的控制范围,为什么要把它放在控制器代码中呢?

before_save过滤器中执行此操作,保证只有在确定所选显示名称可用且记录有效后才能运行。通过这种方式,在实际提交到数据库之前,不会在缓存的记录上更改handle,从而消除了错误生成的URL的问题。

before_save :generate_handle
...

def generate_handle
  self.handle = display_name.parameterize
end