2

也许 STI 不是我想要的,我愿意接受所有建议,但为了这个问题,让我们假设以下现实世界的情况:

您希望您的应用程序为不同的邮件供应商提供 API 数据。使用 STI,您有以下模型

class MailSetting < ActiveRecord::Base
belongs_to :user

end


class MailChimp < MailSetting

end

class AWeber < MailSetting

end

class PostageApp < MailSetting

end

现在让我们启动一些控制台操作:


user = User.first
setting = user.create_mail_setting(:type => "MailChimp")

好的,现在您要添加 API 密钥设置。MailChimp 只使用一个 api_key。Aweber 可以使用 api_key 和签名,而 Postageapp 使用 api_key 和令牌系统。

您会扩展每个子类以包含数据库中所需的任何列吗?你会一起废弃 STI 并让常规类说,MailChimp继承自 AR 吗?

我对 STI 的理由是我知道我的所有用户都会有一个 MailSetting,它是随着时间的推移可能会扩展的类型。但是,我发现以这种方式扩展这些子类很痛苦,因为你不能在user.mail_setting.connect不知道它们来自哪个子类的情况下做一些事情,然后,我需要什么来连接这些人?

想法?

4

3 回答 3

3

您应该使用多态类而不是 STI

UPD

一些链接:

更新 2

想象一下,我们需要 Post 模型。我们有继承自 Post 的文章和主题。

rails g model Post title:string body:text content_type:string content_id:integer

title主题和body文章的常见字段也是如此。user_id现在让我们在主题和link文章中创建具有字段的其他模型

rails g model Topic user_id:integer
rails g model Article link:string

现在我们将编辑模型:

class Post < ActiveRecord::Base
  belongs_to :content, :polymorphic => true, :dependent => :destroy
end

class Topic < ActiveRecord::Base
  has_one :post, :as => :content, :dependent => :destroy
end

class Article < ActiveRecord::Base
  has_one :post, :as => :content, :dependent => :destroy
end

它可能非常复杂,但是这样挖掘:)

于 2011-02-08T21:00:10.310 回答
3

您可以考虑使用store_accessor来自 的方法ActiveRecord::Store

这里给出的 STI 存储方法演示了如何为各个子类提供不同的访问器,这些访问器被序列化到超类的单个列中。

如果您使用的是 PostgreSQL >= 9.2,那么这与它的 JSON 类型完美配合,如果不是,那么您可以让 Rails 进行序列化(通过使用store而不是store_accessor.

TLDR(假设 PostgreSQL >= 9.2):

添加迁移:

add_column :mail_settings, :vendor_settings, :json

在子类中定义相关属性:

class MailChimp < MailSetting
    store_accessor :vendor_settings, :api_key
    validates :api_key, presence: true
end 
于 2015-05-04T22:07:44.027 回答
0

在我看来,您的架构足够无形,您最好使用无架构数据库。也许是基于“NoSQL”文档的解决方案之一?这样您就可以随意在记录中添加和删除字段。

于 2011-02-09T09:44:58.673 回答