日々の反省

学んだことをつらつらと書いていきます。

Rails4のルール 関連付け編


スポンサードリング

関連付けの実現

関連付けは非常に便利である一方、使い方を間違えるとパフォーマンスを大きく落とします。だからそんなに好きじゃなかったです。でも便利な部分もいっぱいあります。バランスを見て今後困らないようにという視点で選択していくことが大事だと思っています。Railsを利用するシーンとしてとにかく早くものを作り、一旦リリースしたい!というのが強ければガンガンに利用してサッと創りあげたいところです。あまりプロダクトが太りすぎないうちに次のステップとしてアプリケーションの特性に応じた対策を行いましょう。もちろんRailsそのものを捨てるのも選択肢ですね。
ちょっと脱線しましたが、、とにかくルールを知っておくことは大事です。サッと調べたい時にご利用ください。

関連付けの種類

種類 多重度 関係先の指定 説明 model migration
belongs_to 1対1 単数形 外部キーを持っている側のテーブルに対するモデルに指定する。従属している状態であり相手方で何かしらのアクションがあった場合に影響を受ける(こともできる) belongs_to customer t.belongs_to :customer
has_one 1対1 単数形 1対1関連の時に外部キーを持っていない側で利用する。 has_one attribute t.belongs_to :customer
has_many 1対多 複数 0個以上のインスタンスを保持する側で利用する。反対側にはbelongs_toを利用。 has_many orders t.belongs_to :customer
has_many :through 多対多 複数 結合モデルを介して多対多関連を表現するために利用する。例えばプロジェクトが並行して進んでおり担当者が入り乱れている場合などを表現します。 projectから見た場合は has_many asigns has_many members through: :asigns memberから見た場合は has_many asigns has_many projects through: asigns asignsで t.belongs_to :memnbers t.belongs_to :projects
has_one :through 1対1 単数形 結合モデルを介して1対1関連を方言するために利用します。 has_one :結合モデルの先のモデル through: 結合モデル t.belongs_to 結合モデル
has_and_belongs_to_many 多対多 複数 結合モデルを介さずに多対多関連を表現するために利用する。実際には中間テーブルが必要だが実装上必要無い場合に採用する has_and_belongs_to_many :結合先モデル t.belongs_to :結合モデル

ポリモーフィック関連付け

1つのモデルが複数のモデルと関連している場合に1つの関連付けだけで表現することができる。例えばcommentモデルはtaskとscheduleの両方に関連している場合は以下のようになる。

class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
end
 
class Task < ActiveRecord::Base
  has_many :comments, as: :commentable
end
 
class Schedule < ActiveRecord::Base
  has_many :comments, as: :commentable
end

Migration上では以下のように記載することで実現できる。

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string  :title
      t.references :commentable, polymorphic: true
      t.timestamps
    end
  end
end

自己結合

自分自身への結合を表現することも可能です。ここはRailsガイドからそのままの例ですが、上司と部下の関係なら以下のようになります。

class Employee < ActiveRecord::Base
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id"
 
  belongs_to :manager, class_name: "Employee"
end

マイグレーション上は以下のとおり。簡単ですね~

class CreateEmployees < ActiveRecord::Migration
  def change
    create_table :employees do |t|
      t.references :manager
      t.timestamps
    end
  end
end

参考

その他の細かいところはRailsガイドでご確認を!

railsguides.jp