Rails: вызвать другое действие контроллера из контроллера - PullRequest
105 голосов
/ 24 апреля 2011

Мне нужно вызвать действие create в контроллере A, из контроллера B.

Причина в том, что мне нужно перенаправить по-другому, когда я звоню из контроллера B.

Может ли этобыть сделано в Rails?

Ответы [ 9 ]

63 голосов
/ 24 апреля 2011

Вы можете использовать перенаправление на это действие:

redirect_to your_controller_action_url

Подробнее: Руководство по рельсам

Чтобы просто отрендерить новое действие:

redirect_to your_controller_action_url and return
43 голосов
/ 09 мая 2015

Чтобы использовать один контроллер из другого, сделайте следующее:

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
39 голосов
/ 24 апреля 2011

Представленная вами логика не совместима с MVC, то есть не Rails.

  • Контроллер отображает представление или перенаправляет

  • Метод выполняет код

Исходя из этих соображений, я советую вам создавать методы в вашем контроллере и вызывать их из ваших действий.

Пример:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

Тем не менее, вы можете делать то же самое через разные контроллеры и вызывать метод с контроллера A, пока вы находитесь в контроллере B.

Словарь чрезвычайно важен, поэтому я очень настаиваю.

30 голосов
/ 05 декабря 2013

Вы можете использовать url_for, чтобы получить URL для контроллера и действия, а затем использовать redirect_to, чтобы перейти к этому URL.

redirect_to url_for(:controller => :controller_name, :action => :action_name)
12 голосов
/ 24 апреля 2011

Это плохая практика вызывать другое действие контроллера.

Вы должны

  1. продублируйте это действие в контроллере B или
  2. оберните его как метод модели, который будет использоваться всеми контроллерами, или
  3. Вы можете расширить это действие в контроллере А.

Мое мнение:

  1. Первый подход не СУХО, но все же лучше, чем призывать к другому действию.
  2. Второй подход хорош и гибок.
  3. Третий подход - это то, что я делал часто. Поэтому я покажу небольшой пример.

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

Таким образом, вы можете отправить этому действию redirect_to параметр, который может быть любым путем, который вы хотите.

6 голосов
/ 24 апреля 2011

Может быть, логика может быть извлечена в помощника? помощники доступны для всех классов и не передают контроль. Вы можете проверить внутри него, возможно, имя контроллера, чтобы увидеть, как оно вызывается.

5 голосов
/ 15 ноября 2017

Состав на помощь!

Учитывая причину, вместо того, чтобы вызывать действия между контроллерами, следует разрабатывать контроллеры для разделения общих и пользовательских частей кода. Это поможет избежать как дублирования кода, так и нарушения шаблона MVC.

Хотя это можно сделать несколькими способами, использование проблем ( композиция ) является хорошей практикой.

# 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

Надеюсь, это поможет.

1 голос
/ 13 января 2016

Вы можете вызвать другое действие внутри действия следующим образом:

redirect_to action: 'action_name'

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

  def action2
  end
end
0 голосов
/ 14 ноября 2012

Отделите эти функции от контроллеров и поместите их в файл модели. Затем включите файл модели в свой контроллер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...