こんにちは。
みなさんRailsで中間テーブルで並び順を制御したい時ってありますよね?
例えば、ユーザーが複数のタグを持つような場合、タグの並び順を制御したい時があります。
そんな時におすすめのTipsを紹介します。
中間テーブルに並び順を持たせる
まずは、中間テーブルに並び順を持たせます。
db/migrate/20211206000000_create_user_tags.rb
class CreateUserTags < ActiveRecord::Migration[7.0]
def change
create_table :user_tags do |t|
t.references :user, null: false, foreign_key: true
t.references :tag, null: false, foreign_key: true
t.integer :position, null: false, default: 0
t.timestamps
end
end
end
app/models/user_tag.rb
class UserTag < ApplicationRecord
belongs_to :user
belongs_to :tag
scope :ordered, -> { order(position: :asc) }
end
はい、これで中間テーブルに並び順を持たせることができました。
中間テーブルの並び順で呼び出すようにする
次に、中間テーブルの並び順で呼び出すようにします。
app/models/user.rb
class User < ApplicationRecord
has_many :user_tags, -> { ordered }, dependent: :destroy
has_many :tags, through: :user_tags
end
app/models/tag.rb
class Tag < ApplicationRecord
has_many :user_tags, -> { ordered }, dependent: :destroy
has_many :users, through: :user_tags
end
これで、中間テーブルの並び順で呼び出すことができました。
解説
ここで、-> { ordered }
というのは、scope :ordered, -> { order(position: :asc) }
を呼び出しているだけです。
Railsのrelationでは、lambdaでscopeを呼び出すことができます。
Active Record の関連付け - Railsガイド
これをしておくことで、中間テーブルの並び順で呼び出すことができます。
大きなアプリケーションでも、user.user_tags.ordered.map(&:tag)
のようなコードが書かれていたりするので、このような書き方をしておくとシンプルに書けるよーというTipsでした。
今回はこのあたりで。