ruby-on-rails - 如何从 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 %>
所以我想从下拉列表中的选定项目中设置brand_id。在这种情况下,我为brand_id 选择了第一项,但我无法更改brand_id。如何设置从下拉列表中选择的brand_id?以及如何保存它。
解决方案
由于您已经将产品设置为嵌套资源,因此您既不需要也不想要该选择。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
推荐阅读
- javascript - r2d3:d3.js 条形图在调整大小时消失
- python - Python 3.10 子进程错误:FileNotFoundError:[Errno 2] 没有这样的文件或目录:'pkill'
- security - 如何使用 openssl 创建附加签名
- javascript - Text -> PNG -> ReadStream,全部在前端完成?
- javascript - 是否可以使用 webpack 将 favicon href 替换为内联 base64?
- c# - Simple Injector 是否具有 Autofac Factory Delegates 之类的功能?
- python - Conda-pack:CondaPackError:由 conda 管理的文件是
- javascript - 在 ReactJS 的 map() 方法中尝试条件渲染时出现问题
- azure-devops - Devops CI 管道不包括在预发布版本上发布
- wordpress - 为什么 update_post_meta 会改变我的元键值?