首页 > 解决方案 > 如何从 Rails 的下拉列表中设置值?

问题描述

我是铁轨上的初学者。我有产品 - 品牌列表。

路线 rb

Rails.application.routes.draw do
  get 'welcome/index'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  resources :brands do
    resources :products
  end
  root 'welcome#index'
end

品牌.rb

class Brand < ApplicationRecord
  has_many :products, dependent: :destroy
  validates :title, presence: true,
                    length: { minimum: 2 }
end

产品.rb

class Product < ApplicationRecord
  belongs_to :brand
end

产品.控制器

class ProductsController < ApplicationController
  #before_action :set_brand
  skip_before_action :verify_authenticity_token

  def new
    if params[:brand_id]
      @brand = Brand.find(params[:brand_id])
    end
    @product = Product.new

  end

  def edit
    @brand = @product.brand
     @product = Product.find(params[:id])
  end

  def update
    @brand = Brand.find(params[:brand_id])
    @product = Product.find(params[:id])
    @product.update(product_params)
    redirect_to brand_path(@brand)
  end

  def create
    @brand = Brand.find(params[:brand_id])
    @product = @brand.products.create(product_params)
    redirect_to brand_path(@brand)
  end

  def destroy
    @brand = Brand.find(params[:brand_id])
    @product = @brand.products.find(params[:id])
    @product.destroy
    redirect_to brand_path(@brand)
  end

  def update
    @brand = Brand.find(params[:brand_id])
    @product = @brand.products.find(params[:id])
    @product.destroy
  end

  helper_method :update

  private
    def product_params
      params.require(:product).permit(:name)
    end

    def set_brand
      @brand = Brand.find(params[:brand_id])
    end

end

.../products/new.html.erb

<h1>Add a new product</h1>
<%= form_with(model: [ @brand, @brand.products.build ], local: true) do |form| %>
  <p>
    <%= form.label :name,"Product name: " %><br>
    <%= form.text_field :name %>
  </p>

  <p>

  </p>
  <%= form.label :title,"Select a Brand" %>
  <%= form.collection_select(:brand_id, Brand.all, :id, :title,{selected: @brand.id}) %>

  <p>
    <%= form.submit "Add a product" %>
  </p>

<% end %>

new.html.erb 图片

所以我想从下拉列表中的选定项目中设置brand_id。在这种情况下,我为brand_id 选择了第一项,但我无法更改brand_id。如何设置从下拉列表中选择的brand_id?以及如何保存它。

标签: ruby-on-railsrubyruby-on-rails-4rubygemsruby-on-rails-5

解决方案


由于您已经将产品设置为嵌套资源,因此您既不需要也不想要该选择。brand_id 参数将通过路径(表单的操作属性)传递。用户将通过点击哪个链接进入新表单来选择他想要添加产品的品牌。

虽然您可以在表单中添加一个选择,但它是您发送时的主要 WTF 时刻:

POST /brands/1/products, { products: { brand_id: 5 }}

它最终创建了一个不属于品牌 1 的产品。如果表单中的参数是空白的,你也会得到一个非常奇怪的结果。

如果真的想要一个用户在表单本身上选择“目标”品牌的表单,您将创建一个非嵌套的表示:

<%= form_with(model: @product) do |f| %>
  <%= f.collection_select :brand_id %>
<% end %>

class ProductsController < ApplicationController
  # GET /products/new
  def new
    @product = Product.new
  end

  # POST /products
  def create
    @product = Product.new(product_params)
    if @product.save
       redirect_to @product
    else
       render :new
    end
  end

  def product_params
     params.require(:product).permit(:foo, :bar, :brand_id)
  end
end

推荐阅读