ActiveRecord::AssociatedObject 使用指南

ActiveRecord::AssociatedObject 使用指南

active_record-associated_object Extract Collaborator Objects from your Active Records, a new concept called Associated Objects active_record-associated_object 项目地址: https://gitcode.com/gh_mirrors/ac/active_record-associated_object

1. 项目介绍

ActiveRecord::AssociatedObject 是一个新的领域概念,旨在帮助你从 Active Record 模型中提取协作对象。这些对象本质上是无状态的 Ruby 对象(POROs),你可以将它们与 Active Record 模型关联,以获得更简洁的代码和自动化的应用/模型组织。

在 Rails 应用中,模型往往会变得非常庞大,Ruby 社区的常见解决方案是使用服务对象(Service Objects)。然而,服务对象有时会变成另一个杂乱的抽屉,无法帮助你构建和形成领域模型的概念。ActiveRecord::AssociatedObject 正是为了解决这个问题而设计的。

2. 项目快速启动

安装

首先,通过 Bundler 将 gem 添加到你的 Gemfile 中:

$ bundle add active_record-associated_object

如果你不使用 Bundler,可以通过以下命令安装 gem:

$ gem install active_record-associated_object

使用示例

假设你有一个 Post 模型,它封装了一个博客文章的内容管理系统:

# app/models/post.rb
class Post < ApplicationRecord
end

你已经确定在发布文章时需要执行多个操作,但这些行为应该放在哪里呢?如果将它们放在 Post 模型中,可能会变得混乱。如果使用经典的服务对象,你只能访问 def call 方法,这可能不够灵活。

相反,你可以识别一个 Publisher 协作对象,这是一个处理发布的 Ruby 类。你可以将其放置在 Post:: 命名空间中,以自动帮助表示该对象属于并协作于 Post

# app/models/post/publisher.rb
class Post::Publisher < ActiveRecord::AssociatedObject
end

然后在 Post 模型中声明它:

# app/models/post.rb
class Post < ApplicationRecord
  has_object :publisher
end

现在,你可以通过 publisher 方法访问 PostPublisher 对象:

post = Post.new
post.publisher # 返回 Post::Publisher 实例

3. 应用案例和最佳实践

测试关联对象

在测试中,遵循 app/models/post.rbapp/models/post/publisher.rb 的命名结构,并添加 test/models/post/publisher_test.rb。然后像测试其他对象一样测试它:

# test/models/post/publisher_test.rb
class Post::PublisherTest < ActiveSupport::TestCase
  setup do
    @publisher = posts(:one).publisher
  end

  test "publish updates the post" do
    @publisher.publish
    assert @publisher.post.reload.published?
  end
end

扩展 Active Record

你可以在关联对象中使用 extension 块来扩展 Active Record 模型:

class Post::Publisher < ActiveRecord::AssociatedObject
  extension do
    has_many :contracts, dependent: :destroy do
      def signed
        all(&:signed?)
      end
    end

    after_create_commit :publish_later, if: -> { contracts.signed? }

    private

    def publish_later
      publisher.publish_later
    end
  end
end

4. 典型生态项目

ActiveJob::Performs

如果你还捆绑了 active_job-performs,你可以使用 performs 宏来简化 Active Job 的样板代码:

gem "active_job-performs"
gem "active_record-associated_object"
class Post::Publisher < ActiveRecord::AssociatedObject
  performs queue_as: :important
  performs :publish
  performs :retract

  def publish
    # 发布逻辑
  end

  def retract(reason:)
    # 撤回逻辑
  end
end

Kredis 集成

ActiveRecord::AssociatedObject 还支持 Kredis 集成,因此你可以在关联对象中使用任何 kredis_* 类型:

class Post::Publisher < ActiveRecord::AssociatedObject
  kredis_datetime :publish_at
end

结语

ActiveRecord::AssociatedObject 通过聚焦于命名空间协作对象的概念,帮助你更好地组织和编写应用。通过使用这个 gem,你可以看到在构建新功能时如何改变你的应用结构和编写方式。

active_record-associated_object Extract Collaborator Objects from your Active Records, a new concept called Associated Objects active_record-associated_object 项目地址: https://gitcode.com/gh_mirrors/ac/active_record-associated_object

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祁婉菲Flora

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值