简体   繁体   中英

debugging the caller inside rails

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

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM