Rails - 将模块包含到控制器中,以便在视图中使用

Sav*_*ova 7 module ruby-on-rails-3

我是Rails的新手,我尝试设置要在视图中使用的模块文件.所以我认为正确的行为是将模块定义为控制器内的帮助器,瞧,它应该正常工作.但是,对我来说情况并非如此.这是结构.

lib
  functions
    -- form_manager.rb
Run Code Online (Sandbox Code Playgroud)

form_manager.rb:

Module Functions 
  Module FormManager
    def error_message() ...
    end
  end
end 
Run Code Online (Sandbox Code Playgroud)

users_controller.rb

class UsersController < ApplicationController

   helper FormManager

   def new ...
Run Code Online (Sandbox Code Playgroud)

好吧,结构就像上面那样,当我从中调用error_message时new.html.erb,给出了错误:uninitialized constant UsersController::FormManager.

所以,首先,我知道在rails 3中lib不会自动加载.假设自动加载lib文件夹不是必须的,我怎样才能完成这项工作以及我缺少什么?

顺便说一句,请不要说这个问题是重复的.我告诉你我差不多2天都在寻找这个废话.

shi*_*ime 14

您的模块未自动加载(至少不在3.2.6中).你必须明确加载它.您可以使用以下代码行来实现此目的

 # in application.rb
 config.autoload_paths += %W(#{config.root}/lib)
Run Code Online (Sandbox Code Playgroud)

您可以使用检查自动加载路径Rails.application.config.autoload_paths.也许它确实适合你?

现在您确定您的模块已加载,您可以rails console通过调用来检查它

> Functions::FormHelper
Run Code Online (Sandbox Code Playgroud)

现在,默认情况下,您无法将该模块用作视图助手.用于#included在包含模块时定义帮助程序.你通过这种方式实现"懒惰评估".我认为你的代码的问题是helper在包含模块之前调用该方法.(如果我错了,有人应该纠正我)

这是代码:

Module Functions 
  Module FormManager
    def error_message() ...
    end

    def self.included m
      return unless m < ActionController::Base
      m.helper_method :error_message
    end

  end
end 
Run Code Online (Sandbox Code Playgroud)

您还应该helper从控制器中删除该行.

编辑:

您无需自动加载即可实现此目的.只是用require "functions/form_manager".您为每个方法定义一个helper_method.如果您希望使用所有模块方法作为帮助程序使用

def self.included m
  return unless m < ActionController::Base
  m.helper_method self.instance_methods
end
Run Code Online (Sandbox Code Playgroud)

EDIT2:

看来你不需要使用self.included.这实现了相同的功能:

class ApplicationController < ActionController::Base

  include Functions::FormManager
  helper_method Functions::FormManager.instance_methods

end
Run Code Online (Sandbox Code Playgroud)