2017-02-19 34 views
0

我正在編寫Rails應用程序以充當僅用於移動應用程序的Web服務。我使用--api--skip-active-record開關創建了它。我的模型有一個DateTime字段。Mongoid - 在JSON API響應中序列化DateTime字段時獲取日期而不是時間

這是我的模型和我在我的控制器中調用的方法的代碼。因爲我使用--api,沒有查看代碼:

class GroceryItem 
    include Mongoid::Document 
    field :name, type: String 
    field :expiry, type: Date 
end 

# grocery_items_controller.rb 
# GET /grocery_items/1 
def show 
    render json: @grocery_item 
end 

在數據庫中,我可以看到,被存儲在現場的時間部分:

db.grocery_items.find() 
{ "_id" : ObjectId("58a9298da1c1d12e7cee02d9"), "name" : "Chocolate", "expiry" : ISODate("2017-02-19T05:13:49.253Z") } 

我也可以看到這在Rails的控制檯:

irb(main):003:0> GroceryItem.first 
=> #<GroceryItem _id: 58a9298da1c1d12e7cee02d9, name: "Chocolate", expiry: 2017-02-19 05:13:49 UTC> 

然而,當我嘗試訪問我的GroceryItem模型類利用該方法屆滿時,我得到一個Date對象。我只得到數據的日期部分,沒有時間部分:

irb(main):004:0> GroceryItem.first.expiry 
=> Sun, 19 Feb 2017 

irb(main):005:0> GroceryItem.first.expiry.class 
=> Date 

irb(main):006:0> GroceryItem.first.expiry.to_s 
=> "2017-02-19" 

呼籲實例to_jsonas_json還省略了數據:

irb(main):008:0> GroceryItem.first.to_json 
=> "{\"_id\":{\"$oid\":\"58a9298da1c1d12e7cee02d9\"},\"expiry\":\"2017-02-19\",\"name\":\"Chocolate\"}" 

irb(main):009:0> GroceryItem.first.as_json 
=> {"_id"=>BSON::ObjectId('58a9298da1c1d12e7cee02d9'), "expiry"=>Sun, 19 Feb 2017, "name"=>"Chocolate"} 

導致我的JSON響應omiting數據。我假設在控制器渲染過程中使用任何to_jsonas_json做渲染:

{ 
    "_id": { 
     "$oid": "58a9298da1c1d12e7cee02d9" 
    }, 
    "expiry": "2017-02-19", 
    "name": "Chocolate" 
} 

我終於能夠找出如何通過調用下面來訪問這些數據。你可以看到,我終於得到了時間Ruby類:

irb(main):010:0> GroceryItem.first.attributes[:expiry] 
=> 2017-02-19 05:13:49 UTC 

irb(main):011:0> GroceryItem.first.attributes[:expiry].class 
=> Time 

,讓我終於有了與ISO8601規範與存儲在MongoDB中的數據不兼容的方式串行化數據的方法:

irb(main):012:0> GroceryItem.first.attributes[:expiry].utc.iso8601 
=> "2017-02-19T05:13:49Z" 

當然,這種行爲是不正確的。當開發人員爲某個字段選擇DataTime類型時,他們必須希望時間部分通過。否則,他們會改用日期類型。我現在明白我可以通過創建視圖來以我認爲合適的方式呈現JSON來覆蓋默認的Rails API和Mongoid配對行爲,但是我正在考慮提交bug報告,因爲我覺得應該將默認行爲更改爲自動在開發人員選擇DateTime字段類型時呈現存儲在數據庫中的所有數據。

我想知道這裏有沒有人對此問題有任何意見,然後再繼續提交錯誤報告。

回答

1

問題似乎是在你的代碼:

class GroceryItem 
    include Mongoid::Document 
    field :name, type: String 
    field :expiry, type: Date 
end 

這裏,到期日期具有的類型,因此它有望沒有時間分量返回日期。我認爲使用適當的類型將解決您的問題。

+0

我實際上在更多的實驗後才發現這一點。我注意到,當我再次嘗試創建一個應用程序並生成腳手架時('''rails g scaffold grocery_item name expiry:datetime''')它工作。這次我的模型的類型爲'''Time''。我無法相信我沒有接受,我覺得我第一次使用'''expiry:datetime'''。 我仍然很高興它的默認工作。 :) – Welkie

+0

@Welkie哈哈,不用擔心,會發生:)沒那麼快「提交bug報告」:D –

+0

這就是爲什麼我總是趁機首先在StackOverflow上受到羞辱。 :D稍微不令人尷尬。 – Welkie

相關問題