2009-06-26 5 views
27

私は、Railsモデルで期間フィールドを使用する最善の方法を探しています。フォーマットはHH:MM:SS(例:01:30:23)にしたいと思います。使用されているデータベースは、ローカルではsqlite、本番環境ではPostgresです。Railsモデルの期間フィールドの使用

私もそう、私はフィールド内のすべてのオブジェクトを見て、そのモデル内のすべてのオブジェクトの合計時間を考え出すとのようなもので終わることができ、この分野で働きたい:

30レコード合計45時間25分34秒

どのように最適ですか? CRUDフォームの移行

  • フォームフィールドの

    • フィールドタイプ(時、分、秒のドロップダウン?)
    • 最も安価な方法は、モデル内のすべてのレコードの全持続時間を生成する
  • 答えて

    41
    • データベースに整数として格納します(おそらく秒数)。
    • あなたのエントリーフォームは、正確なユースケースによって異なります。ドロップダウンは苦しいです。小さなテキストフィールドを時間+分+秒で使用する方が良いでしょう。
    • 延期列に対してクエリを実行して、合計を生成します。SUM整数を使用する場合、これは簡単で高速です。
    • さらに

    • はあなたのビューで時間を表示するには、ヘルパーを使用してください。秒の整数としての継続時間は、123.seconds123をデータベースの整数に置き換えます)を使用して簡単にActiveSupport::Durationに変換できます。いい形の書式設定のためにDurationinspectを使用してください。
    • お使いのモデルでは、おそらく整数ではなくActiveSupport::Durationオブジェクトを返す/取得する属性リーダーとライターが必要になるでしょう。 duration=(new_duration)durationを定義するだけで、内部的に整数引数を持つread_attribute/write_attributeを呼び出します。
    +0

    +1私の短い時間で私の同じコメントを投稿してください! :) –

    +0

    私は秒を使用することを決してしなかった、doh!ヒントをありがとう! – mwilliams

    +0

    出力をフォーマットするのに 'inspect'をどのように使いますか?例? –

    5

    ActiveSupport :: Durationを使用しようとしましたが、出力をクリアするのに問題がありました。

    ruby-durationのように、ある程度の時間と秒単位の精度を表す不変型が好きかもしれません。それは多くのテストとモンゴイドモデルフィールドタイプを持っています。

    私はChronic Durationと一緒に行ったので、人間のデュレーションストリングを簡単に解析したいと思っていました。次に、time_spent(秒)フィールドを持つモデルにモデルを追加する例を示します。

    class Completion < ActiveRecord::Base 
        belongs_to :task 
        belongs_to :user 
    
        def time_spent_text 
        ChronicDuration.output time_spent 
        end 
    
        def time_spent_text= text 
        self.time_spent = ChronicDuration.parse text 
        logger.debug "time_spent: '#{self.time_spent_text}' for text '#{text}'" 
        end 
    
    end 
    
    3

    私はActiveRecord::DurationとしてPostgreSQLのintervalタイプをサポートして使用するためのいくつかのスタブを書いてきました。

    このgistを参照してください(これはRails 4の初期化子として使用できます)。1):https://gist.github.com/Envek/7077bfc36b17233f60ad

    また、私は開いたプルがレールへの要求:Railsの5では https://github.com/rails/rails/pull/16919

    +0

    Rails 5.1用の更新された要点を書きました:https://gist.github.com/vollnhals/a7d2ce1c077ae2289056afdf7bba094a –

    4

    、あなたはISO8601文字列としてactivesupportの::期間を格納する属性:: ActiveRecordを使用することができます。整数よりもActiveSupport :: Durationを使用する利点は、すぐにすぐに日付/時刻の計算に使用できることです。 Time.now + 1.monthのようなことができますが、それは常に正しいです。

    はここに方法は次のとおりです。

    が追加config/initializers/duration_type.rb

    class DurationType < ActiveRecord::Type::String 
        def cast(value) 
        return value if value.blank? || value.is_a?(ActiveSupport::Duration) 
    
        ActiveSupport::Duration.parse(value) 
        end 
    
        def serialize(duration) 
        duration ? duration.iso8601 : nil 
        end 
    end 
    
    ActiveRecord::Type.register(:duration, DurationType) 
    

    移行

    create_table :somethings do |t| 
        t.string :duration 
    end 
    

    モデル

    class Something < ApplicationRecord 
        attribute :duration, :duration 
    end 
    

    使用

    something = Something.new 
    something.duration = 1.year # 1 year 
    something.duration = nil 
    something.duration = "P2M3D" # 2 months, 3 days (ISO8601 string) 
    Time.now + something.duration # calculation is always correct 
    
    関連する問題