おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

nested attributes なレコードを、特定の属性が空の時に削除する

nested attributes なレコードを削除したい場合、accepts_nested_attributes_for に allow_destroy: true オプションを渡すと削除可能になります。削除するには、対象となる対象に { _destroy: 1 } のようなパラメータを渡します。

これを踏まえて素直にフォームを作ろうとすると、削除用のチェックボックスをつける事になるでしょう。しかし次のようなフォームにチェックボックスをつけると、ユーザにとってわかりづらいUIになってしまいます。単純にテキストフィールドを空にして更新したらレコードが削除されて欲しい。

f:id:willnet:20150725173208p:plain

そこで次のようにします。

class User < ActiveRecord::Base
  accepts_nested_attributes_for :family_members,
                                reject_if: :reject_family_member,
                                allow_destroy: true

  def reject_family_member(attributes)
    exists = attributes[:id].present?
    empty = attributes[:email].blank?
    attributes.merge!(_destroy: 1) if exists && empty
    !exists && empty
  end
end

reject_if の手続きの中で、レコードとして保存済みでかつメールアドレスが空のものに { _destroy: 1 } を追加しています。これでチェックボックスなしで nested attributes なレコードを削除することが出来ました。

参考

ruby on rails - Destroy on blank nested attribute - Stack Overflow