Rails 多个 select 放置额外的空白参数
Rails multiple select puts extra blank parameter
我正在尝试使用 collection_select
创建一个 HTML 多个 select,以便能够更新一个实体(Student
),其中包含另一个实体(SubscriptionList
)作为嵌套属性。这是由 HABTM ActiveRecord 的关系支持的。
我通过脚手架为学生创建了以下表格:
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :file_number %><br>
<%= f.text_field :file_number %>
</div>
<div class="field">
<%= f.label :subscription_list %><br>
<%= f.collection_select(:subscription_lists, SubscriptionList.all, :id, :name, {}, {:multiple => true}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
并且它正确地绘制了倍数 select。
但是,如果我填写表格并尝试 PUT 实体,我会得到这个作为参数:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw+mvHAAAbf6ViTQ6tE4lV1Q==", "student"=>{"first_name"=>"玛丽安娜", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]} , "commit"=>"Update Student", "controller"=>"students", "action"=>"update", "id"=>"14" }
那么,我的学生是
"first_name"=>" Mariana", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]}
我觉得收到 ["", "3"]
作为值很奇怪。为什么我收到第一个 ""
值?
我也在这里发布我的控制器(为简洁起见,update
以外的操作已被删除)
class StudentsController < ApplicationController
before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments]
# PATCH/PUT /students/1
# PATCH/PUT /students/1.json
def update
puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}"
puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}"
#puts "\n\n\n\n\n\n\n\n\nWill look for SL with ID: #{params[:subscription_lists_id]}"
all_ids = student_params.subscription_lists.collect {|sl| sl.id }
@student.subscription_lists = SubscriptionList.find(all_ids)
#@student.subscription_lists = SubscriptionList.where(id: all_ids)
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_student
@student = Student.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def student_params
#params[:student]
#params.require(:foo).permit(:bar, {:baz => [:x, :y]})
#params.require(:student).permit(:first_name, :last_name, :file_number, :subscription_lists)
params.require(:student).permit! # No strong parameters...
end
end
事实上,我宁愿接收带有 SubscriptionList
嵌套集合的 Student
而不是只接收一个 ID 数组,但我不确定这是否可能。
任何帮助将不胜感激。
最好的问候
关于您的问题已在 collection select always adding blank value 中得到解答。
如果您没有 select 任何东西,或者您 select 您的选项 select 默认情况下,您将获得 [""]
。为避免这种情况,您必须在集合 select.
之前添加 hidden_field
<div class="field">
<%= f.label :subscription_lists %><br>
<%= f.hidden_field :subscription_lists %>
<%= f.collection_select(:subscription_lists, SubscriptionList.all, :id, :name, {}, {:multiple => true}) %>
</div>
hidden_field
可以在您无所事事时为您提供帮助 select。选的时候怎么样?请试试这个。
def update
if student_params["subscription_lists"].any?
student_params["subscription_lists"].reject!(&:empty?)
end
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
希望对你有所帮助。
这就是我最终所做的,主要是遵循 this tutorial。
对于控制器:
class StudentsController < ApplicationController
before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments]
# PATCH/PUT /students/1
# PATCH/PUT /students/1.json
def update
puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}"
puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}"
@subscription_lists = SubscriptionList.where(:id => params[:subscriptions])
@student.subscription_lists.destroy_all # disassociate the already added
@student.subscription_lists << @subscription_lists
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_student
@student = Student.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def student_params
params.require(:student).permit(:first_name, :last_name, :file_number, subscription_lists: [:id])
end
end
以及表格:
<div class="field">
<%= f.label :subscription_list %><br>
<%= select_tag "subscriptions", options_from_collection_for_select(SubscriptionList.all, 'id', 'name',@student.subscription_lists.map { |j| j.id }), :multiple => true %>
</div>
希望有用
我正在尝试使用 collection_select
创建一个 HTML 多个 select,以便能够更新一个实体(Student
),其中包含另一个实体(SubscriptionList
)作为嵌套属性。这是由 HABTM ActiveRecord 的关系支持的。
我通过脚手架为学生创建了以下表格:
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :file_number %><br>
<%= f.text_field :file_number %>
</div>
<div class="field">
<%= f.label :subscription_list %><br>
<%= f.collection_select(:subscription_lists, SubscriptionList.all, :id, :name, {}, {:multiple => true}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
并且它正确地绘制了倍数 select。
但是,如果我填写表格并尝试 PUT 实体,我会得到这个作为参数:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw+mvHAAAbf6ViTQ6tE4lV1Q==", "student"=>{"first_name"=>"玛丽安娜", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]} , "commit"=>"Update Student", "controller"=>"students", "action"=>"update", "id"=>"14" }
那么,我的学生是
"first_name"=>" Mariana", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]}
我觉得收到 ["", "3"]
作为值很奇怪。为什么我收到第一个 ""
值?
我也在这里发布我的控制器(为简洁起见,update
以外的操作已被删除)
class StudentsController < ApplicationController
before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments]
# PATCH/PUT /students/1
# PATCH/PUT /students/1.json
def update
puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}"
puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}"
#puts "\n\n\n\n\n\n\n\n\nWill look for SL with ID: #{params[:subscription_lists_id]}"
all_ids = student_params.subscription_lists.collect {|sl| sl.id }
@student.subscription_lists = SubscriptionList.find(all_ids)
#@student.subscription_lists = SubscriptionList.where(id: all_ids)
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_student
@student = Student.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def student_params
#params[:student]
#params.require(:foo).permit(:bar, {:baz => [:x, :y]})
#params.require(:student).permit(:first_name, :last_name, :file_number, :subscription_lists)
params.require(:student).permit! # No strong parameters...
end
end
事实上,我宁愿接收带有 SubscriptionList
嵌套集合的 Student
而不是只接收一个 ID 数组,但我不确定这是否可能。
任何帮助将不胜感激。
最好的问候
关于您的问题已在 collection select always adding blank value 中得到解答。
如果您没有 select 任何东西,或者您 select 您的选项 select 默认情况下,您将获得 [""]
。为避免这种情况,您必须在集合 select.
hidden_field
<div class="field">
<%= f.label :subscription_lists %><br>
<%= f.hidden_field :subscription_lists %>
<%= f.collection_select(:subscription_lists, SubscriptionList.all, :id, :name, {}, {:multiple => true}) %>
</div>
hidden_field
可以在您无所事事时为您提供帮助 select。选的时候怎么样?请试试这个。
def update
if student_params["subscription_lists"].any?
student_params["subscription_lists"].reject!(&:empty?)
end
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
希望对你有所帮助。
这就是我最终所做的,主要是遵循 this tutorial。
对于控制器:
class StudentsController < ApplicationController
before_action :set_student, only: [:show, :edit, :update, :destroy, :enrollments]
# PATCH/PUT /students/1
# PATCH/PUT /students/1.json
def update
puts "\n\n\n\n\n\n\n\n\nThese are the params: #{params.inspect}"
puts "\n\n\n\n\nThis is student_params object: #{student_params.inspect}\n\n\nand its class #{student_params.class}"
@subscription_lists = SubscriptionList.where(:id => params[:subscriptions])
@student.subscription_lists.destroy_all # disassociate the already added
@student.subscription_lists << @subscription_lists
respond_to do |format|
if @student.update(student_params)
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { render :show, status: :ok, location: @student }
else
format.html { render :edit }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_student
@student = Student.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def student_params
params.require(:student).permit(:first_name, :last_name, :file_number, subscription_lists: [:id])
end
end
以及表格:
<div class="field">
<%= f.label :subscription_list %><br>
<%= select_tag "subscriptions", options_from_collection_for_select(SubscriptionList.all, 'id', 'name',@student.subscription_lists.map { |j| j.id }), :multiple => true %>
</div>
希望有用