Rails + foreign app - ruby-on-rails

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.

Related

What is the difference between rails and rake?

What is the difference between commands rake and rails in Ruby?
Which one is faster and why?
The difference is in what binary is being called.
If you were to call bundle exec which rake within your Rails app root directory, you'd get something like /home/[USERNAME]/.rbenv/versions/2.5.5/bin/rake and for bundle exec which rails, you'd get /home/[USERNAME]/.rbenv/versions/2.5.5/bin/rails. From there you can cat (cat /home/[USERNAME]/.rbenv/versions/2.5.5/bin/rake) both these paths and see similar code is being ran for each, but the end of the files is different.
rails
gem "railties", version
load Gem.bin_path("railties", "rails", version)
rake
gem "rake", version
load Gem.bin_path("rake", "rake", version)
Here they're both calling load on Gem.bin_path but with different arguments, which are attempting to load separate gems in. You can follow the code further by running a irb/pry/rails console, and setting up the needed require 'rubygems' and version = ">= 0.a", then run Gem.bin_path("railties", "rails", version) and Gem.bin_path("rake", "rake", version) to see what the load is actually trying to run. I'll admit it'll become a bit of a rabbit hole before you come across the logic that eventually ends up identifying a rake task argument passed to rails and it proxy's it to Rake and stop there and defer to this SO answer for the rest.
When rails is ran and passed arguments which were intended to be ran by rake, it will attempt to first find if it was an actual argument intended to be given to the rails command, determine that it wasn't, then attempt to run it as a rake command for you for overall naming simplicity added in by the Rails team in Rails v4.
So which is faster to run? rake for actual rake tasks, as it'll bypass the extra logic in needing to determine it was being passed rake arguments. But also rails specific arguments cannot be ran with rake e.g. bundle exec rake generate will not work (unless you have a generate task). If in doubt, run bundle exec rails --help and in at least Rails v5, it'll output which arguments are rails specific and which are rake specific.
rake is a Make-like program implemented in Ruby.
rails is a web framework, which also has some rake tasks.
This means that you can have a ruby program with rake but without rails, but not the other way around.
By itself, rake will be faster because you don't need to load the whole rails application.
But when launching a rake task, it can have dependencies, for example the :environment dependency in a rails app, which tells rake to load the rails environment and quite a bit of your application depending on the current environment.
In this case, the initialization of a rake task may take as long as a rails command.
Please note that the actual task run needs also to be taken into account, it can be very short or take several minutes.
For example, rake db:migrate, which is a rails task available by default, runs the migrations on the database, which can be time-consuming if the database is already populated and/or you have a lot of migrations

Inheritable Rake task as a Ruby Gem, in a Ruby on Rails application

Is it possible to write an inheritable Rake task as a Gem such that it works like a framework?
For example, one could build all the logic inside this Rake task and expose some high level callback methods, and developers would implement this callback to run tasks.
The important part here is I'm not asking how to call a rake task from my rails app, but how to write a rake task as a gem, so i could just install the gem in my rails app, and then perhaps I could implement a plain .rb file somewhere which gets called by the rake task to handle custom tasks (Instead of the app calling the rake task)

Ignoring a single fixture file while seeding database

I am hosting a project on heroku, written in rails.
I have a fixture file (comments.yml) that I use during testing, but which I do not want to include when seeding my database (via 'heroku run rails db:seed').
How can I communicate to heroku that I want it to ignore 'comments.yml' when seeding?
You could use environment variables and control it in your seed script:
rake db:seed comments=true
and later in your seeds.rb:
unless ENV["comments"]

Send ActionMailer from external ruby file?

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

Running custom SQL to prepare Rails integration test

I am trying to run some custom SQL during the setup of my Rails integration tests to prepare a legacy database (e.g., to create its tables, create any required views, etc.), which is not part of my schema.rb (nor do any migrations for it exist).
Are there any best practices for doing so? Googling has not been very enlightening so far ;-)
The reason why there are not any migrations is that in the development and production RAILS_ENV the database already exists for legacy reasons. If there is a way to run these migrations only for RAILS_ENV=='test', that would maybe also help.
You can pass the Rails environment to Rake on the command line. For example, to only run migrations for the test environment, do:
rake RAILS_ENV=test db:migrate

Resources