Something unusual is happening with my app. I have a model called User and I made one instance from the Rails console. I can get it from the console, but not from the app.
Any hint on what may cause this behaviour?
If I run User.count in console I get 1, in app I get 0.
Running Rails.configuration.database_configuration[Rails.env] gives the same result in console and app: {"adapter"=>"sqlite3", "pool"=>5, "timeout"=>5000, "database"=>"db/development.sqlite3"}
(Running Ruby 2.6.0 and Rails 5.2.3)
I'm starting to think that Rails is making a fool of me 😹
Edit. My controller method:
def index
puts "DB CONF: #{Rails.configuration.database_configuration[Rails.env]}"
puts "USER COUNT: #{User.count}" #prints 0 to console
render plain: "#{User.count}" #prints 0 on page
end
Code in console:
Loading development environment (Rails 5.2.3)
2.6.0 :001 > User.count
(0.5ms) SELECT COUNT(*) FROM "users"
=> 1
Related
Byebug with ActiveRecord in Rails 6 is not logging as expected in my test environment.
When I run a test and use byebug to pause execution ActiveRecord is not logging queries to the console. For example, if I type Candidate.second I see no SQL output:
What I would like to see, and what I do see if I run the same query in my development environment within the rails console:
I've looked through documentation on both ActiveRecord and ByeBug but can't seem to solve this. Any help is appreciated!
Steps to reproduce
Throw a debugger statement into a controller, and run a test:
ActiveRecord is not logging queries into the console when using byebug. For example, if a run a test that hits a controller action:
class JobsController < ApplicationController
# ...
def show
debugger
Candidate.first # arbitrary query
render json: #job
end
end
From the terminal:
rails test test/controllers/jobs_controller.rb
ActiveRecord::Base.logger = Logger.new(STDOUT)
Not sure why it doesn't come by default or how to make it permanent. You have to enable rails logger in the byebug console as well.
When I look for a problem, for example with a specific ActiveRecord object, I often find myself doing the following on my production system:
# RAILS_ENV=production bundle exec
irb(main)> article = Article.find(123)
=> #<Article id: 123, title: "Foobar">
irb(main)> article.do_something(3)
NoMethodError: undefined method `id' for nil:NilClass
Sometimes I can't reproduce, why the line article.do_something(3) throws an error, so I want to debug it directly on my server, in production mode.
The problem now is: How do I step into the method #do_something with the argument 3 on the object / instance article?
Of course, one could set a breakpoint in that method, reload production and let all their customers wait on that breakpoint till I'm done debugging... But that wouldn't be the best idea.
So, is there a way to debug into a method of a specific instance from a running irb / pry session? (both would be ok)
After trying around and more googling, I think I found a solution that works for me.
Log in to your rails console / irb / pry session
Setup your case (e.g. load your models, require dependencies...), so that you can execute the code you want to debug in one line
require 'byebug' (or require 'debugger' for older ruby versions)
Now the interesting part: Put a debugger statement in front of the line you want to debug like this binding.pry; user.do_something or debugger; user.do_something
Now you are in your debugger. Maybe you have to jump to the next line with next (or just n if you have shortcuts enabled) to step into your method.
Here is a complete example from our production system:
[1] pry(main)> require 'byebug'
=> true
[2] pry(main)> user = User.find(2)
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
=> #<User id: 2, name="XXX XXX">
[3] pry(main)> user.full_name
NameError: undefined local variable or method address for #<User:0x0055b168663590>
[4] pry(main)> binding.pry; user.full_name
[68, 73] in /usr/src/app/app/models/user.rb
68: end
69:
70: def full_name
=> 71: "#{address.firstname} #{address.last_name}"
72: end
73: end
(byebug)
sure pry, byebug, etc. are awesome BUT you don't need a gem
Ruby 3 (and newer versions of Ruby 2.x) has irb debugging built in
require 'irb'
def run
a = "hello"
binding.irb # debug starts here, eg puts a
a = "something else"
a
end
run
You can use pry-debugger (through ruby 1.9.3) or pry-byebug (Ruby >= 2).
Both of these allow you to set breakpoints allowing you to interactively step through your code as it runs, inspecting variable values, method return values, etc.
How you'll manage this with production data I'm not exactly sure, but this will allow you to debug a particular method.
I have an initializer in my rails app which I don't want to be started with rails console or rake task.
I put this code into my initializer:
puts "start"
if defined?(Rails::Console)
puts "console"
elsif File.basename($0) == "rake"
puts "rake"
end
puts "end"
When I run 'rails console' I get this:
$ rails console
start
end
Loading development environment (Rails 4.2.0.beta2)
[1] pry(main)>
But inside console:
[1] pry(main)> defined?(Rails::Console)
=> "constant"
However, it works for rake:
$ bundle exec rake routes
start
rake
end
Why it works inside console, but doesn't in initializer?
Or is there a better way to determine console/rake inside initializer?
I understand how to run a simple piece of code in rails console. say
Swimming::Student.create(:name="Jerry")
How do I run a big piece of code (many lines)
Swimming::Student.all.each{ |student|
student.attended = flase
student.save
}
Just hit enter, as you'd expect:
$rails c
Loading development environment (Rails 3.2.13)
2.0.0p0 :001 > Student.all.each do |student| #enter
2.0.0p0 :002 > puts student #enter
2.0.0p0 :003?> end #enter
# here comes the output
I am using resque in my application for delayed jobs, where i cant send emails & sms to bulk number of users asynchronously. And the data is stored in mongodb, mongoid is the ODM connects rails & mongo.
My mongoid model looks like this
class Item
include Mongoid::Document
include Geo::LocationHelper
field :name, :type => String
field :desc, :type => String
#resque queue name
#queue = :item_notification
#resque perform method
def self.perform(item_id)
#item = Item.find(item_id)
end
end
I can able to add jobs to resque, i have verified using resque-web. Whenever i start an resque-worker
QUEUE=item_notification rake resque:work
i got the uninitialized constant Item , since i am using resque as rails gem and starting rake in rails root, i believe my mongoid models should be loaded.
After digging lot, i found that we can explicitly ask rake to load the environment by
QUEUE=item_notification rake environment resque:work
but now also i got the same error uninitialized constant Item
can someone help me out?
and my
Actually, its a problem in dev environment. after adding this line to into resque.rake task file
# load the Rails app all the time
namespace :resque do
puts "Loading Rails environment for Resque"
task :setup => :environment
ActiveRecord::Base.send(:descendants).each { |klass| klass.columns }
end
it works fine
The code taken from GitHub-Resque-Wiki