I am at a total loss with this one. I have a Rails application in which users may create a new vendor for use in the system. This vendor must have a unique name. As such we have a unique index on the database for this field as seen below:
create_table "vendors", force: :cascade do |t|
t.string "vendor_name", limit: 80, null: false
t.datetime "updated_at", null: false
end
add_index "vendors", ["vendor_name"], name: "vendor_name_UNIQUE", unique: true, using: :btree
My issue is that for some reason the Rails validation is not working with this, therefore the application is throwing an exception because the database query is failing. The exception is below:
ActiveRecord::RecordNotUnique in VendorsController#create
Mysql2::Error: Duplicate entry '3 logiq' for key 'vendor_name_UNIQUE': INSERT INTO `vendors` (`vendor_name`, `updated_at`) VALUES ('3 logiq', '2015-12-03 21:14:12')
My Rails validation in the vendor.rb model file is as follows:
validates :vendor_name, presence: true, uniqueness: true, length: { minimum: 5, maximum: 80 }
I know the validation is being run, because I still receive form errors for the length and presence checks. Unsure what I can do at this point. Have I missed something?
Below is my vendors controller code:
def create
@vendor = Vendor.new(vendor_params)
@vendor.comments.build(user_comment: comment_params[:new_comment], system_note: 'Created Vendor', user: current_user, user_agent: request.user_agent, resolution: comment_params[:screen_resolution])
respond_to do |format|
if @vendor.save
format.html { redirect_to vendors_path, notice: 'Vendor was successfully created.' }
format.json { render :show, status: :created, location: @vendor }
else
format.html { @new_item = true; render :new }
format.json { render json: @vendor.errors, status: :unprocessable_entity }
end
end
end
Vendor form view code:
<% if @vendor.errors.any? %>
<div>
<div class="alert alert-danger" role="alert" id="error_explanation">
<h4><strong><%= pluralize(@vendor.errors.count, "error") %></strong> prohibited this vendor from being saved:</h4>
<ul>
<% @vendor.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
The issue was in fact related to case sensitivity. The solution was to add a small bit to the validation line in the vendor model.
The previous validation line:
validates :vendor_name, presence: true, uniqueness: true, length: { minimum: 5, maximum: 80 }
Becomes:
validates :vendor_name, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 5, maximum: 80 }
Notice the difference in the uniqueness
part. Rails does care about case sensitivity by default, therefore my validation was not being ran every single time in my case.
Hope this helps anyone else that comes across this!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With