Raylar: bir denetleyiciden başka bir denetleyici eylemi çağırın


118

B denetleyicisinden denetleyici A'daki oluşturma eylemini çağırmam gerekiyor.

Bunun nedeni, denetleyici B'den aradığımda farklı bir şekilde yeniden yönlendirmem gerektiğidir.

Rails'de yapılabilir mi?



POST veya GET eyleminden mi bahsediyorsunuz? GET ise, basitçe o eyleme yönlendirebilirsiniz. Ancak bunun nedeni, A denetleyicisinden istediğiniz url'ye yönlendirme yapabileceğiniz için oldukça net değil.
Voldy

Yanıtlar:


64

Bu eyleme bir yönlendirme kullanabilirsiniz:

redirect_to your_controller_action_url

Daha fazlası: Ray Kılavuzu

Yalnızca yeni eylemi oluşturmak için:

redirect_to your_controller_action_url and return

5
Üzgünüm ama birinci satır ile ikinci satır arasındaki farkın ne olduğunu söyleyebilir misiniz? Sanırım önce kalan kod satırlarını çalıştıracak ve sonra yönlendirecek. Bu doğru mu?
aks

Sanırım son örnek bir yazım hatasıydı ve renderonun yerine olmalı redirect_to. Ne diyorsun @Spyros?
Magne

1
Merhaba @spyros, redirect_tokullanımına izin vermiyor post: :methodve bu, create@ddayan'ın ilk seferinde sorduğu gibi, başka bir denetleyicinin zaten var olan bir eylemine yönlendirmek için özellikle yararlı olabilir . Bazı durumlarda başka bir nesne yaratmam gereken benzer bir durumum var. Diğer createeylemi çağırmak DRYer olabilir ..
SanjiBukai

53

Bir denetleyiciyi diğerinden kullanmak için şunu yapın:

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
Geri aramaların hala yürütülmesini controller_you_wantistiyorsanız, yapardınızcontroller_you_want.process(:action_you_want)
Constantijn Schepens

3
Teşekkürler! Bu, yeniden yönlendirmek istemediğiniz durumlar için çok yararlıdır, sadece bir denetleyiciden diğerine bir eylemi benimsemek için hızlı bir çözüme ihtiyacınız vardır. Yönlendirme gerçekten farklı bir şey. Ayrıca: render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)diğer denetleyiciden
JSON'u

1
Harika cevap, tam aradığım şey. Bir soru - istek parametrelerinin burada alması gereken format nedir? Altında yaşadıklarını varsayıyorum, controller_you_want.requestancak bu ateşlemeyi bir hash veya parametreler örneğini geçiremedi.
SRack

@SRack'e ne sorduğunuzdan emin değilim. paramsİçin kullanılabilir hale controller_you_wantayarlayarak request3 çizgide. Sorduğun bu mu?
Sammy Larbi

1
5 numaralı raylarda denendi, olması gerektiği gibirender html: controller_you_want.process(:action_you_want)
nazar kuliyev

41

Sunduğunuz mantık MVC değil, Rails değil, uyumlu.

  • Bir denetleyici bir görünüm veya yönlendirme oluşturur

  • Bir yöntem kodu yürütür

Bu düşüncelerden, denetleyicinizde yöntemler oluşturmanızı ve bunları eyleminizden çağırmanızı öneririm.

Misal:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

Bununla birlikte, aynı şeyi farklı denetleyiciler aracılığıyla yapabilir ve denetleyici B'deyken denetleyici A'dan bir yöntem çağırabilirsiniz .

Kelime dağarcığı son derece önemlidir, bu yüzden çok ısrar ediyorum.


Bunu yapmamam gerektiğini biliyorum, ancak bu başvurumun bir parçası değil, sadece başvurumu test etmek ve değerlendirmek için.
ddayan

9
Bayıldım .. yöntemi renderdan ayırın ve gerektiğinde bireysel yöntemi çağırın. Sadece bir soru .. get_variableşimdi başka bir denetleyiciden nasıl çağrılabilir?
FloatingRock

1
@FloatingRock az önce sorunuzu / yorumunuzu fark etti: birkaç seçeneğiniz var: ortak atada tanımlanabilir veya ortak mixin
ekleyebilirsiniz

cevabı seviyorum, sondaki cümle parçasından emin
Gerard Simpson

30

Sen kullanabilirsiniz url_forbir denetleyici ve eylem için URL almak ve daha sonra kullanmak redirect_too URL'ye gitmek için.

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

1
diğeri benim için işe yaramadı, bu daha iyi görünüyor, ama parametreleri nasıl geçiririz?
msanjay

3
@msanjay bunları diğer parametreler olarak url_for'a iletebilirsiniz. Örneğin redirect_to url_for(:controller => :controller_name, :action => :action_name, :param1 => :val1, :param2 => :val2)sonuçlanacak /contorller_name/action_name?param1=val1&param2=val2. Belgelere
Ariel Allon

"Modül :: MyController" gibi bir denetleyiciden "MyOtherController" gibi bir kök denetleyiciye yeniden yönlendirmeyi denersem .. "modül / MyOtherController" çağrısına dönüşecek .. kökü nasıl arayabileceğim hakkında bir fikriniz var mı?
ggez44

12

Bu, başka bir denetleyici eylemi çağırmak için kötü bir uygulamadır.

Malısın

  1. B denetleyicinizde bu eylemi çoğaltın veya
  2. tüm denetleyicilerle paylaşılacak bir model yöntem olarak sarın veya
  3. bu eylemi kontrolör A'da genişletebilirsiniz.

Benim fikrim:

  1. İlk yaklaşım KURU değildir, ancak yine de başka bir eylem için çağrı yapmaktan daha iyidir.
  2. İkinci yaklaşım iyi ve esnektir.
  3. Üçüncü yaklaşım, sık sık yaptığım şeydi. Bu yüzden küçük bir örnek göstereceğim.

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

Böylece redirect_to, istediğiniz herhangi bir yol olabilecek bu eylem parametresine gönderebilirsiniz .


Merhaba, bir model yöntemi olarak çözüm B sarma için, hiç model yoksa nasıl tamamlanır? Bir arama motoru üzerinde çalışıyoruz ve diğer motorlardan arama motorundaki arama görünümlerini aramak istiyoruz. Arama eylemi için hiçbir veri modeli yoktur.
user938363

@ user938363 - Belki iki eylemin de aynı görünümü oluşturmasını sağlayabilir (bu eylemler farklı denetleyicilerde olsa bile). "Oluşturma" çağrısının kendisi kopyalanacaktır, ancak bu kendi içinde yalnızca bir satır çoğaltma - o kadar da kötü değil. Oluşturma çağrısına geçmek için parametrelerin karmasını hazırlayan çok sayıda mantığınız varsa, bunu kendi dosyasına taşıyarak (belki de içindeki bir model /modelsveya sıradan bir sınıf veya modül içerisine /lib) kopyalamayı önleyebilirsiniz . Tek sorun, denetleyiciniz görünüm ile örnek değişkenleri aracılığıyla iletişim kuruyorsa - bu yinelemeyi başka bir şekilde düzeltmeniz gerekir.
antinome

Yeni bir Kullanıcı (kayıt) oluşturan bir UserController'a sahipseniz ve başarılı olduktan sonra bir SessionsController'ı çağırmak ve kullanıcının kimliğini doğrulamak istiyorsanız ne olur? Bu durumda siz bir şekilde SessionsController'ı çağırırsınız. Bununla ilgili herhangi bir fikrin var mı?
dipole_moment

Neden kötü bir uygulama? Sammy Lambi cevabındaki sorun nedir?
vasilakisfil

7

Belki mantık bir yardımcıya dönüştürülebilir? yardımcılar tüm sınıflar için mevcuttur ve kontrolü aktarmazlar. Nasıl çağrıldığını görmek için, belki de denetleyici adını kontrol edebilirsiniz.


6

Kurtarma için kompozisyon !

Nedeni göz önüne alındığında, denetleyiciler arasında eylemleri başlatmak yerine, kodun paylaşılan ve özel bölümlerini ayırmak için denetleyiciler tasarlanmalıdır. Bu, hem kod tekrarını hem de MVC modelini kırmayı önlemeye yardımcı olacaktır.

Bu birkaç yolla yapılabilmesine rağmen, endişeleri ( kompozisyon ) kullanmak iyi bir uygulamadır.

# 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

Umarım yardımcı olur.


2

Bir eylemin içinde başka bir eylemi şu şekilde çağırabilirsiniz:

redirect_to action: 'eylem_adı'

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

  def action2
  end
end

-6

Bu işlevleri denetleyicilerden ayırın ve model dosyasına koyun. Ardından model dosyasını kontrol cihazınıza ekleyin.


Kötü öneri. Sorumlulukları mahvedecek, MVC'ye sahip olmayı işaret edecek. Modelde vb. Oturum / çerez çağrılarıyla ilgili sorunlar
Ain Tohvri
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.