2012-12-19 49 views
5

我目前在rails中開發了一個大型自定義內容管理溶劑來處理許多不同的內容類型(模型)及其關係。Rails應用程序中數據對話的最佳實踐

整個數據模型是建立在有效記錄,並且具有的功能,如內容的進口和出口加同步與其他服務(例如移動同步到內容改變推送到智能電話)。

對於這些任務我有很多數據的對話,在一側的活動記錄模式和在另一邊許多不同的和現有的目標格式的意思。

  • JSON REST服務,以反映在模型層變化的
  • RSS提要
  • 導入/導出發佈新的內容proprietarian XML格式

對於新的數據格式我可以自己定義結構,在大多數情況下意味着讓軌道通過使用整齊的編組功能來處理它

format.html do 
     render 'show' 
    end 
    format.xml do 
     render xml: { content:@content } 
    end 
    format.json do 
     render json: { content:@content } 
    end 

但是當現有數據架構已送達,幾次談話都可以做的情況下:

重命名鍵:在模型中,每一個對象是由一個id屬性標識,但在目標格式的對象屬性是名稱uid或OBJECT-ID ...

內聯相關對象:鑑於我有一個模型稱爲與Address模型相關的Person。使用Rails xml序列化時,地址對象將在標籤下被省略或內聯。在給定的目標格式的地址可能是在Person對象內聯,這意味着下面的輸出將nedded

<person> 
    <name>Ben</name> 
    <street>Some Street</street> 
    <city>Berlin</city> 
</person> 

價值轉型:日期屬性可能需要作爲Unix時間戳,而不是UTC串

天真sollution:

所有這些轉變可以通過任何需要的時候,他們的手來完成,這意味着只要把創建目標數據結構中的一些Ruby代碼:

data = {} 
Person.all.each do |p| 
    # rename property 
    data[:guid] = p.id 
    data[:name] = p.full_name 
    # inline relation 
    data[:street] = p.primary_address.street  
    data[:city] = p.primary_address.locality 
    data[:member_since] = p.created_at.format(...) 
end 
render xml: { persons:data} 

或者對於xml,只能使用轉換生成器模板。

雖然此選項是可行的,也是靈活的,它在整個應用程序的傳播邏輯conversaion,使控制器的成長,在一個大的應用程序,這將是壞可維護性...

我正在尋找是我模型的基於模式的轉換。含義我在某處定義了一個從我的主動記錄模型到目標模式的映射(使用ruby dsl,在xml中...),只是有每當我需要一定的數據格式執行架構的對話:

data = Article.all 
# the parameter is the name of the target schema 
converter = ModelConversation.new(:legacy_contact_list) 
render xml: { contacts: converter.execute(data) } 

那麼我現在實際上是尋找類似於XSLT,但也適用於JSON輸出和紅寶石供電東西。

任何幫助/想法或故事如何在軌道中進行數據對話將不勝感激。

回答

2

我一直在寫XSLT轉換幾年,我只能建議反對XSLT或「類似的東西」。

由於您有一個Ruby應用程序,只需使用Ruby!我認爲它已經符合你的需求。

關於你的關注:

雖然此選項是可行的,也是靈活的,它在整個應用程序的傳播邏輯conversaion,使控制器的成長,在一個大的應用程序,這將是壞可維護性...

這將是在你的控制之下。只要將您的轉換器視爲應用程序的其他任何部分,並保持代碼質量。如果將轉換邏輯放入模型本身或將其轉移到庫中,您的控制器不會增長。重構您的轉換器以保持簡潔。

看你的「天真」的例子

# rename property 
    data[:guid] = p.id 
    data[:name] = p.full_name 
    # inline relation 
    data[:street] = p.primary_address.street  
    data[:city] = p.primary_address.locality 
    data[:member_since] = p.created_at.format(...) 

此代碼基本上說,在你的目標格式,id被稱爲​​,full_name被稱爲name等。我懷疑你可以寫出比你已經提供的代碼更短的代碼。所以我沒有看到這裏需要另一種技術。

+0

哇..你該死的權利。一個軟件工程師我總是要求分離定義和應用程序。這意味着我有一個配置,它定義了執行定義的東西和代碼....但在ruby代碼中是配置(基本上是一個非常酷的想法)...所以我的例子是配置,沒有代碼要執行(除了配置)。這很漂亮。由於所有的樹木,我猜並沒有看到森林;) – room13