22

我正在为我的关系使用nested_form宝石。AddressBook当用户将现有的值空白时Addr,我想删除它Addr而不是用空白保存value

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 公开 Persons 和 Addrs。我看到两种可能的选择:

  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|
  ...

人.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

18
accepts_nested_attributes_for :addrs, 
  allow_destroy: true, 
  :reject_if => proc { |att| att[:name].blank? && attr[:description].blank? }
于 2014-07-21T12:55:42.447 回答
10
accepts_nested_attributes_for :addrs, 
  allow_destroy: true, 
  reject_if: -> { |attr| [name, description].any? &:blank? }
于 2014-07-21T13:01:18.257 回答
5

第三种选择是before_save在 Person 上添加一个回调,它将删除所有空白地址。这个想法有一些优点,但我可能不会接受。

在您提供的两个选项中,我不会对参数进行后处理。会成功的,但工作量太大。此外,控制器代码会变得有点混乱,我坚信非常纤薄的控制器。

在我看来,最简单的选择是在保存后删除空白地址。您可以添加Person#remove_blank_addresses(),然后在成功保存时调用它。您不需要传递参数 - 它可以迭代地址并删除空白地址。它的缺点是创建空地址然后销毁它们,但无论如何你都需要它来更新人。

如果我们谈论的是最干净的解决方案(在我看来),我会引入第三个类来处理所有这些逻辑并让控制器委托给它。控制器很容易单独测试,然后您可以编写一个模型规范来检查所有细节。这是一个多一点的工作,我现在想不出一个好名字(PersonUpdater?),但这可能是一个值得思考的想法。

于 2012-07-19T22:18:51.317 回答
4
accepts_nested_attributes_for :addrs, 
  allow_destroy: true, 
  reject_if: :all_blank
于 2015-07-13T13:23:14.437 回答