Rails 3: application.rb not loading?
I'm migrating a Rails 2 app over to Rails 3, and hitting a major problem. I've got a method being called in my application.html.erb called check_author_role
which is throwing
undefined local variable or method `check_author_role'
The check_author_role method is defined in a file called lib/authenticated_system.rb.
I learned that Rails 3 no longer autoloads the lib/
directory, so I've added the following lines to config/application.rb
:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
I thought that would do it. However I'm still getting the error. This implies that one of the following开发者_如何转开发 is going on:
- config/application.rb isn't being loaded properly
- My autoload syntax is wrong
- I'm defining the method in a deprecated way
- I'm calling the method in a deprecated way
I've been at this for a few hours now and can't make heads or tails of it. All was fine before the Rails 3 update. Anyone have some suggestions?
Here's what lib/authenticated_system.rb
looks like:
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
And here's what app/layout/application.html.erb
looks like:
<!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>
And lastly, here's 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
I admit that I'm fuzzy on how helper methods work, especially in Rails 3. Here's what I'm noticing.
In 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
I'll be honest and say I don't really know what base.send
is all about.
In app/controllers/application.rb
I have the following:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
include AuthenticatedSystem
Again, I'm afraid I don't fully understand what exactly this code is up to.
Curiously I notice that I also have a file in the same directory with a very similar name: app/controllers/application_controller.rb
. It's almost empty, with only three lines.
class ApplicationController < ActionController::Base
protect_from_forgery
end
My hypothesis: app/controllers/application_controller.rb
is the new Rails 3 file, while app/controllers/application.rb
has my old code from my Rails 2 site. I'll test this.
Is the AuthenticatedSystem
module mixed in to your application_controller
?
If so, then methods there will not be automatically available in the views.
You need to add something like:
helper :check_author_role
... in your application_controller
, after mixing in the AuthenticatedSystem
module.
Just for reference, yes, app/controllers/application.rb
was renamed to application_controller.rb
in Rails 2.3
http://guides.rubyonrails.org/2_3_release_notes.html#application-controller-renamed
精彩评论