Rails 4 - цикл через глубоко вложенные параметры, чтобы предотвратить обновление поля пароля до пустого

В форме редактирования существующий пароль отображается в форме пустым, что, по-видимому, является поведением Rails по умолчанию. Однако я пытаюсь избежать обновления пароля (или в моем случае passwords) до пустого, если новый пароль не введен, подобно тому, что описано здесь:

Обновление Rails Activerecord с сохранением неотредактированного поля как пустого

Разница для меня в том, что поле пароля более глубоко вложено и их больше одного.

По сути, у меня есть небольшое приложение для банковских переводов, в котором для каждого :transfer есть два :transfer_accounts, источник и назначение (transfer_accounts — это таблица соединений «has_many, through» для переводов и аккаунты), и оба трансферных аккаунта имеют атрибут :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

person eggroll    schedule 06.11.2015    source источник
comment
Можете ли вы показать содержимое вашего params хэша для запроса?   -  person K M Rakibul Islam    schedule 06.11.2015
comment
Кроме того, попробуйте использовать blank? вместо empty? и посмотрите, есть ли разница? v[:account_attributes][:password].blank?   -  person K M Rakibul Islam    schedule 06.11.2015
comment
Я использовал пустой? вместо пустого?, но получил тот же результат.   -  person eggroll    schedule 06.11.2015
comment
КЛЮЧ: 0, ЗНАЧЕНИЕ: {account_transfer_role=›источник, account_attributes=›{bank_id=›2, name=›Проверка Джо, описание=›Личный расчетный счет Джо, user_name=›joechk, password=›change, account_number=›123456789, routing_number=›1122334455, id=›1}, id=›1} КЛЮЧ: 1, ЗНАЧЕНИЕ: {account_transfer_role=›destination, account_attributes=›{bank_id=›3, name=›Сбережения Джо, description=›Личный сберегательный счет Джо , user_name=›joesav, password=›change, account_number=›098765432, routing_number=›0099887766, id=›2}, id=›2}   -  person eggroll    schedule 06.11.2015


Ответы (1)


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 и == ''.

person James Daniels    schedule 06.11.2015
comment
Это сработало отлично! У меня было ощущение, что я делаю то, что вы описываете, удаляя пустое значение, но я не был уверен, как правильно с этим справиться. Спасибо, Джеймс! (p.s. еще нет репутации, чтобы голосовать) - person eggroll; 06.11.2015