为什么Save在这里失败,SQLite3 :: ConstraintException:列user_id不是唯一的:INSERT INTO“pins”?

时间:2013-11-25 08:46:32

标签: ruby sqlite devise ruby-on-rails-4 paperclip

我正在使用Devise和Paperclip和Rails 4 app。

我正在试图找出无法为同一用户添加其他引脚的原因。正如我从错误中理解的那样,它具有用户唯一性。我对吗?怎么解决?

登录后,我可以创建第一个带有图像和描述的引脚,但我无法创建第二个引脚。我收到了一个错误;

SQLite3::ConstraintException: column user_id is not unique: INSERT INTO "pins" ("created_at", "description", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)

这是终端日志:

Started POST "/pins" for 127.0.0.1 at 2013-11-25 03:32:11 -0500
Processing by PinsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxxxxx", "pin"=>{"image"=>#<ActionDispatch::Http::UploadedFile:000000000000 @tempfile=#<Tempfile:/var/folders/z0/7gq1xnhs0051g0>, @original_filename="cheer_up.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"pin[image]\"; filename=\"cheer_up.png\"\r\nContent-Type: image/png\r\n">, "description"=>"cheer up!"}, "commit"=>"Create Pin"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1
   (0.1ms)  begin transaction
Binary data inserted for `string` type on column `image_content_type`
  SQL (0.5ms)  INSERT INTO "pins" ("created_at", "description", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)  [["created_at", Mon, 25 Nov 2013 08:32:11 UTC +00:00], ["description", "cheer up!"], ["image_content_type", "image/png"], ["image_file_name", "cheer_up.png"], ["image_file_size", 211523], ["image_updated_at", Mon, 25 Nov 2013 08:32:11 UTC +00:00], ["updated_at", Mon, 25 Nov 2013 08:32:11 UTC +00:00], ["user_id", 6]]
SQLite3::ConstraintException: column user_id is not unique: INSERT INTO "pins" ("created_at", "description", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)
   (0.1ms)  rollback transaction
Completed 500 Internal Server Error in 6ms

ActiveRecord::RecordNotUnique (SQLite3::ConstraintException: column user_id is not unique: INSERT INTO "pins" ("created_at", "description", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)):
  app/controllers/pins_controller.rb:25:in `block in create'
  app/controllers/pins_controller.rb:24:in `create'

这是我的Pin模型。

class Pin < ActiveRecord::Base

  # associations
  belongs_to :user
  has_attached_file :image

  # validations
  validates_presence_of :description, :user_id
  validates_attachment :image, presence: true,
                              content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif' ] },
                              size: { less_than: 3.megabytes } 
end

Devise的用户模型

class User < ActiveRecord::Base

  # Virtual attribute for authenticating by either username or email
  # This is in addition to a real persisted field like 'username'
  attr_accessor :login

  has_many :pins

  #https://github.com/thoughtbot/paperclip#quick-start
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, #:recoverable
         :rememberable, :trackable, :validatable

  # https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-using-their-username-or-email-address#tell-devise-to-use-login-in-the-authentication_keys
  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["username = :value OR lower(email) = lower(:value)", { :value => login }]).first
    else
      where(conditions).first
    end
  end        
end

这是我的架构

ActiveRecord::Schema.define(version: xxxxxxxxxx) do

  create_table "pins", force: true do |t|
    t.string   "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
  end

  add_index "pins", ["user_id"], name: "index_pins_on_user_id", unique: true

  create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "username"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  add_index "users", ["username"], name: "index_users_on_username", unique: true

end

1 个答案:

答案 0 :(得分:1)

它失败了,因为您的数据库中有唯一性约束:

查看架构或迁移文件:

add_index "pins", ["user_id"], name: "index_pins_on_user_id", unique: true

如果你相信你不需要它,并且它似乎是错误的,因为has_many :pins模型中有User,你可以创建一个迁移来删除那个不必要的索引:

remove_index(:pins, :name => 'index_pins_on_user_id')