鳩舎

レースしない

関連モデルの命名

今日は Rails での『関連モデル』の名前について考える。

構造としてはこんな感じ。

・ルーム(Room)に所属するユーザー(User)
・ルーム(Room)での管理者権限を持つユーザー(User)

どちらの関連も N:N の関連。いわゆる has_may な感じ。

で、こういう時の命名って Room モデルと User モデルだから RoomUser とか UserRoom とかっていうモデルやテーブルを作りがちなのだけれど、今回は同様の形態の関連が2つあるのでちょっと微妙な事になりそう。

っていうか、まずもって RoomUser モデルってなんだよ。なんのモデルだよそれ。って感じなので名前を考える。

ルーム(Room)に所属するユーザー(User)

関連モデルのデータは大抵2つのフィールドを持っている。 Migration あたりから抜き出すと

t.references :room
t.references :user

みたいな具合。つまるところ room_iduser_id を持っているわけだけれども、この2つを持ちそうなモデルってのは何なんだろう。これだけでは情報が少なさすぎるので、この関連テーブルを使っての集合に Room モデルからどうアクセスするのかを考える。

class Room < AR::Base
  has_many {関連モデル}
  has_many :members,
    through: {関連モデル},
    source: :user
end

あー、部屋のメンバーとしての関連なのかーとわかってきた。そうなったらもう話は簡単で、メンバーであること、というそのものの命名にしよう。 Room::Membership なんてどうだろうか。

class Room::Membership < AR::Base
  belongs_to :room
  belongs_to :user
end

class Room < AR::Base
  has_many :memberships
  has_many :members,
    through: :memberships,
    source: :user
end

『部屋のメンバーであること』のモデルになった。membership.destroy であるユーザーがあるルームのメンバーでなくなるのは、なかなかわかりやすい。

ルーム(Room)での管理者権限を持つユーザー(User)

テーブルの構造は N:N の関連モデルなので Membership と変わらない。どうアクセスされるか見よう。

class Room < AR::Base
  has_many {関連モデル}
  has_many :administrators,
    through: {関連モデル},
    source: :user
end

あー、管理者の関連モデルなのか。なるほどー、という気分になった。先ほどは『メンバーであること』のモデルを作ったけど、じゃあ今回は『権限そのもの』のモデルを作ったほうがすんなり行くかもしれない。

僕は英語が苦手なので、辞書をひっぱり回すと例えば Room::AdministrativePrivilege とかいいんじゃない?という感じになる。

class Room::AdministrativePrivileage < AR::Base
  belongs_to :room
  belongs_to :user
end

class Room < AR::Base
  has_many :administrative_privileges
  has_many :administrators,
    through: :administrative_privileges,
    source: :user
end

名前ながいな!って思うけど、今後新しくジョインするメンバーはソースコードを読んで、その関連モデルが一体なんのための関連モデルか悩まずに済むんじゃなかろうか。

よりよい命名があったら教えてほしい。