คุณจะเปลี่ยนเส้นทางไปยังเพจได้อย่างไรเมื่อการตอบกลับกลับมาใน JSON ต่อไป

ฉันใช้ dropzone.js สำหรับการอัปโหลดภาพ

ในไฟล์ coffeescript js ของฉัน ฉันมีการตั้งค่าสำหรับ dropzone:

Dropzone.autoDiscover = false

dropzone = new Dropzone('#item-form',
  maxFiles: 1
  maxFilesize: 1
  paramName: 'item[image]'
  headers: "X-CSRF-Token" : $('meta[name="csrf-token"]').attr('content')
  addRemoveLinks: true
  clickable: '#image-preview'
  previewsContainer: '#image-preview'
  thumbnailWidth: 200
  thumbnailHeight: 200
  parallelUploads: 100;
  autoProcessQueue: false
  uploadMultiple: false)

$('#item-submit').click (e) ->
  e.preventDefault()
  e.stopPropagation()
  if dropzone.getQueuedFiles().length > 0
    dropzone.processQueue()
  else
    $('#item-form').submit()
  return
return

นอกเหนือจากตัวเลือกต่างๆ การคลิกปุ่มส่งบนแบบฟอร์มของฉัน หากมีรูปภาพอยู่ ระบบจะประมวลผลรูปภาพ และหากไม่มีรูปภาพก็จะส่งแบบฟอร์มต่อไป

ถัดไปคือคอนโทรลเลอร์ของฉัน (รหัสที่เกี่ยวข้อง):

  def create
    @item = current_user.items.build(item_params)

    respond_to do |format|
      if @item.save
        format.html { redirect_to @item, notice: 'Item was successfully created.' }
        format.json { render :show, status: :created, location: @item }
      else
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

กว่าแบบฟอร์มของฉัน:

= form_for @item, html: {id: 'item-form', class: 'form', multipart: true} do |f|
 = f.text_field :name, class: 'form-control'

    %main#image-preview
     Add a Photo
     .fallback
      = f.file_field :image, multiple: false

= f.submit 'Done', id: 'item-submit'

ตอนนี้การตั้งค่านี้ทำให้ทุกอย่างทำงานได้แล้ว ก่อนที่ฉันจะได้รับข้อผิดพลาด Missing Template เนื่องจากฉันต้องสร้างเทมเพลต show.json.erb และหลังจากที่ฉันทำแล้ว เทมเพลตก็แจ้งสิ่งนี้ให้ฉันในบันทึก:

Started POST "/items" for 127.0.0.1 at 2015-10-16 21:36:18 -0700
Processing by ItemsController#create as JSON
...................
   (10.7ms)  COMMIT
  Item Store (142.4ms)  {"id":12}
  Rendered items/show.json.erb (0.4ms)
Completed 201 Created in 2759ms (Views: 6.1ms | Searchkick: 142.4ms | ActiveRecord: 11.9ms)

ตอนนี้ฉันสงสัยว่าเมื่อใช้ JSON หรือในสถานการณ์นี้ทั้งหมด ฉันจะเปลี่ยนเส้นทางไปยังหน้าแสดงรายการได้อย่างไร หากยังคงบังคับให้ฉันใช้ JSON

อัปเดต

เมื่อเปลี่ยนคำตอบของฉันเมื่อรายการถูกบันทึก:

if @item.save
  format.html { redirect_to @item }
  format.json { redirect_to @item }
else

มันทำสิ่งนี้:

Started GET "/items/13" for 127.0.0.1 at 2015-10-16 22:54:29 -0700
Processing by ItemsController#show as JSON
  Parameters: {"id"=>"13"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 2]]
  Item Load (0.4ms)  SELECT  "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1  [["id", 13]]
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 2]]
  Rendered items/show.json.erb (0.7ms)
Completed 200 OK in 137ms (Views: 7.5ms | ActiveRecord: 25.2ms)

ดังนั้นฉันเชื่อว่าฉันต้องทำ GET คำขอเป็น HTML อย่างไรเพื่อให้มันถูกต้อง

อัปเดต 2

ฉันทำสิ่งต่อไปนี้แล้วและต้องสร้างไฟล์ create.json.erb ด้วยเช่นกัน

if @item.save
  format.html { redirect_to @item }
  format.json { redirect_to item_path(@item, format: :html) } and return
else

Started POST "/items" for 127.0.0.1 at 2015-10-16 23:36:13 -0700
Processing by ItemsController#create as JSON............

   (12.9ms)  COMMIT
  Item Store (426.1ms)  {"id":18}
  Rendered items/create.json.erb (19.6ms)
Completed 200 OK in 3892ms.....

มันยังคงไม่เปลี่ยนเส้นทางให้ฉันให้ผลลัพธ์เหมือนเดิม

อัปเดต 3

ดังนั้นการทำ format.json { redirect_to item_path(@item) and return} จะไม่เปลี่ยนเส้นทางไปยังหน้าแสดง แต่เป็นกระบวนการใน JSON และการทำ format.json { redirect_to item_path(@item, format: :html) and return} ทำให้ฉันเหลือ Started GET "/items/19.html ซึ่งผิดเนื่องจากคุณไม่สามารถรับหน้าที่มี .html ในตอนท้ายได้

อัปเดต 3

ยังไม่มีโชคกับการเปลี่ยนแปลงใด ๆ ของ:

format.json {render :show, status: :created, location: item_url(@item, format: :html )}

ฉันคิดว่าฉันต้องเปลี่ยนเส้นทางด้วย window.location ซึ่งเป็นส่วนหนึ่งของ JavaScript ซึ่งอยู่ที่ไหนสักแห่งในโค้ดของฉัน แต่จำเป็นต้องค้นคว้าเพิ่มเติม ฉันไม่สนใจว่าฉันจะสามารถทำงานได้ในรูปแบบ js หรือ html ตราบใดที่มันใช้งานได้

อัปเดต 4

โอเค ฉันสามารถรับพฤติกรรมแบบเดียวกันได้ในแอปทดสอบใหม่ล่าสุดที่ GitHub ของฉันที่นี่: https://github.com/justintech/dropzonetest อันนี้ส่ง Invalid JSON response from server. ดังนั้นฉันเดาว่าแอปจริงของฉันทำสิ่งเดียวกัน แต่มันแค่ผิดพลาดและผ่านการตอบกลับโดยสมบูรณ์ แปลก. รู้สึกอิสระที่จะตรวจสอบออก


person John Huntington    schedule 17.10.2015    source แหล่งที่มา
comment
คุณต้องการตอบกลับด้วยอะไรหาก create_action (ในรูปแบบ JSON) ของคุณสำเร็จ   -  person illusionist    schedule 25.10.2015
comment
@illusionist HTML ถ้าเป็นไปได้   -  person John Huntington    schedule 26.10.2015
comment
หากคุณจะไม่ตอบกลับด้วยรูปแบบ JSON คุณสามารถลบคำสั่ง format.json {} ทั้งหมดได้ และตรวจสอบให้แน่ใจว่าคำขอทั้งหมดที่ลูกค้าสามารถทำได้นั้นอยู่ในคำขอ HTML   -  person illusionist    schedule 26.10.2015
comment
คุณต้องการไฟล์ js.erb หรือไม่? มันไม่ได้แสดงในโค้ด แต่คุณพูดถึงมัน ฉันสามารถทำให้โปรเจ็กต์ v ที่คล้ายกันของฉันทำงานได้โดยไม่ต้องใช้มัน   -  person Timmy Von Heiss    schedule 15.08.2016
comment
คุณได้ตรวจสอบแล้วว่ารหัสคอนโทรลเลอร์ else ทำงานล้มเหลวหรือไม่   -  person Timmy Von Heiss    schedule 15.08.2016


คำตอบ (3)


ลืมส่วนรูปแบบหากคุณต้องการให้ทั้งสองรูปแบบตอบสนองเหมือนกัน สิ่งที่คุณต้องมีคือการเปลี่ยนเส้นทาง ลองเพียง redirect_to(@item)

แก้ไข:

ฉันดูรหัสของคุณ ฉันพบว่างานต่อไปนี้:

items_controller.rb:

def create
  @item = Item.new(item_params)

  respond_to do |format|
    if @item.save
      format.html { redirect_to @item, notice: 'Item was successfully created.' }
      format.json { render json: @item }
    else
      format.html { render :new }
      format.json { render json: @item.errors, status: :unprocessable_entity }
    end
  end
end

ในรายการกาแฟ:

$(document).ready ->
  # disable auto discover
  Dropzone.autoDiscover = false

  dropzone = new Dropzone('#item-form',
    maxFiles: 1
    maxFilesize: 1
    paramName: 'item[image]'
    headers: "X-CSRF-Token" : $('meta[name="csrf-token"]').attr('content')
    addRemoveLinks: true
    clickable: '#image-preview'
    previewsContainer: '#image-preview'
    thumbnailWidth: 200
    thumbnailHeight: 200
    parallelUploads: 100;
    autoProcessQueue: false
    uploadMultiple: false)

  $('#item-submit').click (e) ->
    e.preventDefault()
    e.stopPropagation()
    if dropzone.getQueuedFiles().length > 0
      dropzone.processQueue()
    else
      $('#item-form').submit()

  dropzone.on 'success', (file, responseText) ->
    window.location.href = '/items/' + responseText.id
person Bassel Samman    schedule 25.10.2015
comment
นั่นไม่ได้ผล นั่นคือปัญหาเดิม นั่นคือสาเหตุที่ฉันต้องฟอร์แมตมันหรืออะไรสักอย่าง มันแปลกมากที่ Dropzone.js ทำงานอย่างไร - person John Huntington; 26.10.2015
comment
โอเค คุณแน่ใจหรือว่าการบันทึกสำเร็จ บางทีมันอาจจะล้มเหลวและพยายามเรนเดอร์แทน คุณสามารถเปลี่ยนทิศทางการเรนเดอร์ได้โดยส่งตัวเลือกตำแหน่ง - person Bassel Samman; 26.10.2015
comment
หากคุณดูที่ UPDATE 2 ด้านบน จะเป็นการบันทึกที่สมบูรณ์และสามารถเข้าถึงหน้าแสดงรายการได้ มันเป็นเพียงการเปลี่ยนเส้นทางที่ไม่เกิดขึ้น พื้นที่รูปภาพ dropzone.js จะถูกประมวลผล และหลังจากเสร็จสิ้น หน้านั้นจะยังคงเหมือนเดิม - person John Huntington; 26.10.2015
comment
จริงๆ แล้วสิ่งที่คุณทำในตอนแรกนั้นถูกต้อง ดังนั้นมันจึงแปลก คุณสามารถลองปรับแต่งได้ในกรณี: format.json { render :show, status: :created, location: item_url(@item)} - person Bassel Samman; 26.10.2015
comment
ฉันลองเปลี่ยนสถานะเป็น success และ redirect และรูปแบบเป็น html แต่ก็ยังไม่มีโชค - person John Huntington; 26.10.2015
comment
@JohnHuntington คุณช่วยฉันเขียน dropzone.on 'failure' ในคำถามนี้ได้ไหม - stackoverflow.com/questions/38960487/ - person Timmy Von Heiss; 15.08.2016

หากคุณต้องการ redirect_to หน้า items show ที่คุณทำกับรูปแบบ html ของคุณ ทำไมไม่ทำเช่นเดียวกันกับรูปแบบ json ด้วยเช่นกัน:

  if @item.save
    format.html { redirect_to @item, notice: 'Item was successfully created.' }
    format.json { redirect_to @item, notice: 'Item was successfully created.' }
  # rest of your codes
  end
person K M Rakibul Islam    schedule 17.10.2015
comment
ขอบคุณจนถึงตอนนี้ดูเหมือนว่าฉันจะมาถูกทางแล้ว ตรวจสอบการแก้ไขของฉันเพื่อดูว่าจะเกิดอะไรขึ้นเมื่อฉันทำตามที่คุณพูด - person John Huntington; 17.10.2015
comment
แล้วredirect_to item_path(@item, format: :html)ล่ะ? - person K M Rakibul Islam; 17.10.2015
comment
มันแปลก ๆ. มันส่งคืน Processing by ItemsController#show as HTML เหมือนที่ควร แต่ยังคงอยู่ในหน้าเดียวกัน - person John Huntington; 17.10.2015
comment
คุณช่วยลองหน่อยได้ไหม: redirect_to item_path(@item, format: :html) and return? - person K M Rakibul Islam; 17.10.2015
comment
นั่นทำให้ฉันต้องสร้าง create.json.erb ซึ่งแสดงผล Rendered items/create.json.erb เว้นแต่ว่าผมจะวางมันไม่ถูกที่ ตรวจสอบการแก้ไขของฉันหากคุณต้องการ - person John Huntington; 17.10.2015
comment
ณ ตอนนี้. ไม่แน่ใจจริงๆ ว่ามันเป็นไปได้จริงๆ หรือไม่ คุณช่วยกรุณาโพสต์ไฟล์ routes.rb ของคุณได้ไหม ฉันจะดูและจะติดต่อกลับไปหาคุณ - person K M Rakibul Islam; 17.10.2015
comment
นี่คือเส้นทางของฉันที่ลิงก์ส่วนสำคัญนี้: gist.github.com/justintech/db7bfa5b494d77b7ad2d - person John Huntington; 17.10.2015
comment
ควรประมวลผลโดยการกระทำ show แต่ไม่ใช่ create - person K M Rakibul Islam; 17.10.2015
comment
ลองสิ่งนี้: format.json { redirect_to item_path(@item, format: :html) and return} การกลับมาของคุณนอกบล็อก - person K M Rakibul Islam; 17.10.2015
comment
ฉันคิดว่าฉันเห็นปัญหา ถือว่าทำแบบนี้เหรอ? Started GET "/items/19.html? โดยมีคำ .html อยู่ท้ายลิงก์ นั่นดูแปลก - person John Huntington; 17.10.2015
comment
อาจเป็นเพราะเราระบุ: format: :html หากคุณลบสิ่งนั้นออกไป ก็ควรจะหายไป - person K M Rakibul Islam; 17.10.2015
comment
คุณช่วยทำให้เกิดปัญหานี้ซ้ำในโครงการแยกต่างหากและแบ่งปันลิงก์ GitHub เพื่อให้เราตรวจสอบในเครื่องได้หรือไม่ - person K M Rakibul Islam; 27.10.2015
comment
โอเค ฉันสามารถมีพฤติกรรมแบบเดียวกันในแอปทดสอบใหม่ล่าสุดที่ GitHub ของฉันได้ที่นี่: github.com/ justintech/dropzonetest. อันนี้ส่ง Invalid JSON response from server. ดังนั้นฉันเดาว่าแอปจริงของฉันทำสิ่งเดียวกัน แต่มันแค่ผิดพลาดและผ่านไปโดยสมบูรณ์ แปลก. - person John Huntington; 27.10.2015
comment
ฉันพยายามทำให้มันทำงานตามที่คุณต้องการ แต่ดูเหมือนว่าไม่มีอะไรทำงานได้ตามที่คุณต้องการ ลองคิดต่างลองคิดถึงปัญหาเดิมอีกครั้ง เป้าหมายสูงสุดของคุณคืออะไร? สิ่งที่คุณต้องการทำให้สำเร็จจริงๆ? ฉันแน่ใจว่ามีวิธีที่ดีกว่าในการทำเช่นนั้น! คุณเพียงแค่ต้องโจมตีปัญหาจากมุมที่ต่างออกไป - person K M Rakibul Islam; 27.10.2015
comment
ใช่ ฉันกำลังคิดที่จะเพิ่มรูปภาพในหน้าอื่น น่าลองจังเลย ฉันรู้สึกทราบซึ้ง. - person John Huntington; 27.10.2015

ขอแจ้งให้ทราบ

ประโยคของคุณ:
format.json { redirect_to item_path(@item, format: :html) and return} ทิ้งฉันไว้ด้วย Started GET "/items/19.html ซึ่งผิด เนื่องจากคุณไม่สามารถรับหน้าที่มี .html ต่อท้ายได้

สิ่งนี้ไม่ได้ถูกประมวลผลอย่างที่คุณคิด Rails ไม่ได้ค้นหาหน้าบางหน้าเช่น 1.html แต่ส่งหมายเลข 1 เป็น params[:id] = 1 และ html เป็นรูปแบบคำขอ

เนื่องจากมี .html ในคำขอ

format.html {} ถูกเปิดใช้งาน มิฉะนั้น format.json {} จะถูกเปิดใช้งานหากคำขอคือ /1.json

person illusionist    schedule 25.10.2015
comment
แต่ถึงแม้ว่า format.html จะถูกเปิดใช้งานก็ตาม มันจะยังคงใช้ JSON ในการส่งแบบฟอร์มของฉัน นี่เป็นเรื่องปกติ ทั้งหมดที่ฉันต้องการทำคือหลังจากที่มันประมวลผลรูปภาพของฉันแล้ว ให้ไปที่หน้าถัดไปไม่ว่าจะเป็นไปได้ภายใน HTML หรือ JS - person John Huntington; 26.10.2015
comment
แบบฟอร์มส่งอย่างไร ผ่าน AJAX หรือ Form submit ปกติ? ; ยิ่งไปกว่านั้นมาตรฐานยังบอกว่าหากลูกค้าร้องขอ JSON คุณต้องตอบกลับด้วยข้อมูล JSON ไม่ว่าจะเกิดอะไรขึ้นก็ตาม - person illusionist; 26.10.2015
comment
JSON ส่งมาเมื่อมีรูปภาพ แต่ถ้าไม่มีรูปภาพ ก็จะเป็น HTML ปกติ - person John Huntington; 26.10.2015