【问题标题】:Rails multiple select puts extra blank parameterRails 多选放置额外的空白参数
【发布时间】:2016-01-23 15:20:42
【问题描述】:

我正在尝试使用collection_select 创建一个 HTML 多选,以便能够更新具有另一个实体(SubscriptionList)集合作为嵌套属性的实体(Student)。这是由 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>

它正确地绘制了多选。
但是,如果我填写表格并尝试 PUT 实体,我会将此作为参数:

{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"vXYMRYI1UtX7WJRZM0OPIhHQSSEyNOPyUxkUvScdu45PTL7qVhvlJfQYNvaKG5rw+mvHAAAbf6ViTQ6tE4lV1Q==","学生"=>{"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 数组,但我不确定这是否可能。

任何帮助将不胜感激。
最好的问候

【问题讨论】:

    标签: ruby-on-rails forms ruby-on-rails-4 put


    【解决方案1】:

    关于您的问题已在collection select always adding blank value 中得到解答。

    当您没有选择任何内容或选择默认选项时,您将获得[""]。为避免这种情况,您必须在集合选择之前添加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 在未选择任何内容时为您提供帮助。什么时候选呢?请试试这个。

      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 并最终弄清楚了。我赞成你,因为你的方法似乎是正确的,但我也发布了我选择的解决方案。谢谢!
    【解决方案2】:

    这就是我最终做的事情,主要关注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>
    

    希望有用

    【讨论】:

      猜你喜欢
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 2023-03-12
      • 2016-11-13
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多