允许类别中的多个记录提交到列表
如果选择了多个列表,我希望将多个(数组……)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
用于创建列表的表单视图(简要说明):
"Select a Category" %> "Select a Category" %> "Select a Category" %> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "Select a Category" %> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我在“~~~~~~~~~~~~~~~~~~~~~”之间尝试测试它。 它们甚至没有出现在forms中,我不知道为什么。
当我使用第一个“form.select:category_id”时会出现3次下拉,只有最后选择的下拉保存。 如果我选择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
查看表格:
"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个单独的类别,则只选择最后一个类别。 我希望能够为每个列表选择多个类别。
当然,对于同一属性 ,您有三个相同的下拉列表 ,它只会选择最后一个下拉列表的选定值并将其传递给params
。
您需要将其设置为一个下拉列表,并允许多次选择
<%= 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将使用这些关联为连接表创建条目 。
:multiple => true
允许您选择多个选项并将这些ids
作为数组传递。 比如像category_ids: ["1","2","3"]
现在转到您的控制器代码,您不应该根据您的方法不同来构建类别列表 。 将您的新方法更改为以下
def new @listing = Listing.new end
没有必要使用@categories = Category.all
因为您在select
中明确调用了Category.all
最后listing_params
了listing_params
category_ids
白名单
params.require(:listing).permit(:attr1, .... category_ids: [])
我在“~~~~~~~~~~~~~~~~~~~~~”之间尝试测试它。 它们甚至没有出现在forms中,我不知道为什么。
好吧,你搞乱了accepts_nested_attributes_for
以及fields_for
。 继续阅读!
注意:
另外,正如@IIya Konyukhov所提到的,对于HABTM关联 ,您的架构看起来不同。 您应该更改您的架构,以满足您的工作方法的需要。
更新#1
我使用类别作为搜索列表的方式。 所以我想在创建列表时,能够选择多个类别以与列表一起使用。 和类别将是预先定义的。
上面提到的方法应该符合您的需要,但是在您的代码中需要进行更多调整才能使其正常工作。
1) Category
模型中的关联存在缺陷。 您需要将has_many :listings
has_and_belongs_to_many :listings
更改为has_and_belongs_to_many :listings
2)从Category模型中删除validates_uniqueness_of :category
,因为它无效。
3)从listings
表中删除category_id
4)为listings
和categories
生成HABTM联合表,如下所示
rails generate migration CreateJoinTableCategoryListing category listing
现在,在保存列表后,引擎盖下的rails将为categories_listings
创建条目,这对于上述方法是正确的。
虽然管理员(而非用户)可以/应该添加新的,然后可以将类别添加到现有或新的列表中
这也可以通过与上述相同的方法来完成,以创建具有现有类别的新列表。 只需呈现列表的编辑表单即可为现有列表添加现有类别。 您只需要确保这些路由不同,并且只能由管理员访问。
更新#2:
您需要删除Listing
模型中的当前关联,并在其中添加以下代码。
#listing.rb has_and_belongs_to_many :categories
并从params列表中删除category_id
。 只需保留category_ids: []
params.require(:listing).permit(:attr1, :name, :description, :price, :image, category_ids: [])
您的数据关系似乎不正确。 看一看:
-
Category
模型validationcategory
唯一性。 但是类别表中没有字段类别。 似乎应该使用名称。 -
Listing
模型has and belongs to many
categories
。 对于Rails,它意味着这两个表通过3rd表,categories_listings
连接,其中包含category_id
和listing_id
。 但是你的数据库模式是不同的 – 在你的表中,category_id
属于listings
表,它与[Category
modelhas many
listings
]关联相匹配。 有一个矛盾。
我会将数据模型视为整个应用程序的基础。 拥有正确的数据模型,为控制器和视图编写代码变得透明和明显。 首先修复数据模型并使用嵌套属性来保存关联模型。
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 %>