Devo chiamare l'azione di creazione nel controller A, dal controller B.
Il motivo è che devo reindirizzare in modo diverso quando chiamo dal controller B.
Può essere fatto in Rails?
Devo chiamare l'azione di creazione nel controller A, dal controller B.
Il motivo è che devo reindirizzare in modo diverso quando chiamo dal controller B.
Può essere fatto in Rails?
Risposte:
Puoi utilizzare un reindirizzamento a tale azione:
redirect_to your_controller_action_url
Altro su: Rails Guide
Per eseguire solo il rendering della nuova azione:
redirect_to your_controller_action_url and return
renderinvece di redirect_to. Che ne dici, @Spyros?
redirect_tonon permette l'uso post: :methode questo può essere utile in particolare per reindirizzare a un'azione già esistente createdi un altro controller come @ddayan ha chiesto la prima volta. Ho una situazione simile in cui in qualche situazione dovrei creare un altro oggetto. Chiamare l'altra createazione può essere DRYer ..
Per utilizzare un controller da un altro, procedi come segue:
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, lo faresticontroller_you_want.process(:action_you_want)
render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)sembra funzionare per restituire JSON dall'altro controller
controller_you_want.requestma non sono stati in grado di ottenere questo fuoco passando un'istanza di hash o parametri.
paramsdiventano disposizione controller_you_wantimpostando l' requestnel 3 ° riga. È quello che stai chiedendo?
render html: controller_you_want.process(:action_you_want)
La logica che presenti non è MVC, quindi non è compatibile con Rails.
Un controller esegue il rendering di una vista o un reindirizzamento
Un metodo esegue il codice
Da queste considerazioni, ti consiglio di creare metodi nel tuo controller e di richiamarli dalla tua azione.
Esempio:
def index
get_variable
end
private
def get_variable
@var = Var.all
end
Detto questo, puoi fare esattamente lo stesso attraverso controller diversi ed evocare un metodo dal controller A mentre sei nel controller B.
Il vocabolario è estremamente importante, ecco perché insisto molto.
get_variableora essere richiamati da un altro controller?
È possibile utilizzare url_forper ottenere l'URL di un controller e un'azione e quindi utilizzare per accedere redirect_toa tale 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)risulterà in /contorller_name/action_name?param1=val1¶m2=val2. Vedi i documenti
È una cattiva pratica chiamare un'altra azione del controller.
Dovresti
La mia opinione:
Il terzo approccio è quello che facevo spesso. Quindi mostrerò un piccolo esempio.
def create
@my_obj = MyModel.new(params[:my_model])
if @my_obj.save
redirect_to params[:redirect_to] || some_default_path
end
endQuindi puoi inviare a questo redirect_toparametro di azione , che può essere qualsiasi percorso tu voglia.
/modelso una normale classe o modulo in /lib). L'unico problema è che se il tuo controller comunica con la vista tramite variabili di istanza, dovresti correggere la duplicazione in un altro modo.
Forse la logica potrebbe essere estratta in un aiutante? gli helper sono disponibili per tutte le classi e non trasferiscono il controllo. Puoi controllare al suo interno, forse per il nome del controller, per vedere come è stato chiamato.
Composizione in soccorso!
Data la ragione, piuttosto che invocare azioni tra i controller, è necessario progettare i controller per separare le parti condivise e personalizzate del codice. Ciò contribuirà a evitare entrambi: la duplicazione del codice e l'interruzione del pattern MVC.
Sebbene ciò possa essere fatto in diversi modi, utilizzare le preoccupazioni ( composizione ) è una buona pratica.
# 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
Spero che aiuti.
Separare queste funzioni dai controller e inserirle nel file modello. Quindi includere il file del modello nel controller.