🙆
railsのhas_many関連付けの拡張を検証
Railsガイドの4.6 関連付けの拡張で紹介されている、ActiveRecord関連付けの拡張がCampfireで実装されていたので改めて確認した。
確認用のワンライナースクリプトをruby setup.rb
で動かす。
# setup.rb
require 'active_record'
require 'sqlite3'
# ロギング
ActiveRecord::Base.logger = Logger.new($stdout)
# データベース接続の設定
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'db/development.sqlite3'
)
# テーブルの作成
ActiveRecord::Schema.define do
drop_table :books, if_exists: true
drop_table :authors, if_exists: true
end
ActiveRecord::Schema.define do
create_table :authors, force: true do |t|
t.string :name
end
create_table :books, force: true do |t|
t.string :category_id
t.references :author, foreign_key: true
end
end
# モデルの定義
class Author < ActiveRecord::Base
has_many :books do
def find_by_book_prefix(book_number)
find_by('category_id LIKE ?', "#{book_number[0..2]}%")
end
end
end
class Book < ActiveRecord::Base
belongs_to :author
end
# データの作成
author = Author.create(name: 'John Doe')
author.books.create(category_id: '12345')
author.books.create(category_id: '67890')
# 使用例
found_book = author.books.find_by_book_prefix('123')
puts found_book.category_id if found_book
found_bookの検索は、author_id(proxy_association.owner)で絞り込まれた状態でのqueryログが流れる。
SELECT "books".* FROM "books" WHERE "books"."author_id" = ? AND (category_id LIKE ?) LIMIT ? [["author_id", 1], [nil, "123%"], ["LIMIT", 1]]
下記のようにcontrollerにベタで記載しているコードをmodel側に定義する拡張機能が提供されている。
author.books.find_by('category_id LIKE ?', "123")
この機能を利用したことはないが、findだとモデルscopeとの使いどころに迷うので、ownerを起点としたcreate/updateメソッドを利用を想定する。
Discussion