ฉันต้องการเรียกการดำเนินการสร้างในคอนโทรลเลอร์ A จากคอนโทรลเลอร์ B
เหตุผลก็คือฉันต้องเปลี่ยนเส้นทางที่แตกต่างออกไปเมื่อฉันโทรจากคอนโทรลเลอร์ B
สามารถทำได้ใน Rails หรือไม่?
ฉันต้องการเรียกการดำเนินการสร้างในคอนโทรลเลอร์ A จากคอนโทรลเลอร์ B
เหตุผลก็คือฉันต้องเปลี่ยนเส้นทางที่แตกต่างออกไปเมื่อฉันโทรจากคอนโทรลเลอร์ B
สามารถทำได้ใน Rails หรือไม่?
คำตอบ:
คุณสามารถใช้การเปลี่ยนเส้นทางไปยังการกระทำนั้น:
redirect_to your_controller_action_url
เพิ่มเติมเกี่ยวกับ: Rails Guide
ในการแสดงผลการกระทำใหม่:
redirect_to your_controller_action_url and return
render
redirect_to
คุณพูดอะไร @Spyros?
redirect_to
ไม่อนุญาตให้ใช้post: :method
และสิ่งนี้จะมีประโยชน์โดยเฉพาะอย่างยิ่งในการเปลี่ยนเส้นทางไปยังการcreate
กระทำที่มีอยู่แล้วของคอนโทรลเลอร์อื่นตามที่ @ddayan ถามในครั้งแรก ฉันมีสถานการณ์ที่คล้ายกันซึ่งในบางสถานการณ์ฉันควรสร้างวัตถุอื่น เรียกอีกอย่างcreate
ได้ว่า DRYer ..
หากต้องการใช้คอนโทรลเลอร์ตัวหนึ่งจากอีกตัวให้ทำสิ่งนี้:
def action_that_calls_one_from_another_controller
controller_you_want = ControllerYouWant.new
controller_you_want.request = request
controller_you_want.response = response
controller_you_want.action_you_want
end
controller_you_want
คุณจะทำcontroller_you_want.process(:action_you_want)
render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)
ดูเหมือนว่าจะทำงานเพื่อส่งคืน JSON จากคอนโทรลเลอร์อื่น
controller_you_want.request
แต่ไม่สามารถทำให้การยิงนี้ผ่านอินสแตนซ์แฮชหรือพารามิเตอร์ได้
params
เป็นที่สามารถใช้ได้controller_you_want
โดยการตั้งค่าrequest
ในบรรทัดที่ 3 นั่นคือสิ่งที่คุณถาม?
render html: controller_you_want.process(:action_you_want)
ตรรกะที่คุณนำเสนอไม่ใช่ MVC ไม่ใช่ Rails เข้ากันได้
ตัวควบคุมแสดงมุมมองหรือเปลี่ยนเส้นทาง
วิธีการรันโค้ด
จากการพิจารณาเหล่านี้ฉันแนะนำให้คุณสร้างวิธีการในคอนโทรลเลอร์ของคุณและเรียกใช้จากการกระทำของคุณ
ตัวอย่าง:
def index
get_variable
end
private
def get_variable
@var = Var.all
end
ที่กล่าวว่าคุณสามารถทำได้เหมือนกันทุกประการผ่านคอนโทรลเลอร์ที่แตกต่างกันและเรียกใช้วิธีการจากคอนโทรลเลอร์ A ในขณะที่คุณอยู่ในคอนโทรลเลอร์ B
คำศัพท์มีความสำคัญมากนั่นคือเหตุผลที่ฉันยืนยันมาก
get_variable
ตอนนี้จะเรียกจากคอนโทรลเลอร์อื่นได้อย่างไร?
คุณสามารถใช้url_for
เพื่อรับ URL สำหรับคอนโทรลเลอร์และการดำเนินการจากนั้นใช้redirect_to
เพื่อไปที่ URL นั้น
redirect_to url_for(:controller => :controller_name, :action => :action_name)
redirect_to url_for(:controller => :controller_name, :action => :action_name, :param1 => :val1, :param2 => :val2)
/contorller_name/action_name?param1=val1¶m2=val2
ดูเอกสาร
นี่เป็นแนวทางปฏิบัติที่ไม่ดีในการเรียกการกระทำของคอนโทรลเลอร์อื่น
คุณควร
ความคิดเห็นของฉัน:
แนวทางที่สามคือสิ่งที่ฉันเคยทำบ่อยๆ ผมจะแสดงตัวอย่างเล็ก ๆ น้อย ๆ
def create
@my_obj = MyModel.new(params[:my_model])
if @my_obj.save
redirect_to params[:redirect_to] || some_default_path
end
end
ดังนั้นคุณสามารถส่งไปยังredirect_to
พารามิเตอร์การดำเนินการนี้ซึ่งอาจเป็นเส้นทางใดก็ได้ที่คุณต้องการ
/models
หรือคลาสธรรมดาหรือโมดูลใน/lib
) ปัญหาเดียวคือถ้าคอนโทรลเลอร์ของคุณสื่อสารกับมุมมองผ่านตัวแปรอินสแตนซ์คุณต้องแก้ไขการทำซ้ำด้วยวิธีอื่น
บางทีตรรกะอาจถูกดึงออกมาเป็นตัวช่วย? ผู้ช่วยเหลือสามารถใช้ได้กับทุกชั้นเรียนและไม่ต้องโอนการควบคุม คุณสามารถตรวจสอบภายในบางทีอาจเป็นชื่อคอนโทรลเลอร์เพื่อดูว่ามันถูกเรียกอย่างไร
องค์ประกอบเพื่อการช่วยเหลือ!
ด้วยเหตุผลแทนที่จะเรียกใช้การดำเนินการกับตัวควบคุมเราควรออกแบบตัวควบคุมเพื่อแยกส่วนที่ใช้ร่วมกันและส่วนที่กำหนดเองของโค้ด สิ่งนี้จะช่วยหลีกเลี่ยงทั้งการทำซ้ำรหัสและการทำลายรูปแบบ MVC
แม้ว่าจะทำได้หลายวิธี แต่การใช้ความกังวล ( องค์ประกอบ ) เป็นแนวทางปฏิบัติที่ดี
# controllers/a_controller.rb
class AController < ApplicationController
include Createable
private def redirect_url
'one/url'
end
end
# controllers/b_controller.rb
class BController < ApplicationController
include Createable
private def redirect_url
'another/url'
end
end
# controllers/concerns/createable.rb
module Createable
def create
do_usefull_things
redirect_to redirect_url
end
end
หวังว่าจะช่วยได้
คุณสามารถเรียกการดำเนินการอื่นภายในการดำเนินการดังต่อไปนี้:
redirect_to action: 'action_name'
class MyController < ApplicationController
def action1
redirect_to action: 'action2'
end
def action2
end
end
แยกฟังก์ชันเหล่านี้ออกจากคอนโทรลเลอร์และใส่ไว้ในไฟล์โมเดล จากนั้นรวมไฟล์โมเดลในคอนโทรลเลอร์ของคุณ