Executing a command every time the rails console starts
Asked Answered
A

3

5

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!

Abisia answered 30/6, 2016 at 18:6 Comment(3)
Is there something preventing from writing an alias that will execute what you want when you start the app? Is it specific to one app or all apps you write?Chloechloette
have you tried this? #8544404Inn
Thanks @MauroDias - but I'm looking to run code after rails console starts, not the rails server.Abisia
R
12

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.

Residue answered 20/7, 2018 at 15:23 Comment(0)
I
2

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.

Inn answered 1/7, 2016 at 14:38 Comment(1)
may this help you too: #29687158Inn
W
0

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
Wallflower answered 30/6, 2016 at 18:9 Comment(2)
I can add this to the app, but I'd like to only run it when rails console is starting, not when the app (rails server) is starting. Is there a way I can figure out what is running so I can wrap it in an if block?Abisia
What do you want it to do every time you run the console?Wallflower

© 2022 - 2024 — McMap. All rights reserved.