我在rails中构建了一个小型私人购物车,我使用devise进行身份验证,Postgres用于数据库。
现在我正在尝试从我的PG数据库中删除用户,rails会给我这个错误,而且我现在很丢失。
[1] pry(main)> User.destroy_all
User Load (1.7ms) SELECT "users".* FROM "users"
(0.8ms) BEGIN
SQL (7.4ms) DELETE FROM "users" WHERE "users"."id" = $1 [["id", 1]]
(0.3ms) ROLLBACK
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "orders" violates foreign key constraint "fk_rails_e3cb28f071" on table "order_items"
DETAIL: Key (id)=(1) is still referenced from table "order_items".
: DELETE FROM "users" WHERE "users"."id" = $1
from /Users/myname/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:602:in `exec_prepared'
我已在用户和订单表中更新了foreignKeys,如下面的迁移文件中所示
class UpdateForeignKey < ActiveRecord::Migration
def change
# remove the old foreign_key
remove_foreign_key :orders, :users
# add the new foreign_key
add_foreign_key :orders, :users, on_delete: :cascade
end
end
我试图从order_item表中删除Foreignkey但是控制台给了我这个错误
Table 'order_items' has no foreign key on column '_id'/Users/myname/Documents/Vefir/stores/brainstore/db/migrate/20160607140507_update_foreign_key_order_item.rb:4:in `change'
ArgumentError: Table 'order_items' has no foreign key on column '_id'
/Users/myname/Documents/Vefir/stores/brainstore/db/migrate/20160607140507_update_foreign_key_order_item.rb:4:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
我还在dependent: :destroy
和order.rb
模型中添加了user.rb
,但我不确定这是否正常。
有人能引导我走向正确的方向吗?我不知道我还能做什么?
下面的是user.rb,order.rb order_item.rb和schema.rb
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates_presence_of :name, :address, :city, :country, :postal_code
end
order.rb
class Order < ActiveRecord::Base
belongs_to :user, dependent: :destroy
has_many :order_items, dependent: :destroy
def total_price
order_items.inject(0) { |sum, item| sum + item.total_price }
end
end
order_item.rb
class OrderItem < ActiveRecord::Base
belongs_to :order, dependent: :destroy
belongs_to :product, dependent: :destroy
def total_price
self.quantity * self.product.price
end
end
schema.rb
ActiveRecord::Schema.define(version: 20160607135951) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "category_names", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "order_items", force: :cascade do |t|
t.integer "order_id"
t.integer "product_id"
t.integer "quantity"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "order_items", ["order_id"], name: "index_order_items_on_order_id", using: :btree
add_index "order_items", ["product_id"], name: "index_order_items_on_product_id", using: :btree
create_table "orders", force: :cascade do |t|
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "orders", ["user_id"], name: "index_orders_on_user_id", using: :btree
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.float "price"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "category_id", default: 1
end
add_index "products", ["category_id"], name: "index_products_on_category_id", using: :btree
create_table "users", force: :cascade 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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.string "name"
t.string "address"
t.string "phone"
t.string "postal_code"
t.string "country"
t.string "city"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_foreign_key "order_items", "orders"
add_foreign_key "order_items", "products"
add_foreign_key "orders", "users", on_delete: :cascade
add_foreign_key "products", "categories"
端
答案 0 :(得分:2)
对此的答案是进行另一次这样的迁移。
class UpdateForeignKeyOrderItem < ActiveRecord::Migration
def change
# remove the old foreign_key
remove_foreign_key :order_items, :orders
# add the new foreign_key
add_foreign_key :order_items, :orders, on_delete: :cascade
end
end