我正在将Rails 2应用程序迁移到Rails 3,遇到了一个主要问题。我的应用程序中调用了一个名为check_author_role
的方法。html.erb正在抛出
undefined local variable or method `check_author_role'
check_author_role方法在一个名为lib/authenticated_system.rb的文件中定义
我了解到Rails3不再自动加载lib/
目录,所以我在config/application.rb
中添加了以下行:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
我原以为那样就可以了。但是我还是犯了错误。这意味着以下情况之一正在发生:
- config/application.rb没有正确加载
- 我的自动加载语法错误
- 我正在以一种不推荐使用的方式定义该方法
- 我以一种不推荐使用的方式调用该方法
我已经做了几个小时了,对它一无所知。在Rails3更新之前一切都很好。有人有什么建议吗?
以下是lib/authenticated_system.rb
的样子:
module AuthenticatedSystem
protected
def check_author_role
check_role('author')
end
def check_role(role)
if logged_in? && @current_user.has_role?(role)
true
else
access_denied
end
end
end
以下是app/layout/application.html.erb
的样子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://www.w3.org/2005/10/profile">
...
</head>
<body>
...
<% if check_author_role %>
...
<% end %>
...
</body>
</html>
最后,这里是config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(:default, Rails.env) if defined?(Bundler)
module MyApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
...
end
end
我承认我对helper方法的工作方式很模糊,尤其是在Rails3中。以下是我注意到的。
在lib/authenticated_system.rb
:中
# Inclusion hook to make methods
# available as ActionView helper methods.
def self.included(base)
base.send :helper_method, :current_user, :logged_in?, :check_role, :check_administrator_role, :check_author_role, :has_role, :has_administrator_role, :has_author_role
end
老实说,我真的不知道base.send
是怎么回事。
在app/controllers/application.rb
中,我有以下内容:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
include AuthenticatedSystem
再说一遍,恐怕我还不完全理解这个代码到底在干什么
奇怪的是,我注意到我在同一目录中也有一个名称非常相似的文件:app/controllers/application_controller.rb
。它几乎是空的,只有三行。
class ApplicationController < ActionController::Base
protect_from_forgery
end
我的假设是:app/controllers/application_controller.rb
是新的Rails 3文件,而app/controllers/application.rb
是我的Rails 2站点上的旧代码。我来测试一下。
您的application_controller
中是否混合了AuthenticatedSystem
模块?
如果是这样,那么那里的方法将不会在视图中自动可用。
您需要添加以下内容:
helper :check_author_role
在您的application_controller
中,在AuthenticatedSystem
模块中混合后。
仅供参考,是的,在Rails 2.3 中将app/controllers/application.rb
重命名为application_controller.rb
http://guides.rubyonrails.org/2_3_release_notes.html#application-控制器重命名为