Je dois appeler l'action de création dans le contrôleur A, à partir du contrôleur B.
La raison en est que je dois rediriger différemment lorsque j'appelle du contrôleur B.
Cela peut-il être fait dans les rails?
Je dois appeler l'action de création dans le contrôleur A, à partir du contrôleur B.
La raison en est que je dois rediriger différemment lorsque j'appelle du contrôleur B.
Cela peut-il être fait dans les rails?
Réponses:
Vous pouvez utiliser une redirection vers cette action:
redirect_to your_controller_action_url
En savoir plus: Guide des rails
Pour simplement rendre la nouvelle action:
redirect_to your_controller_action_url and return
render
place redirect_to
. Que dites-vous, @Spyros?
redirect_to
ne permet pas d'utiliser post: :method
et cela peut être utile notamment pour rediriger vers une create
action déjà existante d'un autre contrôleur comme @ddayan l'a demandé à la première fois. J'ai une situation similaire où, dans certaines situations, je devrais créer un autre objet. Appeler l'autre create
action peut être DRYer ..
Pour utiliser un contrôleur à partir d'un autre, procédez comme suit:
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
vous le feriezcontroller_you_want.process(:action_you_want)
render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)
semble fonctionner pour renvoyer JSON de l'autre contrôleur
controller_you_want.request
mais n'ont pas pu obtenir ce tir en passant une instance de hachage ou de paramètres.
params
devenir disponible controller_you_want
en définissant le request
dans la 3ème ligne. C'est ce que vous demandez?
render html: controller_you_want.process(:action_you_want)
La logique que vous présentez n'est pas compatible MVC, donc pas Rails.
Un contrôleur rend une vue ou une redirection
Une méthode exécute du code
A partir de ces considérations, je vous conseille de créer des méthodes dans votre contrôleur et de les appeler depuis votre action.
Exemple:
def index
get_variable
end
private
def get_variable
@var = Var.all
end
Cela dit, vous pouvez faire exactement la même chose avec différents contrôleurs et invoquer une méthode à partir du contrôleur A pendant que vous êtes dans le contrôleur B.
Le vocabulaire est extrêmement important c'est pourquoi j'insiste beaucoup.
get_variable
maintenant être appelé depuis un autre contrôleur?
Vous pouvez utiliser url_for
pour obtenir l'URL d'un contrôleur et une action, puis utiliser redirect_to
pour accéder à cette 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)
aboutira /contorller_name/action_name?param1=val1¶m2=val2
. Voir la documentation
C'est une mauvaise pratique d'appeler une autre action de contrôleur.
Vous devriez
Mon avis:
La troisième approche est ce que je faisais souvent. Je vais donc montrer un petit exemple.
def create
@my_obj = MyModel.new(params[:my_model])
if @my_obj.save
redirect_to params[:redirect_to] || some_default_path
end
end
Vous pouvez donc envoyer ce redirect_to
paramètre d' action , qui peut être le chemin de votre choix.
/models
ou une classe ou un module ordinaire dans /lib
). Le seul problème est que si votre contrôleur communique avec la vue via des variables d'instance - vous devrez corriger cette duplication d'une autre manière.
Peut-être que la logique pourrait être extraite dans un assistant? les helpers sont disponibles pour toutes les classes et ne transfèrent pas le contrôle. Vous pouvez vérifier dedans, peut-être pour le nom du contrôleur, pour voir comment il a été appelé.
La composition à la rescousse!
Étant donné la raison, plutôt que d'appeler des actions entre les contrôleurs, il faut concevoir des contrôleurs pour séparer les parties partagées et personnalisées du code. Cela aidera à éviter à la fois la duplication de code et la rupture du modèle MVC.
Bien que cela puisse être fait de plusieurs façons, l'utilisation des préoccupations ( composition ) est une bonne pratique.
# 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
J'espère que cela pourra aider.
Séparez ces fonctions des contrôleurs et placez-les dans un fichier modèle. Incluez ensuite le fichier de modèle dans votre contrôleur.