我是ruby的新手,在下面的场景中遇到了麻烦。我正在努力建立账单和项目之间的关系。在我的情况下,我想在运行时生成一个账单,比如当用户点击创建新账单时,他会被引导到一个路径,比如http://localhost:3000/bills/new然后他有一个项目列表,他必须通过选中复选框并添加数量来从中进行选择。我有三张桌子,物品,账单,账单。它们有以下字段:
create_table "bill_items", force: :cascade do |t|
t.integer "bill_id"
t.integer "item_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "quantity"
end
create_table "bills", force: :cascade do |t|
t.integer "user_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "items", force: :cascade do |t|
t.string "name"
t.float "price"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "category_id"
end
我的模型是这样创建的:
帐单.rb
class Bill < ApplicationRecord
has_many :bill_items
has_many :items, through: :bill_items
accepts_nested_attributes_for :bill_items, :allow_destroy => true, :reject_if => :all_blank
end
项目.rb
class Item < ApplicationRecord
has_many :bill_items
has_many :bills, through: :bill_items
end
BillItem.rb
class BillItem < ApplicationRecord
belongs_to :bill
belongs_to :item
end
我的表格如下:
<%= form_for @bill do |f| %>
<% if @allItems %>
<% @allItems.each_with_index do |item, index| %>
<tr class="table-success" scope="col-8">
<%= f.fields_for :bill_items do |s| %>
<td class="text-secondary"><%= item.category.name %></td>
<%= s.hidden_field :name, value: item.name %>
<td class="text-primary"><%= s.label item.name %></td>
<td><%= check_box_tag "item_ids[]", item.id, false, class: 'selectable' %> </td>
<td><%= s.number_field(:quantity, in: 1.0..100.0, step: 1) %></td>
<td><%= s.label :price, item.price %></td>
<% end %>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<div class="form-group row justify-content-center">
<%= f.submit "Create Order with Selected items", class: "btn btn-secondary" %>
</div>
<% end %>
然后我的控制器设置如下:
def new
@bill = Bill.new
@bill_items = @bill.bill_items.build
end
def create
byebug
@bill = Bill.new(bill_params)
@bill.save
redirect_to new_bill_path
end
private
def bill_params
params.require(:bill).permit(bill_items_attributes: [:quantity, :item_ids])
end
当我运行代码并将数据发送到表单并通过byebug检查参数时,它会显示以下参数,而我选择了ID 1和4的两个项目:
<ActionController::Parameters {"authenticity_token"=>"hVnrTkWxWwuXqS4tb01INVkNwRaFooVERKe2L8YkXykyPqImKCVRrvqjhK8sA0Q26nsOS+dSNdLvIOPTfis8nQ==", "bill"=>{"bill_items_attributes"=>{"0"=>{"name"=>"sheer", "quantity"=>"2"}, "1"=>{"name"=>"burger", "quantity"=>""}, "2"=>{"name"=>"custurs", "quantity"=>""}, "3"=>{"name"=>"sib", "quantity"=>"4"}}}, "item_ids"=>["1", "4"], "commit"=>"Create Order with Selected items", "controller"=>"bills", "action"=>"create"} permitted: false>
然后我点击提交,它只在数据库中保存账单,并给我错误
Unpermitted parameter: :name
Unpermitted parameter: :name
Unpermitted parameter: :name
Unpermitted parameter: :name`
我尝试了很多技术,但都找不到解决方案。如果有人能帮我做这件事,那将是非常有帮助的。即使我需要重新设计我的逻辑,也要帮助我。谢谢
<td><%= check_box_tag "item_ids[]", item.id, false, class: 'selectable' %> </td>
必须是
<td><%= check_box_tag "bill[item_ids[]]", item.id, false, class: 'selectable' %> </td>
问题:命名的嵌套属性不匹配
票据模型接受:items
的嵌套属性在控制器上,您已指定:bill_items_attributes
和表单生成bill_items的字段-f.fields_for :bill_items
解决方案:使一致
票据模型-
accepts_nested_attributes_for :items
票据控制器-
permit(items_attributes:
表单new.html.erb-
f.fields_for :items
然而,这将给items_id带来另一个问题,我不确定在那里要实现什么。
您收到这些错误是因为您在表单中有隐藏字段:name
,这在提交表单时是不需要的。我删除了它。但是,强参数和复选框命名存在问题。我纠正了强参数,并保留了复选框命名的描述性,这样你就可以看到表单将如何生成它
试试这个代码。我能够用这个代码创建记录。
bills_controller.rb
private
def bill_params
params.require(:bill).permit(bill_items_attributes: [:quantity, :item_id])
end
new.html.erb
<%= form_for @bill do |f| %>
<% if @allItems %>
<% @allItems.each_with_index do |item, index| %>
<%= f.fields_for :bill_items do |s| %>
<tr class="table-success" scope="col-8">
<td class="text-primary"><%= s.label item.name %></td>
<td><%= check_box_tag "bill[bill_items_attributes][#{index}][item_id]", item.id, false, class: 'selectable' %> </td>
<td><%= s.number_field(:quantity, in: 1.0..100.0, step: 1) %></td>
<td><%= s.label :price, item.price %></td>
</tr>
<% end %>
<% end %>
<% end %>
<div class="form-group row justify-content-center">
<%= f.submit "Create Order with Selected items", class: "btn btn-secondary" %>
</div>
<% end %>