views:

27

answers:

1

I have a model that has an overriden to_param method returning the (unique) name of a record. This works quite fine, however with one caveat - the user can edit the name.

If I have record #1 with name="abc" and record #2 with name="xyz", then a user editing record #2 and changing name to "abc" will get an error upon saving as the validates_uniqueness_of constraint is violated. However when Rails constructs the edit.html.erb page again, it uses the unvalidated data - including to to_param which is now linking everything to record #1 ("abc"). Consequent saves thus act on record #1 instead of record #2.

What would be the recommended best practice to prevent this horrendous result? Should I reset the name value before redirecting upon an error (but what if the name was okay and the error was elsewhere) or should I change my views to manually insert the id instead of using the automatics of Rails?

+2  A: 

Probably the easiest thing to do would be to not rely on the name attribute but instead another attribute that is hidden from the user.

eg. if you had a permalink:string column on the model you could do something like:

Class ModelName < ActiveRecord::Base

  before_save :update_permalink

  validates_presence_of :name    

  def to_param
    permalink
  end

  private
  def update_permalink
    self.permalink = name.parameterize
  end
end
Mark Connell