Как передать аргументы в задачу Rake с средой в Rails?
Я могу передать аргументы следующим образом:
desc "Testing args"
task: :hello, :user, :message do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{args[:user]}. #{:message}"
end
Я также могу загрузить текущую среду для приложения Rails
desc "Testing environment"
task: :hello => :environment do
puts "Hello #{User.first.name}."
end
То, что я хотел бы сделать, это иметь переменные и среду
desc "Testing environment and variables"
task: :hello => :environment, :message do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{:message}"
end
Но это недействительный вызов задачи. Кто-нибудь знает, как я могу это достичь?
Ответы
Ответ 1
Когда вы передаете аргументы для задач rake, вы можете потребовать среду, используя опцию: needs. Например:
desc "Testing environment and variables"
task :hello, :message, :needs => :environment do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{args.message}"
end
Обновлено на комментарий @Peiniau ниже
Что касается Rails > 3.1
task :t, arg, :needs => [deps] # deprecated
Пожалуйста, используйте
task :t, [args] => [deps]
Ответ 2
Просто следить за этой старой темой; вот что я думаю, что текущий Rakefile (с давних времен) должен там делать. Это обновленная и исправленная версия текущего выигрышного ответа (hgimenez):
desc "Testing environment and variables"
task :hello, [:message] => :environment do |t, args|
args.with_defaults(:message => "Thanks for logging on")
puts "Hello #{User.first.name}. #{args.message}" # Q&A above had a typo here : #{:message}
end
Вот как вы его вызываете (http://guides.rubyonrails.org/v4.2/command_line.html#rake):
rake "hello[World]"
Для нескольких аргументов просто добавьте их ключевые слова в массив объявления задачи (task :hello, [:a,:b,:c]...
) и разделите их запятыми:
rake "hello[Earth,Mars,Sun,Pluto]"
Примечание: количество аргументов не проверяется, поэтому нечетная планета не учитывается:)
Ответ 3
Просто для полноты, вот пример из docs, упомянутый выше:
task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
args.with_defaults(:first_name => "John", :last_name => "Dough")
puts "First name is #{args.first_name}"
puts "Last name is #{args.last_name}"
end
Примечания:
- Вы можете опустить вызов
#with_defaults
, очевидно.
- Вы должны использовать
Array
для своих аргументов, даже если есть только один.
- Предварительные требования не обязательно должны быть
Array
.
-
args
- это экземпляр Rake::TaskArguments
.
-
t
является экземпляром Rake::Task
.
Ответ 4
Альтернативный способ сделать это: использовать переменные среды ОС. Преимущества такого подхода:
- Все зависимые задачи грабли получают параметры.
- Синтаксис намного проще, не зависящий от грабли DSL, который трудно понять и со временем меняет.
У меня есть задача rake, которая требует трех параметров командной строки. Вот как я его вызываю:
$ rake eaternet:import country=us region=or agency=multco
Это очень чистый, простой и просто синтаксис bash, который мне нравится. Вот моя рейк-задача. Также очень чисто и без магии:
task import: [:environment] do
agency = agency_to_import
puts "Importing data for #{agency}..."
agency.import_businesses
end
def agency_to_import
country_code = ENV['country'] or raise "No country specified"
region_slug = ENV['region'] or raise "No region specified"
agency_slug = ENV['agency'] or raise "No agency specified"
Agency.from_slugs(country_code, region_slug, agency_slug)
end
Этот конкретный пример не показывает использование зависимостей. Но если задача :import
зависела от других, они также имели бы доступ к этим параметрам. Но, используя обычный метод опций rake, они бы этого не сделали.
Ответ 5
Хотя эти решения работают, на мой взгляд, это слишком сложно.
Кроме того, если вы сделаете это так в zsh, вы получите ошибки, если скобки в вашем массиве не экранированы с помощью '\'.
Я рекомендую использовать массив ARGV, который отлично работает, намного проще и менее подвержен ошибкам. Например:
namespace :my_example do
desc "Something"
task :my_task => :environment do
puts ARGV.inspect
end
end
затем
rake my_example:my_task 1 2 3
#=> ["my_example:my_task", "1", "2", "3"]
Единственное, что вам нужно иметь в виду, это то, что ARGV [0] - это имя процесса, поэтому используйте только ARGV [1..- 1].
Я понимаю, что, строго говоря, это не отвечает на вопрос, так как он не использует: среду как часть решения. Но ОП не указал, почему он включил это условие, чтобы он мог по-прежнему применяться к его прецеденту.