how to test ruby scripts, in rails app - ruby-on-rails

I got some cron jobs that i wanna test, where should i out them, how can i run them with rails commands and if the got some dependencies like files and stuff how can i load their fixture?
to be more concrete lets say i got a rb file thats reads a file from a the app folder, do some parsing, and writes stuff to db.
where to put the test and how to connect it with rails?

My method is to create a folder called app/jobs, then name the classes in the folder accordingly. The jobs are then called using script/rails runner. The runner interface loads rails and you have access to all of your models.
class SomeOddJob
def run
#do something
end
end
from your cron job you'd run the job like this (in production mode):
0 5 * * * /path/to/script/rails runner -e production "SomeOddJob.run"

Related

How do I prevent an initializer script from running when I execute a test?

I'm using a Rails 5.1 environment. I have a script located at
config/initializers/websockets.rb
This is run when my server starts, however, I don't want this script to run when I execute tests, for instance ...
localhost:mine satishp$ rails test test/lib/websocket_client_test.rb
How do I prevent the initializers scripts from running when I'm executing my tests, or at least this specific file?
Initializers are just Ruby scripts that are executed when Rails is starting up so you can put whatever code you want in them. In particular, you can look at Rails.env:
if(!Rails.env.test?)
# Do whatever needs to be done...
end
or environment variables:
if(!ENV['SUPPRESS_WEB_SOCKET_INIT'])
#...
end
and then set the SUPPRESS_WEB_SOCKET_INIT environment variable when you run your tests (or reverse the logic if that's a better fit).
These are blunt instruments though so you might want to reconsider your approach. Perhaps it would make more sense to initialize your websocket stuff the first time it is needed and then set up some mocks to replace the functionality in your tests.
Move the initializer script out of the directory, then move it back afterward.
localhost:mine satishp$ mv $RUBY_DIRECTORY/config/initializers/websockets.rb /home/satishp && \
rails test test/lib/websocket_client_test.rb && \
cp /home/satishp/websockets.rb $RUBY_DIRECTORY/config/initializers/websockets.rb

Write to rails database from my ruby script that is running by cron

I have a ruby script that is running every 24 hours via cron. It just does some scraping of a site and saves the data to a CSV file. Instead, I want to write it directly to a rails db so I can use it from within my rails app.
I have tried calling the class such as Class.new but this does not work. How can I write this directly into a rails db?
You can run class methods in your Rails app from Cron like this:
0 0 * * * cd path/to/your/app; RAILS_ENV=production script/runner "Scapper.process"

Delayed_job and Prawn scripts

How do I run Prawn scripts with Delayed_job.
(Currently using Bj but not supported in Rails3)
This code does not work.
/lib/report_job.rb
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
bundle exec rails runner "#{Rails.root}/jobs/#{prawn_script_name}.rb #{#current_user.account_id} "
end
/reports_controller.rb
def generate_report(prawn_script_name)
Delayed::Job.enqueue(ReportJob.new("#{prawn_script_name}.rb","#{#current_user.account_id}"))
end
delayed_job table is populated as expected.
--- !ruby/struct:ReportJob
prawn_script_name: statements.rb
account_id: '18'
Error in last_error field.
{undefined method `runner' for ReportJob:0xc28f080
Any suggestions?
I think there are several misunderstandings here:
you meant to call runner from outside your app, e.g., in a shell script or command line. in other words, bundle exec rails runner are all commands and arguments of commands, not ruby methods or variables. runner is the first expression that is eval'd inside your perform method, hence your error.
rails runner just brings up your apps environment and evals the string or path argument given.
note account_id within the perform task, another mistake in your code I guess.
What you wanted to do could be a simple system call.
It seems your prawn script needs the environment, so simply calling
system "ruby #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
won't work.
Now you could surely execute the script with runner from your project directory.
system "bundle exec rails runner #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
but doing this via a system call within your environment is quite redundant. Delayed jobs already have access to your rails environment. so just simply load them.
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
load "#{Rails.root}/jobs/#{prawn_script_name}.rb"
end
end
hope this helps

Rails 3 Create Script to Manipulate My DB

I'm trying to create a script to mess around with the db entries in my rails application, but I don't know how to properly set it up to gain access to all my models etc.
I can do this easily with scripts like seeds.rb using 'rake db:seed' to execute or in my application controllers, but I want to create scripts outside of these that I can run in the background or just once.
Do I need to include something, or call the script with a certain rails command? And as a second related question, is there any way for me to execute rails commands like 'rake db:seed' from within a ruby script? The only method I know of right now that works is running 'rails console' and executing commands there.
require 'config/environment.rb'
When the script is in your rails root...

Loading a model in a cron file, in Rails

I have a directory called cron, inside my app directory. In the cron directory, I have put my cron file. How do I access the model inside my cron file?
Which is the best place to put my cron file?
edit:
I'm trying to execute the cron file, directly like ruby cron.rb
I'm assuming what you want to do is run a script (which you have saved in the cron folder) as a cronjob, but you want it to load the Rails environment, including access to your ActiveRecord models, before it runs.
If this is the case, what you want to use is the script/runner script in your Rails app, supplying it with the name of the script you want to run, e.g.
script/runner cron/my_cron_script.rb
If you want to add this as a cronjob, add it to your crontab as follows. Edit your crontab with the crontab -e command and put something like the following there:
* * * * * /path/to/my/app/script/runner /path/to/my/app/cron/my_cron_script.rb

Resources