ruby-on-rails 导轨,钩入控制器

wgx48brx  于 2022-11-19  发布在  Ruby
关注(0)|答案(2)|浏览(195)

好吧,我的问题是:
我有一个HomeController,它有一个动作,比如index,可以为我的网站呈现一个登陆页面。
我希望在主页上有一个动态导航栏,我希望HomeController#index转到我的应用中的每个其他Controller,并调用一个特定的方法,该方法将返回一个包含链接详细信息的对象,例如,HomeController#index将转到ContactController并调用一个方法get_link,该方法将返回如下内容:

{label: "Contact", url: "/contact"}

类似地,HomeController#index将尝试在每个其他控制器上调用get_link,直到它收集了链接对象的Array,然后将其传递到视图以呈现导航。
我尝试通过模块中的元编程并使用**included钩子方法来实现这一点(从Sitepoint tutorial获得我的引用)。但是那不起作用。然后我在某个地方读到我可能不得不使用ActiveSupport::Concern**来实现这种功能,但是我不知道如何去做。我曾经在PHP CMS上工作过,比如Drupal和WordPress,他们使用钩子来实现这种功能。这也差不多是我想要的,有什么想法吗

tgabmvqs

tgabmvqs1#

在Rails风格中,MVC控制器不是一堆垃圾的倾倒场。事实上,控制器的唯一公共方法是对应于HTTP请求的操作:

class ThingsController

  before_action :set_thing, except: [:new, :index]

  # THIS IS THE "PUBLIC API" OF THE CONTROLLER:

  # GET /things
  def index
    @things = Thing.all
  end

  # GET /things/:id
  def show
  end

  # EVERYTHING ELSE IS PRIVATE!
  private

    def set_thing
      @thing = Thing.find(params[:id])
    end
end

实际上,控制器应该只被Rails路由器或你的控制器测试示例化。虽然你可以创建类方法并在你的控制器上调用它们,但这也是一个巨大的反模式。
根据single responsibility pattern,控制器的工作是在被路由层调用时仅仅响应HTTP请求。
那么你解决这样一个案子:

  • 视图局部
  • 助手方法
  • 初始设定式/ config

具体如何解决这个问题取决于用例--内容是静态的,还是要构建类似CMS的东西?

vyswwuz2

vyswwuz22#

首先,您需要立即加载所有控制器:

Rails.application.eager_load!

然后,获取应用程序中的控制器列表:

controllers = ApplicationController.descendants

从这里你可以调用他们的类方法

controllers[0].get_link

请注意,这些方法应该宣告为类别方法,如下所示:

def self.get_link
end

这可能会降低你的应用程序的速度,因为它会急切地加载所有的东西。总的来说,这在我看来不是一个好主意,因为你的应用程序中的控制器几乎是静态的。考虑使用路径助手,比如contact_path。查看Rails Routing Docs了解详细信息。

相关问题