Saving Issue Custom Field Values via Rake Task in Redmine - ruby-on-rails

Hi I have a rake task which when executed via console work, but doesn't work when rake task is called. Actually it confirms that save occurred, while values aren't updated. Seems like some active record commit is missing, because the only difference in logs I see is begin commit dumps if run (via console), while there isn't such sections in Redmine's debug.log when run as rake task...
Here is it's content:
namespace :redmine do
namespace :myplugin do
desc 'Updates custom field for idle tickets.'
task :update_idle => :environment do
Issue.open.each do |issue|
begin
days = DateTime.now.to_time - DateTime.parse(issue.updated_on.to_s).to_time
days = days/86400
if days > 0
cfv = issue.custom_field_values.detect {|cfv| cfv.custom_field_id == 19 }
cfv.value = days.ceil
if issue.save
puts "#{issue.id} saved"
else
puts "#{issue.id} not saved"
end
end
end
end
end
end
end

The problem with above code is, that it works in Redmine 3.4 both in console, and as Rake task, but in Redmine 4, it only works in console.
Eventually I was able to perform change on issue's custom field on Redmine 4 via Rake task in the following way:
namespace :redmine do
namespace :myplugin do
desc 'Updates custom field for idle tickets.'
task :update_idle => :environment do
Issue.open.each do |issue|
begin
days = DateTime.now.to_time - DateTime.parse(issue.updated_on.to_s).to_time
days = days/86400
if days > 0
issue.custom_values.each do |x|
if x.custom_field_id == 19
x.value = days.ceil
x.save
end
end
issue.save
true
end
end
end
end
end
end

Related

Rails: Log rake task

I am trying to log the output of a rake task to a new logger. Ideally the solution would work in development and production.
Here is my task:
task :clients, [:field] => [:setup_logger] do |t, args|
clients = Client.all
problems = []
group = clients.group_by { |client| client[args[:field]] }
unique_ids = group.keys
unique_ids.each do |unique_id|
problems << [unique_id, group[unique_id].length] if group[unique_id].length != 1
end
if !problems.blank?
logger = Logger.new("db_issues.log")
logger.error "look at me"
logger.close
end
p problems
end
When I run this, even though problems is not blank, no new log file is created. How am I supposed to accomplish this?
The problem is the logger.close, look after boot you server for a message like this:
log writing failed. closed stream
try removing logger.close from your code and restarting your server.

Rake task to backup in-memory sqlite database

I was wondering how to write a rake task for backing up the default rails database. I tried the following. However, nothing seems to be getting written in the file.
namespace :mockdb do
desc "Back up the database"
task :backup => :environment do
puts "Backing up the database.."
system "sqlite3 .dump > #{dump_path}"
puts "Phew! All data has been backed up!"
end
def dump_path
Rails.root.join('db/mock.sql').to_path
end
end
Apparently the system was not able to find sqlite3. I had to give the installation path. Following is the final snippet
namespace :mockdb do
sqlite_path = "/usr/bin/sqlite3"
sql_file = "db/#{Rails.env}.sqlite3"
desc "Back up the database"
task :backup => :environment do
puts "Backing up the database.."
system "#{sqlite_path} #{sql_file} .dump > #{dump_path}"
puts "All data has been backed up!"
end
def dump_path
Rails.root.join('db/mock.sql').to_path
end
end

A General Method to be invoked before every rake execution

In my rails project (Rails 3.1, Ruby 1.9.3) there are around 40 rake tasks defined. The requirement is that I should be able to create an entry (the rake details) in a database table right when we start each rake. The details I need are the rake name, arguments, start time and end time. For this purpose, I don't want rake files to be updated with the code. Is it possible to do this outside the scope of rake files.
Any help would be greatly appreciated!!
Try this
https://github.com/guillermo/rake-hooks
For example in your Rakefile
require 'rake/hooks'
task :say_hello do
puts "Good Morning !"
end
before :say_hello do
puts "Hi !"
end
#For multiple tasks
namespace :greetings do
task :hola do puts "Hola!" end ;
task :bonjour do puts "Bonjour!" end ;
task :gday do puts "G'day!" end ;
end
before "greetings:hola", "greetings:bonjour", "greetings:gday" do
puts "Hello!"
end
rake greetings:hola # => "Hello! Hola!"
This seems to be a bit awkward, But it may help others.
Rake.application.top_level_tasks
will return an array of information including Rake name and its arguments.
Reference attached below.
pry(main)> a = Rake.application.top_level_tasks
=> ["import_data[client1,", "data.txt]"]
When you create rake task, you can pass a parent task which will run before your task:
task my_task: :my_parent_task do
# ...
end
If your task depends from more than 1 task, you can pass an array of parent tasks
task my_task: [:my_prev_task, :my_another_prev_task] do
# ...
end

rake task only visible from the command line not from rails console or in rspec

I have the following in my rails app in (Rails.root/lib/tasks/me.rake):
task :abc do
puts "here is abc"
end
and am able to call:
rake abc # works
but the following don't work:
irb> rake :abc # doesn't work
bash>rake -T # doesn't show up
nor:
describe 'query task061', task061:true do
it 'should query' do
FactoryGirl.create(:location2)
Q.count.should == 1
rake['abc'].invoke
end
end
What else do I need to do to allow a task to be called in these ways?
thx
Give a description to task and see if it works, it should be,
desc "your task desc"
task :abc do
puts "here is abc"
end

How can I read a CSV file as a rake task and instantiate a model class? - getting ActiveRecord connection error

I am writing a Ruby on Rails application which has a Rake task that can parse a CSV file.
Here is the code:
desc "Import Channels into DB\n Usage: rake channel_import"
task :import_channels, :path_to_channel_list do |t, args|
require "#{Rails.root}/app/models/channel"
require "csv"
filePath = args.path_to_channel_list
puts "Filepath received = #{filePath}"
csv = CSV.read("#{filePath}", :encoding => 'windows-1251:utf-8')
csv.each_with_index do |row, i|
if [0].include?(i)
puts "Skipping over row #{i}"
next
end
if(row.nil?)
puts "row[#{i}] was nil"
else
channelName = nil
classif = nil
owner = nil
channelName = row[0].force_encoding('UTF-8')
classif = row[1].force_encoding('UTF-8')
owner = row[2].force_encoding('UTF-8')
if (channelName.nil?)
puts "Channel name for row #{i} was nil"
#add entry to Log file or errors database
next #skip this row of the csv file and go to next row
else
channel_hash = Hash.new("name" =>"#{channelName}", "classification" => "#{classif}", "owner" => "#{owner}" )
end
puts "\nChannel Name = #{channelName}\nClassification = #{classif}\n Ownership = #{owner}"
#If channel name exists in the Database, update it
xisting_channel = nil
xisting_channel = Channel.find_by channel_name: '#{channelName}'
if(xisting_channel.nil?)
#create a new channel
#new_channel = Channel.create(channel_hash)
puts "Inserted....#{#new_channel.inspect}"
else
#update existing channel
Channel.update(xisting_channel.id, :classification => "#{classif}", :ownership => "#{owner}" )
puts "Updated...."
puts "channel_hash = #{channel_hash.inspect} "
end#end if/else
end#end if/else
end #end CSV.each
end
When I run this code I get the following error message:
MRMIOMP0903:am AM$ rake import_channels[/XXXXXXXX/Channellist.csv]
Filepath received = /XXXXXXX/Channellist.csv
Skipping over row 0
Channel Name = APTN HD+
Classification = Specialty
Ownership = Aboriginal Peoples Television Network
rake aborted!
ActiveRecord::ConnectionNotEstablished
I tried to create a Channel object using IRB and it worked just fine. The DB is created and I'm seeing it using MySQL WorkBench. All tables are there, however, I am unable to create the Channel object from the Rake task.
My hypothesis is, perhaps outside of a certain folder/hierarchy the app cannot access the ActiveRecord::Base class or something like this.
Any suggestions on how to make this work?
UPDATE:
BAsed on the answer by Phillip Hallstrom
I changed the top line to load the environment
task :import_channels => :environment do|t, args|
Then tried rake import_channels and got this error:
rake aborted!
undefined method `safe_constantize' for #<Hash:0x007fbeacd89920>
You need to load the environment prior to running your Rake task. I'm not familiar with your multiple task name options there, but for a simple example, you'd want this:
task : import_channels => :environment do

Resources