레일 모델에서 지속 시간 필드 사용
-
20-08-2019 - |
문제
레일 모델에서 지속 시간 필드를 사용하는 가장 좋은 방법을 찾고 있습니다. 형식이 HH : MM : SS (예 : 01:30:23)가되기를 원합니다. 사용중인 데이터베이스는 로컬로 SQLITE이고 프로덕션의 우편둥이입니다.
또한 필드의 모든 객체를 살펴보고 해당 모델의 모든 객체의 총 시간을 제시하고 다음과 같은 것들로 끝날 수 있도록이 필드로 작업하고 싶습니다.
총 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에서는 activerecord :: 속성을 사용하여 activesupport :: 기간을 ISO8601 문자열로 저장할 수 있습니다. ActiveSupport :: Integers의 지속 시간을 사용하는 장점은 즉시 날짜/시간 계산에 사용할 수 있다는 것입니다. 당신은 같은 일을 할 수 있습니다 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 :: 지속 시간을 사용해 보았지만 출력을 명확하게하는 데 어려움이있었습니다.
당신은 좋아할 것입니다 루비 기간, 몇 초 만에 정확도로 어느 정도 시간을 나타내는 불변의 유형. 많은 테스트와 몽마 드 모델 필드 유형이 있습니다.
나는 또한 인간의 지속 시간을 쉽게 구문 분석하고 싶었다. 그래서 나는 함께 갔다. 만성 기간. 다음은 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
나는 PostgreSQL을 지원하고 사용하기 위해 스터브를 썼습니다. interval
AS를 입력하십시오 ActiveRecord::Duration
.
이 요점을 참조하십시오 (Rails 4.1에서 이니셜 라이저로 사용할 수 있음) : : https://gist.github.com/envek/7077bfc36b17233f60ad
또한 레일에 풀 요청을 열었습니다.https://github.com/rails/rails/pull/16919