我正在編寫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_json
和as_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_json
或as_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字段類型時呈現存儲在數據庫中的所有數據。
我想知道這裏有沒有人對此問題有任何意見,然後再繼續提交錯誤報告。
我實際上在更多的實驗後才發現這一點。我注意到,當我再次嘗試創建一個應用程序並生成腳手架時('''rails g scaffold grocery_item name expiry:datetime''')它工作。這次我的模型的類型爲'''Time''。我無法相信我沒有接受,我覺得我第一次使用'''expiry:datetime'''。 我仍然很高興它的默認工作。 :) – Welkie
@Welkie哈哈,不用擔心,會發生:)沒那麼快「提交bug報告」:D –
這就是爲什麼我總是趁機首先在StackOverflow上受到羞辱。 :D稍微不令人尷尬。 – Welkie