【问题标题】:RoR | Best Practices when abstracting an Active Record回滚 |抽象 Active Record 时的最佳实践
【发布时间】:2012-06-02 03:00:45
【问题描述】:

我的任务是抽象/继承一个活动记录类。我正在制作一个博客,其中 post 是一个带有标题、slug 日期等的基础超级......所有你希望找到的多余的东西。

这里是事情的转折点,我想将 Post 子分类为许多其他子帖子类型,例如音频帖子、视频帖子、图片帖子、香草帖子。我认为你说对了。显然每个子类型都有自己的属性和成员。

  1. 除了为每个子帖子类型创建名称、slug 等之外,继承或可能接口基类的最佳实践是什么? (“我更喜欢组合而不是继承”)

  2. 一旦我弄清楚如何正确地抽象出我的模型,我想找出一些多态的方式来表达类似 Blog.find(1).posts 的内容并获取所有帖子类型的数组。

我意识到这可能不是以多态方式查询所有帖子类型的最佳性能,因此请随意寻找更好的方式。

【问题讨论】:

  • 为什么不直接使用一般的Post 模型并拥有type 字段?您想要图片帖子、音频帖子等单独的表格吗?

标签: ruby-on-rails ruby model-view-controller ruby-on-rails-3.2


【解决方案1】:

虽然我个人也更喜欢组合而不是继承,但 ActiveRecord 不喜欢。在这种情况下,如果您想使用 ActiveRecord 提供的工具,您应该查看Single Table Inheritance,它可以解决您的两个问题。但是,它确实使用了继承。

切换到非 ActiveRecord orm 可能会为您提供一种方法,而无需通过继承完成所有操作。我使用过DataMapper,它更喜欢组合,过去取得了成功,但它不像 ActiveRecord 那样功能丰富,可能无法满足您的需求。

【讨论】:

  • 我会听取您的建议并研究单表继承。
【解决方案2】:

除了单表继承,也可以考虑使用has_one关联。

你所有的子类型都有一个 post-info,它是一般的帖子名称、slug 等(并且一个 post-info 在多态上属于一个子类型)。

这样,您将拥有一个帖子信息表,以及每个子类型的表。

但是,在模型中你必须做更多的处理:

class PostInfo < ActiveRecord::Base
  belongs_to :post, :polymorphic => true
  # will need these 2 fields: :post_id, :post_type (might be AudioPost, ImagePost, etc)
end

class AudioPost < ActiveRecord::Base
  has_one :post_info, :as => :post

  # you may also want these:
  accept_nested_attributes_for :post_info
  delegate :name, :slug, :posted_at, :to => :post_info
end

所以现在如果你想获得所有的帖子,你可以:

Blog.find(1).post_infos

post_info.post # => audio_post, image_post, or whatever depending on post_type

如果您不想使用.post_infos,您也可以更改所有这些名称,例如:

class Post < ActiveRecord::Base
  belongs_to :actual_post # actual_post_id, actual_post_type
end

class AudioPost < ActiveRecord::Base
  has_one :post, :as => :actual_post
  accept_nested_attributes_for :post
  delegate :name, :slug, :posted_at, :to => :post
end

现在,你有:

posts = Blog.find(1).posts

actual_post = posts.first.actual_post # => an audio_post instance

actual_post.name # => same as actual_post.post.name, so you do not need the name field in the AudioPost model

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多