Вопрос по ruby-on-rails, ruby – Использование поля длительности в модели Rails

27

Я ищу лучший способ использования поля длительности в модели Rails. Я бы хотел, чтобы формат был ЧЧ: ММ: СС (например, 01:30:23). Используемая база данных - это sqlite локально и Postgres в производстве.

Я также хотел бы поработать с этим полем, чтобы я мог взглянуть на все объекты в поле и определить общее время всех объектов в этой модели и получить что-то вроде:

30 records totaling 45 hours, 25 minutes, and 34 seconds.

Итак, что будет работать лучше всего?

Field type for the migration Form field for the CRUD forms (hour, minute, second drop downs?) Least expensive method to generate the total duration of all records in the model

Ваш Ответ

4   ответа
8

: Attributes для хранения ActiveSupport :: Durations в виде строк ISO8601. Преимущество использования 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
5

: Duration, но у меня были проблемы с получением четкого вывода.

Вам может понравитьсярубиновая продолжительностьнеизменный тип, представляющий некоторое количество времени с точностью в секундах. Он имеет множество тестов и тип поля модели 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
41
Store as integers in your database (number of seconds, probably). Your entry form will depend on the exact use case. Dropdowns are painful; better to use small text fields for duration in hours + minutes + seconds. Simply run a SUM query over the duration column to produce a grand total. If you use integers, this is easy and fast.

Use a helper to display the duration in your views. You can easily convert a duration as integer of seconds to ActiveSupport::Duration by using 123.seconds (replace 123 with the integer from the database). Use inspect on the resulting Duration for nice formatting. (It is not perfect. You may want to write something yourself.) In your model, you'll probably want attribute readers and writers that return/take ActiveSupport::Duration objects, rather than integers. Simply define duration=(new_duration) and duration, which internally call read_attribute / write_attribute with integer arguments.
Я никогда не думал об использовании секунд, дох! Спасибо за чаевые! mwilliams
+1 за публикацию моего комментария за меньшее время, чем я! :)
Как вы используетеinspect отформатировать вывод? Пример?
3

interval введите какActiveRecord::Duration.

Посмотрите эту суть (вы можете использовать ее как инициализатор в Rails 4.1):https://gist.github.com/Envek/7077bfc36b17233f60ad

Также я открыл там запросы на получение к Rails: https://github.com/rails/rails/pull/16919

Мы написали обновленную суть для Rails 5.1:gist.github.com/vollnhals/a7d2ce1c077ae2289056afdf7bba094a

Похожие вопросы