【问题标题】:Should I use DataMapper entities only for persistence purposes?我应该仅将 DataMapper 实体用于持久性目的吗?
【发布时间】:2016-10-21 11:13:45
【问题描述】:

我正在创建一个非 Rails 应用程序并将 DataMapper 用作 ORM。

对于将映射到 SQL 表的实体,我声明了包含 DataMapper::Resource 的类。

问题是。可以将这些类的实例用作普通对象(传递给方法、操作值等)吗?或者它们应该只用于持久化数据(例如在 Repository 类中)?

我是 Ruby 世界的新手,不知道约定。 如果我有一个用户实体,它有方法创建等,创建另一个类用户是个好主意,它只存储信息(将有状态 - 字段并且没有方法)? Java中POJO(Plain old java object)的类比?

【问题讨论】:

  • 视情况而定。你会用这些 PORO 做什么?
  • 例如,存储从用户那里检索到的信息。存储在会话中。等等(不同种类的非数据库持久化操作)

标签: ruby ruby-datamapper


【解决方案1】:

我可以看到为普通对象列表创建包装类有一些好处。正如您在评论中提到的,如果您想以不同的方式存储数据,那么编写不同的类很有用。

但是,对于典型的 DataMapper 或 ActiveRecord 用法,我认为为纯对象列表创建包装类并不常见,尤其是在您没有向集合中添加任何方法的情况下。它不常见的主要原因是 ActiveRecord 或 DataMapper 中的查询结果已经类似于数组。此外,通过将模型实例转换为哈希值,您并没有真正获得任何附加功能。让我举个例子:

# collections are array-like
User.all.map(&:name) == User.all.to_a.map(&:name)

# converting a record to a hash doesn't add much
user = User.first
user_hash = user.attributes 
user.name == user_hash[:name]

话虽如此,有一个警告,这与 ORM 中的可链接方法有关:

# this is valid chaining
User.all.where(name: "max")

# this raises a NoMethodError for 'where'
User.all.to_a.where(name: "max")

where 是 ORM 方法,而不是数组方法。因此,如果您将查询结果转换为数组,您将无法访问它。出于这个原因,区分数组和查询集合是很有用的。

但是,创建一个空的包装类到底能带来多少好处呢?

class RecordsInMemory
  def initialize(query_collection)
    @list = query_collection.map(&:attributes)
  end
end
records_in_memory = RecordsInMemory.new(User.all)
records_in_memory.list.map(&:name)

# versus ...

records_in_memory = User.all.map(&:attributes)
records_in_memory.map(&:name)

如果您认为从长远来看您会将方法添加到普通对象列表中,那么您应该将其放入一个类中。但除此之外,我认为使用明确命名的变量就足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-04
    • 2011-02-26
    • 2018-11-29
    • 2015-11-15
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 2015-08-12
    相关资源
    最近更新 更多