Где разместить вспомогательные функции для rake-задач и тестовых файлов в Ruby on Rails?

В моем приложении Rails у меня есть файл sample_data.rb внутри /lib/tasks, а также набор тестовых файлов в моем каталоге /spec.

Все эти файлы часто имеют общие функции, такие как:

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

Где я должен разместить эти вспомогательные функции? Есть ли какая-то конвенция по этому поводу?

Спасибо за любую помощь!


person Tintin81    schedule 01.03.2013    source источник
comment
Какое это имеет отношение к рейку? Все, что я вижу, это файлы .rb. Это вводящее в заблуждение название.   -  person Taylored Web Sites    schedule 06.02.2020


Ответы (3)


Вы можете создать статический класс со статическими функциями. Это будет выглядеть примерно так:

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.

person BlackHatSamurai    schedule 01.03.2013
comment
Спасибо за вашу помощь! В какой каталог вы бы поместили этот класс? - person Tintin81; 02.03.2013
comment
Тебе решать. Я бы, наверное, поместил его в каталог контроллера. - person BlackHatSamurai; 02.03.2013
comment
Нееет, не каталог контроллера. Именно поэтому существует папка lib. Папка app/controllers должна содержать только контроллеры. - person nathanvda; 25.11.2013

Если вы уверены, что это относится только к рейку, вы также можете добавить непосредственно в RAILS_ROOT/Rakefile (вероятно, это не относится к используемому вами примеру).

Я использую это, чтобы упростить синтаксис вызова rake:

#!/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.

person kik    schedule 28.05.2013
comment
Именно поэтому я оказался здесь! Хотел узнать, куда поставить обертку для Rake::Task['namespace:task'].reenable; Rake::Task['namespace:task'].invoke. - person jibiel; 20.12.2015

Вы разделяете методы в модуле и помещаете такой модуль в папку 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, также требующей того же кода.

person nathanvda    schedule 25.11.2013
comment
чтобы заставить ваш пример кода модуля FakeData работать, оператор module_function должен быть вставлен до определения функции random_address, а не после. - person wehal3001; 15.08.2016