Я могу передать аргументы следующим образом:
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
Но это недействительный вызов задачи. Кто-нибудь знает, как я могу это достичь?
Когда вы передаете аргументы для задач 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]
:needs
следующим образом: «Этот формат все еще поддерживается для совместимости, но не рекомендуется для использования». (Я упоминаю об этом только для будущих браузеров, поскольку он предполагает, что в конечном итоге :needs
больше не будут поддерживаться. Раздел называется «Формат устаревших параметров задачи» ...)
Просто следить за этой старой темой; вот что я думаю, что текущий 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]"
Примечание: количество аргументов не проверяется, поэтому нечетная планета не учитывается:)
Просто для полноты, вот пример из 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
.args.empty?
дал мне странные результаты. args
выглядит как хеш, но это Rake::TaskArguments
. Поэтому, если вам нужно особое поведение при отсутствии аргументов, вызовите #to_hash
или #to_s
прежде чем проверять, является ли args
пустым.
Альтернативный способ сделать это: использовать переменные среды ОС. Преимущества такого подхода:
У меня есть задача 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, они бы этого не сделали.
country=us ruby -e "puts ENV['country']"
не то же самое, что ruby -e "puts ENV['country']" country=us
(переменная окружения в первом против аргумента во втором).
Хотя эти решения работают, на мой взгляд, это слишком сложно.
Кроме того, если вы сделаете это так в 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].
Я понимаю, что, строго говоря, это не отвечает на вопрос, так как он не использует: среду как часть решения. Но ОП не указал, почему он включил это условие, чтобы он мог по-прежнему применяться к его прецеденту.
:environment
необходима для загрузки кода приложения Rails. И, пробуя его в приложении Rails, я получаю: ["my_example:my_task", "1", "2", "3"] rake aborted! Don't know how to build task '1' (see --tasks)