2011-10-09 40 views
11

我最近寫了ParseResource,這是一個用於Parse.com's REST API的Ruby API封裝器。爲API封裝器實現類似於ActiveRecord的關聯

這裏的一些基本用法:

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 => "[email protected]") 
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 

我喜歡任何意見,指針和陷阱的人誰從人誰擁有解析的REST API的把握來實現類似的事情還有。

+0

你聽說過[nulldb](https://github.com/nulldb/nulldb)嗎? –

回答

0

它看起來像Parse通過存儲對象作爲鍵值對的哈希來工作。所以基本上你有一個身份證,然後可以讓你的想象力運行。

要做像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的界面,包括關聯,並具有更改數據存儲的能力。