我最近写了ParseResource,它是Parse.com's REST api的Ruby API包装器。
以下是一些基本用法:
class Post < ParseResource
fields :title, :author, :body
end
p = Post.create(:title => "Hello world", :author => "Alan", :body => "ipso lorem")
该项目相当年轻,我真正想要实现的功能是关联。像这样:
class Author < ParseResource
has_many :posts
fields :name, :email
end
class Post < ParseResource
belongs_to :author
fields :title, :body
end
a = Author.create(:name => "Alan", :email => "alan@example.com")
p = Post.create(:title => "Associated!", :body => "ipso lorem", :author => a)
p.author.class #=> Author
p.author.name #=> "Alan"
a.posts #=> an array of Post objects
我喜欢任何已经实现类似功能的人以及掌握Parse REST API的人的任何建议,指示和陷阱。
答案 0 :(得分:3)
我发现使用DataMapper(http://datamapper.org)很容易让它几乎适用于任何数据存储区。您可以编写与数据存储区对话的适配器,然后直接使用DataMapper的所有功能,就像数据在SQL中一样。这是一个链接,解释了一些关于编写这些适配器之一的信息。 http://www.killswitchcollective.com/articles/55_datamapperabstractadapter_101
答案 1 :(得分:0)
看起来Parse的工作原理是将对象存储为键值对的散列。所以基本上你有一个id,然后是一个哈希,你可以让你的想象力运行。
要执行ActiveRecord之类的关联,您需要主键(例如,Author.id)和外键(例如,Post.author_id)。 Author.id很简单 - 只需将其作为Parse对象的id即可。然后在帖子中存储帖子的作者ID,用'author_id'键入。这就是数据方面。
在代码中有几个级别的实现需要考虑。对于检索,你的目标是制作这样的方法:
class Author
def posts
@posts ||= Post.find(:all, :id => id)
end
end
class Post
def author
@author ||= Author.find(author_id)
end
end
这不是太难,可以通过多种方式完成,例如使用元编程。更难的是拯救。你的目标,至少从作者方面来说,是这样的:
class Author
def after_save
super
posts.each do |p|
p.author_id = id
p.save
end
end
end
或者更确切地说,我应该说这是可能根据场景瞄准的目标。实施协会的一个陷阱是决定何时做事。你不想让你的生活变得复杂,但你也不想疯狂地使用API调用。考虑简单地更新作者的姓名:
a = Author.find(1)
a.name = "Joe"
a.save
正如书面after_save
将加载现有帖子(它通过设置@posts的posts
),在每个帖子上设置author_id(在这种情况下不需要这样做),然后保存帖子即使没有改变它们。此外,如果帖子在保存期间失败怎么办?在这种情况下,需要进行事务处理,以便您可以回滚整个事物并防止状态不一致。
您可以在ActiveRecord code中看到,在保存父级时如何处理子级问题存在大量逻辑。结果是光滑和透明的关联,但涉及各种其他事情; proxies,association classes等
我的建议是这样的。决定你是否真的需要光滑和透明的关联。如果没有,那么元编程一些访问器和便利方法,并留在那。否则,请花时间直接研究ActiveRecord关联代码,或者考虑使用DataMapper,AFAIK为您提供类似ActiveRecord的接口,包括关联,并能够更改数据存储。