Reading the Rails source code is a great way to understand how a feature works in Rails. However, stepping through the specific Rails method you're interested in is even better. You can inspect the local variables, follow the conditional path, and learn exactly what's happening behind the scenes. This post shows how you can debug the Rails source code to do exactly that.
At first glance, the method looks straightforward. Upon receiving a request, Rails checks if the request is verified and calls the
handle_unverified_request method if it's not verified.
# actionpack/lib/action_controller/metal/request_forgery_protection.rb def verify_authenticity_token # :doc: mark_for_same_origin_verification! if !verified_request? logger.warn unverified_request_warning_message if logger && log_warning_on_csrf_failure handle_unverified_request end end
Reading the source code of the
verified_request? method reveals that a few different checks need to happen to verify a request. Since Ruby is so readable, you can still read the following code and understand what's going on, but it would be sweet to step inside each method and understand precisely how Rails verifies a request.
def verified_request? # :doc: !protect_against_forgery? || request.get? || request.head? || (valid_request_origin? && any_authenticity_token_valid?) end
Debugging Rails Source Code
Let's say I want to debug the
verified_request? method. For this, I need to open the source file where that method is defined and insert a breakpoint in it.
Step 1: Open the source file
To open the relevant gem, go to your application in the terminal and run the
bundle open gem_name command. Since the above method is defined in the
RequestForgeryProtection module defined in the ActionPack gem, I will open that.
> bundle open actionpack
Assuming you have configured the
EDITOR environment variable, Ruby will open the above gem in the editor so you can inspect the code. Now you can navigate to the file containing the code you're interested in.
Step 2: Insert a breakpoint
For debugging the method, we need to insert a breakpoint. For this, I will use the
pry-byebug gem. If you aren't already using it, you can install it using the
bundle add pry-byebug command. Also, define the following debugger shortcuts in the
if defined?(PryByebug) Pry.commands.alias_command 'c', 'continue' Pry.commands.alias_command 's', 'step' Pry.commands.alias_command 'n', 'next' Pry.commands.alias_command 'f', 'finish' end
Once set up, put a breakpoint using the
binding.pry statement at the beginning of the method.
def verified_request? binding.pry !protect_against_forgery? || request.get? || request.head? || (valid_request_origin? && any_authenticity_token_valid?) end
That's it. Save the file.
Step 3: Restart the application
If your application is running, restart it, so Rails loads the latest source code containing our breakpoints. Now, Ruby will pause the execution wherever you have placed the breakpoint when your application is running.
Now you can step through the Rails source code as you'd in your regular application.
I hope it helps. If you have any questions or run into any problems, let me know. I look forward to your feedback.