Modelの関連付けを利用する

元記事はこちら

翻訳

Bad Smell

class PostsController < ApplicationController
  def create
    @post = Post.new(params[:post])
    @post.user_id = current_user.id
    @post.save
  end
end

この例では、user_idは明らかに@postに割り当てられます。大きな問題にはなりませんがModelの関連付けを利用すれば、この行は書かずに済みます。

Refactor

class PostsController < ApplicationController
  def create
    @post = current_user.posts.build(params[:post])
    @post.save
  end
end

class User < ActiveRecord::Base
  has_many :posts
end

userとpostの間に1対多の関連付けを定義したので、current_user.posts.build または current_user.posts.create によってpostを生成することができますし、current_userのidはactiverecordによって自動的にpostのuser_id属性に割り当てられます。

感想

動かすには

class Post < ActiveRecord::Base
  belongs_to :user
end

が必要かな。

正直このへんはよくわかっていないので整理。

Active Record の関連付け (アソシエーション) | Rails ガイド

アソシエーション 関連 特徴
belongs_to 1:1 外部キーを持つ方のモデルに設定する。
has_one 1:1 外部キーを持たれる方のモデルに設定する。
has_many 1:n 外部キーを持たれる方のモデルに設定する。
has_many :through n:n :through以下には中間テーブルの名前が入る
has_one :through 1:1 :through以下には中間テーブルの名前が入る
has_and_belongs_to_many n:n 中間テーブルのmodelを持たない。(DBにテーブルは必要)

リレーションシップのモデルそれ自体を独立したエンティティとして扱いたい(両モデルの関係そのものについて処理を行いたい)のであれば、中間に結合モデルを使用するhas_many :throughリレーションシップを選ぶのが最もシンプルです。リレーションシップのモデルで何か特別なことをする必要がまったくないのであれば、結合モデルの不要なhas_and_belongs_to_manyリレーションシップを使用するのがシンプルです

ふむ。関連テーブルをmodelから意識する必要がなければhas_and_belongs_to_manyを使うと。