我正在使用nested_form gem作为我的AddressBook关系.当用户空白现有Addr的值时,我想删除该Addr而不是使用空白值保存
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方法运行良好,但它不给我所需要的一切
>有效吗通过验证保持我的空白Addrs
> a [:id] .blank?当用户空白和现有记录时,避免拒绝
现在,当用户空白该值时,我需要删除(而不是保存)现有的Addr.此外,我通过RESTful API公开了Person和Addrs.我看到两个可能的选择:
> Post过程中的params哈希添加魔法_destroy = 1参数. IOW,模拟按下删除按钮的用户活动.
>将其封装在Addr模型中,使得具有空白值的更新被有效地视为删除.
根据这里的建议,我是如何实现的:
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
解决方法
第三种替代方法是在Person上添加一个before_save回调,将删除所有空白的地址.这个想法有一些优点,但我可能不会去.
在您提出的两个选项中,我不会通过后处理参数.它会奏效,但工作太多了.此外,对于控制器代码将会变得有点麻烦,我坚信一个非常苗条的控制器.
在我的头脑中,最简单的选择是在保存后删除空白地址.您可以添加Person#remove_blank_addresses(),然后在成功保存后调用它.您不需要传入参数 – 它可以迭代地址并删除空白地址.它的缺点是创建空地址,然后摧毁它们,但是您仍然需要更新人员.
如果我们谈论最干净的解决方案(在我看来),我将介绍一个第三个类来处理所有这些逻辑,并让控制器委托给它.控制器将足够轻松测试,然后您可以编写一个模型规范,以检查所有的细节细节.这是一个更多的工作,我现在不能想到一个好的名字(PersonUpdater?),但它可能是一个值得考虑的想法.