Rails: Rufen Sie eine andere Controller-Aktion von einem Controller auf

Ich muss die Erstellungsaktion in Controller A von Controller B aufrufen.

Der Grund ist, dass ich anders redirect muss, wenn ich von Controller B aus rufe.

Kann es in Rails gemacht werden?

Sie können eine Weiterleitung zu dieser Aktion verwenden:

redirect_to your_controller_action_url 

Mehr zu: Railsführer

Um nur die neue Aktion zu rendern:

 redirect_to your_controller_action_url and return 

Die Logik, die Sie präsentieren, ist nicht MVC, dann nicht Rails, kompatibel.

  • Ein Controller rendert eine Ansicht oder eine Weiterleitung

  • Eine Methode führt Code aus

Aus diesen Überlegungen rate ich Ihnen, Methoden in Ihrem Controller zu erstellen und sie von Ihrer Aktion aus aufzurufen.

Beispiel:

  def index get_variable end private def get_variable @var = Var.all end 

Das heißt, Sie können genau das gleiche durch verschiedene Controller tun und eine Methode von Controller A beschwören, während Sie in Controller B sind.

Wortschatz ist extrem wichtig, deshalb bestehe ich sehr darauf.

Um einen Controller von einem anderen zu verwenden, mach folgendes:

 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 

Sie können url_for , um die URL für einen Controller und eine Aktion url_for , und dann redirect_to , um zu dieser URL zu url_for .

 redirect_to url_for(:controller => :controller_name, :action => :action_name) 

Dies ist eine schlechte Vorgehensweise, um eine andere Controller-Aktion aufzurufen.

Du solltest

  1. duplizieren Sie diese Aktion in Ihrem Controller B, oder
  2. wickeln Sie es als eine Modellmethode ein, die für alle Controller freigegeben wird, oder
  3. Sie können diese Aktion in Controller A erweitern.

Meine Meinung:

  1. Der erste Ansatz ist nicht DRY, aber es ist immer noch besser, als eine andere Aktion zu fordern.
  2. Der zweite Ansatz ist gut und flexibel.
  3. Der dritte Ansatz ist, was ich oft gemacht habe. Also werde ich ein kleines Beispiel zeigen.

     def create @my_obj = MyModel.new(params[:my_model]) if @my_obj.save redirect_to params[:redirect_to] || some_default_path end end 

Sie können also an diese Aktion redirect_to param senden, was ein beliebiger Pfad sein kann.

Vielleicht könnte die Logik in einen Helfer extrahiert werden? Helfer stehen allen classn zur Verfügung und übertragen keine Kontrolle. Sie könnten darin nachschauen, vielleicht nach dem Namen des Controllers, um zu sehen, wie er aufgerufen wurde.

Komposition zur Rettung!

Aus diesem Grund sollte man, anstatt Aktionen über Controller hinweg aufzurufen, Controller so auslegen, dass sie gemeinsame und benutzerdefinierte Teile des Codes trennen. Dies wird helfen, beides zu vermeiden – Code-Duplikation und brechendes MVC-Muster.

Obwohl dies auf verschiedene Arten getan werden kann, ist die Verwendung von Bedenken ( Zusammensetzung ) eine gute Praxis.

 # 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 

Ich hoffe, das hilft.

Sie können eine andere Aktion innerhalb einer Aktion wie folgt aufrufen:

redirect_to Aktion: ‘Aktionsname’

 class MyController < ApplicationController def action1 redirect_to action: 'action2' end def action2 end end 

Trennen Sie diese functionen von den Controllern und fügen Sie sie in die Modelldatei ein. Fügen Sie dann die Modelldatei in Ihren Controller ein.