我是否应仅将DataMapper实体用于持久性目的?

时间:2016-10-21 11:13:45

标签: ruby ruby-datamapper

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

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

的类

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

我是Ruby世界的新手,并不了解惯例。 如果我有一个User实体,其中有方法创建,所有等等,那么创建另一个类User是一个好主意,它只会存储信息(将有状态字段而没有方法)? Java中POJO(普通旧java对象)的类比?

1 个答案:

答案 0 :(得分:0)

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

对于典型的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)

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