我一直试图找到一个解决方案2天就没有了。
我有一个名为Course
的模型,其中包含以下列:
create_table :courses do |c|
c.integer :member_limit
c.string :color
c.float :rating
c.timestamps
end
我还有一个Content
模型,其中Course
的列受益,但也有益于我数据库中的其他模型,例如:
create_table :contents do |c|
c.references :contentable, polymorphic: true, index: true
c.string :title
c.text :description
c.text :script
c.string :cover
c.string :media_type
...
c.integer :creator_id, index: true, foreign_key: :user_id
end
我无法设置Course < Content
,因为我会丢失课程内部的列,例如member_limit
等等,所以我选择了Polymorphic。不过,我希望避免拨打course.content.title
,只需撰写course.title
,但也可以同样方式访问course.member_limit
,并使用course.save
保存这两个字段。
您建议采用哪种最佳方法?
目前的结构。
课程:
class Course < ApplicationRecord
has_one :content, as: :contentable, dependent: :destroy
after_initialize :init
def init
if self.new_record?
self.content ||= build_content
end
end
end
内容:
class Content < ApplicationRecord
belongs_to :creator, optional: true, class_name: 'User'
end
答案 0 :(得分:0)
我认为你的前提是错误的,因为不应该做你想做的事情。我解释一下:
你想要什么,可以通过这样的辅助方法来完成:
class Course < AR
def title
content.title
end
end
哪个是丑陋的,违反了有史以来编写的所有编码论点,以及它的不良做法。但是,除了一些可以避免必须逐个编写辅助方法的元魔法(注意我说写,因为最终,它们将被实现),最终结果必须是这样的。没有其他办法可以做到这一点。所以我的答案是,不要这样做。
理解多态并不容易。它易于实现但很难知道何时。你想要一个包含几个其他资源的列的抽象框,因为。在创建“......内容模型,其中包含课程受益但也有益于我的数据库中的其他模型的内容模型”时,您没有给出任何理由。我问。为什么?有什么好处?为什么这样?它的运作和预期一样好吗?它更容易使用和扩展吗?它被封装了吗?它是干燥的,休息的,固体的,以及最近使用的所有其他首字母缩略词吗?
简短的回答是否定的。事实并非如此。所以不要这样做。让课程课程有标题。如果另一张桌子也有标题,那又怎样?你知道世界上有多少个表有“名称”栏吗?如果我们都希望以你的方式实现它,我们会有类似的东西:
class School < Ar
belongs_to :name
def full_name
name.body
end
end
class Student < Ar
belongs_to :name
def full_name
name.body
end
end
显然没用。因此,如果它对一列无用,为什么它对更多列有用呢?
结论:
在STI中,“内容”表中的所有列都将包含所有要成为课程的其他表的列。对于资源来说,这是一种很好的做法,基本上,数据是相同的或几乎(看起来很像你所描述的),并且你不想在所有子类中重复代码。通过在每个子类中重复父类代码,可以在没有STI的情况下实现所有STI。
那么,简短的回答(有点晚了没有?)。不,你不能做你想做的事。你可以
def title=
等方法。你要重新实施所有这些吗?对不起长度,只看到这个错误太多次了。