【发布时间】:2017-09-22 13:10:06
【问题描述】:
我在使用 Rails 5.1 中的自定义名称时遇到了 has_many 关系问题
我有一个包含用户、目录中的项目和收藏夹的域模型。一个用户可以拥有许多最喜欢的项目。
收藏夹也可以有其他项目。
我将其作为修改现有应用的学习练习,因此我已通过专用迁移添加每个关系:
class AddUserToFavourite < ActiveRecord::Migration[5.1]
def change
add_reference :favourites, :user, foreign_key: true
end
end
class AddItemToFavourite < ActiveRecord::Migration[5.1]
def change
add_reference :favourites, :item, foreign_key: true
end
end
class AddAdditionalItemsToFavourite < ActiveRecord::Migration[5.1]
def change
add_reference :favourites, :additional_item, foreign_key: { to_table: :items }
end
end
生成的架构是:
ActiveRecord::Schema.define(version: 20170921111049) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "favourites", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.bigint "item_id"
t.bigint "additional_item_id"
t.index ["additional_item_id"], name: "index_favourites_on_additional_item_id"
t.index ["item_id"], name: "index_favourites_on_item_id"
t.index ["user_id"], name: "index_favourites_on_user_id"
end
create_table "items", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "favourites", "items"
add_foreign_key "favourites", "items", column: "additional_item_id"
add_foreign_key "favourites", "users"
end
这是我的模型的样子:
# user.rb
class User < ApplicationRecord
has_many :favourites
end
# item.rb
class Item < ApplicationRecord
belongs_to :additional_item, class_name: 'Favourite', optional: true
end
# favourite.rb
class Favourite < ApplicationRecord
belongs_to :user
belongs_to :item
has_many :additional_items, class_name: 'Item', foreign_key: 'additional_item_id'
end
这是我对Favourite 的规范:
# favourite_spec.rb
require 'rails_helper'
RSpec.describe Favourite, type: :model do
it { should belong_to :user }
it { should belong_to :item }
it { should have_many(:additional_items).with_foreign_key('additional_item_id') }
it 'can be created with no additional items' do
expect(Favourite.create!(name: 'Name', user: User.create!, item: Item.create!).additional_items).to be_empty
end
end
如果我运行测试,我会收到此错误:
ActiveRecord::StatementInvalid:
PG::UndefinedColumn: ERROR: column items.additional_item_id does not exist
LINE 1: SELECT 1 AS one FROM "items" WHERE "items"."additional_item...
^
: SELECT 1 AS one FROM "items" WHERE "items"."additional_item_id" = $1 LIMIT $2
我了解错误的含义。表 items 没有 additional_item_id 列。您也可以在架构中看到它。
我不明白为什么它应该在那里?收藏夹表中的外键还不够吗?
我在编写迁移或模型中的关系时做错了什么?
我对 Rails 和 DB 理论和设计非常生疏,因此请随时指出我犯的任何愚蠢错误。谢谢:)
【问题讨论】:
标签: ruby-on-rails activerecord ruby-on-rails-5 ruby-on-rails-5.1