복붙노트

[RUBY-ON-RAILS] 열쇠 속성을 중첩 4.0 강력한 매개 변수를 레일이 해시 포인트

RUBY-ON-RAILS

열쇠 속성을 중첩 4.0 강력한 매개 변수를 레일이 해시 포인트

나는 레일 4.x의 베타 놀아 carrierwave 작업 중첩 된 속성을 얻으려고 노력했다. 확실하지 내가 무슨 일을하고있어 올바른 방향의 경우. 주변 검색하고 결국 레일 소스와 강력한 매개 변수를보고 난 후에 나는 노트 아래를 발견했다.

https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb

그 당신이이 가지고 내에서 매일 매일 속성을 지정해야 말을 그래서, 나는 다음을 시도 :

파람의 예 :

{"utf8"=>"✓",
 "authenticity_token"=>"Tm54+v9DYdBtWJ7qPERWzdEBkWnDQfuAQrfT9UE8VD=",
 "screenshot"=>{
   "title"=>"afs",
   "assets_attributes"=>{
     "0"=>{
       "filename"=>#<ActionDispatch::Http::UploadedFile:0x00000004edbe40
                      @tempfile=#<File:/tmp/RackMultipart20130123-18328-navggd>,
                      @original_filename="EK000005.JPG",
                      @content_type="image/jpeg",
                      @headers="Content-Disposition: form-data; name=\"screenshot[assets_attributes][0][filename]\"; filename=\"EK000005.JPG\"\r\nContent-Type: image/jpeg\r\n">
     }
   }
 },
 "commit"=>"Create Screenshot"}

제어 장치

def screenshot_params
  params.require(:screenshot).permit(:title,
    :assets_attributes => [:filename => [:@tempfile,:@original_filename,:@content_type,:@headers] 

위의 "작업"하지 않습니다 (그 트리거하지 carrierwave) 그러나 나는 더 이상 무엇입니까 오류 (허가되지 않은 매개 변수 : 파일 이름) 나는 전 발견되는 표준 중첩 된 예를 사용하여 :

def screenshot_params
  params.require(:screenshot).permit(:title, assets_attributes: :filename)

사람이 도움을 줄 수 있다면 그것은 좋은 것입니다. 나는 점을 그 해시에 키와 중첩와 예를 찾을 수 없습니다.

해결법

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

    1.내 다른 대답은 대부분 틀렸다 - 새 응답.

    내 다른 대답은 대부분 틀렸다 - 새 응답.

    당신의 PARAMS의 해시 : 파일 이름이 다른 해시와 연결되지 않은, 그것은는 ActiveDispatch : HTTP를 : UploadedFile 개체와 연결되어 있습니다. 마지막 코드 라인 :

    def screenshot_params
      params.require(:screenshot).permit(:title, assets_attributes: :filename)
    

    이 허용 스칼라 유형 중 하나가 아니므로, 그러나, 파일 이름 속성은 실제로 올바른 허용되지 않고있다. 당신이 콘솔을 열고 초기화하면 PARAMS이 모양 객체 :

    params = ActionController::Parameters.new screenshot: { title: "afa", assets_attributes: {"0" => {filename: 'a string'}}}
    

    다음 마지막 줄에 실행 :

    p = params.require(:screenshot).permit(:title, assets_attributes: :filename)
    # => {"title" => "afa", "assets_attributes"=>{"0"=>{"filename"=>"abc"}}}
    

    당신이 업로드 한 파일과 PARAMS 해시에 대해 동일한 작업을 수행하는 경우에는, 당신은 얻을

    upload = ActionDispatch::Http::UplaodedFile.new tempfile: StringIO.new("abc"), filename: "abc"
    params = ActionController::Parameters.new screenshot: { title: "afa", assets_attributes: {"0" => {filename: upload}}}
    p = params.require(:screenshot).permit(:title, assets_attributes: :filename)
    
    # => {"title" => "afa", "assets_attributes"=>{"0"=>{}}}
    

    그래서, 아마 레일에 버그 또는 풀 요청 가치가있다, 그리고 그 사이에, 당신은 직접 원료 PARAMS 개체를 사용하여 파일 이름 매개 변수에 액세스해야합니다 :

    params[:screenshot][:assets_attributes]["0"][:filename]
    
  2. ==============================

    2.그래서, 당신은 has_many 양식 및 강력한 매개 변수를 처리하고 있습니다.

    그래서, 당신은 has_many 양식 및 강력한 매개 변수를 처리하고 있습니다.

    이 문제 엔 params 해시의 일부입니다 :

    "assets_attributes"=>{
        "0"=>{
              "filename"=>#<ActionDispatch::Http::UploadedFile:0x00000004edbe40
                      @tempfile=#<File:/tmp/RackMultipart20130123-18328-navggd>,
                      @original_filename="EK000005.JPG",
                      @content_type="image/jpeg",
                      @headers="Content-Disposition: form-data; name=\"screenshot[assets_attributes][0][filename]\"; filename=\"EK000005.JPG\"\r\nContent-Type: image/jpeg\r\n">
     }
    }
    

    이 같은 강력한 매개 변수를 정의 할 때 ...

    permit(:assets_attributes => [:filename]) 
    

    레일 파일 이름을 예상 곳이 "0"을 받고 있기 때문에 상황이, 휴식

    그 숫자의 의미는 무엇입니까? 그것은 당신이 당신의 양식을 통해 제출하는 자산의 ID입니다. 이제 처음에 당신은 당신이 좋아하는 뭔가를해야 생각할 수도

    permit(:assets_attributes => [:id => [:filename]])
    

    이 모습은 다른 강력한 매개 변수 구문 규칙을 따릅니다 좋아한다. 그러나, 더 나은 또는 더 나쁜, 그들은 좀 더 쉽게 일을 한, 당신은 쓰기에있는 모든입니다 :

    permit(:assets_attributes => [:asset_id, :filename])
    

    편집하다 - jpwynn가 레일의 주석에 지적 4.2.4+ 올바른 구문은

    permit(:assets_attributes => [:id, :filename])
    

    그 작동합니다.

    당신은 강한 PARAMS와 함께 벽에 충돌 할 때 할 수있는 가장 좋은 방법은 컨트롤러 및 테스트 일에 디버거를 밖으로 던져입니다. params.require (: 뭔가) .permit (: other_things)는 작동 찾을 때까지 전체 PARAMS 해시에 다른 일을 시도 할 수 있도록 단지 방법 체인입니다.

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

    3.시험

    시험

    def screenshot_params
      params.require(:screenshot).permit(:title, :assets_attributes => [:filename, :id, :screenshot_id])
    end
    

    나는 약 한달 전에이 문제와이 솔루션을 발굴 주위에 약간의 검색을했다. 문제를 해결하는 것이 screenshot_id (또는 둘 다, 내가 기억할 수) : ID 또는 : 그것은을 추가했다. 하지만 이것은 내 코드에서 작동합니다.

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

    4.사실 그냥 흰색 - 목록 방법 중첩 된 모든 매개 변수가있다.

    사실 그냥 흰색 - 목록 방법 중첩 된 모든 매개 변수가있다.

    params.require(:screenshot).permit(:title).tap do |whitelisted|
      whitelisted[:assets_attributes ] = params[:screenshot][:assets_attributes ]
    end
    

    이 방법은 다른 솔루션에 비해 장점이있다. 그것은 깊은 중첩 된 매개 변수를 허용 할 수 있습니다.

    다른 솔루션은 좋아하지만 :

    params.require(:screenshot).permit(:title, :assets_attributes => [:filename, :id, :screenshot_id])
    

    하지 마십시오.

    출처:

    https://github.com/rails/rails/issues/9454#issuecomment-14167664

  5. ==============================

    5.나는 같은 문제가 그냥 지금 모든 당신이 할 필요가 고정 도착했다

    나는 같은 문제가 그냥 지금 모든 당신이 할 필요가 고정 도착했다

    params.require(:vehicle).permit(:user_id, assets_attributes: [:id, :image]).
    

    사용 놀리려는 보석은 어떤 종류의 자산 객체 속성이 것은 확실 프로그래머에게 ID를하게 참조하고 완벽하게 작동해야 다른없는 속성을 추가 할 수 있습니다. 클립 자산을 사용하고하면 차량 클래스 안에 내 중첩 된 객체이며 이미지의 첨부 자산에 추가됩니다. 당신이 모델의 유효성 검사를 할 수 있도록

    accepts_nested_attributes_for :assets, allow_destroy: true
    validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
    

    자산을 통해보기 루프에서 각 이미지를 얻을 수 있습니다

    <%= @vehicle.assets.size %>
        <% for asset in @vehicle.assets %>
            <%=link_to image_tag (asset.image.url(:thumb)) %>
        <% end %>
    

    오전이 해결되면 문제는 인덱스 컬럼과 이미지를 가진 각각의 이미지와 배열이 asset_attributes입니다

    귀하의 form_for이 유사한 무언가를해야하고 원하는 경우 업로드가 자신의 이미지가의 하단에 코드를 사용하여 볼 수 있도록 당신은 또한 미리보기를 포함 할 수 있습니다

    <div class="field">
        <h3>Vehicle Image Upload</h3>
        <%= f.fields_for :assets do |asset_fields| %>
    
            <% if asset_fields.object.new_record? %>
                <p>
                    <%= asset_fields.file_field :image %>
                </p>
            <% end %>
        <% end %>
    </div>
    
    <div class="field">
        <h4>Vehicle Image</h4>
        <%= f.fields_for :assets do |asset_fields| %>
    
            <% unless asset_fields.object.new_record? %>
              <%= link_to image_tag(asset_fields.object.image.url(:thumb)),
                        asset_fields.object.image.url(:original)%>
              <%= asset_fields.check_box :_destroy %>
            <% end %>
        <% end %>
    </div>
    
  6. ==============================

    6.살균 인덱스 속성 accepts_nested_attributes_for 컨트롤러 살균에 저장하기 전에.

    살균 인덱스 속성 accepts_nested_attributes_for 컨트롤러 살균에 저장하기 전에.

    before_action :sanitize_fields_params, :only => [:create, :update]
    
    def sanitize_fields_params
    
        product_free_shippings_attributes = params[:product][:product_free_shippings_attributes]
    
        product_free_shippings_attributes.each do |index, key_value|
          params[:product][:product_free_shippings_attributes]["#{index}"][:weight] = clear_decimal(key_value[:weight])
          params[:product][:product_free_shippings_attributes]["#{index}"][:height] = clear_decimal(key_value[:height])
          params[:product][:product_free_shippings_attributes]["#{index}"][:width] = clear_decimal(key_value[:width])
          params[:product][:product_free_shippings_attributes]["#{index}"][:depth] = clear_decimal(key_value[:depth])
        end
     end
    
     def clear_decimal(field) 
        return (field.to_s.gsub(/[^\d]/, '').to_d / 100.to_d) unless field.blank?
      end
    
  7. from https://stackoverflow.com/questions/14483963/rails-4-0-strong-parameters-nested-attributes-with-a-key-that-points-to-a-hash by cc-by-sa and MIT license