I have a rake task that pulls some data from a MS SQL db, and recently I noticed that some special characters get encoded as a question mark '?'. While trying to dig into this issue, I realized that I could only repo it as a rake task, but not from the console.
Here is a snippet of what the code looks like:
require 'dbi'
namespace :db do
task :test => :environment do
db2 = DBI.connect("DBI:ODBC:DRIVER=FreeTDS;SERVER=x.x.x.x;PORT=1433;DATABASE=MyDB;TDS_VERSION=8.0;UID=user_id;PWD=pass")
rows = db2.execute('select * from Topic where id = 123')
rows.each { |r| puts r['name'] }
rows.finish
end
end
when I run this as:
rake RAILS_ENV=production db:test
it produces:
The Devil?s Tail
But when I run the exact same commands using:
/> script/console production
I get
The Devil`s Tail
Notice the back tick? Anyone have any idea why may be causing this? I double checked the ENV variables, and they both have LANG: en_US.UTF-8
EDIT
Forgot to mention I am using ruby 1.8.7p72 and Rails 2.3.4
Related
I am working on importing data from web based CSV into database, so I created a rake task that imports data into database. However I tried to make running my rails app a little seamless and I integrated the import rake task and running rails server into foreman.
However, when I run foreman start, the processes start but terminates after the rake task finishes. I also will like that rake task to start first before running rails s
Here is what I have done below:
lib/tasks/web_import.rake
require 'open-uri'
require 'csv'
namespace :web_import do
desc 'Import users from csv'
task users: :environment do
url = 'http://blablabla.com/content/people.csv'
# I forced encoding so avoid UndefinedConversionError "\xC3" from ASCII-8BIT to UTF-8
csv_string = open(url).read.force_encoding('UTF-8')
counter = 0
duplicate_counter = 0
user = []
CSV.parse(csv_string, headers: true, header_converters: :symbol) do |row|
next unless row[:name].present? && row[:email_address].present?
user = CsvImporter::User.create row.to_h
if user.persisted?
counter += 1
else
duplicate_counter += 1
end
end
p "Email duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?
p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added in total"
end
end
Procfile
rake: rake web_import:users
server: rails s
when I run forman start, the image below shows the process
I will like the rake task in the foreman to run first before running rails s command. I also don't want it to terminate by itself. I don't know what am doing wrong.
Any help is appreciated.
I solved this by refactoring the Procfile. Instead of having two tasks, I merged it to just one command using && so I can determine which command takes the prefix and which one takes the suffix.
So I changed the profile to:
tasks: rake web_import:users && rails s -p 3000
With this I have my import run first and server command being the last.
If you noticed, I added port with -p flap so as not make sure server is listening on port 3000. Note adding port is optional.
I hope this helps someone as well.
I'm trying to add the sandbox to my rails spree application and have run into this error
(using windows 8/powershell with Rails 4.1.6). I'm going by this manual: https://github.com/spree/spree/issues/411
This link Use older version of Rake
seems to have a similar issue but I am not sure how to take the necessary steps to achieve it.
When I try:
C:\Ruby193\openUpShop> bundle exec rake sandbox
I get:
rake aborted!
Don't know how to build task 'sandbox'
I'm am new to rails and am still not sure how everything works so a throughout explanation
with step by step instructions would be greatly appreciated! Thanks.
you can use a file sandbox.rb
# use example: rake task:sub_task -- --sandbox
if ARGV.any? {|arg| arg == '--sandbox' }
puts "** << USING SANDBOX!! >> **"
# beginning
$sandbox = -> do
ActiveRecord::Base.connection.begin_transaction
end
# end
at_exit do
ActiveRecord::Base.connection.rollback_transaction
end
end
then only you need add at the beginning of your task.rake file
require_relative 'path_to_your/sandbox.rb'
..and add at the beggining of your task code
desc "description task"
task example_task: :environment do
$sandbox.call if $sandbox.present?
...
Here is my simple rake task :
desc 'Create objects from csv'
task :add_missing_information_from_url, [:url] => [:environment] do |t, args|
url = args[:url]
puts "STARTED"
CSV.new(open(url), :headers => :first_row).to_enum.with_index(1).each do |line, i|
user = User.find(line['id'])
next if user.nil?
user.flag = true
user.save
puts "#{i} - #{user.firstname}"
end
end
For starters doesn't do anything smart. But for some reason this doesn't work on Heroku. This is how I execute the task (my namespace is dbs):
heroku run rake dbs:add_missing_information_from_url['http://lvh.me/file.csv']
Or on dev machine :
bundle exec rake dbs:add_missing_information_from_url['http://lvh.me/file.csv']
This is the only output I get from the console when running heroku task :
Running `rake dbs:add_missing_information_from_url[http://lvh.me/file.csv]` attached to terminal... up, run.7246
And returns to my shell after it has executed with nothing printed, nor the user objects get saved.
However when I run it on my dev machine, all works fine, starting by printing STARTED onwards.
What am I doing wrong here?
Is it me or does your log actually outputs this :
Running `rake dbs:add_missing_information_from_url[http://lvh.me/file.csv]` attached to terminal... up, run.7246
If you take a closer look at the argument in the [http://lvh.me/file.csv], it appears not to be a string. You would want your log to output ['http://lvh.me/file.csv'].
So I suggest you try running your task like this :
heroku run rake dbs:add_missing_information_from_url['"http://lvh.me/file.csv"']
I need to make a custom Rails 4 rake task to delete all records in database using ip:
task :delete_records, [:ip] => :environment do |t, args|
User.destroy_all(ip: args.ip)
end
I try to execute it using the following command:
bundle exec rake delete_records["127.0.0.1"] but I've the error:
no matches found: delete_records["127.0.0.1"]
How can I fix it? Thank in advance!
I'm guessing you used this answer for help - although we've done rake tasks before, we've never used one with arguments like this
--
Test
We've created custom rake tasks before - they reside in lib/tasks
I would test out yours by doing the following:
#lib/tasks/your_task.rake
desc "Remove all records for particular IP"
task :delete_records, [:id] => :environment do
args.with_defaults(:ip => "127.0.0.1")
User.destroy_all ip: args.ip
end
If this does not work, it will mean there's something wrong with the definition of your task (it's not in the correct folder or something)
The above should determine if your argument definition is the issue; if it isn't you should let me know so we can work to fix it
I've got a plugin that is a bit heavy-weight. (Bullet, configured with Growl notifications.) I'd like to not enable it if I'm just running a rake task or a generator, since it's not useful in those situations. Is there any way to tell if that's the case?
It's as simple as that:
if $rails_rake_task
puts 'Guess what, I`m running from Rake'
else
puts 'No; this is not a Rake task'
end
Rails 4+
Instead of $rails_rake_task, use:
File.basename($0) == 'rake'
I like NickMervin's answer better, because it does not depend on the internal implementation of Rake (e.g. on Rake's global variable).
This is even better - no regexp needed
File.split($0).last == 'rake'
File.split() is needed, because somebody could start rake with it's full path, e.g.:
/usr/local/bin/rake taskname
$0 holds the current ruby program being run, so this should work:
$0 =~ /rake$/
It appears that running rake will define a global variable $rakefile, but in my case it gets set to nil; so you're better off just checking if $rakefile has been defined... seeing as __FILE__ and $FILENAME don't get defined to anything special.
$ cat test.rb
puts(global_variables.include? "$rakefile")
puts __FILE__
puts $FILENAME
$ cat Rakefile
task :default do
load 'test.rb'
end
$ ruby test.rb
false
test.rb
-
$ rake
(in /tmp)
true
./test.rb
-
Not sure about script/generator, though.
The most stable option is to add $is_rake = true at the beginning of Rakefile and use it from your code.
Use of $0 or $PROGRAM_NAME sometimes will fail, for example when using spring and checking variables from config/initializers
You can disable the plugin using environment variable:
$ DISABLE_BULLET= 1 rake some:task
And then in your code:
unless ENV['DISABLE_BULLET']
end
We could ask this
Rake.application.top_level_tasks
In a rails application, this is an empty array, whereas in a Rake task, the array has the task name in it.
top_level_tasks probably isn't a public API, so it's subject to changes. But this is the only thing I have found.