我有一个包含三个字段的用户模型: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>
答案 0 :(得分:2)
也许我应该尝试在模型中设置句柄?
^这个。
控制器不是这样做的地方。如果它是在幕后发生的模型逻辑,超出用户的控制范围,为什么要把它放在控制器代码中呢?
在before_save
过滤器中执行此操作,保证只有在确定所选显示名称可用且记录有效后才能运行。通过这种方式,在实际提交到数据库之前,不会在缓存的记录上更改handle
,从而消除了错误生成的URL的问题。
before_save :generate_handle
...
def generate_handle
self.handle = display_name.parameterize
end