STI 和扩展子类以包括“额外”数据库中的列?

发布于 2024-10-16 15:04:29 字数 815 浏览 3 评论 0 原文

也许 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅蓝的眸勾画不出的柔情 2024-10-23 15:04:29

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

UPD

一些链接:

UPD 2

想象一下,我们需要 Post 模型。我们有继承自 Post 的 Article 和 Topic。

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

所以 titlebody 是 Topic 和 Article 的公共字段。现在让我们使用主题中的 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

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

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.

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

So title and body are common fields for Topic and Article. Lets now create other models with user_id field in Topic and link in Article

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

Now we will edit models:

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

It can be quite complicated, but digg this way :)

戒ㄋ 2024-10-23 15:04:29

您可以考虑使用 ActiveRecord: 中的 store_accessor 方法:存储

此处给出的 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 

You may consider using the store_accessor method from ActiveRecord::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 of store_accessor.

TLDR (assuming PostgreSQL >= 9.2):

Add a migration:

add_column :mail_settings, :vendor_settings, :json

Define relevant attributes in sub-classes:

class MailChimp < MailSetting
    store_accessor :vendor_settings, :api_key
    validates :api_key, presence: true
end 
奈何桥上唱咆哮 2024-10-23 15:04:29

在我看来,您的模式足够无形,您最好使用无模式数据库。也许是基于“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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文