开发者

Rails validation problem

I've got a User model with three fields, :email, :display_name and :handle. Handle is created behind the scenes from the :display_name.

I'm using the following validations:

 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." }

I use the handle as the to_param in the model. If the user fails the validation by submitting a :display_name that already exists, then tries to change it and resubmit the form, Rails seems to use the new handle as the validation for the email -- in other words, it assumes that the email doesn't belong to the current user and validation on the email then fails. At this point, Rails assumes that the changed display name/handle is the one to use for the look up and the update action can't complete at all, because it can't find the user based on the new handle.

Here's the update method:

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

This problem doesn't happen when the validation first fails on a duplicate email, so I'm assuming it's something about the way I've writt开发者_开发知识库en the update method -- maybe I should try setting the handle in the model?


maybe I should try setting the handle in the model?

^ This.

The controller isn't the place to do something like this. If it's model logic that's happening behind the scenes, beyond the user's control, why put it in controller code?

Do it instead in a before_save filter, which is guaranteed to run only after the chosen display name is determined to be available and the record is deemed valid. In this way the handle won't be changed on the cached record until it is actually committed to the db, eliminating the problem of the incorrectly generated URL.

before_save :generate_handle
...

def generate_handle
  self.handle = display_name.parameterize
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜