Quickly debug helper methods in script\console - ruby-on-rails

How would I quickly debug helper methods in script\console. I'm talking about making changes and then debugging, over and over again.
This is a lot easier with Model methods, since all I have to do is use
reload!
to test the updated code, whereas to test a helper method, I have to do something like this
foo = ActionView::Base.new
foo.extend YourHelperModule
each time to I want to test a change.
What does reload! do? and can I modify it to add the above lines of code?

I don't think you can do that without hacking Rails. However, there's a workaround - debugging helper method in rails debugger:
1) gem install ruby-debug
2) ruby script/server --debugger
3) place <% debugger %> into some view and open that page in browser
4) server window "turns into" console, where you can debug helper methods
5) 'return' command ends the debugging
If you modify the helper method and run the debugger again, you will get recent version of the method.
More info about debugger is here: http://railscasts.com/episodes/54-debugging-with-ruby-debug

I would suggest not using script console and writing tests in either Test::Unit or rspec instead. Google should get you pointed in the right direction there is a ton of information out there.

If you're doing something "again and again" then you should be automating it. Assuming you know what your helper function should do then as mentioned elsewhere you should be able to write a test (or tests) for it.
Here's a sample that tests application_helper. It lives in my test/unit directory:
require 'test_helper'
class ApplicationHelperTest < ActiveSupport::TestCase
include ApplicationHelper
test "number_as_pct shows 2dp as default" do
assert_equal "1.10%", number_as_pct(0.011)
end
test "number_as_pct shows more dp when required" do
assert_equal "1.1000%", number_as_pct(0.011, :precision => 4)
end
end

Related

Call a method and initiate debugging from the rails console without editing the source code?

Sometimes when I'm working in the rails console, I find I want to step through a particular method (from my rails app) in the debugger. In the past I have done this by temporarily adding a debugger statement to the source code of the method, then calling that method from the console.
Is there a way I can "step into" a method from the console, without editing its source code?
This would be particularly nice on a shared development server, so that I wouldn't need to throw in random debugger statements with vi and remember to remove them later.
I tried the following but not surprisingly it doesn't work:
$ rails c --debugger
=> Debugger enabled
Loading development environment (Rails 3.2.13)
irb(main):001:0> def startdebug
irb(main):002:1> debugger
irb(main):003:1> MyModel.last.my_method
irb(main):004:1> end
=> nil
irb(main):005:0> startdebug
It says
*** No sourcefile available for (irb)
And soon I end up stepping through irb code rather than my_method.
mhm this sound a bit like metaprogramming for me, you may inject a debugging method at runtime in your model, which will add the debugging statement just before the method call so you can inspect the call as needed, like:
m = MyModel.last
m.class.send(:define_method, :debug_my_method){debugger; my_method}
m.debug_my_method
this should do on the irb (just tested it on may rails console)

main_app Namespace unknown in Rspec, only in unit suite tests (batch)

I have a helper class, ApplicationHelper, that has a method, build_links(). I have another class, AppleClass, that refers to that method.
AppleClass
def foo
....
build_links
end
end
ApplicationHelperClass
def build_links
main_app.blah_path(1)
end
end
The complication here is that there's an Engine, so I usually explicitly reference "main_app.blah_path" not just "blah_path".
The test against foo passes by itself, in its file, and when I run all helpers. It fails, though, when I include it in all the unit tests - "rake spec:suite:unit", and with our entire suite. All Apple tests pass, all ApplicationHelper tests pass. The only failing ones are when one method is referring to the other method, in routes, outside of the engine, in the full suite.
`undefined local variable or method `main_app' for #
<RSpec::Core::ExampleGroup::Nested_45::Nested_1:0x007fc134b30130>`
My suspicion is that the test helper, or some config, is not loading the engine's routes early enough, and thus links to "main_app" don't make sense. If I remove main_app, the test fails until it's run in the main suite.
Does anyone have tips on troubleshooting what's really going on? Also, could I kickstart the routing somehow in test_helper?
ruby-1.9.3-p385, rails 3.2.13, rspec 2.13.0
I had the same issue and found that if I added this method to the top of my Controller RSpec test case, then it resolved the issue entirely.
def main_app
Rails.application.class.routes.url_helpers
end
I think this issue is related to this question

Running an EventMachine inside of script/runner

I successfully used em-dir-watcher as shown in its example.rb file from the command line, but I found myself needing to call a method from another class and so I opted to go the script/runner route instead, invoking rails.
I copy/pasted the example code and placed inside of a self.methodName and encountered this error:
myapp/vendor/rails/railties/lib/commands/runner.rb:48: undefined method `watch' for EventMachine:Module (NoMethodError)
Even if I run something totally simple like:
def self.watcher
EM.run {
dw = EMDirWatcher.watch '.' do |paths|
paths.each do |path|
puts path
end
end
puts "Monitoring"
}
end
and invoke script/runner:
script/runner "require 'rubygems'; require 'em-dir-watcher'; Myclass.watcher"
I still get the error. What am I doing wrong?
After spending another day trying to sort through the stack, I've concluded that there's some inherently weird interaction between em-dir-watcher and script/runner. After moving over to another eventmachine-based gem that could do the same task (directory_watcher), everything worked great.
I know that there are performance and feature tradeoffs between the two gems, but for my purposes, I don't notice a difference.

How can I see what actually happens when a Test::Unit test runs?

In a Rails application I have a Test::Unit functional test that's failing, but the output on the console isn't telling me much.
How can I view the request, the response, the flash, the session, the variables set, and so on?
Is there something like...
rake test specific_test_file --verbose
You can add puts statements to your test case as suggested, or add calls to Rails.logger.debug() to your application code and watch your log/development.log to trace through what's happening.
In your test you have access to a bunch of resources you can user to debug your test.
p #request
p #response
p #controller
p flash
p cookie
p session
Also, remember that your action should be as simple as possibile and all the specific action execution should be tested by single Unit test.
Functional test should be reserved to the the overall action execution.
What does it mean in practice? If something doesn't work in your action, and your action calls 3 Model methods, you should be able to easily isolate the problem just looking at the unit tests. If one (or more) unit test fails, then you know which method is the guilty.
If all the unit tests pass, then the problem is the action itself but it should be quite easy to debug since you already tested the methods separately.
in the failing test use p #request etc. its ugly, but it can work
An answer to a separate question suggested
rake test TESTOPTS=-v
The slick way is to use pry and pry-nav gems. Be sure to include them in your test gem group. I use them in the development group as well. The great thing about pry and pry nav is you can step through your code with a console, so you can not only see the code as it's executed, but you can also enter console commands during the test.
You just enter binding.pry in the places in the code you want to trigger the console. Then using the 'step' command, you can move line by line through the code as it's executed.

How do I use a custom log for my rake tasks in Ruby on Rails?

I have a rake task that calls functions like this:
namespace :blah do
task :hello_world => :environment do
logger.info("Hello World")
helloworld2
end
end
def helloworld2
logger.info("Hello Again, World")
end
I want the log output to a custom log, and I really don't want to have to pass a log reference every time I make a function call. I found this somewhere (can't find it again):
def logger
##logger ||= Logger.new("#{RAILS_HOME}/log/blah.log")
end
But this does not work for me and I am not sure what it even does because I grabbed the code a long time ago and haven't used it until now. I can't search for ## on google (tried +"##" rails) to see what it does. Any help on this issue would be great. I am hoping for a quick solution and not having to install a gem or plugin (unless there is a really really good reason to.
Thanks!
rake disables logging in production mode. make sure you're running in development mode if you want it to log
What do you mean by "does not work for me"? I just tried this same code and it worked - created a new log file and put some text in it.
##logger is a class variable, it's a language issue, not Rails' one. I believe there's no need in further explanations :)
You've probably mistaken typing "function helloworld2" :)
Advanced Rails Recipes Recipe 84 from #topfunky shows how to define a custom logger. He has some code in the environment config file (production would look like this): RAILS_ROOT/config/environments/production.rb:
config.logger = RAILS_DEFAULT_LOGGER = Logger.new(config.log_path)
I'd test that out instead of redefining the class variable as you have. He might have something on http://nubyonrails.com to check as well.

Resources