简体   繁体   English

Rails多项选择放置额外的空白参数

[英]Rails multiple select puts extra blank parameter

I'm trying to create an HTML multiple select using collection_select , to be able to update an entity (a Student ) which has a collection of another entity (a SubscriptionList ) as a nested attribute. 我正在尝试使用collection_select创建HTML多重选择,以便能够更新具有另一个实体( SubscriptionList )的集合作为嵌套属性的实体( Student )。 This is backed up by a HABTM ActiveRecord's relation. 这由HABTM ActiveRecord的关系备份。
I have created the following form for the Student via scaffolding: 我通过脚手架为学生创建了以下表格:

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

and it draws the multiple select properly. 并正确绘制多重选择。
However, if I fill the form and try to PUT the entity, I'm getting this as the params: 但是,如果我填写表格并尝试放置实体,则将其作为参数:

{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw+mvHAAAbf6ViTQ6tE4lV1Q==", "student"=>{"first_name"=>" Mariana", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]}, "commit"=>"Update Student", "controller"=>"students", "action"=>"update", "id"=>"14"} {“ utf8” =>“✓”,“ _method” =>“ patch”,“ authenticity_token” =>“ vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw + mvHAAAbf6> Q”“ _”“ =>“González”,“文件编号” =>“” 12345678“,”订阅列表“ => [”“,” 3“]},”提交“ =>”更新学生“,”控制器“ =>”学生“,”操作“ =>”更新“,” id“ =>” 14“}

So, my Student is 所以,我的学生是

"first_name"=>" Mariana", "last_name"=>"González", "file_number"=>"12345678", "subscription_lists"=>["", "3"]}

I find it very strange to be receiving ["", "3"] as the values. 我发现接收["", "3"]作为值非常奇怪。 Why I'm receiving this first "" value? 为什么我收到第一个""值?

I'm also posting here my Controller (actions other that update have been deleted for brevity) 我也在此处发布了我的控制器(为简便起见,删除了其他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

In fact, I'd rather receive a Student with a nested collection of SubscriptionList instead of just receving an array of ids, but I'm not sure if this is even possible. 实际上,我宁愿接收带有嵌套SubscriptionList集合的Student ,而不是仅仅接收ID数组,但是我不确定这是否可行。

Any help would be really appreciated. 任何帮助将非常感激。
Best regards 最好的祝福

About your question has been answered in collection select always adding blank value . 关于您的问题已在集合中回答,请选择始终添加空白值

You will get [""] when you did not select anything or you select your options select as default. 当您未选择任何内容或选择默认选项时,将显示[""] To avoid this you have to add hidden_field before the collection 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>

The hidden_field helps you when it's nothing selected. 当未选择任何内容时, hidden_fieldhidden_field帮助。 How about when you choose it? 选择时如何? Please try this. 请尝试这个。

  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

I hope this help you. 希望对您有所帮助。

This is what I ended up doing, mostly following this tutorial . 这就是我最终要做的,主要是按照本教程进行的

For the Controller: 对于控制器:

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

And the form: 以及形式:

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

Hope it's useful 希望它有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM