世界が幸せで在ります様に

ITエンジニアになりたい人・エンジニアの人にとって役立ちそうな商品を紹介するブログ

同じactive_hashに紐づくカラムが複数あるときの書き方

active hashを使っていて、複数のカラムに同じクラスを使いたいときの書き方。

github.com

 select box用の日付クラスをactive hashで定義し、モデルでは、平日と土日などのカラムをそれぞれ持ち、このactive hashクラスを利用する

複数のカラムと対応させたいときに少し迷ったのでコードを読んだ結果書き方をメモっておく。

環境

  • Ruby v2.5.1
  • Rails v5.2.1

結論から書くと以下の感じ。

class Info < ApplicationRecord
  belongs_to_active_hash :weekday_begin_id, class_name: 'TimeSelect', foreign_key: :weekday_begin, shortcuts: %i[timer] # rubocop:disable Metrics/LineLength
  belongs_to_active_hash :weekday_end_id, class_name: 'TimeSelect', foreign_key: :weekday_end, shortcuts: %i[timer] # rubocop:disable Metrics/LineLength

belongs_to_active_hashでカラム名を書くところまでは同じだが、このあと多少挙動が変わる。

 ここでは、class_nameとforeign_keyを別途指定した。

  • class_name:実際のactive hashで作成したクラス
  • foreign_key:モデルのactive hashと紐付けるためのキー

https://github.com/zilkey/active_hash/blob/master/lib/associations/associations.rb#L26-L87 具体的にはこの箇所

    options = {
          :class_name => association_id.to_s.camelize,
          :foreign_key => association_id.to_s.foreign_key,
          :shortcuts => []
        }.merge(options)
        # Define default primary_key with provided class_name if any
        options[:primary_key] ||= options[:class_name].constantize.primary_key
        options[:shortcuts] = [options[:shortcuts]] unless options[:shortcuts].kind_of?(Array)

        define_method(association_id) do
          options[:class_name].constantize.send("find_by_#{options[:primary_key]}", send(options[:foreign_key]))
        end

optionsにいろいろと指定されているところが、association_idを変化させている形になる。今回のように、association_idが複数あるとそれも上手くいかないので、直接指定する形になる。

仮に、association_idしか指定していない場合、class_nameをWeekdayBeginIdのような形で探しに行ってしまう。

 

Effective Ruby

Effective Ruby

 

 

プロフィールと免責事項