Rails-将模块包含到控制器中,以在视图中使用 [英] Rails - include module into controller, to be used in the view

查看:72
本文介绍了Rails-将模块包含到控制器中,以在视图中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 ...

嗯,结构类似于上面,当我从new.html.erb调用error_message时,它给了我错误:uninitialized constant UsersController::FormManager.

因此,首先,我知道在rails 3中lib是不会自动加载的.假设不是强制性要求自动加载lib文件夹,我该如何进行这项工作以及我遗漏了什么?

顺便说一句,请不要说这个问题是重复的.我告诉您,我一直在寻找这种垃圾了将近2天.

解决方案

您的模块未自动加载(至少在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

这篇关于Rails-将模块包含到控制器中,以在视图中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆