允许类别中的多个记录提交到列表 [英] Allowing multiple records in category to submit to listing

查看:52
本文介绍了允许类别中的多个记录提交到列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果选择了多个,我希望将多个(一组...)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) 为 listingscategories 生成一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆