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_accounts
、source 和 destination (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 和 == ''
。
在编辑表单中,现有密码在表单中显示为空白,这似乎是默认的 Rails 行为。但是,我正在尝试避免在未输入新密码时将密码(或在我的情况下为密码s)更新为空白,类似于此处描述的内容:
Rails Activerecord update saving unedited field as blank
对我来说不同的是密码字段嵌套更深,而且不止一个。
基本上我有一个小型银行转账应用程序,其中每个 :transfer
有两个 :transfer_accounts
、source 和 destination (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 和 == ''
。