Why is `:environment` passed to a rake task as an array? - ruby-on-rails

I am looking at the first line of following rake task:
task :generate_course_group_progress_report => [:environment] do
Why is [:environment] passed as the value of the hash as an array instead of :environment? what does this do? This doesn't seem to break the task.
Is there a scenario where I would pass multiple variables to the hash, i.e [:environment, :something_else]?

No, you can use it also as a symbol.
task test_task: :environment do
# some code
end

Related

Check if a value exists in a database and return the value if it does Rails

I am running Rails here with a User model that contains an :email_address column
I have an array - emails_to_check[email1,email2,email3] that i want to check if they exist in the User database.
I only want to return the values that DO exist in the database
Here's a simple one-liner for you. There may be more performant ways, but this is maybe the most straight-forward and idiomatic Rails.
emails_to_check = ['email1', 'email2', 'email3']
User.where(email_address: emails_to_check).pluck(:email_address)
Here is the resulting SQL query:
SELECT `users`.`email_address` FROM `users` WHERE `users`.`email_address` IN ('email1', 'email2', 'email3');
so i solved this using a rake task
task :find_users_in_array,[:emails_to_find] => :environment do |task, args|
emails = args[:emails_to_find].split
emails.each do |email|
if User.find_by(email:email)
puts "#{email}"
end
end
end
I can pass in a list using rake:find_users_in_array[email1 email2 email3]

Running a 1 time task to enter values into database in Ruby

I have now added a new column to my table in database. I want to add some values to some rows in this new column. I know the logic and all. But actually I dont know the way to add this, or write a 1 time task to do this in ruby on rails. Can any one help me. I just need some idea.
data = Model.where(#your_condition)
if the value is same for all
data.update_all(:new_column => "new value")
if the value is different for all
data.each do |d|
d.update_attributes(:new_column => "some value")
end
You can create a rake task for this, and run it once.
Create a file lib/tasks/my_namespace.rake
namespace :my_namespace do
desc "My Task description"
task :my_task => :environment do
# Code to make db change goes here
end
end
You can invoke the task from the command line in project root folder like
rake my_namespace:my_task RAILS_ENV=production

Rails - Soulmate, export to json one item per line

I'm trying to use Soulmate to make the search and autocompletion. However it requires a json file with all data under a model and one item per line. When I export with to_json i get all object separated by comma.
This is what I want to print:
{"id":1,"term":"Dodger Stadium","score":85,"data":{"url":"\/dodger-stadium-tickets\/","subtitle":"Los Angeles, CA"}}
{"id":28,"term":"Angel Stadium","score":85,"data":{"url":"\/angel-stadium-tickets\/","subtitle":"Anaheim, CA"}}
{"id":30,"term":"Chase Field ","score":85,"data":{"url":"\/chase-field-tickets\/","subtitle":"Phoenix, AZ"}}
{"id":29,"term":"Sun Life Stadium","score":84,"data":{"url":"\/sun-life-stadium-tickets\/","subtitle":"Miami, FL"}}
{"id":2,"term":"Turner Field","score":83,"data":{"url":"\/turner-field-tickets\/","subtitle":"Atlanta, GA"}}
And this is what I print with to_json
[{"id":1,"first_name":"Philip","last_name":"nalle","location":"nallemia","email":"hejsan#hej.com","active":false,"created_at":"2013-06-26T15:00:38.990Z","updated_at":"2013-06-26T15:00:38.990Z"},{"id":2,"first_name":"Philip","last_name":"nalle","location":"hejsan123","email":"hejsan#asd.com","active":false,"created_at":"2013-06-26T15:01:45.905Z","updated_at":"2013-06-26T15:01:45.905Z"},{"id":3,"first_name":"hejsan","last_name":"hejsan","location":"asd","email":"asd#asda.com","active":false,"created_at":"2013-06-26T15:08:20.354Z","updated_at":"2013-06-26T15:08:20.354Z"},{"id":4,"first_name":"well well","last_name":"hello","location":"asd123","email":"asd#asd.com","active":false,"created_at":"2013-06-26T15:10:27.121Z","updated_at":"2013-06-26T15:12:29.991Z"}]
Don't mind the actual data inside the json, I just copied a sample from soulmates readme. This is the rake task.
desc "Save all participants to json"
task :save_to_json => :environment do
File.open("participants.json", "w") { |f| f.write(Participant.all.to_json)}
end
To achieve what you want, you need to output elements one by one.
It will also save memory if instead of .all you grab them by 1000 if there are many of them.
desc "Save all participants to json"
task :save_to_json => :environment do
File.open("participants.json", "w") do |f|
Participant.all.each do |participant|
f.write("#{participant.to_json}\n")
end
end
end

Rake Execute With Multiple Arguments

I'm calling a rake task within a task and I'm running into a roadblock when it comes to calling execute
response = Rake::Task["stuff:sample"].execute[:match => "HELLO"]
or
response = Rake::Task["stuff:sample"].execute[:match => "HELLO",:freq=>'100']
Calling task
task :sample, [:match,:freq] => :environment do |t, args|
The error I get back is 'can't convert Hash into Integer'
Any ideas?
I think the problem is in code you're not posting. Works fine for me:
james#James-Moores-iMac:/tmp$ head r.rb call.rb
==> r.rb <==
task :sample, [:match,:freq] do |t, args|
puts "hello world"
puts args[:match]
end
==> call.rb <==
require 'rubygems'
require 'rake'
load 'r.rb'
Rake::Task["sample"].execute :match => "HELLO"
james#James-Moores-iMac:/tmp$ ruby call.rb
hello world
HELLO
james#James-Moores-iMac:/tmp$
The square brackets in your execute syntax confuse me. Is that a special rake syntax (that you may be using incorrectly) or do you mean to send an array with one element (a hash)?
Isn't it the same as this?
response = Rake::Task["sample"].execute([:match => "HELLO",:freq=>'100'])
Beyond that, Task#execute expects Rake:TaskArguments.
class TaskArguments
...
# Create a TaskArgument object with a list of named arguments
# (given by :names) and a set of associated values (given by
# :values). :parent is the parent argument object.
def initialize(names, values, parent=nil)
You could use:
stuff_args = {:match => "HELLO", :freq => '100' }
Rake::Task["stuff:sample"].execute(Rake::TaskArguments.new(stuff_args.keys, stuff_args.values))
You could also use Task#invoke, which will receive basic args. Make sure you Task#reenable if you invoke it multiple times.
This post is pretty old but I found the first answer is wrong by passing a hash inside an array. We can send arguments by passing them as a hash as following
response = Rake::Task["sample"].execute(match: "HELLO", freq: 100)
Inside the rake task, we can access them in args as args[:match] and args[:freq].to_i

Passing a parameter or two to a Rake task

I have a rake task that I want to pass parameters to. For example, I want to issue a command like
<prompt> rake db:do_something 1
and inside the rake task:
...
cust = Customer.find( the_id_passed_in )
# do something with this customer record, etc...
...
Pretty straightforward, right?
The way rake commands accept and define arguments is, well, not pretty.
Call your task this way:
<prompt> rake db:do_something[1,2]
I've added a second parameter to show that you'll need the comma, but omit any spaces.
And define it like this:
task :do_something, :arg1, :arg2 do |t, args|
args.with_defaults(:arg1 => "default_arg1_value", :arg2 => "default_arg2_value")
# args[:arg1] and args[:arg2] contain the arg values, subject to the defaults
end
While passing parameters, it is better option is an input file, can this be a excel a json or whatever you need and from there read the data structure and variables you need from that including the variable name as is the need.
To read a file can have the following structure.
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
Example json
{
"name_task": "I'm a task",
"user_id": 389,
"users_assigned": [389,672,524],
"task_id": 3
}
Execution
rake :name_task

Resources