如何在ActiveRecord中分离持久性?

时间:2013-02-19 16:49:25

标签: ruby-on-rails persistence abstraction rails-activerecord

我目前在Ruby(不是Rails)中构建一个应用程序,它使用ActiveRecord作为ORM,使用sqlite作为数据库。

示例代码,只是为了澄清我的问题:

class User < ActiveRecord::Base
  has_many :logins, :foreign_key => :user_id
  has_many :categories, :foreign_key => :user_id
  has_many :news, :foreign_key => :user_id
  has_many :settings, :foreign_key => :user_id

  class << self
    def get_user_by_id(id)
      find(id)
    end

    def insert(username, password)
      create(:username => username, :password => password)
    end
  end
end

代码(关系,模型等)暂时并不复杂。但是,当我的模型开始变大时,我不想在同一个类中混合业务逻辑和持久性逻辑。我希望能够更改我的持久性方法(文件,内存,其他数据库orm)。有没有确定的方法来达到这个目的?我在Rails中看到,“瘦瘦的控制器,胖模型”很常见,但我正在寻找解决方法。

1 个答案:

答案 0 :(得分:1)

不幸的是,ActiveRecord模式可能不是适合您情况的最佳解决方案。 The definition of the Active Record pattern说:

  

对象包含数据和行为。大部分数据都是   持久性的,需要存储在数据库中。 Active Record使用   最明显的方法是将数据访问逻辑放在域中   宾语。这样所有人都知道如何读取和写入数据   并从数据库。

也许您可能希望查看Data Mapper模式(以及Data Mapper ORM),它专门用于分离业务逻辑和持久性。

那就是说,如果你真的必须使用ActiveRecord,我会投入一些组合,比如:

class UserRepository < ActiveRecord::Base
  # all the persistence stuff goes in here
end

class User
  def initialize(login, repository=UserRepository)
    @repository = repository
    @user = @repository.find_by_login(login)
  end

  def instanography
    #complicated business logic
  end

  def method_missing(m, *args, &block)
    @user.send(m, *args, &block)
  end
end

如上例所示,我将使User对象充当真实活动记录对象的代理,保留所有业务逻辑并隐藏持久性内容。