その他
    ホーム 技術発信 DoRuby Active Record のカラム名にエイリアスを使えるようにする Utusemi gem

    Active Record のカラム名にエイリアスを使えるようにする Utusemi gem

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    Active Record のカラム名にエイリアスを利用できるようにするための gem「Utusemi」を紹介します。

    ■ はじめに

    Utusemi は Active Record のカラム名にエイリアスを利用できるようにするための Ruby on Rails 3, 4 向けの gem です。

    Ruby on Rails にはモデルのインスタンスに対してエイリアスを張るための alias_attribute というメソッドが存在します。Utusemi は、これに加えてモデルクラスの where メソッドや order メソッドでもエイリアスが使えるようにするための gem になります。

    カラム名へのエイリアスは以下のようなケースで利用されることが想定されます。

    1. カラム名が長いので実装上は短く済ませたい
    2. 既存のコードを変えずに DB のカラム名変更に対応したい
    3. gem で用意されている固定カラム名をアプリケーションの特定カラム名にマッピングさせたい

    では早速インストールの仕方から紹介していきます。

    ■ インストール方法

    他の gem と同じように Bundler を使ってインストールするのがおすすめです。

    この場合は Gemfile に下記の1行を追記し、bundle install を実行します。

    gem 'utusemi'
    

    また、Bundler を利用しない場合は下記のコマンドでもインストールできます。

    gem install utusmei
    

    ■ 設定ファイルの書き方

    エイリアス先のカラムとエイリアス元のカラムを設定していきます。

    例として、下記のコードを config/initializer/utusemi.rb に設置します。

    Utusemi.configure do
      map :sample do
        name :first_name
      end
    end
    

    ■ 使い方

    上記で設定したエイリアスの設定名を utusemi メソッドに渡すことで、エイリアスを有効にできます。

    irb> User.utusemi(:sample).where(name: 'John')
    SELECT "users".* FROM "users" WHERE "users"."first_name" = 'John'
    

    例では sample というエイリアス設定を有効にすることで、User モデルの first_name カラムに対して name という名前でアクセスしています。

    また、utusemi メソッドを介して取得したインスタンスでもエイリアスが有効です。

    irb> user = User.utusemi(:sample).where(name: 'John').first
    irb> user.name
    #=> "John"
    

    ■ 詳細なメソッドの説明

    ActiveRecord::Base.utusemi

    モデルクラスに対するエイリアスを設定します。

    「使い方」の項で紹介した例では、このメソッドを利用しています。

    引数にはエイリアス設定名のシンボルまたは文字列を渡します。

    引数を省略した場合はモデル名の小文字単数形をエイリアス設定名として利用します。

    irb> Utusemi.configure do
      map(:user) { nickname :first_name }
    end
    
    irb> User.utusemi.where(nickname: 'John')
    SELECT "users".* FROM "users" WHERE "users"."first_name" = 'John'
    

    ActiveRecord::Base.utusemi!

    モデルクラスに対してエイリアスを設定する、破壊的メソッドです。

    ActiveRecord::Base.utusemi! を1度でも呼び出したモデルは、その後もエイリアスが有効な状態となります。

    irb> User.where(name: 'John')
    SQL:Error: Unknown column 'users.name' ...
    
    irb> User.utusemi!(:sample)
    irb> User.where(name: 'John')
    SELECT "users".* FROM "users" WHERE "users"."first_name" = 'John'
    

    ActiveRecord::Base#utusemi

    モデルインスタンスに対するエイリアスを設定します。

    irb> user = User.first
    
    irb> user.name
    NoMethodError: undefined method `name' for #<user:...>
    
    irb> user.utusemi(:sample).name
    #=> "John"
    

    ActiveRecord::Base#utusemi!

    モデルインスタンスに対してエイリアスを設定する、破壊的メソッドです。

    ActiveRecord::Base#utusemi! を1度でも呼び出したインスタンスは、その後もエイリアスが有効な状態となります。

    irb> user = User.first
    
    irb> user.name
    NoMethodError: undefined method `name' for #<user:...>
    
    irb> user.utusemi(:sample)
    irb> user.name
    #=> "John"
    

    ■ 関連モデルに対するエイリアス

    エイリアスの有効状態は関連モデルにも引き継がれます。

    例として、User モデルに対して Blog モデルが複数紐付いている場合を詳細します。

    app/models/user.rb

    class User < ActiveRecord::Base
      has_many :blogs
    end
    

    app/models/blog.rb

    class Blog < ActiveRecord::Base
      belongs_to :user
    end
    

    config/initializers/utusemi.rb

    Utusemi.configure do
      map :user do
        name :first_name
      end
    
      map :blog do
        url_path :permanent_link_url
      end
    end
    

    このようなファイル構成となっているとき、次のような書き方ができます。

    irb> user = User.first
    irb> user.utusemi.blogs.where(url_path: 'path-to-link')
    SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" = 1 AND "blogs"."permanent_link_url" = 'path-to-link'
    

    ■ リンク

    https://github.com/hyoshida/utusemi