0

In side a rails app, after setting a breakpoint inside an action method of controller using byebug, when I type some gibberesh, I find that a method from my application_controller.rb is automatically executed before printing out "undefined local variable or method"

How is this magic happening? How do I trace this... I don't want this method run when gibberish is typed...

(byebug) abcd1234abcd1234
  WpPost Load (4.8ms)  SELECT  `wp_posts`.`post_title`, `wp_posts`.`post_date`, `wp_posts`.`post_name` FROM `wp_posts` WHERE `wp_posts`.`post_status` = 'publish' AND (post_date_gmt >= '2017-01-30 23:31:52.437270')  ORDER BY post_date DESC LIMIT 3
*** NameError Exception: undefined local variable or method `abcd1234abcd1234' for #<FooController:0x007fa717745bd8>

nil
(byebug) 

Some code

# foo_controller.rb
class FooController < ApplicationController

  def show
    byebug  # I type abcd1234abcd1234 at this prompt
    # ...

# application_controller.rb
class ApplicationController < ActionController::Base
  before_filter :something
  before_filter :something2
  before_filter :load_blog_posts, :something3

  def ....
  end

  def load_blog_posts
    @wp_posts = WpPost.where(post_status: 'publishh')
                  .where("post_date_gmt >= ?", Time.now - 1.week )
                  .order("post_date DESC")
                  .limit(3)
                  .select(:post_title, :post_date, :post_name)
  end
american-ninja-warrior
  • 7,397
  • 11
  • 46
  • 80
  • 1
    Interestingly, my application controller has a lot of before_filters, the last before filter is actually a call to the method that references WpPost... – american-ninja-warrior Feb 06 '17 at 23:36
  • Yeah, it's definitely a filter that is causing this behavior... Does that solve your problem? – James Milani Feb 06 '17 at 23:37
  • no the problem still exists... i can't remove that filter because its a crucial part of our application. .. – american-ninja-warrior Feb 06 '17 at 23:38
  • So, you want to bypass the filter due to certain conditions? What are those conditions? Just when you use `byebug`? – James Milani Feb 06 '17 at 23:41
  • What I want is, when I type something that's not recognized, ruby or rails should print the NameError, it shouldn't run any sql, or any controller methods. ... – american-ninja-warrior Feb 06 '17 at 23:43
  • I'm confused... AFAIK `byebug` is a debugger. When you run it, it's like being inside irb... so if you type gibberish... it will process it as ruby commands... because that's the whole point of it. It lets you run ruby within the context of your code... so that you can test various things to debug with. What you seem to be asking for... is to make the debugger not be a debugger anymore... – Taryn East Feb 06 '17 at 23:46
  • but abcd1234abcd1234 has no relationship to the "def load_blog_posts", so when I type abcd1234abcd1234, why is application_controller.rb:load_blog_posts() being run? – american-ninja-warrior Feb 06 '17 at 23:52

1 Answers1

0

EDIT 2:

I think that the SQL statement is just printing to the log late.

Does it happen a second time if you type abcd1234abcd1234 a second time? I don't think it will.

Also, you could try changing the statement to make some kind of benign change to an object, and if you at the same time run a rails c console, you'll see that the change has already taken place once it gets to the byebug statement, it just simply hasn't printed to STDOUT yet.

I was able to test this in a test app by loading entire DB tables with code like this:

def show
  User.all
  Thing.all
  byebug
end

And I would get this:

(byebug) ksjdfiisddjfj
  User Load (0.5ms)  SELECT "users".* FROM "users"
  Thing Load (0.5ms)  SELECT "things".* FROM "things"

*** NameError Exception: undefined local variable or method `ksjdfiisddjfj' for #<ThingsController:0x007ff7cbe771e0>

nil
(byebug) sdfsdf
*** NameError Exception: undefined local variable or method `sdfsdf' for #<ThingsController:0x007ff7cbe771e0>

nil
(byebug) 

EDIT:

The behavior of filters are inherited so every before_action in your application_controller will be run before every method of the classes that inherit from that controller.

Here's a link to the docs: http://edgeguides.rubyonrails.org/action_controller_overview.html

See section 8 Filters.

If you simply do not what that action to run before your show method, then you can add a skip_before_action :load_blog_posts, only:[:show].

I think what you want to do, is introduce your byebug call as the first before_action:

    1: class SomethingController < ApplicationController
=>  2:   before_action { byebug }
    3:   before_action :validate_current_something
    4:   before_action :validate_permissions_for_something, only: [ :edit, :update, :destroy ]

This will allow you get the state that you're looking for...

James Milani
  • 1,921
  • 2
  • 16
  • 26