【问题标题】:Implementing ActiveRecord-like associations for an API wrapper为 API 包装器实现类似 ActiveRecord 的关联
【发布时间】:2011-12-04 03:30:40
【问题描述】:

我最近写了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 的人提供任何建议、指示和陷阱。

【问题讨论】:

标签: ruby parsing rest activerecord associations


【解决方案1】:

我发现使用 DataMapper (http://datamapper.org) 很容易让它与几乎任何数据存储一起工作。您可以编写一个与您的数据存储对话的适配器,然后直接使用 DataMapper 的所有功能,就好像您的数据在 SQL 中一样。这是一个链接,它解释了有关编写其中一个适配器的一些信息。 http://www.killswitchcollective.com/articles/55_datamapperabstractadapter_101

【讨论】:

    【解决方案2】:

    看起来 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 的界面,包括关联,并且能够更改数据存储。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      • 2015-07-22
      相关资源
      最近更新 更多