Rails:コントローラーから別のコントローラーアクションを呼び出す


118

コントローラーBからコントローラーAの作成アクションを呼び出す必要があります。

その理由は、コントローラーBから呼び出しているときに別の方法でリダイレクトする必要があるためです。

Railsでできますか?



POSTまたはGETアクションについて話していますか?GETの場合は、単にそのアクションにリダイレクトできます。ただし、コントローラーAから任意のURLにリダイレクトできるため、その理由は明確ではありません。
Voldy、2011

回答:


64

そのアクションへのリダイレクトを使用できます:

redirect_to your_controller_action_url

詳細:Railsガイド

新しいアクションをレンダリングするには:

redirect_to your_controller_action_url and return

5
申し訳ありませんが、1行目と2行目の違いは何ですか。最初に残りのコード行を実行してからリダイレクトすると思います。あれは正しいですか?
AKS

おそらく最後の例はタイプミスであり、のrender代わりにすべきだと思いredirect_toます。@Spyros、なんて言うの?
Magne

1
こんにちは@spyros、はredirect_to使用post: :methodを許可していません。これはcreate、@ ddayanが最初に要求したように、別のコントローラの既存のアクションにリダイレクトするのに特に役立ちます。同様の状況で、別のオブジェクトを作成する必要がある場合があります。他のcreateアクションを呼び出すとDRYer ..
SanjiBukai 2017

53

あるコントローラーを別のコントローラーから使用するには、次のようにします。

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

18
コールバックを引き続き実行しcontroller_you_wantたい場合は、次のようにしますcontroller_you_want.process(:action_you_want)
Constantijn Schepens

3
ありがとう!これは、リダイレクトしたくない場合に非常に役立ちます。あるコントローラーから別のコントローラーにアクションを採用するための簡単なソリューションが必要なだけです。リダイレクトは本当に違うものです。またrender status: :ok, json: JSON.parse(controller.render(:action_you_want).first)、他のコントローラーからJSONを返すように機能しているようです
Yourpalal

1
正解、ちょうど私が探していたもの。1つの質問-要求パラメーターがここで取る必要のある形式は何ですか?私は彼らが住んでいると思いcontroller_you_want.requestますが、ハッシュまたはパラメーターのインスタンスを渡してこの発砲を取得できませんでした。
SRack

@SRackに何を要求しているのかわかりません。params利用可能になるcontroller_you_want設定することで、request3行目に。それはあなたが求めていることですか?
Sammy Larbi 2017年

1
レール5で試しましたが、レンダリングする必要がありますrender html: controller_you_want.process(:action_you_want)
nazar kuliyev

41

あなたが提示するロジックはMVCではなく、Railsと互換性がありません。

  • コントローラーがビューまたはリダイレクトをレンダリングする

  • メソッドがコードを実行する

これらの考慮事項から、コントローラーでメソッドを作成し、アクションからそれらを呼び出すことをお勧めします。

例:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

つまり、別のコントローラを介してまったく同じことを実行し、コントローラBにいる間にコントローラAからメソッドを呼び出すことができます。

語彙は非常に重要なので、私は強く主張します。


私はそれをすべきではないことを知っていますが、これは私のアプリケーションの一部ではなく、単にアプリケーションをテストおよび評価するためのものです。
ddayan 2011

9
Love it ..レンダリングからメソッドを分離し、必要に応じて個々のメソッドを呼び出します。ただ1つの質問.. get_variable別のコントローラーからどのように呼び出すことができますか?
FloatingRock

1
@FloatingRockがあなたの質問/コメントに気づきました:いくつかのオプションがあります:共通の祖先で定義するか、共通のミックスインを含めることができます
2015

答えが好きで、末尾の文の断片が不明
Gerard Simpson

30

を使用url_forしてコントローラとアクションのURLを取得し、を使用redirect_toしてそのURLに移動できます。

redirect_to url_for(:controller => :controller_name, :action => :action_name)

1
もう1つは私にはうまくいかなかったようですが、これは見栄えがよくなりますが、パラメーターをどのように渡すのですか?
msanjay 14

3
@msanjayを他のパラメータとしてurl_forに渡すことができます。たとえば、redirect_to url_for(:controller => :controller_name, :action => :action_name, :param1 => :val1, :param2 => :val2)結果はになり/contorller_name/action_name?param1=val1&param2=val2ます。ドキュメントを
Ariel Allon、2014

「Module :: MyController」のようなコントローラから「MyOtherController」のようなルートコントローラにリダイレクトしようとすると、「module / MyOtherController」の呼び出しに解決されます。ルートを呼び出す方法はありますか?
ggez44 2018年

12

これは、別のコントローラーアクションを呼び出すのは悪い習慣です。

あなたがすべき

  1. コントローラBでこのアクションを複製する、または
  2. すべてのコントローラーで共有されるモデルメソッドとしてラップする、または
  3. このアクションはコントローラーAで拡張できます。

私の意見:

  1. 最初のアプローチはDRYではありませんが、別のアクションを要求するよりも優れています。
  2. 2番目のアプローチは優れており、柔軟性があります。
  3. 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パラメータに送信できます。これは、任意のパスにすることができます。


こんにちは、モデルメソッドとしてのソリューションBのラップで、モデルがまったくない場合はどのようにラップアップしますか?私たちは検索エンジンに取り組んでおり、他のエンジンから検索エンジンの検索ビューを呼び出したいと考えています。検索アクションのデータモデルはまったくありません。
user938363 2013

@ user938363-2つのアクションが両方とも同じビューをレンダリングする可能性があります(これらのアクションが異なるコントローラーにある場合でも)。「レンダー」呼び出し自体は複製されますが、それ自体は1行の複製にすぎません。それほど悪くはありません。レンダーコールに渡すパラメーターのハッシュを準備する多くのロジックがある場合は、それを独自のファイル(おそらくのモデル、/modelsまたはの通常のクラスまたはモジュール/lib)に移動することで、その重複を回避できます。唯一の問題は、コントローラーがインスタンス変数を介してビューと通信する場合です。その重複を別の方法で修正する必要があります。
アンチノーム2014

新しいユーザー(登録)を作成するUserControllerがあり、成功したときにSessionsControllerを呼び出してユーザーを認証したい場合はどうなりますか?この場合、何らかの方法でSessionsControllerを呼び出します。これについて何か考えはありますか?
dipole_moment 2015年

なぜそれが悪い習慣なのですか?サミー・ランビの答えの問題は何ですか?
vasilakisfil 2017

7

おそらく、ロジックをヘルパーに抽出できますか?ヘルパーはすべてのクラスで使用でき、コントロールを転送しません。その中で、おそらくコントローラー名をチェックして、それがどのように呼び出されたかを確認できます。


6

作曲救助に!

理由を考えると、コントローラ全体でアクションを呼び出すのではなく、コードの共有部分とカスタム部分を分離するようにコントローラを設計する必要があります。これにより、コードの重複と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

お役に立てば幸いです。


2

次のように、アクション内で別のアクションを呼び出すことができます。

redirect_toアクション: 'action_name'

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

  def action2
  end
end

-6

これらの関数をコントローラーから分離し、モデルファイルに入れます。次に、モデルファイルをコントローラーに含めます。


悪い提案。責任をめちゃくちゃにして、MVCを持っていることを指摘します。モデルなどでのセッション/ Cookie呼び出しの問題
Ain Tohvri
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.