目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Active Record のカラム名にエイリアスを利用できるようにするための gem「Utusemi」を紹介します。
■ はじめに
Utusemi は Active Record のカラム名にエイリアスを利用できるようにするための Ruby on Rails 3, 4 向けの gem です。
Ruby on Rails にはモデルのインスタンスに対してエイリアスを張るための alias_attribute というメソッドが存在します。Utusemi は、これに加えてモデルクラスの where メソッドや order メソッドでもエイリアスが使えるようにするための gem になります。
カラム名へのエイリアスは以下のようなケースで利用されることが想定されます。
- カラム名が長いので実装上は短く済ませたい
- 既存のコードを変えずに DB のカラム名変更に対応したい
- 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'