Rails 3.0 引擎 - 在 ActionController 中执行代码

发布于 2024-09-14 05:42:20 字数 1079 浏览 4 评论 0原文

我正在将 Rails 插件升级为可与最新 3.0RC1 版本配合使用的引擎,但在找出扩展 ActionController 的最佳(也是最正确)方法时遇到了一些麻烦。我看过这篇文章由DHH和这个问题在这里,但是我的问题更多关于如何正确调用 ActionController 中的代码。

例如,我需要在引擎的控制器中调用以下内容:

class ApplicationController < ActionController::Base
  helper :all

  before_filter :require_one_user
  after_filter :store_location

  private
    def require_one_user
      # Code goes here
    end

    def store_location
      # Code goes here
    end
end

我知道如何正确包含我的两个私有函数,但我找不到一种方法让它正确调用helperbefore_filterafter_filter

我非常感谢一些链接或一种使这项工作有效的方法。我尝试将我的控制器命名为 ApplicationController 以外的名称,并让真正的 ApplicationController 扩展它,但这似乎也不起作用。我真的很期待任何能让引擎用户的生活尽可能轻松的解决方案。理想情况下,他们不必扩展我的类,但他们会将所有功能内置到自己的 ApplicationController 中。

I am upgrading my Rails plugin to be an engine that works with the latest 3.0RC1 release and I'm having a bit of trouble figuring out the best (and most correct) way to extend ActionController. I've seen this post by DHH and this question here on SO, but my question is more about how to properly call code within the ActionController.

For instance, I need to call the following within my engine's controller:

class ApplicationController < ActionController::Base
  helper :all

  before_filter :require_one_user
  after_filter :store_location

  private
    def require_one_user
      # Code goes here
    end

    def store_location
      # Code goes here
    end
end

I know how to properly include my two private functions, but I can't find a way to get it to properly call helper, before_filter and after_filter.

I would greatly appreciate some links or a way to make this work. I have tried naming my controller something other than ApplicationController and having the real ApplicationController extend it, but that doesn't seem to work either. I'm really up for any solution that makes the life of the engine user as easy as possible. Ideally, they wouldn't have to extend my class, but they'd have all of the functionality built into their own ApplicationController.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幸福%小乖 2024-09-21 05:42:20

您可能还想查看引擎子类中的初始值设定项,因此不必在控制器类中包含视图助手。这将使您能够控制这些模块的加载顺序。

这是我一直在使用的:


module MyEngine  
  class Engine < Rails::Engine  
    initializer 'my_engine.helper' do |app|  
      ActionView::Base.send :include, MyEngineHelper  
    end  

    initializer 'my_engine.controller' do |app|  
      ActiveSupport.on_load(:action_controller) do  
         include MyEngineActionControllerExtension  
      end
    end
  end
end

另外,动作控制器扩展的另一个选项是使用 mixin 模块。这将允许您使用 before_filter、after_filter 等。


module MyEngineActionControllerExtension
  def self.included(base)
    base.send(:include, InstanceMethods) 
    base.before_filter :my_method_1
    base.after_filter :my_method_2
  end

  module InstanceMethods
   #...........
  end
end

另一件事...如果您在 gem 的顶层创建默认的 Rails 目录,则不必担心需要帮助程序或控制器。您的引擎子类可以访问它们。所以我在这里添加我的应用程序控制器和应用程序帮助器扩展:

/myengine/app/helpers/myengine_application_helper_extension.rb
/myengine/app/controllers/my_engine_action_controller_extension.rb

我喜欢这个设置,因为它看起来类似于 Rails 应用程序中的 application_controller 和 application_helper 。 ,这只是个人喜好,但我尝试保留与 Rails 直接相关的任何内容,例如 /my_engine/app 内的控制器、助手和模型,以及 /my_engine/lib 内与插件相关的任何内容。

再说一遍 Jose Valim 的教程,了解有关初始化器的更多信息:
https://gist.github.com/e139fa787aa882c0aa9c (engine_name 现在已弃用,但该文档的大部分内容似乎最新)

You may also want to look into the initializers inside your engine subclass, so you don't have to include view helpers inside your controller class. And this will give you control over the load order of these modules.

Here is what I have been using:


module MyEngine  
  class Engine < Rails::Engine  
    initializer 'my_engine.helper' do |app|  
      ActionView::Base.send :include, MyEngineHelper  
    end  

    initializer 'my_engine.controller' do |app|  
      ActiveSupport.on_load(:action_controller) do  
         include MyEngineActionControllerExtension  
      end
    end
  end
end

Also, another option for the action controller extension is using a mixin module. This will let you use the before_filter, after_filter, etc..


module MyEngineActionControllerExtension
  def self.included(base)
    base.send(:include, InstanceMethods) 
    base.before_filter :my_method_1
    base.after_filter :my_method_2
  end

  module InstanceMethods
   #...........
  end
end

One other thing... if you create the default rails directories at the top level of your gem, you don't have to worry about requiring the helpers or controllers. Your engine subclass has access to them. So I add my application controller and application helper extensions here:

/myengine/app/helpers/myengine_application_helper_extension.rb
/myengine/app/controllers/my_engine_action_controller_extension.rb

I like this setup because it looks similar to the application_controller and application_helper in your rails app. Again, this is just personal preference, but I try to keep anything that is directly rails related, such as controllers, helpers and models inside /my_engine/app and anything that is related to the plugin in general inside /my_engine/lib

Check out this tutorial by Jose Valim for more info on initializers:
https://gist.github.com/e139fa787aa882c0aa9c (engine_name is deprecated now, but most of this doc seems up-to-date)

汹涌人海 2024-09-21 05:42:20

所以,我终于找到了解决方案,希望它对其他人有帮助。

您需要在 lib 目录中创建一个文件,因为您实际上要扩展该类。我做了myplugin/lib/extensions/action_controller_base.rb

然后,在 myplugin/lib/myplugin.rb 文件内执行以下操作:

require 'extensions/action_controller_base.rb'

myplugin/lib/extensions/action_controller_base.rb 内添加以下内容:

require 'action_controller'  # Make sure ActionController::Base is defined

ActionController::Base.class_eval {
  private
    def my_method_1
      # Code Goes Here
    end

    def my_method_2
      # Code Goes Here
    end
}

ActionController::Base.instance_eval {
  helper_method :my_method_1, :my_method_2

  before_filter :my_method_1
  after_filter :my_method_2
}

如果需要要拥有视图助手,请在 myplugin/lib/helpers 目录(或 lib 内的任何内容,名称“helpers”无关紧要)中创建它们,并将以下内容添加到 的底部>myplugin/lib/extensions/action_controller_base.rb

require 'helpers/helper_file_1'
require 'helpers/helper_file_2'

ActionView::Base.send :include, MyHelper1
ActionView::Base.send :include, MyHelper2

So, I finally figured out the solution and I hope it helps someone else.

You need to create a file in your lib directory because you are actually going to extend the class. I did myplugin/lib/extensions/action_controller_base.rb.

Then, inside of your myplugin/lib/myplugin.rb file, do the following:

require 'extensions/action_controller_base.rb'

Inside of myplugin/lib/extensions/action_controller_base.rb put the following:

require 'action_controller'  # Make sure ActionController::Base is defined

ActionController::Base.class_eval {
  private
    def my_method_1
      # Code Goes Here
    end

    def my_method_2
      # Code Goes Here
    end
}

ActionController::Base.instance_eval {
  helper_method :my_method_1, :my_method_2

  before_filter :my_method_1
  after_filter :my_method_2
}

If you need to have view helpers, create them in the myplugin/lib/helpers directory (or anything inside of lib, the name "helpers" doesn't matter) also and add the following to the bottom of myplugin/lib/extensions/action_controller_base.rb:

require 'helpers/helper_file_1'
require 'helpers/helper_file_2'

ActionView::Base.send :include, MyHelper1
ActionView::Base.send :include, MyHelper2
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文