ふわ

2021年04月04日に参加

学習履歴詳細

custom constraintsをlib直下のモジュールに定義する

groupdate gemのメソッドが有効にならずエラーが出てしまう。
MySQLのTimezoneの設定に関する記事を読み込み、エラーを解決した。

アプリ制作

実現したいこと

体調グラフ機能で、クエリパラメータを使用せずにURI・コントローラを設計する。

取り組んだこと

  • TogglのDashboardのURIを観察してまとめる。

    • ルートは当日の週に設定
    • 当日の週or当月は /period/thisWeek(or Month)
    • 当日の前週or前月は/period/prevWeek(or Month)
    • それ以外の期間は/from/yyyy-mm-dd/to/yyyy-mm-dd
  • URIの設計を再度行う。

  /statistics => statistics#report 

  /statistics/:column/period/week or month => statistics#select_period

  /statistics/:column/from/yyyy-mm-dd/to/yyyy-mm-dd => select#select_date
  • groupdate gemの導入

    • 理由
    • 週や月を前後するロジックをいちいち書いているとコントローラが肥大化するため
    • Time zone support must be installedとあったので、下記コマンドを実行
    • mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
    • 以下の記事に従ってMysqlのdefault timezoneをAsia/Tokyoに変更
    • Set MySQL Timezone
    • MacのローカルのMySQLのタイムゾーンをAWSのRDSのMySQLの設定と合わせる
    • groupdate gem のメソッドがrails consoleで使用可能になった。
    • groupdateをrails consoleで動かしてみる

       #=> key: 週の初めの日(Dateオブジェクト)
       #=> value: その週のレコードの配列
       group = diaries.group_by_week(series: true) { |n| n.diary_date }
      
        # 7月1週目の週のactivityカラムの集計をする
       date = Date.parse('2019-06-30', '%Y-%m-%d')
      
       group[date].map do |diary|
           diary.activity
       end
       #[-2, -1, 1, 0, -2, -2]
       ## コードめちゃ短くて済む!!
      
  • custom constraints の設定

    • URIのセグメントをバリデーションする処理をコントローラに記述していたが、コントローラが肥大化してしまう。routeのconstraintでそれを代わりに行うことで、コントローラを軽くする・
  # config/routes.rb
  Rails.application.routes.draw do

    get 'statistics/:column/period/:week_or_month', to: 'statistics#select_period', constraints: Constraint::SelectPeriodConstraint.new

    get 'statistics/:column/from/:date_begin/to/:date_end', to: 'statistics#select_date', constraints: Constraint::SelectDateConstraint.new
  end 

  # app/lib/constraint/select_date_constraint.rb
  module Constraint
    class SelectDateConstraint
      def matches?(request)
        date_regex = /\d{4}\-\d{1,2}\-\d{1,2}/
        date_regex.match(request.query_parameters['date_begin']) && date_regex.match(request.query_parameters['date_end'])
      end
    end
  end

  # app/lib/constraint/select_period_constraint.rb
  module Constraint
    class SelectPeriodConstraint
      PERIODS = ['thisWeek', 'thisMonth', 'prevWeek', 'prevMonth']

      def matches?(request)
        PERIODS.include?(request.query_parameters['week_or_month'])
      end
    end
  end

分からないこと

  • コントローラのbefore_actionで複数のメソッドを実行したい。1つのメソッドは引数を取る。

    • 下のようなことがしたい。これができるのかは分からない。Procとかまだやってない...
  class StatisticsController < ApplicationController
    before_action do
     require_user_logged_in,
     set_current_user,
     set_params(statistics_params)
    end
  # 省略
  end 
  • StatisticsControllerでReportを生成する処理をどうやって簡素に書くか?
    • 期間を表す単語(thisWeek, prevMonth等)で期間をしていする方法、date_begindate_endを直接指定する2つのやり方がある。
    • groupdate gem を使ってどう書けば良いか?
    • 重複の処理を書かないようにする。

プロを目指す人のためのRuby入門

  • 第9章 例外処理を理解する
Ruby
Rails

2019年10月08日(火)

7.0時間