tl,dr :我如何通过嵌套属性确保我的has_many的顺序与构建中设置的属性值一致,并始终分配相同的嵌套参数哈希键号(0 ,1,等)并始终以相同的顺序出现在表单中?
希望我能描述一下这样才有意义。我有一个小型原型应用程序模拟两个帐户,源帐户和目标帐户之间的简单银行转帐。我有一个Transfer
类,一个Account
类和一个TransferAccounts
类,它是Transfer
和Account
之间many_to_many关联的直接连接。
以下是new
中的TransfersController
操作:
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
bank_selections
account_selections
end
强大的参数:
def transfer_params
params.require(:transfer).
permit(:name, :description,
transfer_accounts_attributes:
[:id, :account_id, :account_transfer_role,
account_attributes:
[:id, :bank_id, :name, :description, :user_name,
:password, :routing_number, :account_number
]
])
end
因此,与transfer_accounts
相关联的两个transfer
均具有account_transfer_role
属性,其中一个设置为 source ,另一个设置为< EM>目的地
现在,填写表单并提交时,参数在控制台中如下所示:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxxxxxxxxxxxxxxx==",
"transfer"=>{"name"=>"Test Transfer 2", "description"=>"Second test transfer",
"transfer_accounts_attributes"=>{"0"=>{"account_transfer_role"=>"source", "account_id"=>"1",
"account_attributes"=>{"bank_id"=>"1", "name"=>"George's Checking",
"description"=>"George's personal checking account", "user_name"=>"georgeckg",
"password"=>"[FILTERED]", "account_number"=>"111111111", "routing_number"=>"101010101",
"id"=>"3"}, "id"=>"3"}, "1"=>{"account_transfer_role"=>"destination", "account_id"=>"2",
"account_attributes"=>{"bank_id"=>"2", "name"=>"George's Savings",
"description"=>"George's personal savings account", "user_name"=>"georgesav",
"password"=>"[FILTERED]", "account_number"=>"111101111", "routing_number"=>"100100100",
"id"=>"4"}, "id"=>"4"}}}, "commit"=>"Update Transfer", "id"=>"2"}
如您所见,transfer_account
哈希中的每个transfer_account_attributes
都有一个ID键, 0 或 1 (例如..."0"=>{"account_transfer_role"=>"source"...
)。现在,我一直在假设(我认为可能会回来咬我,并且它已经),因为它们是在new
动作中构建的顺序,所以源 transfer_account
始终具有 0 的ID密钥,目标 transfer_account
的ID密钥始终为 1 ,这使我在控制器的其他地方使用这些id键,就好像 0 代表源而 1 代表目的地
所有似乎都工作正常,直到我尝试创建新帐户或使用现有帐户的不同排列,创建新的或编辑现有的转移,突然显示表单目的地列出第一< / strong>和 source second ,之前没有发生过,导致条目现在目的地与 0 与 1 关联的em>和 source ,打破了上面提到的控制器中的代码。
为了更清楚,以下是表格:
#transfer_form
= simple_form_for @transfer do |t|
.form-inputs
= t.input :name, label: 'Transfer Name'
= t.input :description, required: false, label: 'Transfer Description'
= t.simple_fields_for :transfer_accounts do |ta|
- role = ta.object.account_transfer_role.titleize
= ta.input :account_transfer_role, as: :hidden
= ta.input :account_id, collection: @valid_accounts,
include_blank: 'Select account...',
label: "#{ role } Account",
error: 'Account selection is required.'
.account_fields{id: "#{ role.downcase }_account_fields"}
= ta.simple_fields_for :account do |a|
= a.input :bank_id, collection: @valid_banks,
include_blank: 'Select bank...',
label: "#{ role } Bank",
error: 'Bank selection is required.',
class: "#{ role.downcase }_account_input_field"
= a.input :name, label: "#{ role } Account Name",
class: "#{ role.downcase }_account_input_field"
= a.input :description, required: false,
label: "#{ role } Account Description",
class: "#{ role.downcase }_account_input_field"
= a.input :user_name, label: "#{ role } Account User Name",
class: "#{ role.downcase }_account_input_field"
= a.input :password, label: "#{ role } Account Password",
class: "#{ role.downcase }_account_input_field"
= a.input :account_number, label: "#{ role } Account Number",
class: "#{ role.downcase }_account_input_field"
= a.input :routing_number, label: "#{ role } Account Routing Number",
class: "#{ role.downcase }_account_input_field"
= t.submit
如何确保 源始终是 ,因此始终与ID键 0 和 目标总是第二个 ,始终与ID键 1 相关联?
答案 0 :(得分:0)
答案似乎就像更改:transfer_accounts
模型中的Transfer
关联行一样简单:
has_many :transfer_accounts, inverse_of: :transfer
到此:
has_many :transfer_accounts, -> { order('account_transfer_role DESC') }, inverse_of: :transfer
如果有人认为它没有按我认为的那样做,请告诉我,因为目前它似乎正在解决我的问题。