【问题标题】:Difficulty structuring a relationship between a parent model and multiple polymorphic children models难以构建父模型和多个多态子模型之间的关系
【发布时间】:2013-07-06 18:18:21
【问题描述】:
  • 我有User 那个has_one :profile

  • 我有 Profile,它有一些属性,每个个人资料都有共同点。

  • 我希望一些Users 具有Coach_profileStudent_profileSub_profile

我打算在Profile 和这些Sub_profiles 之间使用多态关系,以允许每个User 拥有它们的基本Profile,然后拥有它们相应的Sub_profile

这就是我纠结的地方。

我很难确定 belongs_tohas_one :profileas: :sub_profile polymorphic: truedependent: :destroy 方法都属于哪里。

此时,了解如何构建此类解决方案的人将能够写出这些关系 - 但我觉得我需要解释我的(有缺陷的)推理,以便以我的方式构建它,以便有人可以帮助我明白为什么我做错了。

我的问题:

同样重要的是要注意,以防不明显,以下代码结构不会产生实际工作所需的代码(如上所述)。我遇到如下错误:

> Coach_profile.create
RuntimeError: Circular dependency detected while autoloading constant Coach_profile

并尝试类似:

> user.profile.build_coach_profile

结果为@​​987654340@

我的代码背后的原因:

按照我现在构建代码的方式,我无法弄清楚如何使用 build_sub_profilesbuild_coach_profile(例如),因为我设计关系的方式不允许这样做。

  • 我想要我的Profilesbelongs_to :sub_profile, polymorphic: true, dependent: :destroy,因为我希望在我的profile 表中有一个sub_profile_id,这样我就可以
    • 参考profile.sub_profile
    • 有不同类型的sub_profiles
    • profile 被销毁时,销毁关联的 sub_profiles
  • 我想要我的sub_profilescoachstudent 个人资料)到has_one :profile, as: :sub_profile
    • 所以我的每个sub_profile 类型都可以通过我的profile 表的sub_profile_idsub_profile_type 字段属于profile

用户.rb

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_one :profile

end

profile.rb

#  id               :integer          not null, primary key
#  user_id          :integer
#  first_name       :string(255)      not null
#  middle_name      :string(255)
#  last_name        :string(255)      not null
#  phone_number     :integer
#  birth_date       :date             not null
#  created_at       :datetime
#  updated_at       :datetime
#  sub_profile_id   :integer
#  sub_profile_type :string(255)
#

class Profile < ActiveRecord::Base
    belongs_to :user
    belongs_to :sub_profile, polymorphic: true, dependent: :destroy

    validates_presence_of :first_name, :last_name, :birth_date
    validates_length_of :phone_number, {is: 10 || 0}
end

coach_profile.rb

#  id             :integer          not null, primary key
#  coaching_since :date
#  type_of_coach  :string(255)
#  bio            :text
#  created_at     :datetime
#  updated_at     :datetime
#

class CoachProfile < ActiveRecord::Base
  has_one :profile, as: :sub_profile
end

student_profile.rb

#  id                     :integer          not null, primary key
#  playing_since          :date
#  competition_level      :string(255)
#  learn_best_by          :string(255)
#  desirable_coach_traits :text
#  goals                  :text
#  bio                    :text
#  created_at             :datetime
#  updated_at             :datetime
#

class StudentProfile < ActiveRecord::Base
  has_one :profile, as: :sub_profile
end

我在这里错误地处理了一些事情。如何正确设置多个sub_profiles 和父profile 之间的多态关系?

【问题讨论】:

  • 只需将 Profile 和 SubProfile 之间的 belongs_to has_one 反向,您将在几分钟内弄清楚其他所有内容。
  • 我将子配置文件更改为 belongs_to :profile, polymorphic: true 而不是 has_one :profile, as: :sub_profile 并将 as: :sub_profile 部分移至配置文件中的 has_one 行,因为我似乎无法使用 as: :model on一个belongs_to 电话。然后,我将 belongs_to :profile, as: :sub_profile 添加到了 sub_profiles 的迁移中。尝试Coach_profile.create 时仍然出现循环依赖错误,我想我仍然缺少一些东西。如果您有任何意见,那就太好了,但我会继续挖掘。

标签: ruby-on-rails activerecord polymorphic-associations ruby-on-rails-4


【解决方案1】:

你确定关系是这里的问题吗?你说你正在调用Coach_profile.create,但rails 类名应该像CoachProfile 一样没有下划线,看起来你的就是这样。 CoachProfile.create 会报同样的错误吗?

您可能只是混淆了使用时自动加载源文件的 Rails 代码。

此外,无法按照 Michael 的建议切换到 Profile has_one :sub_profile,因为它无法确定要在哪个表中查找子配置文件。在多态关系中,类型列处于打开状态与外键相同的表。

【讨论】:

  • CoachProfile.create 没有给出同样的错误。事实上,它创建了对象。现在要弄清楚如何正确调用 profile.build_coach_profile 的内容。
  • 你可以自己写一个 build_coach_profile 方法;它不会为您生成(请参阅auto-generated methods)。你只需要做profile.sub_profile = CoachProfile.build
  • 您完全正确-感谢您提供自动生成的方法链接(我还没有想到一些 Rails 的“魔法”)。现在享受将控制器包装在这一切周围的乐趣 - 然而,再一次,可能比我想象的要容易。
猜你喜欢
  • 2011-11-25
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2017-06-26
  • 2021-05-16
  • 2023-03-27
相关资源
最近更新 更多