ใช้ Rails link_to สำหรับลิงก์ที่โพสต์


86

ฉันมีลิงค์ที่ต้องส่งคำขอโพสต์ โดยปกติฉันจะใช้ jQuery และป้องกันพฤติกรรมเริ่มต้นของลิงก์จากนั้นส่งแบบฟอร์มไปยังปลายทาง ดูเหมือนว่า Rails น่าจะช่วยฉันได้บ้าง แน่นอนว่าlink_toวิธีนี้มีตัวเลือกสำหรับการระบุวิธีการ POST http:

link_to "Profile", 'http://example.com/profile', method: :post

ใช้งานได้ แต่ฉันต้องเพิ่มพารามิเตอร์ 2 ตัวด้วย ฉันเหนื่อย:

link_to "Profile", 'http://example.com/profile', method: post, param1: 'value1', param2: 'value2'

ที่เพิ่งเพิ่มพารามิเตอร์เหล่านั้นลงใน<a>องค์ประกอบ HTML แต่ไม่ได้ส่งพารามิเตอร์เหล่านั้นเมื่อคลิกลิงก์:

<a rel="nofollow" param1="value1" param2="value2" data-method="post" href="http://example.com/profile">Profile</a>

มีวิธีทำคำขอ POST พร้อมพารามิเตอร์โดยใช้link_toหรือวิธี Rails อื่น ๆ หรือไม่? ฉันใช้ Rails 3.2.9


ไม่คิดว่าจะทำได้ น่าจะดีที่สุดในคอนโทรลเลอร์ของคุณด้วย net / http หรือ HTTParty?
Mike Campbell

ไม่สามารถทำได้ในคอนโทรลเลอร์ของฉันผู้ใช้จะต้องถูกส่งไปยังไซต์อื่น ดูเหมือนว่าคุณพูดถูกไม่มีกลไกการเชื่อมโยงในตัวที่จะทำสิ่งนี้ให้ฉัน
ที่.

คำตอบ:


143

คำตอบสั้น ๆ ก็คือถ้าสิ่งที่คุณหมายถึง "พารามิเตอร์" คือช่องฟอร์มคุณก็ไม่สามารถทำได้ (อย่างน้อยก็ไม่ตรงไปตรงมาที่ฉันเห็น) คุณควรใช้แบบฟอร์มที่มีปุ่มส่งแทนซึ่งมีลักษณะเป็นลิงก์ (หากเป็นแบบที่คุณต้องการให้ดูเหมือน)

หากในทางกลับกันคุณหมายถึงพารามิเตอร์การค้นหาสิ่งนี้จะใช้ได้:

link_to "Profile", profile_path(@profile.id, param1: 'value1', param2: 'value2'), method: :post

1
เพิ่งอัปเดตคำถามของฉันจริงๆแล้วฉันใช้ URL ภายนอกสำหรับลิงก์เหล่านี้
ที่.

ฉันได้เพิ่มบันทึกโดยทั่วไปแล้วโดยบอกว่าสิ่งที่คุณต้องการทำไม่สามารถทำได้โดยใช้ลิงก์ คุณต้องมีแบบฟอร์มที่มีปุ่มส่ง
Chris Salzberg

3
สิ่งสำคัญคือต้องทราบว่าหากผู้ใช้ปิดใช้งานจาวาสคริปต์ลิงก์จะเริ่มต้นเป็นคำขอ "GET"
bkunzi01

9

คุณสามารถเข้ารหัสพารามิเตอร์ใน URL ด้วยวิธีนี้:

link_to "Profile", 'http://example.com/profile?' + {param1: 'value1', param2: 'value2'}.to_param, method: :post

หากไม่ตรงกับความต้องการของคุณคุณควรใช้แบบฟอร์มมากกว่ากlink_to.


นี่เป็นวิธีที่ดีมากในการเพิ่มพารามิเตอร์
nathanvda

ใช้ไม่ได้กับความต้องการของฉันพารามิเตอร์ต้องเป็นพารามิเตอร์ POST แต่ขอบคุณฉันไม่รู้เกี่ยวกับวิธีการ to_param คุณต้องมี?โปรไฟล์หลัง
ที่.

ตกลงฉันเข้าใจแล้วฉันคิดว่าคุณต้องเขียนแบบฟอร์ม คุณสามารถเขียนวิธีการช่วยเหลือซึ่งจะสร้างแบบฟอร์มนี้หากคุณต้องการตรรกะนี้ซ้ำหลาย ๆ
Adrien Coquio

1
แม้ว่าจะไม่ตอบคำถามของ OP คุณควรใช้ตัวช่วย url สำหรับสิ่งนี้เช่นเดียวกับคำตอบของ @ shioyama
Ben West

@BenWest: ไม่ได้ใช้ตัวช่วยในตอนแรกและฉันคิดว่ามันมีความหมาย (อาจเป็น URL ภายนอกเป็นต้น)
Adrien Coquio

3

โปรดทราบว่าหากผู้ใช้ปิดใช้งาน JS หรือคุณได้ลบไลบรารี JS ที่ไม่สร้างความรำคาญที่มาตามค่าเริ่มต้นระบบlink_toจะส่งGETคำขอโดยไม่โต้ตอบ

โดยทั่วไปฉันไม่ค่อยชอบที่จะมีลิงก์ที่ดำเนินการPOSTตามคำขอ ฉันคิดว่านั่นคือบทบาทของฟอร์มและปุ่ม

ดังนั้นทางเลือกที่ง่าย (และปลอดภัยกว่า) คือการใช้ Rails button_to helper:

button_to 'Profile', profile_path(@profile, param1: 'value1', param2: 'value2')

button_toยังสนับสนุนmethodตัวเลือกนี้ แต่เนื่องจากเป็นค่าเริ่มต้นpostดังนั้นฉันจึงได้ละเว้นไป


เห็นด้วยกับคอสตัส ยิ่งไปกว่านั้น link_to พร้อมวิธีการโพสต์ทำงานได้ไม่ดีบน Internet Explorer
Pierre-Yves O

1

ในการโพสต์ข้อมูลคุณต้องมีแบบฟอร์ม อย่างไรก็ตามคุณไม่จำเป็นต้องมีปุ่มส่ง หากคุณต้องการให้สิ่งนี้ดูเหมือนลิงก์ด้วยเหตุผลบางประการคุณสามารถทำให้เป็นลิงก์ที่ส่งแบบฟอร์มผ่าน JavaScript ได้ ในตัวอย่างด้านล่างรีซอร์ส POST เป็นเพียงแอ็คชัน REST ที่ไม่ต้องการฟิลด์ใด ๆ ดังนั้นจึงไม่มีตัวควบคุมอินพุตแบบฟอร์ม หากคุณต้องการโพสต์ข้อมูลเพียงแค่ใส่ฟิลด์อินพุตที่ซ่อนอยู่ในแบบฟอร์ม

<%= form_tag('http://something_postable', :method => :post, :class => 'internal') %></form>
<%= link_to_function('Label for Link', 'previous("form").submit()', :title => 'Hover text for link') %>

ฟอร์มถูกกำหนดคลาสเพื่อให้คุณสามารถจัดสไตล์หรือซ่อนผ่าน CSS (เช่น 'display: inline')


1

พารามิเตอร์และเมธอด http ควรอยู่ด้วยกัน {param1: 'value1', param2: 'value2', :method: :post}

<%= link_to "Profile", profile_path(@profile), {param1: 'value1', param2: 'value2', method: :post} %>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.