Rails 4 - 遍历深度嵌套的参数以防止将密码字段更新为空白

Rails 4 - Loop through deeply nested params to prevent update of password field to blank

在编辑表单中,现有密码在表单中显示为空白,这似乎是默认的 Rails 行为。但是,我正在尝试避免在未输入新密码时将密码(或在我的情况下为密码s)更新为空白,类似于此处描述的内容:

Rails Activerecord update saving unedited field as blank

对我来说不同的是密码字段嵌套更深,而且不止一个。

基本上我有一个小型银行转账应用程序,其中每个 :transfer 有两个 :transfer_accountssourcedestination (transfer_accounts 是一个 "has_many, through" 加入 table 用于转账和账户)并且两个转账账户都有一个 :account:password 属性。

我的尝试在更新操作的顶部是这样的:

params[:transfer][:transfer_accounts_attributes].each do |k, v|
  v[:account_attributes][:password].delete if v[:account_attributes][:password].empty?
end  

这没用。留空的密码将更新为空。

如果参数留空,我将如何遍历参数并防止其中一个或两个密码更新?

这是我的控制器:

class TransfersController < ApplicationController

  def new
    @transfer = Transfer.new
    @transfer.transfer_accounts.build(account_transfer_role: 'source').build_account
    @transfer.transfer_accounts.build(account_transfer_role: 'destination').build_account
    @valid_banks = Bank.all.collect {|c| [c.name, c.id]}  # available banks seeded in database
  end

  def index
    @transfers = Transfer.all
  end

  def show
    @transfer = resource
  end

  def create
    @transfer = Transfer.new(transfer_params)
    if @transfer.save
      redirect_to transfers_path, notice: "Transfer Created"
    else
      redirect_to transfers_path, alert:  "Transfer Not Created"
    end
  end

  def edit
    resource
    @valid_banks = Bank.all.collect {|c| [c.name, c.id]}  # available banks seeded in database
  end

  def update
    if resource.update_attributes(transfer_params)
      redirect_to transfers_path(resource),     notice: "Transfer Updated"
    else
      redirect_to edit_transfer_path(resource), alert:  "Transfer Not Updated"
    end
  end

  def destroy
    resource.destroy
  end


  private

  def resource
    @transfer ||= Transfer.find(params[:id])
  end

  def transfer_params
    params.require(:transfer).
      permit(:name, :description,
             transfer_accounts_attributes:
               [:id, :account_transfer_role,
                account_attributes:
                  [:id, :bank_id, :name, :description, :user_name,
                   :password, :routing_number, :account_number
                  ]
               ])
  end

end
params[:transfer][:transfer_accounts_attributes].each do |k, v|
  v[:account_attributes].delete(:password) if v[:account_attributes][:password].blank?
end

您必须调用 hash.delete,而不是删除已经为空的值的内容。 .blank? 也是你的朋友,因为它会处理 nil 和 == ''