2

我目前正在用 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

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

4

1 回答 1

1

不幸的是,ActiveRecord 模式可能不是适合您的情况的最佳解决方案。Active Record 模式的定义说:

一个对象同时携带数据和行为。这些数据大部分是持久的,需要存储在数据库中。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 对象充当真实活动记录对象的代理,保留所有业务逻辑并隐藏持久性内容。

于 2013-02-19T18:01:31.360 回答