更新时间:2023-09-20 08:02:16
您的模块未自动加载(至少在3.2.6中未加载).您必须显式加载它.您可以使用以下代码行
实现此目的 # in application.rb
config.autoload_paths += %W(#{config.root}/lib)
您可以使用Rails.application.config.autoload_paths
检查自动加载路径.也许确实是为您定义的?
现在您确定模块已加载,可以通过调用
# in application.rb
config.autoload_paths += %W(#{config.root}/lib)
在rails console
中对其进行检查.
> Functions::FormHelper
现在,默认情况下您不能使用该模块作为视图助手.当包含模块时,使用#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
您还应该从控制器中删除helper
行.
您可以在不自动加载的情况下实现此目的.只需使用require "functions/form_manager"
.您为每个方法定义一个helper_method.如果您希望像助手一样使用所有模块方法,则可以使用
def self.included m
return unless m < ActionController::Base
m.helper_method self.instance_methods
end
似乎不需要使用self.included
.这样可以实现相同的功能:
class ApplicationController < ActionController::Base
include Functions::FormManager
helper_method Functions::FormManager.instance_methods
end
I'm really new to Rails and I try to setup a module file to be used in the view. So I believe the correct behavior is to define the module as a helper within a controller and voila, it should be working. However, that's not the case for me. Here is the structure.
lib
functions
-- form_manager.rb
form_manager.rb:
Module Functions
Module FormManager
def error_message() ...
end
end
end
users_controller.rb
class UsersController < ApplicationController
helper FormManager
def new ...
Well, the structure is like the above and when I call the error_message from new.html.erb
it gives me the error: uninitialized constant UsersController::FormManager
.
So, first of all, I know that in rails 3 lib is not automatically loaded. Assuming that it is not mandatory to autoload the lib folder, how can I make this work and what am I missing?
BTW, please don't say that this question is duplicate. I'm telling you I've been searching for this crap for almost 2 days.
Your module is not autoloaded (at least not in 3.2.6). You have to load it explicitly. You can achieve this with the following line of code
# in application.rb
config.autoload_paths += %W(#{config.root}/lib)
You can check your autoload paths with Rails.application.config.autoload_paths
. Maybe it's indeed defined for you?
Now you're sure your module gets loaded, you can check it in rails console
by calling
> Functions::FormHelper
Now you can't use that module as a view helper by default. Use #included
to define the helper when your module gets included. You achieve "lazy evaluation" this way. I think the problem with your code is that the helper
method gets called before the module gets included. (somebody should correct me if I'm wrong)
Here's the code:
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
You should also remove the helper
line from your controller.
EDIT:
You can achieve this without autoloading. Just use require "functions/form_manager"
. You define a helper_method for every method. If you wish use all the module methods as helpers use
def self.included m
return unless m < ActionController::Base
m.helper_method self.instance_methods
end
EDIT2:
It appears that you don't need to use self.included
. This achieves the same functionality:
class ApplicationController < ActionController::Base
include Functions::FormManager
helper_method Functions::FormManager.instance_methods
end