복붙노트

[RUBY-ON-RAILS] 왜 첫 번째 요소가 포함 된 배열을 사용하여 다중 선택 항상 내 레일에서 비어?

RUBY-ON-RAILS

왜 첫 번째 요소가 포함 된 배열을 사용하여 다중 선택 항상 내 레일에서 비어?

나는 레일 3.2.0.rc2을 사용하고 있습니다. 난 내가 사용자가 배열의 하위 집합을 선택하고 모델에서 하나의 열에 저장된 데이터베이스, 자신의 선택을 절약 할 수 있도록 형태를 통해 제공하고있어 정적 배열을 가지고있는 모델을 가지고있다. 나는 배열을 저장하고 (즉, 열을 읽을 때 배열에 다시와) 레일이 제대로 YAML으로 사용자의 선택을 변환하는 데이터베이스 컬럼에 사용되는 직렬화를했습니다. 나는 선택을 할 수있는 다중 선택 폼 입력을 사용하고 있습니다.

내 문제는 내가 사용자의 부분 집합 배열이 항상 서버에 전송있어 빈 첫 번째 요소를 가지고 것을 제외하고 기대하는 것처럼, 나는 현재를 가지고있는 방법은, 모든 작품이이다.

이것은 큰 문제가되지이며, 기본이 동작은 의도적으로 것 레일 저에게 보이지 않는 한 나는 사실 후에,하지만 난 그냥 구문 오류의 일종을 만드는 것 같은 느낌이 인하 코드를 작성할 수 어떤 이유없이 빈 요소를 추가 할 수 있습니다. 내가 뭔가를 놓친이나 설정의 어떤 종류를 사용하지 않도록하는 것을 잊었다해야합니다. 제가 누락 이해하는 데 도움 (또는 내가 intertubes에 찾을 수 있었던 것보다 더 깊이이 설명 좋은 문서에 날 지점)하십시오.

당신이 볼 수 있듯이, 데이터베이스에서이 추가, 빈, 전송되는 배열의 요소 세트가있다. 어떻게 그 제거합니까? 내 f.select 호출에서 누락 매개 변수가 있습니까?

많은 감사 감사합니다 :)

편집 : 이것은 f.select 문에서 생성 된 HTML 코드입니다. 내 문제의 원인 일 수 있습니다 생성되는 숨겨진 입력이있는 것처럼 보입니다? 왜가?

<input name="model[subset_array][]" type="hidden" value>
<select id="model_subset_array" multiple="multiple" name="model[subset_array][]" selected="selected">
    <option value="value1" selected="selected">Value1</option>
    <option value="value2">Value2</option>
    <option value="value3" selected="selected">Value3</option>
    <option...>...</option>
</select>

해결법

  1. ==============================

    1.숨겨진 필드는 문제를 일으키는 것입니다. 그러나 그것은 좋은 이유가있다 : 모든 값이 해제 될 때, 당신은 여전히 ​​subset_array 매개 변수를받을 수 있습니다. 레일 문서에서 (당신은이 모든 것을 볼 수있는 오른쪽으로 스크롤해야 할 수도 있습니다) :

    숨겨진 필드는 문제를 일으키는 것입니다. 그러나 그것은 좋은 이유가있다 : 모든 값이 해제 될 때, 당신은 여전히 ​​subset_array 매개 변수를받을 수 있습니다. 레일 문서에서 (당신은이 모든 것을 볼 수있는 오른쪽으로 스크롤해야 할 수도 있습니다) :

      # The HTML specification says when +multiple+ parameter passed to select and all options got deselected
      # web browsers do not send any value to server. Unfortunately this introduces a gotcha:
      # if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
      # the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
      # any mass-assignment idiom like
      #
      #   @user.update_attributes(params[:user])
      #
      # wouldn't update roles.
      #
      # To prevent this the helper generates an auxiliary hidden field before
      # every multiple select. The hidden field has the same name as multiple select and blank value.
      #
      # This way, the client either sends only the hidden field (representing
      # the deselected multiple select box), or both fields. Since the HTML specification
      # says key/value pairs have to be sent in the same order they appear in the
      # form, and parameters extraction gets the last occurrence of any repeated
      # key in the query string, that works for ordinary forms.
    

    편집 : 마지막 단락은 당신이 뭔가를 선택하는 경우 빈 하나를 볼 수없는 것을 제안하지만, 나는 그것이 잘못된 생각합니다. 여기에 언급 한 바와 같이이 레일에 커밋 만든 사람 (https://github.com/rails/rails/commit/faba406fa15251cdc9588364d23c687a14ed6885 참조)이 체크 박스에 사용하는 레일 같은 트릭을 (할 노력하고있다 : https://github.com / 레일 / 레일 / 풀 / 1552),하지만 난 매개 변수가이 경우에 더 값이 무시되도록 배열을 보냈 형성하기 때문에 다중 선택 상자를 위해 일할 수 있다고 생각하지 않습니다.

    내 느낌 그래서이 버그 것입니다.

  2. ==============================

    2.에서 레일 4 :

    에서 레일 4 :

    include_hidden 옵션을 : 당신은 통과 할 수있을 것입니다. https://github.com/rails/rails/pull/5414/files

    지금은 빠른 수정으로 : 당신은 당신의 모델에서 현재 사용할 수 있습니다 :

    before_validation do |model|
      model.subset_array.reject!(&:blank?) if model.subset_array
    end
    

    이것은 단지 모델 수준에서 모든 빈 값을 삭제합니다.

  3. ==============================

    3.또 다른 빠른 수정이 컨트롤러 필터를 사용하는 것입니다 :

    또 다른 빠른 수정이 컨트롤러 필터를 사용하는 것입니다 :

    def clean_select_multiple_params hash = params
      hash.each do |k, v|
        case v
        when Array then v.reject!(&:blank?)
        when Hash then clean_select_multiple_params(v)
        end
      end
    end
    

    이 방법은 모델 층을 건드리지 않고 컨트롤러에 걸쳐 재사용 할 수 있습니다.

  4. ==============================

    4.레일 4+ 세트에서 : false로 select_tag에 include_hidden

    레일 4+ 세트에서 : false로 select_tag에 include_hidden

    <%= form.grouped_collection_select :employee_id, Company.all, :employees, :name, :id, :name, { include_hidden: false }, { size: 6, multiple: true } %>
    
  5. ==============================

    5.http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box

    http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box

  6. ==============================

    6.컨트롤러에서 :

    컨트롤러에서 :

    arr = arr.delete_if { |x| x.empty? }
    
  7. ==============================

    7.업데이트 전에 컨트롤러 .delete ( "") : 리뷰] [staff_ids] 나는 PARAMS을 사용하여 고정.

    업데이트 전에 컨트롤러 .delete ( "") : 리뷰] [staff_ids] 나는 PARAMS을 사용하여 고정.

    내보기에서 :

    = form_for @review do |f|
      = f.collection_select :staff_ids, @business.staff, :id, :full_name, {}, {multiple:true}
    = f.submit 'Submit Review'
    

    내 컨트롤러에서 :

    class ReviewsController < ApplicationController
      def create
      ....
        params[:review][:staff_ids].delete("")
        @review.update_attribute(:staff_ids, params[:review][:staff_ids].join(","))
      ....
      end
    end
    
  8. ==============================

    8.나는 페이지의 자바 스크립트 부분에이를 작성하여 작동합니다

    나는 페이지의 자바 스크립트 부분에이를 작성하여 작동합니다

    $("#model_subset_array").val( <%= @model.subset_array %> );
    

    광산은 더 다음과 같습니다 :

    $("#modela_modelb_ids").val( <%= @modela.modelb_ids %> );
    

    확실하지 않음이 미래에 나에게 두통을 얻을 것입니다하지만 지금은 잘 작동합니다.

  9. ==============================

    9.사용 jQuery를 :

    사용 jQuery를 :

    $('select option:empty').remove(); 
    

    옵션 드롭 다운에서 빈 옵션을 제거합니다.

  10. from https://stackoverflow.com/questions/8929230/why-is-the-first-element-always-blank-in-my-rails-multi-select-using-an-embedde by cc-by-sa and MIT license