Necesito llamar a la acción de creación en el controlador A, desde el controlador B.
La razón es que necesito redirigir de manera diferente cuando llamo desde el controlador B.
¿Se puede hacer en Rails?
Necesito llamar a la acción de creación en el controlador A, desde el controlador B.
La razón es que necesito redirigir de manera diferente cuando llamo desde el controlador B.
¿Se puede hacer en Rails?
Respuestas:
Puede usar una redirección a esa acción:
redirect_to your_controller_action_url
Más sobre: Guía de rieles
Para representar la nueva acción:
redirect_to your_controller_action_url and return
render
lugar de redirect_to
. ¿Qué dices, @Spyros?
redirect_to
no permite su uso post: :method
y esto puede ser útil particularmente para redirigir a una create
acción ya existente de otro controlador como @ddayan pidió la primera vez. Tengo una situación similar en la que, en alguna situación, debería crear otro objeto. Llamar a la otra create
acción puede ser más SECO ..
Para usar un controlador de otro, haga esto:
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 haríacontroller_you_want.process(:action_you_want)
render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)
parece funcionar para devolver JSON desde el otro controlador
controller_you_want.request
pero no pudieron hacer que este disparo pasara una instancia de hash o parámetros.
params
estén disponibles para controller_you_want
ajustando el request
de la tercera línea. ¿Es eso lo que estás preguntando?
render html: controller_you_want.process(:action_you_want)
La lógica que presenta no es MVC, entonces no es compatible con Rails.
Un controlador muestra una vista o redirecciona
Un método ejecuta código
A partir de estas consideraciones, le aconsejo que cree métodos en su controlador y los llame desde su acción.
Ejemplo:
def index
get_variable
end
private
def get_variable
@var = Var.all
end
Dicho esto, puede hacer exactamente lo mismo a través de diferentes controladores y convocar un método desde el controlador A mientras está en el controlador B.
El vocabulario es sumamente importante por eso insisto mucho.
get_variable
puede llamar ahora desde otro controlador?
Puede usar url_for
para obtener la URL de un controlador y una acción y luego usar redirect_to
para ir a esa 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)
dará como resultado /contorller_name/action_name?param1=val1¶m2=val2
. Ver los documentos
Esta es una mala práctica para llamar a otra acción del controlador.
Debieras
Mi opinión:
El tercer enfoque es el que solía hacer a menudo. Así que mostraré un pequeño ejemplo.
def create
@my_obj = MyModel.new(params[:my_model])
if @my_obj.save
redirect_to params[:redirect_to] || some_default_path
end
end
Entonces puede enviar a este redirect_to
parámetro de acción , que puede ser cualquier ruta que desee.
/models
o una clase o módulo ordinario /lib
). El único problema es que si su controlador se comunica con la vista a través de variables de instancia, tendría que arreglar esa duplicación de otra manera.
¿Quizás la lógica podría extraerse en un ayudante? los ayudantes están disponibles para todas las clases y no transfieren el control. Puede verificar dentro de él, tal vez el nombre del controlador, para ver cómo se llama.
Composición al rescate!
Dada la razón, en lugar de invocar acciones entre controladores, uno debería diseñar controladores para separar partes compartidas y personalizadas del código. Esto ayudará a evitar tanto la duplicación de código como la ruptura del patrón MVC.
Aunque eso se puede hacer de varias maneras, usar preocupaciones ( composición ) es una buena práctica.
# 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
Espero que ayude.
Separe estas funciones de los controladores y colóquelas en el archivo de modelo. Luego incluya el archivo del modelo en su controlador.