Executing a command every time the rails console starts

二次信任 提交于 2019-12-02 01:39:06

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:

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:

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

Mauro Dias

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.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!