Ich muss die Erstellungsaktion in Controller A von Controller B aus aufrufen.
Der Grund ist, dass ich anders umleiten muss, wenn ich von Controller B aus anrufe.
Kann es in Rails gemacht werden?
Ich muss die Erstellungsaktion in Controller A von Controller B aus aufrufen.
Der Grund ist, dass ich anders umleiten muss, wenn ich von Controller B aus anrufe.
Kann es in Rails gemacht werden?
Antworten:
Sie können eine Umleitung zu dieser Aktion verwenden:
redirect_to your_controller_action_url
Mehr dazu: Rails Guide
So rendern Sie einfach die neue Aktion:
redirect_to your_controller_action_url and return
render
stattdessen sein redirect_to
. Was sagst du, @Spyros?
redirect_to
erlaubt nicht zu verwenden post: :method
und dies kann besonders nützlich sein, um zu einer bereits vorhandenen create
Aktion eines anderen Controllers umzuleiten, wie @ddayan beim ersten Mal gefragt hat. Ich habe eine ähnliche Situation, in der ich in einer bestimmten Situation ein anderes Objekt erstellen sollte. Das Aufrufen der anderen create
Aktion kann DRYer sein ..
Gehen Sie folgendermaßen vor, um einen Controller von einem anderen zu verwenden:
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
, tun Sie diescontroller_you_want.process(:action_you_want)
render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)
scheint zu funktionieren, um JSON vom anderen Controller zurückzugeben
controller_you_want.request
aber nicht in der Lage waren, diese Auslösung durch eine Hash- oder Parameterinstanz zu bringen.
params
werden verfügbar controller_you_want
durch Einstellen der request
in der 3. Zeile. Fragen Sie das?
render html: controller_you_want.process(:action_you_want)
Die von Ihnen präsentierte Logik ist nicht MVC, dann nicht Rails-kompatibel.
Ein Controller rendert eine Ansicht oder leitet um
Eine Methode führt Code aus
Aufgrund dieser Überlegungen empfehle ich Ihnen, Methoden in Ihrem Controller zu erstellen und diese aus Ihrer Aktion heraus aufzurufen.
Beispiel:
def index
get_variable
end
private
def get_variable
@var = Var.all
end
Das heißt, Sie können genau dasselbe über verschiedene Controller tun und eine Methode von Controller A aufrufen, während Sie sich in Controller B befinden.
Der Wortschatz ist extrem wichtig, deshalb bestehe ich sehr darauf.
get_variable
jetzt von einem anderen Controller aufgerufen werden?
Sie können verwenden url_for
, um die URL für einen Controller und eine Aktion abzurufen und dann redirect_to
zu dieser URL zu wechseln.
redirect_to url_for(:controller => :controller_name, :action => :action_name)
redirect_to url_for(:controller => :controller_name, :action => :action_name, :param1 => :val1, :param2 => :val2)
ergibt sich /contorller_name/action_name?param1=val1¶m2=val2
. Siehe die Dokumente
Dies ist eine schlechte Praxis, um eine andere Controller-Aktion aufzurufen.
Du solltest
Meine Meinung:
Der dritte Ansatz ist der, den 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 diesen Aktionsparameter redirect_to
senden, der ein beliebiger Pfad sein kann.
/models
oder eine gewöhnliche Klasse oder ein Modul in /lib
). Das einzige Problem besteht darin, dass Ihr Controller über Instanzvariablen mit der Ansicht kommuniziert. Sie müssen diese Duplizierung auf andere Weise beheben.
Vielleicht könnte die Logik in einen Helfer extrahiert werden? Helfer stehen allen Klassen zur Verfügung und übertragen keine Kontrolle. Sie können darin nach dem Namen des Controllers suchen, um zu sehen, wie er aufgerufen wurde.
Zusammensetzung zur Rettung!
Aus diesem Grund sollte man Controller so gestalten, dass sie gemeinsam genutzte und benutzerdefinierte Teile des Codes trennen, anstatt Aktionen über Controller hinweg aufzurufen. Dies hilft, sowohl das Duplizieren von Code als auch das Brechen des MVC-Musters zu vermeiden.
Obwohl dies auf verschiedene Arten geschehen 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
Hoffentlich hilft das.
Trennen Sie diese Funktionen von den Controllern und fügen Sie sie in die Modelldatei ein. Fügen Sie dann die Modelldatei in Ihren Controller ein.