【问题标题】:How to inherit from models in Rails, where one type extends another without intertwining如何从 Rails 中的模型继承,其中一种类型扩展另一种而不交织
【发布时间】:2012-02-11 19:38:59
【问题描述】:

我知道这方面的帖子数量,但我仍然不知道该怎么做。我有一个模型“InspirationItem”,它基本上是一篇博客文章。现在我还想要第二个模型,“Special”。特价商品就像灵感物品,但它们具有额外的属性,例如“摘录”和“主题”。所以我想扩展“InspirationPost”模型。

我尝试创建一个模型“Post”,它同时扩展了“InspirationItem”和“Special”,但“InspirationItem”并没有真正添加任何属性。然后,我从 InspirationItem/Special 创建一个“has_one”关系,并尝试使用“delegate”来处理“Post”模型中的所有逻辑。然而,这根本不像我期望的那样工作。

这是我的一些代码。这将是我的灵感项目:

class InspirationItem < ActiveRecord::Base
    has_one :post, :as => :item

    delegate            :title, :title=,
                        :body, :body=,
                        :category_names, :category_names=,
                        :hide_from_overview, :hide_from_overview=,
                        :to => :post, :allow_nil => true

end

这是一个简短的帖子:

class Post < ActiveRecord::Base

    attr_accessible :title, :body, :embed, :hide_from_overview, :visual, :thumbnail, :category_names
    # All sorts of logics
end

重要的是我不希望 InspirationItem.all 也返回 Specials,这就是我使用 Post 模型的原因。我还希望常规错误处理适用于所有模型。提前致谢!

【问题讨论】:

  • 你研究过单表继承吗?这可能比尝试通过关系将 Post 模型包含在 InspirationItem 中更有意义。
  • 是的,我有,但是 Special 的属性比 Inspiration 多很多,所以我认为 Inspiration 实例有这么多空列会很丑。
  • 好吧,我最终听从了你的建议。现在不再创建关系,而是使用 posts 表。
  • “过早的优化是万恶之源” - Donald Knuth。除非空列对您来说是个问题,否则请选择一组易于编码的模型。如果从长远来看,稀疏数据库成为问题,您可以随时尝试在数据库中解决问题。
  • 这样的愿望;)我已经像这样构建它,就像一个魅力。谢谢。

标签: ruby-on-rails inheritance activerecord associations


【解决方案1】:

如果你想要一个模型的 ActiveRecord 子类,但不希望父类搜索任何子类,那么这样的方法应该可以工作(我将使用你的 InspirationItem 类):

class InspirationItem < ActiveRecord::Base
  def self.descendants
    super.reject {|klass| klass == Special}
  end
end

class Special < InspirationItem
end

这有点老套,但会强制 ActiveRecord 仅在您搜索 InspirationItem.all 时返回 InspirationItems。这不应该影响验证。

编辑:回复:这些表会是什么样子。

create_table :inspiration_items do |t|
  t.string :type # needed for the Single Table Inheritance mechanism
  # whatever other columns you need for InspirationItems
end

【讨论】:

  • 看起来不错,在这种情况下我的桌子会是什么样子?
  • 我刚刚用 InspirationItems 类的表格外观更新了我的答案。由于 Special 将是 InspirationItem 的子类,因此它们将使用相同的数据库表。
  • 这太好了,谢谢。我仍然创建了一个资源 Post,而不是 self.desendants 魔法,并且 InprirationItem 和 Special 都继承自它。这样,我总是可以选择 Post.all,这是一个将来会变得相关的场景。
  • 是的,这很神奇,我很高兴你能够避免它。为两者使用一个共同的超类绝对是一个更好的主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 2021-06-13
  • 2017-04-16
  • 2020-12-30
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多