简体   繁体   English

Rails数据库唯一性验证不起作用

[英]Rails database uniqueness validation not working

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. 我有一个Rails应用程序,用户可以在其中创建一个新的供应商,以便在系统中使用。 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. 我的问题是由于某些原因Rails验证不能解决这个问题,因此应用程序抛出了异常,因为数据库查询失败了。 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: vendor.rb模型文件中的My Rails验证如下:

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. 注意uniqueness部分的差异。 Rails does care about case sensitivity by default, therefore my validation was not being ran every single time in my case. Rails默认情况下会关注区分大小写,因此在我的情况下,我的验证并没有每次都运行。

Hope this helps anyone else that comes across this! 希望这可以帮助遇到这个的任何人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM