22

私は自分の関係にnested_form宝石を使用しています。AddressBookユーザーが既存の値を空白にした場合、空白で保存するのではなく、Addrそれを削除したいAddrvalue

class Person < ActiveRecord::Base
  has_many :addrs, dependent: :destroy
  attr_accessible :name, :addrs_attributes
  accepts_nested_attributes_for :addrs, reject_if: :addr_blank, allow_destroy: true

  def addr_blank(a)
    valid? && a[:id].blank? && a[:value].blank? 
  end

class Addr < ActiveRecord::Base
  belongs_to :person
  attr_accessible :kind, :label, :value, :person_id

私の:reject_if方法はうまく機能しますが、必要なものがすべて得られるわけではありません

  1. valid?検証を通じて空白のアドレスを保持します
  2. a[:id].blank?ユーザーが空白にして既存のレコードを削除した場合の拒否を回避します

ここでAddr、ユーザーがvalue. また、RESTful API を介して Person と Addrs を公開しています。次の 2 つのオプションが考えられます。

  1. paramsハッシュを後処理して、魔法のパラメーターを追加します_destroy=1。IOW、削除ボタンを押すユーザー アクティビティをエミュレートします。
  2. これをモデル内にカプセル化Addrして、空白の更新valueが事実上削除と見なされるようにします。

ここでのアドバイスに基づいて、私がそれを実装した方法は次のとおりです。

people_controller.rb

def update
  @person = Person.find(params[:id])
  @person.destroy_blank_addrs(params[:person])
  respond_to do |format|
  ...

person.rb

def destroy_blank_addrs(person_params)
  if valid? && person_params[:addrs_attributes]
    person_params[:addrs_attributes].each do |addr_params_array|
      addr_params= addr_params_array[1] 
      addr_params[:_destroy] = '1' if !addr_params[:id].blank? && addr_params[:value].blank? 
    end
  end
end
4

4 に答える 4

10
accepts_nested_attributes_for :addrs, 
  allow_destroy: true, 
  reject_if: -> { |attr| [name, description].any? &:blank? }
于 2014-07-21T13:01:18.257 に答える
5

before_save3 番目の方法は、空のアドレスをすべて削除するコールバックを Personに追加することです。このアイデアにはある程度のメリットがありますが、私はおそらくそれを採用しません。

あなたが提示した2つのオプションのうち、私はパラメータの後処理には行きません. それはうまくいくでしょうが、それはあまりにも多くの仕事です。その上、コントローラーのコードは少し乱雑になりますが、私は非常にスリムなコントローラーを強く信じています。

私の頭の中で最も簡単なオプションは、保存後に空白のアドレスを削除することです。追加Person#remove_blank_addresses()して、保存が成功したときに呼び出すことができます。パラメータを渡す必要はありません。アドレスを反復処理して空白のアドレスを削除するだけです。空のアドレスを作成してから破棄するという欠点がありますが、とにかく人を更新するにはそれが必要です.

(私の意見では) 最もクリーンなソリューションについて話している場合は、そのすべてのロジックを処理し、コントローラーを委任する 3 番目のクラスを導入します。コントローラーは単独で簡単にテストできるので、すべての核心的な詳細をチェックするモデル仕様を作成できます。もう少し作業が必要で、今はいい名前PersonUpdaterが思い浮かびませんが (?)、考えてみる価値のあるアイデアかもしれません。

于 2012-07-19T22:18:51.317 に答える