【问题标题】:Executing a command every time the rails console starts每次 Rails 控制台启动时执行命令
【发布时间】:2016-11-02 23:28:15
【问题描述】:

我有一个要执行的设置命令每次我启动rails console -

MyClass.some_method()

我厌倦了每次启动 rails c 时都重新输入它 - 有没有办法让它在每次启动新控制台时自动运行?

谢谢!

【问题讨论】:

  • 当你启动应用程序时,是否有什么东西阻止你编写一个别名来执行你想要的东西?它是特定于一个应用程序还是您编写的所有应用程序?
  • 感谢@MauroDias - 但我希望在 rails console 启动后运行代码,而不是 rails 服务器。

标签: ruby-on-rails ruby-on-rails-4 rails-console


【解决方案1】:

我们这样做是为了在每次控制台启动时询问租户。这需要一些调查,但我们让它工作得相当优雅。请注意,这适用于 Rails 5.2,但自 Rails 4 以来它的工作方式基本相同。

另外需要注意的是,这是专门编写的,因为我们希望能够在启动时运行该方法一次,然后能够在使用控制台时再次运行它,比如如果我们想在会话期间切换租户.

第一步是在 lib 文件中创建一组模块和类。这是从我们的示例中提取的示例:

# 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

下一步是将以下内容添加到您的 application.rb 文件中:

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

现在,每次你运行 rails 控制台,它都会做一些事情:

如果您只是希望在每次控制台启动时运行一次,这比需要的要复杂得多。相反,您可以只使用 MyApp::Application 中的 console() 方法,它将运行您想要的任何代码作为the load_console step 的一部分。

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

    console do
      puts "do something"
    end
  end
end

我们遇到的一个问题是它在打印出环境之前运行代码,所以如果您正在执行任何打印或交互,感觉有点奇怪:

不过,你可能不像我们那么挑剔。做任何让你和你的团队最开心的事情。

【讨论】:

    【解决方案2】:

    我不知道这是否是一个好习惯,但您可以检查服务器是否在控制台上运行,例如 Aditya awnsered

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

    请注意,当像 Swartz 所说的那样运行 Spring 时,这在 Rails 初始化期间不起作用。

    【讨论】:

    【解决方案3】:

    我会尝试为它创建一个 Rake 任务并使用 after_initialize 调用它:

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

    【讨论】:

    • 我可以将它添加到应用程序中,但我只想在 rails 控制台启动时运行它,而不是在应用程序(rails 服务器)启动时运行它。有没有办法可以找出正在运行的内容,以便将其包装在 if 块中?
    • 每次运行控制台时希望它做什么?
    猜你喜欢
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 2012-06-21
    • 2014-11-06
    • 2016-05-20
    • 1970-01-01
    相关资源
    最近更新 更多