Send ActionMailer from external ruby file? - ruby-on-rails

i want to make a cronjob which execute a specific ruby file in the script directory of my rails app. how can i achieve, that i can execute an actionmailer to use deliver? how do i get this mailer into this ruby file?
thanks!

Skipping the part about creating a task in crontab, here is what you can do:
Create a rake task, in lib/tasks, which sends that email and invoke the rake task from your cron job. I have done this and this works, pretty well for me.
Load the Rails environment explicitly in your ruby script. I do this in some daemons.
You can do something like this :
require File.dirname(__FILE__) + "/../config/application"
Rails.application.require_environment!
Use the rails runner. rails runner -h will give you the necessary information

Related

Run Rails Runner from Ruby Script

I have a Ruby script in a subdirectory of a Ruby on Rails application that runs in the background and performs some support tasks. In this script, would like have access to the Rails environment and the value of an application controller constant.
The best approach to retrieve these values I could find so far is based in Rails runner. If I run
cd .. && Rails runner "puts [Rails.env, ApplicationController::CONSTANT_NAME]"
from the subdirectory in shell, I get the desired values. But when I try to use the same command in my script, I get an undefined method error for active_storage:
/home/user/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.2/lib/rails/railtie/configuration.rb:96:in `method_missing': undefined method `active_storage' for #<Rails::Application::Configuration:0x0000563603fbdaa8> (NoMethodError)
The code in the script is
puts %x|cd .. && rails runner "puts [Rails.env, ApplicationController::CONSTANT_NAME]"|
The Rails application and the Ruby script run under the same user. I have Rails 6.0.3.2 and Ruby 2.6.5.
What you want to do is write a Rake task instead:
# lib/tasks/foo.rake
namespace :foo do
description "#TODO write a descripion"
task bar: :environment do
# your logic goes here
puts [Rails.env, ApplicationController::CONSTANT_NAME]
end
end
This task can be invoked via bin/rake foo:bar. bar: :environment loads the Rails environment for this task.
This is a lot less hacky/wonky then using the rails runner, and is the defacto way of writing tasks/scripts in Ruby that are meant to invoked from the command line.

How do I create a ruby script that runs script/console and then runs commands using that environment?

I've noticed I've been having to do:
bundle exec script/console
<wait for console to load>
require migration
generate some data
a lot... and I was wondering if there is a way to have this all in a bash script or something. so i could just do ./generatedata and have it run the above commands.
I've found that custom rake tasks are an awesome tool for when you have work which requires running code in the rails environment. Check out this railscast http://railscasts.com/episodes/66-custom-rake-tasks
If you want to run a one-off command in the console, you can use the rails runner command. So if you had a ./generatedata.rb script which performs the ruby commands you want to execute in the console, you can just call rails runner ./generatedata.rb and it will run your ruby script in the rails environment against the database. Alternatively, you could add the shebang line to the ./generatedata.rb script: #!/usr/bin/env rails runner. Then you only need to execute the ./generatedata.rb script and it will use rails runner automatically.

How do I run a ruby script, that I put in my /lib/tasks/ directory in my Rails app, once?

Eventually I would like to get to setting it up as a Rake task and do a cron job, but for right now...all I want to do is take my ruby script that used to work as a standalone script and have it work within my Rails app.
I renamed the file to be .rake instead of .rb and tried doing rake my_script at the command-line, but that gave me this error message:
rake aborted!
Don't know how to build task 'my_script'
(See full trace by running task with --trace)
How do I run this script within my Rails environment?
This is the first time I am doing something like this, so any assistance would be greatly appreciated.
Thanks.
I think what you're looking for is rails runner. I know in Rails 2.3.x you'd do
ruby script/runner <your file>
In Rails 3 it might be slightly different.
http://guides.rubyonrails.org/command_line.html#rails-runner
The primary difference between a runner and a rake task is : runner would boot rails while rake task doesn't (you can tell it to do so).
Since rake can do both (boot/no boot), there's no concept of runner in rails-3 anymore.
So, create a rake task: whatever_name.rake
Example:
desc "This task does awesome stuff"
task :do_awesome_stuff do
awesome_method
end
def awesome_method
#put your ruby code here
end
Now from your command prompt, type rake do_awesome_stuff to execute this rake task.
To make it boot Rails, change task definition to this:
task :do_awesome_stuff => :environment do

script/runner in rails 3

I have 2 jobs I would like to run and they are dependant on Models in my rails application.
I added the ruby files in a separate folder called Jobs, that I have appended to the rail project.
Whenever I try to run them via ruby command I get the following error:
uninitialized constant Feedback (NameError).
Feedback here is a model I'm using in my rails app.
My questions: because the jobs I'm using are actually compatible with the script/runner command of rails 2, is there an alternative with Rails 3? If not how can I write ruby programs that depend on models I have in a rails app without getting the error I mentioned above.
Use rails runner
$ rails -h
Usage: rails COMMAND [ARGS]
...
runner Run a piece of code in the application environment
All commands can be run with -h for more information.
The "Rails 3 way" to do this is with Rake using the :environment prerequisite, which loads the Rails environment. Like so:
task :name => :environment do |t|
# actions
end
In the block you can load and execute your jobs.
If you haven't written Rake scripts before, here's a good tutorial. It's quite easy.

Rails + foreign app

I have rails website that shows information from database. And I have ruby script that should add data in this database. Can I somehow connect this script to my rails app to use its models?
You can either load the Rails environment by doing a require
require File.dirname(__FILE__) + '/config/environment'
or use a Rake task (http://railscasts.com/episodes/66-custom-rake-tasks).
You could write a rake task and load in your data to the DB. Yes, your rake task can reference models and you have access to all the associated AR methods etc. It goes without saying that you can also run the rake task on development, production etc.
You can add this scripts under lib tasks, tell your rails application to include lib files. Inside those files, you can access rails models to insert data in database.
After that you may run those scripts by calling from rake tasks. Create some rakes under lib/tasks.
Those rake tasks can again be called via cron jobs to work repeatedly for you.

Resources