Rake is beautiful tool, helping automate many tasks using Ruby. When You want to pass some arguments You can add VAR=value
on command line and then in task use ENV['VAR']
to access passed value. But it is not what You alway want. Sometimes You want more compact and clean way to pass arguments.
Starting with Rake 0.8.0 You can create tasks with arguments:
task :name, [:first_name, :last_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
Now You can pass some arguments:
C:\>rake name (in C:/) First name is John Last name is Dough C:\>rake name[Jim,Weirich] (in C:/) First name is Jim Last name is Weirich
Cool. I guess I don’t need to explain how arguments and setting default values does work?
However I have noticed some error. First documentation skip needed key in example when task have some dependency on other task (:needs
) and argument names should be provided not as an array (for task without dependencies both array and list form are working). Here is example of task with two arguments and one dependency, which does work (I’m using Rake 0.8.3):
task :name, :first_name, :last_name, :needs => [:other] 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 task :other do end
What You can do with args?
Here it is modified task from Chad Fowlers Rails Recipes to dump data from database to fixtures. Handy to populate fixtures with some data entered with WWW interface:
desc 'Create YAML test fixtures from data in an existing database. Defaults to development database. Set RAILS_ENV to override. Use args table and limit to dump one table and limit number of records' task :extract_fixtures, :table, :limit, :needs => :environment do |t, args| args.with_defaults(:table => nil, :limit => nil) limit = args.limit.nil? ? "" : "LIMIT #{args.limit}" sql = "SELECT * FROM %s #{limit}" skip_tables = ["schema_info" ] if args.table.nil? tables = ActiveRecord::Base.connection.tables - skip_tables else tables = [ "#{args.table}"] end ActiveRecord::Base.establish_connection tables.each do |table_name| i = "000" File.open("#{RAILS_ROOT}/test/fixtures/#{table_name}.yml" , 'w' ) do |file| data = ActiveRecord::Base.connection.select_all(sql % table_name) file.write data.inject({}) { |hash, record| hash["#{table_name}_#{i.succ!}" ] = record hash }.to_yaml end end end
You can dump all fixtures or only single table and limit it to first X entries. I find it useful recipe, I hope it can be used by someone else, too.
Leave a Reply