[RUBY] Implementation policy to dynamically save and display Timezone in Rails

Background and requirements

There was a request to save the time of an event such as Meeting considering all time zones.

For example Meeting1 will be held in Tokyo from 11:00. Meeting2 will be held in UTC from 10:00.

I want to express something like.

Implementation procedure

--Fix the default Timezone of Rails API server. --Save Timezone in DB --Determine where to insert the logic that dynamically changes the Timezone. --Check if time type is saved in DB considering timezone --Validation to prevent passing strings without timezone information when saving

Pin the default Timezone of the Rails API server.

First, Rails has multiple time zones to consider.

https://qiita.com/joker1007/items/2c277cca5bd50e4cce5e

This time, to avoid confusion, I set all Timezones below to UTC.

Save Timezone in DB

Save the variable that is the basis for changing the timezone. Since the timezone is changed via ActiveSupport, you can write the following validation so that the valid value is saved.

# tz :string
class Meeting < ApplicationRecord 

validates :tz, inclusion: { in: ActiveSupport::TimeZone::MAPPING.values }, presence: true

end

Decide where to insert the logic to change the timezone to dynamic at the time of GET with API.

When returning a value in the API, add logic that dynamically changes the Timezone and returns the time. In this case, I incorporated it into Serialzer. Since this logic is related to display, as a result, we decided to put it in a layer close to View.


#  tz :string
class Meeting < ApplicationRecord 
  ~abridgement~

  def timezone
    ActiveSupport::TimeZone.new(tz)
  end

  def use_timezone
    Time.use_zone(timezone) do
      yield
    end
  end
end

class MeetingSerializer

  attribute :start_time do |record|
    record.use_timezone do
      record.start_time
    end
  end

end

Check if the time type is saved in the DB considering the timezone

Save is with timezone information, if you pass a string, ActiveRecord will do it nicely.

# actieve_The timezone of record is UTC

[47] pry(main)> meeting
=> #<Meeting:0x00007ff2c7ad4618
 id: "162b1ed7-5502-42f8-8bed-592d2dae7db1",
 start_at: Mon, 05 Oct 2020 16:00:00 UTC +00:00,
 created_at: Tue, 06 Oct 2020 06:28:39 UTC +00:00,
 updated_at: Thu, 08 Oct 2020 02:11:54 UTC +00:00>
[48] pry(main)> meeting.start_at="2020-10-06T01:00:00+0900"
=> "2020-10-06T01:00:00+0900"
[49] pry(main)> meeting.start_at
=> Mon, 05 Oct 2020 16:00:00 UTC +00:00

Validation so that strings without timezone information are not passed when saving

I created a controller module like the one below, and made validation bite with before_action.


module ValidateTimeFormat
  class TimeFormatError < StandardError
  end

  extend ActiveSupport::Concern

  included do
    rescue_from ValidateTimeFormat::TimeFormatError, with: :render_time_format_error
  end

  TIME_FORMAT = '%FT%T%z'

  def render_time_format_error(msg)
    render json: { message: msg }, status: :bad_request
  end

  def validate_time_format(time_str)
    DateTime.strptime(time_str, TIME_FORMAT).zone
  rescue Date::Error
    raise ValidateTimeFormat::TimeFormatError, :time_format_is_invalid
  end
end

Summary

Rails had an image that there are many points to consider in the Time system. With this implementation, I fully understood ()

Please follow us on twitter. !!

https://twitter.com/yoshixj

Recommended Posts

Implementation policy to dynamically save and display Timezone in Rails
Dynamically display titles with content_for and yield-Ruby on Rails
How to set the display time to Japan time in Rails
Change date and time to Japanese notation in Rails
Calendar implementation and conditional branching in Rails Gem simple calendar
[Rails] How to display an image in the view
Save and display multiple images
[Rails] How to define macros in Rspec and standardize processing
Display Flash messages in Rails
How to display a graph in Ruby on Rails (LazyHighChart)
How to dynamically switch between FIN and RST in Netty
[Rails] How to display information stored in the database in view
Remove nil and blank string array in rails Array and display them concatenated
[Webpacker] Summary of how to install Bootstrap and jQuery in Rails 6.0
[rails] How to display parent information in child view in nested relationships
How to delete large amounts of data in Rails and concerns
Things to remember and concepts in the Ruby on Rails tutorial
[rails6.0.0] How to save images using Active Storage in wizard format
[Rails] Save start time and end time
[rails] How to display db information
Enable jQuery and Bootstrap in Rails 6 (Rails 6)
[rails] Login screen implementation in devise
[Rails] How to write in Japanese
Remove "assets" and "turbolinks" in "Rails6".
CRUD features and MVC in Rails
How to introduce jQuery in Rails 6
How to install Swiper in Rails
[Rails] Implementation procedure of the function to tag posts without gem + the function to narrow down and display posts by tags
# 8 seed implementation to build bulletin board API with authentication authorization in Rails 6
Trial and error to display national holidays in Android app development. Part 2
Trial and error to display national holidays in Android application development. Part 1
How to display the text entered in text_area in Rails with line breaks
Change the save destination of the image to S3 in the Rails app. Part 2
How to embed and display youtube videos in Rails (You can also get the URL you entered by editing)
How to implement search functionality in Rails
How to change app name in rails
Install Webpacker and Yarn to run Rails
How to insert a video in Rails
Java implementation to create and solve mazes
[Rails] How to display error messages individually
How to use MySQL in Rails tutorial
Steps to set a favicon in Rails
[Rails] [Memo] When to add = to <%%> and when not
[rails] How to configure routing in resources
How to implement ranking functionality in Rails
[Rails] Implement star rating (input, save, display)
[Rails] How to use video_tag to display videos
How to use credentials.yml.enc introduced in Rails 5.2
Java to C and C to Java in Android Studio
How to display error messages in Japanese
# 6 show, create implementation to build bulletin board API with authentication authorization in Rails 6
A memo to simply create a form using only HTML and CSS in Rails 6
# 7 update, destroy implementation to build bulletin board API with authentication authorization in Rails 6