允许类别中的多个记录提交到列表 [英] Allowing multiple records in category to submit to listing
问题描述
如果选择了多个,我希望将多个(一组...)category_id 保存到每个列表中.以下是所有设置的方式,包括类别如何与列表一起工作.
I want multiple (an array of...) category_id's to be saved to each listing, if more than one are chosen. Below is how everything is set up, including how categories work alongside with listings.
类别模型:
class Category < ApplicationRecord
validates_uniqueness_of :category
has_many :listings
上市模型:
has_and_belongs_to_many :categories, required: false
attr_accessor :new_category_name
before_save :create_category_from_name
# has_many :categories
方案(用于类别和列表):
Scheme (for categories and listings):
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "listings", force: :cascade do |t|
t.string "name"
t.text "description"
t.decimal "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image"
t.integer "user_id"
t.integer "category_id"
t.index ["category_id"], name: "index_listings_on_category_id"
end
然后我在 seed.rb 中定义了类别,然后在需要添加它们时使用 rails db:seed 输入它们.
I then have the categories defined within the seed.rb and then rails db:seed to input them when i need to add them.
列出新控制器:
def new
@listing = Listing.new
@categories = Category.all
3.times do
@listing.categories.build
end
end
用于创建列表的表单视图(简要):
Form Views for creating a Listing (in brief):
<%= form_with(model: listing, local: true) do |form| %>
<%= form.label "Choose Up to 3 Categories (1 required)"%>
<div class="space">
<%= form.select :category_id, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category" %>
<%= form.select :category_id, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category" %>
<%= form.select :category_id, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category" %>
</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<%= form.label "Choose Up to 3 Categories (1 required)"%>
<div class="space">
<% form.fields_for :category_id do |c| %>
<%= c.select :category_id, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category" %>
<% end %>
</div>
<% form.fields_for :category_id do |c| %>
<%= c.text_field :category_id %>
<% end %>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<%= form.label "最多选择 3 个类别(需要 1 个)"%><div class="space"><% form.fields_for :category_id 做 |c|%><%= c.select :category_id, options_from_collection_for_select(Category.all, :id, :name), :prompt =>选择一个类别"%><%结束%>
Between the "~~~~~~~~~~~~~~~~~~~~~" are my attempts to testing it. They don't even show up within the form though, which I don't know why.
<% form.fields_for :category_id 做 |c|%><%= c.text_field :category_id %><%结束%>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When I use the first "form.select :category_id" which brings up 3 drop downs, only the last selected drop down saves. If i select 3 separate categories, only the last one picked will save. I want to be able to have multiple categories chosen for each listing.
在~~~~~~~~~~~~~~~~~~~~~"之间是我测试它的尝试.他们甚至没有出现在表单中,我不知道为什么.
How do i allow multiple categories to be saved when creating a new listing? Whether a dropdown, checkboxes, etc. Just need the possibility of more than one to save to one listing, if more than one are chosen by the user.
当我使用第一个form.select :category_id"时,它会显示 3 个下拉列表,只有最后一个选择的下拉列表会保存.如果我选择 3 个单独的类别,则只有最后一个选择会保存.我希望能够为每个列表选择多个类别.
UPDATE:
如何在创建新列表时允许保存多个类别?无论是下拉菜单、复选框等.如果用户选择了多个列表,则只需要保存多个列表的可能性即可.
Schema:
更新:
架构:
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category", :multiple => true %>
查看表单:
params.require(:listing).permit(:attr1, :name, :description, :price, :image, :category_id, category_ids: [])
控制参数:
Category
has_and_belongs_to_many :listings
Listing
belongs_to :category, required: false
belongs_to :categories_listings, required: false
型号:
解决方案
推荐答案
当我使用第一个form.select :category_id"时,它带来了 3 滴下来,只有最后选择的下拉保存.如果我选择 3 个单独的类别,只有最后一个选择会保存.我希望能够为每个列表选择多个类别.
You need to set it as one dropdown and allow multiple selections on it like so
当然,对于相同的属性,您有三个相同的下拉列表,它只会选择最后一个下拉列表的选定值并将其传递给params代码>.
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category", :multiple => true %>
您需要将其设置为一个下拉菜单并允许多选像这样
Notice the changes :category_ids
and :multiple => true
. :category_ids
is a method(collection_singular_ids
) that ships for many-to-many associations which will be used by Rails under the hood to create entries for the joined table.
:multiple => true
allows you to select more than one option and pass those ids
as array. For instance like this category_ids: ["1","2","3"]
注意 :category_ids
和 :multiple => 的变化真的
.:category_ids
是一种方法(collection_singular_ids
) 用于多对多关联,Rails 在后台使用这些关联为连接表创建条目.
Now coming to your controller code, you shouldn't be building the listings for categories as your approach is different. Change you new method to below
:multiple =>true
允许您选择多个选项并将这些 ids
作为数组传递.例如像这样 category_ids: ["1","2","3"]
def new
@listing = Listing.new
end
现在来看您的控制器代码,您不应该为类别构建列表,因为您的方法不同.将您的新方法更改为以下
It is also not necessary to have @categories = Category.all
as you are explicitly calling Category.all
in the select
And finally whitelist category_ids
in the listing_params
like so
也不需要 @categories = Category.all
,因为您在 select
中明确调用了 Category.all
>
最后在listing_params
中将category_ids
列入白名单
params.require(:listing).permit(:attr1, .... category_ids: [])
<块引用>
在~~~~~~~~~~~~~~~~~~~~~"之间是我测试它的尝试.他们甚至没有出现在表格中,我不知道为什么.
Between the "~~~~~~~~~~~~~~~~~~~~~" are my attempts to testing it. They don't even show up within the form though, which I don't know why.
好吧,你搞砸了accepts_nested_attributes_for
以及 fields_for
.继续阅读!
Well, you are messing up with accepts_nested_attributes_for
and as well with fields_for
. Read on!
注意:
另外,正如 @IIya Konyukhov 所提到的,对于 HABTM 关联,您的架构看起来有所不同.您应该更改您的架构以适应您的工作方式的需要.
Also as @IIya Konyukhov mentioned, your schema looks different for a HABTM association. You should alter your schema for to fit the needs of your approach to work.
更新 #1
我使用类别作为搜索列表的一种方式.所以我想要,创建列表时,能够选择多个类别跟着清单走.和类别将被预定义.
I'm using categories as a way to search through listings. so i want, when creating a listing, to be able to choose multiple categories to go along with the listing. and categories will be pre-defined.
上述方法应该可以满足您的需求,但需要在您的代码中进行更多调整才能使其正常工作.
The above mentioned approach should fit your need, but there are more tweaks need to be done in your code to make it work.
1) Category
模型中的关联有缺陷.您需要将 has_many :listings
更改为 has_and_belongs_to_many :listings
1) The associations in Category
model are flawed. You need to change has_many :listings
to has_and_belongs_to_many :listings
2) 从 Category 模型中删除 validates_uniqueness_of :category
,因为它无效.
2) Remove validates_uniqueness_of :category
from the Category model as it is not valid.
3) 从 listings
表中删除 category_id
3) Remove category_id
from listings
table
4) 为 listings
和 categories
生成一个 HABTM 连接表,如下所示
4) Generate a HABTM joined-table for listings
and categories
as below
rails generate migration CreateJoinTableCategoryListing category listing
现在保存列表后,引擎盖下的 rails 将为 categories_listings
创建条目,这对于上述方法是正确的.
Now upon saving the listing, rails under the hood will create entries for categories_listings
which will be correct for above mentioned approach.
虽然,管理员将/应该能够添加新的(而不是由用户)然后能够将类别添加到现有或新上市
Although, new ones will/should be able to be added by admins (not by users) to then have the ability to add the category to an existing or new listing
这也可以通过与上述相同的方法来完成,以使用现有类别创建新列表.只需渲染列表的编辑表单,即可为该现有列表添加现有类别.您只需要确保这些路由不同并且只能由管理员访问.
This can also be done by the same approach as above for to create a new listing with existing categories. And just render the edit form of the listing to add an existing category for that existed listing. You just need to make sure these routes are different and can only be accessed by admins.
更新 #2:
您需要在 Listing
模型中删除您当前的关联,并在其中添加以下代码.
You need to remove your current associations in Listing
model and add the following code in it.
#listing.rb
has_and_belongs_to_many :categories
并且还从参数列表中删除 category_id
.保持 category_ids: []
And also remove category_id
from the params list. Just keep category_ids: []
params.require(:listing).permit(:attr1, :name, :description, :price, :image, category_ids: [])
这篇关于允许类别中的多个记录提交到列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!