質問

Rails モデルで期間フィールドを使用する最良の方法を探しています。形式を HH:MM:SS にしたいのですが (例:01:30:23)。使用中のデータベースはローカルでは sqlite で、本番環境では Postgres です。

また、このフィールドを使用して、フィールド内のすべてのオブジェクトを調べて、そのモデル内のすべてのオブジェクトの合計時間を計算して、次のような結果を得ることができるようにしたいと考えています。

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

では、何が最も効果的でしょうか?

  • 移行のフィールド タイプ
  • CRUD フォームのフォーム フィールド (時、分、秒のドロップダウン?)
  • モデル内のすべてのレコードの合計期間を生成する最も安価な方法
役に立ちましたか?

解決

  • データベースに整数として保存します (おそらく秒数)。
  • 入力フォームは正確な使用例によって異なります。ドロップダウンは苦痛です。時間 + 分 + 秒単位の小さなテキスト フィールドを使用することをお勧めします。
  • 単に実行してください SUM 期間列をクエリして総計を算出します。整数を使用する場合、これは簡単かつ高速です。

さらに:

  • ヘルパーを使用して、ビューに期間を表示します。期間を秒の整数として簡単に変換できます。 ActiveSupport::Duration を使用して 123.seconds (交換する 123 データベースからの整数を使用します)。使用 inspect 結果として得られるものについて Duration 素敵な書式設定のために。(完璧ではありません。自分で何か書いてみてもいいかもしれません。)
  • モデルでは、おそらく戻り/取得する属性のリーダーとライターが必要になるでしょう。 ActiveSupport::Duration 整数ではなくオブジェクトです。単純に定義する duration=(new_duration) そして duration, 、内部的に呼び出します read_attribute / write_attribute 整数引数を使用します。

他のヒント

Railsの5では、ISO8601文字列としてactivesupportの::期間を格納する属性:: ActiveRecordを使用することができます。整数上activesupportの::継続を使用する利点は、箱から出してすぐ、日付/時刻の計算のためにそれらを使用することができるということです。あなたは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

私はactivesupportの::期間を使用してみましたが、トラブル出力を明確にするなっていた。

あなたはルビー期間に、正確にある程度の時間を表して不変タイプを好むかもしれませんすぐに。これは、テストやMongoidモデルフィールドの種類がたくさんあります。

私は慢性継続すると一緒に行ったので、また、簡単に人間の期間の文字列を解析したかったです。ここでは秒フィールドに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

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

ます。https://gist.github

この主旨を参照してください(あなたは、Railsの4.1の初期化子として使用することができます) .COM / Envek / 7077bfc36b17233f60adする

また、私はそこにレールにプルリクエストをオープンしました: https://github.com/rails/rails/pull/16919する

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top