我正在尝试为我的项目创建“组件”,并且每个组件都属于四种类型(部分,组合,LearningIntentions或EssentialQuestion)之一。一个节是一个组件,可以包含多个组件,但是一个节不能包含一个节。
但是,当我运行自己的规范时,出现错误Expected Component to have a has_many association called components (no association called components)
。但是,当我将规范从section_spec.rb移到component_spec.rb时,它可以工作。这是怎么回事?
component.rb(模型):
class Component < ApplicationRecord
# == Constants =============================
TYPES = %w( Section Composition LearningIntentions EssentialQuestion )
# == Associations ==========================
belongs_to :project
belongs_to :section,
class_name: 'Component',
foreign_key: :section_id,
optional: true
# # == Validations ===========================
validates :type,
presence: true,
inclusion: { in: TYPES }
end
section.rb(模型):
class Section < Component
# == Associations ==========================
has_many :components,
class_name: 'Component',
foreign_key: :section_id
# == Validations ===========================
validates :section_id, presence: false
end
section_spec.rb:
RSpec.describe Section, type: :model do
subject! { build(:component, :section) }
# == Associations ==========================
it { is_expected.to have_many(:components) }
end
答案 0 :(得分:0)
但是当我将规范从section_spec.rb移到component_spec.rb
时,它可以工作
在我看来,rspec的位置并不是此处失败的原因。您做错了什么,就是在您的 section_spec.rb 中将一个Component
实例分配为subject
,因此,它希望关联:components
出现在该Component
实例。
将代码更改为下面的代码,并查看其是否有效:
RSpec.describe Section, type: :model do
subject { build(:section) }
it { is_expected.to have_many(:components) }
end
如果您要构建一个分配了其组件的Section
实例,请定义一个trait
并按以下方式使用它:
# Factory
factory :section do
trait :with_components do
after(:build) do |s|
# Modify this to create components of different types if you want to
s.components = [create(:component)]
end
end
end
# Rspec
subject { build(:section, :with_components) }
在您的Component
模型中,这种关联看起来很混乱:
belongs_to :section,
class_name: 'Component',
foreign_key: :section_id,
optional: true
您确定要将一个Component
实例链接到另一个Component
实例吗?
同时,您想使用外键:section_id
而不是常规的component_id
吗?
您的应用程序中已经有一个模型Section
。这可能会引起混乱。见下文:
component = Component.first
component.section
=> #<Component id: 10001> # I would expect it to be a `Section` instance looking at the association name