开发者

rails model validation in the database

开发者 https://www.devze.com 2023-04-08 12:10 出处:网络
I have a table and have the validation for uniqueness setup in the table. eg. create 开发者_如何学运维table posts (

I have a table and have the validation for uniqueness setup in the table. eg.

create 开发者_如何学运维table posts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY UNIQUE, title varchar(255) unique, content text );

Here title is unique. Do also need to inform the model class about this uniqueness? If not when i insert a duplicate title, it gives me error. How do I catch that. Currently rails shows me the backtrace and i could not put my own error messages

def create
  @f = Post.new(params[:post])
  if @f.save
    redirect_to posts_path
  else
    @flash['message'] = "Duplicated title"
    render :action=>'new'
  end 
end 

I am not being redirected to the new and instead show a big backtrace.


Use the validates_uniqueness_of validation. "When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified attribute (that maps to a column)"


You will have to add all of the validations to your models. There is a gem called schema_validations, which will inspect your db for validations and create them in your models for you. https://github.com/lomba/schema_validations


Yes you do as noted in other answers, the answer is validate_uniqueness_of - http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000086. Note, even though you have a validation in your model a race condition does exist where Rails may try and do two inserts unaware of there being a unique record already in the table

When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

Because this check is performed outside the database there is still a chance that duplicate values will be inserted in two parallel transactions. To guarantee against this you should create a unique index on the field. See add_index for more information.

So what you have done, by creating a unique index on the database is right, though you may get database driver exceptions in your exception log. There are workarounds for this, such as detecting when inserts happen (through a double click).


The Michael Hartl Rails Tutorial covers uniqueness validation (re. the "email" field) here. It appears the full uniqueness solution is:

  1. Add the :uniqueness validation to the model.
  2. Use a migration to add the unique index to the DB.
  3. Trap the DB error in the controller. Michael's example is the Insoshi people_controller--search for the rescue ActiveRecord::StatementInvalid statement.

Re. #3, it looks like Michael just redirects to the home page on any DB statement exception, so it's not as complex (nor as accurate) as the parsing suggested by @Ransom Briggs, but maybe it's good enough if, as @Omar Qureshi says, the uniqueness constraint covers 99% of the cases.

0

精彩评论

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

关注公众号