Let's say I wanted a greeting every time the Rails console comes up:
Scotts-MBP-4:ucode scott$ rails c
Loading development environment (Rails 4.2.1)
Hello there! I'm a custom greeting
2.1.5 :001 >
Where would I put the puts 'Hello there! I\'m a custom greeting' statement?
Another Stackoverflow answer suggested, and I've read this elsewhere too, that I can put that in an initializer like this:
# config/initializers/console_greeting.rb
if defined?(Rails::Console)
puts 'Hello there! I\'m a custom greeting'
end
That doesn't work for me though :(. Even without the if defined?(Rails::Console) I still don't get output. Seems like initializers are not run when I enter a console, despite what others suggest.
I use ~/.irbrc for similar purposes (I require a gem in each console session). For example, my .irbrc
if (defined? Rails)
# Rails specific
end
# common for all irb sessions
You could use your project name to limit executing code to only one project's console:
if (defined? Rails) && (defined? YourProject)
# code goes here
end
The following will work in Rails 6:
Just pass a block to Rails.application.console, e.g
# config/initializers/custom_console_message.rb
if Rails.env.production?
Rails.application.console do
puts "Custom message here"
end
end
Now when starting the rails production console, the custom message will be printed. This code will not be executed when you start rails server.
Remove the if Rails.env.production? if you want this to run in all environments.
Related
I'm pretty tired of writing this line every time I want to open the Rails console:
irb(main):001:0> ActsAsTenant.current_tenant = User.find(1).account
Is there any way to run command/script before every "rails c"/"irb" invocation?
Thanks in advance!
Put the code you want to execute into .irbrc file in the root folder of your project:
echo 'ActsAsTenant.current_tenant = User.find(1).account' >> .irbrc
bundle exec rails c # ⇐ the code in .irbrc got executed
Sidenote: Use Pry instead of silly IRB. Try it and you’ll never roll back.
I wrote an extended answer to this in another question but the short answer is that if you are using Rails 3 or above you can use the console method on YourApp::Application to make it happen:
module YourApp
class Application < Rails::Application
...
console do
ActsAsTenant.current_tenant = User.find(1).account
end
end
end
You could put your setup code in a rb file, for example:
foo.rb:
def irb_setup
ActsAsTenant.current_tenant = User.find(1).account
end
launch irb like this:
irb -r ./foo.rb
and call the method (which will autocomplete pressing tab)
2.3.0 :001 > init_irb
In fact maybe you could put the code directly, without any method, and it would be executed when it is loaded. But I'm not sure if that would work or mess with the load order.
In my Rails app, there are some cases where code is being outputted with the puts command (for debugging purposes). Is there anyway to follow this output in the rails console (with the rails c command)? Or is there any other way to debug/view logs in the rails console?
Thanks!
For debugging, use Rails.logger instead of puts. For example:
Rails.logger.info "Some debugging info"
This will be logged to a log file in rails_app_root/log directory. If you are running in development environment locally, it will be logged to rails_app/log/development.log file.
Now, to see the log as they come in you can use tail command, like this:
tail -f log/development.log
Hope it helps.
Rails.logger is the best solution,one more think i want to add,if you want separate log file you could use like this
def read(args)
unless args.blank?
cache_key= self.get_cache_key(args)
end
logger = Logger.new("#{Rails.root}/log/cache_read.log")
logger.error("cache read scope == #{cache_key.to_s}")
end
so cache_read.log file having only this method log only.
I have this code in an initializer:
if $0 == 'irb'
# ...
end
It works fine with Rails 2.3 but in Rails 3 the value of $0 is 'script/rails' no matter if it was started with rails c or rails s. ARGV is an empty array. How can I detect if the application has been started with "rails c" or "rails console"?
You could try this perhaps
if defined?(Rails::Console)
# in Rails Console
else
# Not in Rails Console
end
Many years later there is a better method to do this registering blocks to run for the console (using the railtie interface).
So in the initializer you can write:
Rails.application.console do
# your code here
end
The good think about this is that it also works for runner and it should also work with spring (but I didn't test that).
If there is a simple script and to distinguish whether it is running by itself or being run inside the Rails app environment, I tried using
if defined? Product
# something
end
but it failed to be recognized even though Product is defined and can be used otherwise. Since then I tried using
if defined? RAILS_ENV
instead and it works well, but wonder why the defined? Product doesn't work?
This should work
if Product
# something
end
defined? ModelName returns nil for all my models.
Loading development environment (Rails 2.3.8)
>> defined? Post
=> nil
But then if I do this
>> Post; defined? Post
=> "constant"
Probably because nothing is loaded until you touch it. Hope this helps.
Edit: Ah ok well then, script/runner is a non-interactive form of script/console, I would think it loads the whole Rails app and runs from that context. If you need to identify wether the call was made from script/runner I can only think of passing a parameter to the function Model.long_running_method(:runner => true) and do your conditional check on that or if that is not convenient enough set a ENV constant ENV['something_runner']. And do the condition check on that instead.
I'm new to Rails and I'm aware it has things such as unit-testing built in. But I'm interested in doing some more simple tests that are equivalent to your "printf" in C. So I'm testing a login page I've written and want to trace the code to see what each line like my find methods are returning. I try outputting with "puts" but I don't get anything in the command-line.
I use puts statements all the time as well as the ruby debugger! It's great.
In rails you can do a couple things. I put "puts" in my code and when I run script/server at the command line, the output appears in my Terminal.app. I am running a Mac, but I am sure that there is a similar way to trace the activity of your app on your platform of choice.
The other option is to use the logger statement. you can call
logger.debug("My #{variable}")
and find these statements right in your log/development.log file.
Also, if you are running on a *nix system, you can use the "tail" command to trace the last statement written to your log one at a time.
tail -f log/development.log
This way you could write your statements and see them as they are happening. There are several levels of logging:
logger.warn
logger.info
logger.debug
logger.fatal
each environment (development, testing, production) will determine what "level" of logging will be called, so you may write log statements willy nilly with logger.debug while in development, but those log statements won't be written when you deploy based on the default log levels.
User something like this:
logger.info "method called with #{params.inspect}"
(you can put any variable inside the #{})
Once you're having fun with that, check out ./script/console and ruby-debug
Are you familiar with ruby-debug?
Install the ruby-debug gem.
Start your server with the -u option.
script/server -u
Put a debugger statement in your code where you want to stop.
You will have console access to your variables as well as the ability to step through your code.
Check the ruby-debug documentation for more details.
I've done this before - with Passenger, you don't have script/server's output, so I wrote this:
# extras/sexy_logging.rb
module SexyLogging
def log(text)
return true if RAILS_ENV == 'production'
string = "\e[0;32mLog:\e[m #{text}"
(100 - string.length).times do
string << ' '
end
string << "(#{caller.first})"
logger.debug string
end
end
ActiveRecord::Base.send :include, SexyLogging
ActionController::Base.send :include, SexyLogging
Then you can write
log variable
or
log 'Testing user'
tail -f log/development.log |grep Log:
and only see what you're logging, line by line and with colours.