【问题标题】:how can i set value from dropdown list on rails?如何从 Rails 的下拉列表中设置值?
【发布时间】:2020-05-07 20:57:06
【问题描述】:

我是新手。我有产品 - 品牌列表。

路由 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

products.controller

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 picture

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

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rubygems ruby-on-rails-5


    【解决方案1】:

    您忘记允许product_params 中的参数。应该是:

    params.require(:product).permit(:name, :brand_id)
    

    createupdate 方法会忽略不允许的参数。

    【讨论】:

      【解决方案2】:

      由于您已经将产品设置为嵌套资源,因此您既不需要也不想要该选择。 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
      

      【讨论】:

      • 为什么我不能保存它们?我用了你的代码。当我点击按钮时,它无法保存。
      • 因为验证可能失败?我打赌你可以自己解决这个问题。您的原始代码的问题在于您实际上并没有检查记录是否已保存/更新。你只是假设它总是会成功。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 2021-06-26
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多