【发布时间】:2016-02-11 10:09:20
【问题描述】:
我正在尝试创建一个 ORM 来包装 DynamoDB (NoSQL) 查询。此 ORM 由存储在 DynamoDB 中的模型继承。实际上是ActiveRecord的风格:
class User < ActiveRecord::Base; end
变成
class User < DynamOrm; end
require 'aws-sdk'
class DynamOrm
CLIENT = Aws::DynamoDB::Client.new
def find(key, options = {})
query = CLIENT.get_item({
table_name: 'my_table',
key: key,
consistent_read: true,
return_consumed_capacity: "INDEXES"
}.merge(options))
if query.item.nil?
raise 'NO ITEM FOUND'
else
self.new(query.item)
end
end
end
完成后,我不用担心通过我的 ORM 查询我的 DynamoDB 数据库。
User.find({ id: 52 }) # => #<User:0x007fc5bc8a64a0>
它返回我的User 的一个实例。我想链接一个名为filter 的方法。像这样:
User.find({ id: 52 }).filter({ gender: 'male' })
为此,我没有在find 方法中返回实例,而是将实例存储在一个变量中,然后返回Class。在我的filter 类方法中,我返回User 实例。
class DynamOrm
# [...]
def self.find(key, options = {})
# [...]
if query.item.nil?
raise 'NO ITEM FOUND'
else
@result = self.new(query.item)
self
end
end
def self.filter(filters)
#
# APPLY MY FILTERS ON `@result`
#
return @result
end
end
我有时必须使用filter,但有时不用。与ActiveRecord 一样,有时我将不得不使用order 或limit,但并非总是如此。所以,当我只想使用find 时,它会返回一个类而不是一个实例。一个简单的User.find({ id: 1 }) 将返回类User。
如何重现 AR 方式,即直接在我的模型 (@user = User.find()) 上调用 ORM 并获取此模型的实例 @user.inspect # => #<User:0x007fc5bc8a64a0 @id=1, @gender="male" >?
【问题讨论】:
-
我很困惑,为什么你使用
find方法从数据库中获取1条记录,然后你想按性别过滤呢?过滤器仅在对多条记录调用时才有意义,例如在来自where方法的结果上 -
无论如何,在我关于 DynamoDB 约束的用例中,这是有充分理由的。但是您可以将
find转置为where,这不会改变我的需求:-) -
然后你可以做出类似 AR 的行为,当在 AR 中调用
where时,你会返回ActiveRecord::Relation,然后你可以调用order,sort,group_byans so在。它不返回User实例或User类 -
谢谢 Nermin。我可以问你一个例子吗?
-
这很相关@AndreyDeineko
标签: ruby chaining method-chaining chain