也许 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 并只创建从 AR 继承的常规类(例如 MailChimp
)吗?
我对 STI 的推理是,我知道我的所有用户都会有一个 MailSetting,这种类型可能会随着时间的推移而扩展。但是,我发现以这种方式扩展这些子类很痛苦,因为您无法在不知道它们来自哪个子类以及我需要什么的情况下执行诸如 user.mail_setting.connect
之类的事情连接这些人?
想法?
Maybe STI isn't what I want, and I'm open to all suggestions, but for the sake of this questions let's assume the following real world situation:
You want your app to house API data for different Mail Vendors. Using STI, you have the following models
class MailSetting < ActiveRecord::Base
belongs_to :user
end
class MailChimp < MailSetting
end
class AWeber < MailSetting
end
class PostageApp < MailSetting
end
Now let's pull up some console action:
user = User.first
setting = user.create_mail_setting(:type => "MailChimp")
Ok, now you want to add the API key settings. MailChimp just uses an api_key. Aweber may user an api_key and signature, and Postageapp, say, uses an api_key and token system.
Would you extend each subclass to include whatever columns you needed in the database?
Would you scrap STI all together and just make regular classes say, MailChimp
, that inherits from AR?
My reasoning for STI was that i know all of my users will have a MailSetting, it's the type that may expand over time. However, i find it a pain in the butt to extend these subclasses this way cause you can't do things like user.mail_setting.connect
without knowing what subclass they are from, and then, what i needed to connect these guys?
Thoughts?
发布评论
评论(3)
您应该使用多态类而不是 STI
UPD
一些链接:
UPD 2
想象一下,我们需要 Post 模型。我们有继承自 Post 的 Article 和 Topic。
所以
title
和body
是 Topic 和 Article 的公共字段。现在让我们使用主题中的user_id
字段和文章中的link
创建其他模型现在我们将编辑模型:
它可能非常复杂,但这样挖掘:)
You should use Polymorphic classes instead of STI
UPD
some links:
UPD 2
Imagine, we need Post model. And we have Article and Topic that inherit from Post.
So
title
andbody
are common fields for Topic and Article. Lets now create other models withuser_id
field in Topic andlink
in ArticleNow we will edit models:
It can be quite complicated, but digg this way :)
您可以考虑使用
ActiveRecord: 中的
。store_accessor
方法:存储此处给出的 STI 存储方法演示了如何为个人子提供类不同的访问器,这些访问器被序列化到超类的单个列中。
如果您使用的是 PostgreSQL >= 9.2,那么这与其 JSON 类型完美配合,如果没有,那么您可以让 Rails 进行序列化(通过使用
store
而不是store_accessor
.TLDR(假设 PostgreSQL >= 9.2):
添加迁移:
在子类中定义相关属性:
You may consider using the
store_accessor
method fromActiveRecord::Store
.The STI store approach given here demonstrates how you can give individual sub-classes different accessors, which are serialized in to a single column on the super-class.
If you're using PostgreSQL >= 9.2 then this works perfectly with its JSON type, if not then you can let Rails do the serializing (by using
store
instead ofstore_accessor
.TLDR (assuming PostgreSQL >= 9.2):
Add a migration:
Define relevant attributes in sub-classes:
在我看来,您的模式足够无形,您最好使用无模式数据库。也许是基于“NoSQL”文档的解决方案之一?这样您就可以根据需要在记录中添加和删除字段。
It looks to me like your schema is sufficiently formless that you'd be better off using a schema-free database. One of the "NoSQL" document based solutions, perhaps? That way you can add and remove fields to your records as you please.