2017-02-19 7 views
0

私は、モバイルアプリケーションのWebサービスとしてのみ動作するRailsアプリケーションを作成しています。 --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のコンソールで:私は私のGroceryItemモデルクラスのメソッドを使用して有効期限にアクセスしようとすると、

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

しかし、私は、Dateオブジェクトを取得します。私はデータの日付部分を取得し、時間ではなく部分:データをomiting私の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"} 

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を呼び出すには、データを省略します。私は、コントローラ内のレンダリングプロセスがレンダリングを行うために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 

私は最終的にMongoDBに格納されたデータと一致するように、ISO8601規格と互換性のある方法でデータをシリアル化する方法を持ってできるようになります:

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

確かにこの動作は正しくありません。開発者がフィールドのDataTimeタイプを選択するときは、時間コンポーネントが必要になります。それ以外の場合は、Date型を代わりに使用します。今ではデフォルトのRails APIとMongoidのペア設定の動作を、JSONを適切な方法でレンダリングするビューを作成してオーバーライドすることができるようになったが、デフォルトの動作を自動的に変更する必要があるため開発者が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

@ウィルキーハハ、心配することはありません:)とても速く「バグレポートを提出する」:D –

+0

これは私が常にStackOverflowで屈辱を受ける機会を利用する理由です。 :Dほんの少し恥ずかしい。 – Welkie

関連する問題