Rails技术问题:如何在class_eval中使用current_user方法?
undefined method 'current_user' in VotesController class_eval Hey there! Let's break down why you're seeing that error when trying to use current_user in your controller extension, and how to fix it.
First, let's recap your code for context:
VotesController.class_eval do
def create
...
@current_user = current_user
end
end
Why this is happening
current_user is almost always an instance method provided by authentication libraries like Devise, injected into your controllers (usually via your ApplicationController). The error usually pops up because:
- Load order issue: Your extension file is loading before the authentication helper (like Devise's) gets added to
VotesController. When you runclass_evalearly in the Rails boot process,VotesControllermight not have thecurrent_usermethod yet. - Missing module inclusion: If
VotesControllerdoesn't inherit fromApplicationController(which includes the auth helpers), or the auth module wasn't properly included,current_userwon't exist.
Step-by-step fixes
1. Verify the method exists first (debug check)
Add a quick debug line to confirm if current_user is available in the controller instance when your extension runs:
VotesController.class_eval do def create # Check if the method exists (true means it's there) puts "Current user method available? #{respond_to?(:current_user, true)}" @current_user = current_user # ... rest of your code end end
If this prints false, the method isn't loaded yet—so we need to adjust when your extension runs.
2. Fix the load order
Move your extension to load after Rails finishes initializing all controllers and helpers. The easiest way is to wrap your require in an initializer:
- Create a new file in
config/initializers:
# config/initializers/load_votes_controller_extension.rb Rails.application.config.after_initialize do require Rails.root.join('lib', 'extends', 'votes_controller_extended.rb') end
This ensures your extension runs only after all controllers (including their auth helpers) are fully set up.
3. Use a Rails Concern (cleaner alternative)
Instead of using class_eval directly, use Rails' ActiveSupport::Concern for a more maintainable extension:
First, rewrite your extension as a concern:
# lib/concerns/votes_controller_extension.rb module VotesControllerExtension extend ActiveSupport::Concern # Add any before_actions or other controller hooks here if needed included do # before_action :some_method, only: [:create] end def create @current_user = current_user # ... rest of your create logic end end
Then load it in the initializer:
# config/initializers/load_votes_controller_extension.rb Rails.application.config.after_initialize do VotesController.send(:include, VotesControllerExtension) end
This follows Rails' best practices for extending controllers and avoids common context issues.
4. Manually include auth helpers (if needed)
If VotesController doesn't inherit from ApplicationController (which should include your auth library's helpers), you can manually include the module in your extension:
VotesController.class_eval do # Replace with your auth library's helper module (e.g., Devise) include Devise::Controllers::Helpers def create @current_user = current_user # ... end end
Final checks
- Make sure
VotesController < ApplicationController(most Rails apps set this up by default) - Confirm your auth library (like Devise) is properly installed and configured in
ApplicationController
内容的提问来源于stack exchange,提问作者Orsay

