has_manyな関連性のモデルを、元レコードの保存時に削除する


ActiveRecordでhas_manyを指定しているモデルを操作する画面を作る時に、以下の様な事で悩んでいた

class Account < ActiveRecord::Base
  has_many :roles
end

class Role < ActiveRecord::Base
  belongs_to :account
end

# コントローラー側のメソッド内
def update 
  account = Account.find_by(params[:id])

  account.roles = [] #=> ここでrolesがdeleteされてしまう
  params[:roles].each do | role | 
    # ...
  end

  unless account.save
    render :action => "edit"
  end
end

account.rolesにパラメータが来てないものは削除したいが、削除するために=[]とするとその時点で保存されてしまう

has_manyで保存時に作成するものはbuildで良いが、削除はどうするのか……
と探していたらあった。

has_many側の不要なやつはdeleteして更新したい
http://d.hatena.ne.jp/itmammoth/20120422/1335087511

def update 
  account = Account.find_by(params[:id])

  params[:roles].each do | role | 
    # ...
  end
  account.roles.each do | role | 
    role.mark_for_destruction unless roles.map{|r| r[:name]}.include?(role.name)
  end

  unless account.save
    render :action => "edit"
  end
end

なお、このレコードが削除フラグが立っているかは marked_for_destruction?で見れば良い

role.marked_for_destruction?

もっと良い方法があれば是非教えてください