允许类别中的多个记录提交到列表
Allowing multiple records in category to submit to listing
如果选择了多个,我希望将多个(一组...)category_id 保存到每个列表中。以下是所有内容的设置方式,包括类别如何与列表一起使用。
类别模型:
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
方案(针对类别和列表):
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 在我需要添加它们时输入它们。
新上市控制器:
def new
@listing = Listing.new
@categories = Category.all
3.times do
@listing.categories.build
end
end
用于创建列表的表单视图(简要):
<%= 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.select :category_id" 弹出 3 个下拉菜单时,只有最后一个 selected 下拉菜单保存。如果我 select 3 个不同的类别,只有最后一个被选中的会被保存。我希望能够为每个列表选择多个类别。
创建新列表时如何允许保存多个类别?是否下拉,复选框等。如果用户选择了多个,则只需要多个保存到一个列表的可能性。
更新:
架构:
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 "categories_listings", id: false, force: :cascade do |t|
t.integer "category_id", null: false
t.integer "listing_id", null: false
end
查看表单:
<%= 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
您的数据关系似乎有误。看看:
Category
模型验证 category
的唯一性。但是categoriestable里面没有字段类别。似乎应该改用名字。
Listing
型号 has and belongs to many
categories
。对于 Rails,这意味着这 2 个 table 通过第 3 个 table、categories_listings
连接,其中包含 category_id
和 listing_id
。但是您的数据库架构不同 - 在您的 table 中 category_id
属于 listings
table,它匹配 [Category
模型 has many
listings
] 协会。有矛盾。
我会将数据模型视为整个应用程序的基础。拥有正确的数据模型,为控制器和视图编写代码变得透明和明显。首先修复您的数据模型并使用 nested attributes 保存关联模型。
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.
当然,对于相同的属性,您有三个相同的下拉菜单,它只会选择最后一个下拉菜单的select编辑值并将其传递给 params
.
您需要将其设置为一个下拉菜单并允许多个select离子像这样
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category", :multiple => true %>
请注意 :category_ids
和 :multiple => true
的变化。 :category_ids
是一种为 多对多 关联提供的方法(collection_singular_ids
),Rails 将在幕后将其用于 为加入的 table.
创建条目
:multiple => true
允许您 select 多个选项并将那些 ids
作为数组传递。比如这样 category_ids: ["1","2","3"]
现在来看您的控制器代码,您不应该为类别构建列表,因为您的方法不同。将您的新方法更改为以下
def new
@listing = Listing.new
end
也没有必要 @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
and as well with fields_for
。继续阅读!
注:
此外,正如 @IIya Konyukhov 提到的,您的模式对于 HABTM 关联来说看起来不同。您应该更改架构以适应您的工作方法的需要。
更新 #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.
上述方法应该符合您的需要,但您的代码中需要进行更多调整才能使其正常工作。
1) Category
模型中的关联存在缺陷。您需要将 has_many :listings
更改为 has_and_belongs_to_many :listings
2) 从类别模型中删除 validates_uniqueness_of :category
,因为它无效。
3) 从 listings
table
中删除 category_id
4) 为 listings
和 categories
生成一个 HABTM joined-table 如下
rails generate migration CreateJoinTableCategoryListing category listing
现在保存列表后,rails 将在后台为 categories_listings
创建条目,这对于上述方法是正确的。
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
这也可以通过与上述相同的方法来创建具有现有类别的新列表。只需呈现列表的编辑表单即可为该现有列表添加现有类别。您只需要确保这些路由不同并且只能由管理员访问。
更新#2:
您需要删除 Listing
模型中的当前关联并在其中添加以下代码。
#listing.rb
has_and_belongs_to_many :categories
并从参数列表中删除 category_id
。只要保持 category_ids: []
params.require(:listing).permit(:attr1, :name, :description, :price, :image, category_ids: [])
has_and_belongs_to_many 只支持嵌套参数数组
你应该允许这样的参数 params.require(:listing).permit(:attr, ..., category_ids: [])
然后使用此代码更改表格
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select Categories", multiple: true %>
如果选择了多个,我希望将多个(一组...)category_id 保存到每个列表中。以下是所有内容的设置方式,包括类别如何与列表一起使用。
类别模型:
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
方案(针对类别和列表):
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 在我需要添加它们时输入它们。
新上市控制器:
def new
@listing = Listing.new
@categories = Category.all
3.times do
@listing.categories.build
end
end
用于创建列表的表单视图(简要):
<%= 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.select :category_id" 弹出 3 个下拉菜单时,只有最后一个 selected 下拉菜单保存。如果我 select 3 个不同的类别,只有最后一个被选中的会被保存。我希望能够为每个列表选择多个类别。
创建新列表时如何允许保存多个类别?是否下拉,复选框等。如果用户选择了多个,则只需要多个保存到一个列表的可能性。
更新:
架构:
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 "categories_listings", id: false, force: :cascade do |t|
t.integer "category_id", null: false
t.integer "listing_id", null: false
end
查看表单:
<%= 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
您的数据关系似乎有误。看看:
Category
模型验证category
的唯一性。但是categoriestable里面没有字段类别。似乎应该改用名字。Listing
型号has and belongs to many
categories
。对于 Rails,这意味着这 2 个 table 通过第 3 个 table、categories_listings
连接,其中包含category_id
和listing_id
。但是您的数据库架构不同 - 在您的 table 中category_id
属于listings
table,它匹配 [Category
模型has many
listings
] 协会。有矛盾。
我会将数据模型视为整个应用程序的基础。拥有正确的数据模型,为控制器和视图编写代码变得透明和明显。首先修复您的数据模型并使用 nested attributes 保存关联模型。
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.
当然,对于相同的属性,您有三个相同的下拉菜单,它只会选择最后一个下拉菜单的select编辑值并将其传递给 params
.
您需要将其设置为一个下拉菜单并允许多个select离子像这样
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category", :multiple => true %>
请注意 :category_ids
和 :multiple => true
的变化。 :category_ids
是一种为 多对多 关联提供的方法(collection_singular_ids
),Rails 将在幕后将其用于 为加入的 table.
:multiple => true
允许您 select 多个选项并将那些 ids
作为数组传递。比如这样 category_ids: ["1","2","3"]
现在来看您的控制器代码,您不应该为类别构建列表,因为您的方法不同。将您的新方法更改为以下
def new
@listing = Listing.new
end
也没有必要 @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
and as well with fields_for
。继续阅读!
注:
此外,正如 @IIya Konyukhov 提到的,您的模式对于 HABTM 关联来说看起来不同。您应该更改架构以适应您的工作方法的需要。
更新 #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.
上述方法应该符合您的需要,但您的代码中需要进行更多调整才能使其正常工作。
1) Category
模型中的关联存在缺陷。您需要将 has_many :listings
更改为 has_and_belongs_to_many :listings
2) 从类别模型中删除 validates_uniqueness_of :category
,因为它无效。
3) 从 listings
table
category_id
4) 为 listings
和 categories
生成一个 HABTM joined-table 如下
rails generate migration CreateJoinTableCategoryListing category listing
现在保存列表后,rails 将在后台为 categories_listings
创建条目,这对于上述方法是正确的。
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
这也可以通过与上述相同的方法来创建具有现有类别的新列表。只需呈现列表的编辑表单即可为该现有列表添加现有类别。您只需要确保这些路由不同并且只能由管理员访问。
更新#2:
您需要删除 Listing
模型中的当前关联并在其中添加以下代码。
#listing.rb
has_and_belongs_to_many :categories
并从参数列表中删除 category_id
。只要保持 category_ids: []
params.require(:listing).permit(:attr1, :name, :description, :price, :image, category_ids: [])
has_and_belongs_to_many 只支持嵌套参数数组
你应该允许这样的参数 params.require(:listing).permit(:attr, ..., category_ids: [])
然后使用此代码更改表格
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select Categories", multiple: true %>