问题 在Ruby on Rails中为rake任务和测试文件放置辅助函数的位置?


在我的Rails应用程序中,我有一个文件 sample_data.rb 内 /lib/tasks 以及我内心的一堆测试文件 /spec 目录。

所有这些文件通常共享通用功能,例如:

def random_address
  [Faker::Address.street_address, Faker::Address.city].join("\n")
end

我应该把这些辅助函数放在哪里?对此有什么约定吗?

谢谢你的帮助!


8251
2018-03-01 17:43


起源



答案:


您可以使用静态函数创建静态类。这看起来像这样:

class HelperFunctions

     def self.random_address
          [Faker::Address.street_address, Faker::Address.city].join("\n")
     end

     def self.otherFunction
     end
end

然后,您需要做的就是:

  1. 在您要使用的文件中包含您的帮助程序类
  2. 执行它像:

    HelperFunctions::random_address(anyParametersYouMightHave)
    

执行此操作时,请确保在您的内容中包含任何依赖项 HelperFunctions 类。


8
2018-03-01 21:43



谢谢你的帮助!你会把那个类放在什么目录中? - Tintin81
随你便。我可能把它放在控制器目录中。 - BlackHatSamurai
Nooooo不是控制器目录。这正是为什么有一个 lib 夹。该 app/controllers 文件夹应该只包含控制器。 - nathanvda


答案:


您可以使用静态函数创建静态类。这看起来像这样:

class HelperFunctions

     def self.random_address
          [Faker::Address.street_address, Faker::Address.city].join("\n")
     end

     def self.otherFunction
     end
end

然后,您需要做的就是:

  1. 在您要使用的文件中包含您的帮助程序类
  2. 执行它像:

    HelperFunctions::random_address(anyParametersYouMightHave)
    

执行此操作时,请确保在您的内容中包含任何依赖项 HelperFunctions 类。


8
2018-03-01 21:43



谢谢你的帮助!你会把那个类放在什么目录中? - Tintin81
随你便。我可能把它放在控制器目录中。 - BlackHatSamurai
Nooooo不是控制器目录。这正是为什么有一个 lib 夹。该 app/controllers 文件夹应该只包含控制器。 - nathanvda


如果您确定它只是特定的rake,您也可以直接添加 RAILS_ROOT/Rakefile (对于您使用的示例,情况可能并非如此)。

我用它来简化rake的invoke语法:

#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

def invoke( task_name )
  Rake::Task[ task_name ].invoke
end

MyApp::Application.load_tasks

那样,我可以使用 invoke "my_namespace:my_task" 在rake任务而不是 Rake::Task[ "my_namespace:my_task" ].invoke


6
2018-05-28 14:23



究竟为什么我最终来到这里!想知道在哪里放一个包装纸 Rake::Task['namespace:task'].reenable; Rake::Task['namespace:task'].invoke。 - jibiel


您在模块中共享方法,并将此类模块放在其中 lib 夹。

就像是 lib/fake_data.rb 含

module FakeData
  def random_address
    [Faker::Address.street_address, Faker::Address.city].join("\n")
  end

  module_function 
end

在rake任务中只需要模块,然后调用 FakeData.random_address

但是,如果它像每次运行测试时需要做的种子,你应该考虑将它添加到你的将军 before all

例如。我的 spec_helper 看起来像这样:

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"

  include SetupSupport

  config.before(:all) do
    load_db_seed
  end
end

和模块 SetupSupport 定义于 spec/support/setup_support.rb 看起来如下:

module SetupSupport

  def load_db_seed
    load(File.join(Rails.root, 'db', 'seeds.rb'))
  end

end

不确定是否需要加载种子,或者已经这样做了,但这也是生成所需假数据的理想位置。

请注意,我的安装支持类是在 spec/support 因为代码只与我的规范相关,所以我没有rake任务也需要相同的代码。


0
2017-11-25 10:13



为了使你的 FakeData 模块示例代码工作,它会出现 module_function 应插入声明 之前 定义 random_address 功能,而不是 后。 - wehal3001