user2490003
user2490003

Reputation: 11890

Executing a command every time the rails console starts

I have a setup command that I want executed every time I start the rails console -

MyClass.some_method()

I get tired of retyping it each time I fire up rails c - is there a way to have it automatically get run every time a new console is started?

Thanks!

Upvotes: 5

Views: 2794

Answers (3)

Jeremy Baker
Jeremy Baker

Reputation: 4272

We do this in order to ask for the tenant every time the console starts. It took a bit of investigation, but we got it working fairly elegantly. Note that this works with Rails 5.2 but it has worked mostly the same way since Rails 4.

Another thing to note is that this is written specifically because we wanted to be able to run the method once on start and then be able to run it again while using the console, say if we wanted to switch the tenant during a session.

The first step is to create a set of modules and classes in a lib file. Here is an example extracted from ours:

# lib/console_extension.rb
module ConsoleExtension
  # This module provides methods that are only available in the console
  module ConsoleHelpers
    def do_someting
      puts "doing something"
    end
  end

  # This is a simple class that allows us access to the ConsoleHelpers before
  # we get into the console
  class ConsoleRunner
    include ConsoleExtension::ConsoleHelpers
  end

  # This is specifically to patch into the startup behavior for the console.
  #
  # In the console_command.rb file, it does this right before start:
  #
  # if defined?(console::ExtendCommandBundle)
  #   console::ExtendCommandBundle.include(Rails::ConsoleMethods)
  # end
  #
  # This is a little tricky. We're defining an included method on this module
  # so that the Rails::ConsoleMethods module gets a self.included method.
  #
  # This causes the Rails::ConsoleMethods to run this code when it's included
  # in the console::ExtendCommandBundle at the last step before the console
  # starts, instead of during the earlier load_console stage.
  module ConsoleMethods
    def included(_klass)
      ConsoleExtension::ConsoleRunner.new.do_someting
    end
  end
end

The next step is to add the following into your application.rb file:

module MyApp
  class Application < Rails::Application
    ...

    console do
      require 'console_extension' # lib/console_extension.rb
      Rails::ConsoleMethods.send :include, ConsoleExtension::ConsoleHelpers
      Rails::ConsoleMethods.send :extend, ConsoleExtension::ConsoleMethods
    end
  end
end

Now, every time you run rails console, it will do something:

enter image description here

If you're just looking to run something once every time the console starts, this is more complicated than it needs to be. Instead, you can just use the console() method in MyApp::Application and it will run whatever code you want as part of the load_console step.

module MyApp
  class Application < Rails::Application
    ...

    console do
      puts "do something"
    end
  end
end

One issue we had with this was that it runs the code before it prints out the environment, so if you're doing any printing or interaction it feels a bit weird:

enter image description here

You may not be as picky as we are though. Do whatever makes you and your team the happiest.

Upvotes: 15

Mauro Dias
Mauro Dias

Reputation: 1093

I dont know if its a good practice, but you can check if server is running on Console, like Aditya awnsered

if defined?(Rails::Console)
  MyClass.some_method()
end

Note that this won't work during Rails initialization when running Spring like Swartz said.

Upvotes: 2

dan-klasson
dan-klasson

Reputation: 14180

I would try creating a Rake task for it and invoke it with after_initialize:

config.after_initialize do
  IndividualProject::Application.load_tasks
  Rake::Task[ 'foo:bar' ].invoke
end

Upvotes: 0

Related Questions