Je ne parviens pas à avec une relation has_many
avec le nom personnalisé dans Rails 5.1Rails 5, relation has_many avec échec du test de nom personnalisé
J'ai un modèle de domaine avec les utilisateurs, les éléments d'un catalogue et favoris. Un utilisateur peut avoir beaucoup d'objets favoris.
Un favori peut également contenir des éléments supplémentaires.
Je fais cela comme un exercice d'apprentissage sur la modification des applications exisiting, donc je l'ai ajouté chaque relation avec une migration dédiée:
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
Le schéma résultant est:
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
Cette est comment mes modèles ressemblent:
# 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
Ceci est ma spécification pour 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
Si je lance les tests que je reçois cette erreur:
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
Je comprends ce que signifie l'erreur. La table items
n'a pas de colonne additional_item_id
. Vous pouvez également le voir dans le schéma.
Ce que je ne comprends pas c'est pourquoi devrait-il être là? La clé étrangère sur la table Favoris n'est-elle pas suffisante? Est-ce que je fais quelque chose de mal dans la façon dont j'ai écrit la migration ou les relations dans les modèles?
Je suis très rouillé avec Rails et la théorie et la conception de DB, alors n'hésitez pas à signaler toute erreur stupide que j'ai faite. Merci :)