Tôi có một nhiệm vụ cào cần chèn một giá trị vào nhiều cơ sở dữ liệu.
Tôi muốn chuyển giá trị này vào tác vụ cào từ dòng lệnh hoặc từ một tác vụ cào khác .
Tôi có thể làm cái này như thế nào?
Tôi có một nhiệm vụ cào cần chèn một giá trị vào nhiều cơ sở dữ liệu.
Tôi muốn chuyển giá trị này vào tác vụ cào từ dòng lệnh hoặc từ một tác vụ cào khác .
Tôi có thể làm cái này như thế nào?
Câu trả lời:
tùy chọn và phụ thuộc cần phải nằm trong mảng:
namespace :thing do
  desc "it does a thing"
  task :work, [:option, :foo, :bar] do |task, args|
    puts "work", args
  end
  task :another, [:option, :foo, :bar] do |task, args|
    puts "another #{args}"
    Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
    # or splat the args
    # Rake::Task["thing:work"].invoke(*args)
  end
endSau đó
rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}LƯU Ý: biến
tasklà đối tượng tác vụ, không hữu ích lắm trừ khi bạn biết / quan tâm đến nội bộ Rake.
RAILS LƯU Ý:
Nếu chạy tác vụ từ đường ray, tốt nhất là tải trước môi trường bằng cách thêm
=> [:environment]đó là cách để thiết lập các tác vụ phụ thuộc .
  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  endrake thing:work[1, 2, 3]vì nó sẽ không hoạt động và bạn sẽ gặp lỗiDon't know how to build task
                    rake thing:work'[1,2,3]'
                    rake thing:work\[1,2,3\]hoặc thế nàyrake 'thing:work[1,2,3]'
                    :environmentbiểu tượng khỏi nhiệm vụ của mình. các ứng dụng đường ray có một: nhiệm vụ môi trường ...
                    tcó nghĩa là task, tại sao không chỉ sử dụng tasklàm tên param?
                    Bạn có thể chỉ định các đối số chính thức trong rake bằng cách thêm các đối số ký hiệu vào lệnh gọi tác vụ. Ví dụ:
require 'rake'
task :my_task, [:arg1, :arg2] do |t, args|
  puts "Args were: #{args} of class #{args.class}"
  puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
  puts "arg2 was: '#{args[:arg2]}' of class #{args[:arg2].class}"
end
task :invoke_my_task do
  Rake.application.invoke_task("my_task[1, 2]")
end
# or if you prefer this syntax...
task :invoke_my_task_2 do
  Rake::Task[:my_task].invoke(3, 4)
end
# a task with prerequisites passes its 
# arguments to it prerequisites
task :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task
# to specify default values, 
# we take advantage of args being a Rake::TaskArguments object
task :with_defaults, :arg1, :arg2 do |t, args|
  args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
  puts "Args with defaults were: #{args}"
endSau đó, từ dòng lệnh:
> cào my_task [1, sai]
Các đối số là: {: arg1 => "1" ,: arg2 => "false"} của lớp Rake :: TaskArgument
arg1 là: '1' của Chuỗi lớp
arg2 là: 'false' của Chuỗi lớp
> cào "my_task [1, 2]"
Các đối số là: {: arg1 => "1" ,: arg2 => "2"}
> rake invoke_my_task
Các đối số là: {: arg1 => "1" ,: arg2 => "2"}
> rake invoke_my_task_2
Các đối số là: {: arg1 => 3 ,: arg2 => 4}
> rake with_prere condition [5,6]
Các đối số là: {: arg1 => "5" ,: arg2 => "6"}
> cào với_defaults
Các đối số có mặc định là: {: arg1 =>: default_1 ,: arg2 =>: default_2}
> rake with_defaults ['x', 'y']
Các đối số có giá trị mặc định là: {: arg1 => "x" ,: arg2 => "y"}
Như đã minh họa trong ví dụ thứ hai, nếu bạn muốn sử dụng khoảng trắng, các trích dẫn xung quanh tên đích là cần thiết để giữ cho shell không bị tách ra khỏi các đối số tại khoảng trắng.
Nhìn vào mã trong rake.rb , có vẻ như rake không phân tích các chuỗi nhiệm vụ để trích xuất các đối số cho các điều kiện tiên quyết, vì vậy bạn không thể làm được task :t1 => "dep[1,2]". Cách duy nhất để xác định các đối số khác nhau cho một điều kiện tiên quyết sẽ là gọi nó một cách rõ ràng trong hành động tác vụ phụ thuộc, như trong :invoke_my_taskvà :invoke_my_task_2.
Lưu ý rằng một số shell (như zsh) yêu cầu bạn thoát dấu ngoặc: rake my_task\['arg1'\]
WARNING: 'task :t, arg, :needs => [deps]' is deprecated.  Please use 'task :t, [args] => [deps]' instead.
                    zsh: no matches found: ...), vì vậy bạn cần thoát dấu ngoặc : rake my_task\['arg1'\]. Từ robot
                    Ngoài việc trả lời bằng kch (tôi không tìm thấy cách để lại nhận xét cho điều đó, xin lỗi):
Bạn không phải chỉ định biến là ENVbiến trước rakelệnh. Bạn chỉ có thể đặt chúng như các tham số dòng lệnh thông thường như thế:
rake mytask var=foovà truy cập những người từ tệp rake của bạn dưới dạng các biến ENV như sau:
p ENV['var'] # => "foo"pcó nghĩa là gì?
                    Nếu bạn muốn truyền các đối số có tên (ví dụ với tiêu chuẩn OptionParser), bạn có thể sử dụng một cái gì đó như thế này:
$ rake user:create -- --user test@example.com --pass 123lưu ý --rằng, điều đó là cần thiết để bỏ qua các đối số Rake tiêu chuẩn. Nên làm việc với Rake 0.9.x , <= 10.3.x .
Rake mới hơn đã thay đổi phân tích cú pháp --và bây giờ bạn phải đảm bảo rằng nó không được truyền cho OptionParser#parsephương thức, ví dụ như vớiparser.parse!(ARGV[2..-1])
require 'rake'
require 'optparse'
# Rake task for creating an account
namespace :user do |args|
  desc 'Creates user account with given credentials: rake user:create'
  # environment is required to have access to Rails models
  task :create do
    options = {}
    OptionParser.new(args) do |opts|
      opts.banner = "Usage: rake user:create [options]"
      opts.on("-u", "--user {username}","User's email address", String) do |user|
        options[:user] = user
      end
      opts.on("-p", "--pass {password}","User's password", String) do |pass|
        options[:pass] = pass
      end
    end.parse!
    puts "creating user account..."
    u = Hash.new
    u[:email] = options[:user]
    u[:password] = options[:pass]
    # with some DB layer like ActiveRecord:
    # user = User.new(u); user.save!
    puts "user: " + u.to_s
    puts "account created."
    exit 0
  end
endexit ở cuối sẽ đảm bảo rằng các đối số phụ sẽ không được hiểu là nhiệm vụ Rake. 
Ngoài ra các phím tắt cho các đối số nên hoạt động:
 rake user:create -- -u test@example.com -p 123Khi các kịch bản cào trông như thế này, có lẽ đã đến lúc tìm kiếm một công cụ khác cho phép điều này vượt ra ngoài.
--option-names. Đề nghị duy nhất của tôi sẽ là sử dụng exitthay abortvì abortsẽ để lại cho bạn mã trả về 1 cho trình bao. Nếu tác vụ cào là một phần của tập lệnh cấp cao hơn, thì phổ biến hơn là giả sử lối thoát khác không là một loại lỗi.
                    --? Giống như chuyển các rakeđối số cho nhiệm vụ thực tế hoặc một cái gì đó? Thích task :my_task, :*args do |t, args|hay sao?
                    {username}ở đây để làm. Nó được sử dụng ở đâu? Tại sao nó không ở đó -u {username}? Chúc mừng
                    10.4.1và hoàn nguyên 10.4.2. github.com/ruby/rake/commit/
                    Tôi đã tìm thấy câu trả lời từ hai trang web này: Net Maniac và Aimred .
Bạn cần có phiên bản> 0,8 cào để sử dụng kỹ thuật này
Mô tả nhiệm vụ cào bình thường là thế này:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
  #interesting things
endĐể vượt qua các đối số, làm ba điều:
Để truy cập các đối số trong tập lệnh, sử dụng args.arg_name
desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
  args.display_times.to_i.times do
    puts args.display_value
  end
endĐể gọi tác vụ này từ dòng lệnh, hãy truyền cho nó các đối số trong [] s
rake task_name['Hello',4]sẽ xuất
Hello
Hello
Hello
Hellovà nếu bạn muốn gọi tác vụ này từ một tác vụ khác và truyền nó vào đối số, hãy sử dụng lệnh gọi
task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
endsau đó là lệnh
rake callersẽ xuất
In Caller
hi
hiTôi đã không tìm thấy một cách để vượt qua các đối số như là một phần của sự phụ thuộc, khi đoạn mã sau bị phá vỡ:
task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end'task :t, arg, :needs => [deps]' is deprecated.  Please use 'task :t, [args] => [deps]' instead.
                    Một tùy chọn khác thường được sử dụng là để vượt qua các biến môi trường. Trong mã của bạn, bạn đọc chúng thông qua ENV['VAR']và có thể chuyển chúng ngay trước rakelệnh, như
$ VAR=foo rake mytaskrake blah -- --these --go --to --a-program(lưu ý --để nói với rake rằng các công tắc của nó đã kết thúc), xem stackoverflow.com/questions/5086224/ Lỗi
                    Tôi không thể tìm ra cách vượt qua args và cả môi trường: cho đến khi tôi tìm ra cách này:
namespace :db do
  desc 'Export product data'
  task :export, [:file_token, :file_path] => :environment do |t, args|
    args.with_defaults(:file_token => "products", :file_path => "./lib/data/")
       #do stuff [...]
  end
endVà sau đó tôi gọi như thế này:
rake db:export['foo, /tmp/']desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
endrake task_name[hello, world]
                    Tôi chỉ muốn có thể chạy:
$ rake some:task arg1 arg2Đơn giản phải không? (Không!)
Rake phiên dịch arg1và arg2như các nhiệm vụ, và cố gắng chạy chúng. Vì vậy, chúng tôi chỉ phá thai trước khi nó làm.
namespace :some do
  task task: :environment do
    arg1, arg2 = ARGV
    # your task...
    exit
  end
endLấy đó, ngoặc!
Disclaimer : Tôi muốn có thể làm điều này trong một dự án thú cưng nhỏ. Không dành cho sử dụng "thế giới thực" vì bạn mất khả năng xâu chuỗi các tác vụ cào (tức là rake task1 task2 task3). IMO không đáng Chỉ dùng cái xấu xí rake task[arg1,arg2].
_, arg1, arg2 = ARGVnhư là đối số đầu tiên được coi là tên của nhiệm vụ cào. Nhưng đó exitlà một mẹo gọn gàng.
                    rake task[arg1,arg2] && rake task2 && rake task3Không chắc chắn nếu điều đó ít xấu xí hơn rake task[arg1,arg2] task2 task3. Có lẽ ít hiệu quả hơn mặc dù.
                    _, *args = ARGVlà hoàn hảo để nắm bắt tất cả các đối số tiếp theo! Cảm ơn đống!
                    Tôi sử dụng một đối số ruby thông thường trong tệp cào:
DB = ARGV[1]sau đó tôi loại bỏ các tác vụ cào ở dưới cùng của tệp (vì rake sẽ tìm kiếm một tác vụ dựa trên tên đối số đó).
task :database_name1
task :database_name2dòng lệnh:
rake mytask db_nameđiều này cảm thấy sạch sẽ hơn với tôi so với var = foo ENV var và tác vụ tranh luận [blah, blah2]. 
còn sơ khai là một chút vui nhộn, nhưng không quá tệ nếu bạn chỉ có một vài môi trường là thiết lập một lần
dupở cuối: db = ARGV [1] .dup
                    db = ARGV[1].dup unless ARGV[1].nil?để ngăn chặn ngoại lệ của một con số không.
                    Các cách để vượt qua đối số là chính xác trong câu trả lời ở trên. Tuy nhiên, để chạy tác vụ cào với các đối số, có một kỹ thuật nhỏ liên quan đến phiên bản mới hơn của đường ray
Nó sẽ hoạt động với rake "không gian tên: taskname ['argument1']"
Lưu ý các trích dẫn ngược trong khi chạy tác vụ từ dòng lệnh.
Để truyền đối số cho tác vụ mặc định, bạn có thể làm một cái gì đó như thế này. Ví dụ: nói "phiên bản" là đối số của bạn:
task :default, [:version] => [:build]
task :build, :version do |t,args|
  version = args[:version]
  puts version ? "version is #{version}" : "no version passed"
endSau đó, bạn có thể gọi nó như vậy:
$ rake
no version passedhoặc là
$ rake default[3.2.1]
version is 3.2.1hoặc là
$ rake build[3.2.1]
version is 3.2.1Tuy nhiên, tôi chưa tìm được cách nào để tránh chỉ định tên tác vụ (mặc định hoặc bản dựng) trong khi truyền các đối số. Rất thích nghe nếu có ai biết một cách.
Tôi thích cú pháp "chuỗi truy vấn" để truyền đối số, đặc biệt là khi có rất nhiều đối số được truyền.
Thí dụ:
rake "mytask[width=10&height=20]""Chuỗi truy vấn" là:
width=10&height=20Cảnh báo: lưu ý rằng cú pháp là rake "mytask[foo=bar]"và KHÔNG rake mytask["foo=bar"]
Khi phân tích cú pháp bên trong tác vụ cào bằng Rack::Utils.parse_nested_query, chúng ta nhận được Hash:
=> {"width"=>"10", "height"=>"20"}(Điều thú vị là bạn có thể vượt qua băm và mảng, bên dưới)
Đây là cách để đạt được điều này:
require 'rack/utils'
task :mytask, :args_expr do |t,args|
  args.with_defaults(:args_expr => "width=10&height=10")
  options = Rack::Utils.parse_nested_query(args[:args_expr])
endĐây là một ví dụ mở rộng hơn mà tôi đang sử dụng với Rails trong đá quý delay_job_active_record_threaded của mình :
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"Phân tích cú pháp theo cách tương tự như trên, với sự phụ thuộc môi trường (để tải môi trường Rails)
namespace :dj do
  task :start, [ :args_expr ] => :environment do |t, args|
    # defaults here...
    options = Rack::Utils.parse_nested_query(args[:args_expr])  
  end
endĐưa ra những điều sau đây trong options
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}Nếu bạn không thể bận tâm để nhớ vị trí đối số là gì và bạn muốn làm gì đó như hàm băm đối số ruby. Bạn có thể sử dụng một đối số để truyền vào một chuỗi và sau đó regex chuỗi đó thành hàm băm tùy chọn.
namespace :dummy_data do
  desc "Tests options hash like arguments"
  task :test, [:options] => :environment do |t, args|
    arg_options = args[:options] || '' # nil catch incase no options are provided
    two_d_array = arg_options.scan(/\W*(\w*): (\w*)\W*/)
    puts two_d_array.to_s + ' # options are regexed into a 2d array'
    string_key_hash = two_d_array.to_h
    puts string_key_hash.to_s + ' # options are in a hash with keys as strings'
    options = two_d_array.map {|p| [p[0].to_sym, p[1]]}.to_h
    puts options.to_s + ' # options are in a hash with symbols'
    default_options = {users: '50', friends: '25', colour: 'red', name: 'tom'}
    options = default_options.merge(options)
    puts options.to_s + ' # default option values are merged into options'
  end
endVà trên dòng lệnh bạn nhận được.
$ rake dummy_data:test["users: 100 friends: 50 colour: red"]
[["users", "100"], ["friends", "50"], ["colour", "red"]] # options are regexed into a 2d array
{"users"=>"100", "friends"=>"50", "colour"=>"red"} # options are in a hash with keys as strings
{:users=>"100", :friends=>"50", :colour=>"red"} # options are in a hash with symbols
{:users=>"100", :friends=>"50", :colour=>"red", :name=>"tom"} # default option values are merged into optionsHầu hết các phương pháp được mô tả ở trên không hiệu quả với tôi, có thể chúng không được dùng trong các phiên bản mới hơn. Hướng dẫn cập nhật có thể được tìm thấy ở đây: http://guides.rubyonrails.org/command_line.html#custom-rake-t task
một bản sao và dán ans từ hướng dẫn có ở đây:
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
  # You can use args from here
endGọi nó như thế này
bin/rake "task_name[value 1]" # entire argument string should be quotedĐể chạy các tác vụ cào với kiểu đối số truyền thống:
rake task arg1 arg2Và sau đó sử dụng:
task :task do |_, args|
  puts "This is argument 1: #{args.first}"
endThêm bản vá sau của đá quý cào:
Rake::Application.class_eval do
  alias origin_top_level top_level
  def top_level
    @top_level_tasks = [top_level_tasks.join(' ')]
    origin_top_level
  end
  def parse_task_string(string) # :nodoc:
    parts = string.split ' '
    return parts.shift, parts
  end
end
Rake::Task.class_eval do
  def invoke(*args)
    invoke_with_call_chain(args, Rake::InvocationChain::EMPTY)
  end
endTrong khi truyền tham số, tùy chọn tốt hơn là một tệp đầu vào, đây có thể là excel một json hoặc bất cứ thứ gì bạn cần và từ đó đọc cấu trúc dữ liệu và các biến bạn cần từ đó bao gồm tên biến là cần thiết. Để đọc một tập tin có thể có cấu trúc sau.
  namespace :name_sapace_task do
    desc "Description task...."
      task :name_task  => :environment do
        data =  ActiveSupport::JSON.decode(File.read(Rails.root+"public/file.json")) if defined?(data)
    # and work whit yoour data, example is data["user_id"]
    end
  end{
  "name_task": "I'm a task",
  "user_id": 389,
  "users_assigned": [389,672,524],
  "task_id": 3
}rake :name_task