Running code after Rails is done loading? - ruby-on-rails

I have a periodic task that needs to execute once a minute (using delayed_job). I would like for Rails to automatically queue it up as soon as it's finished loading, if one such task isn't already present in the system.
What is a good place for me to run some code right at the end of the entire Rails boot flow? Someone suggested config/environments/development.rb (or other environment), but delayed_job give me ActiveRecord issues when I queue up jobs from there.
I consulted http://guides.rubyonrails.org/initialization.html, and there doesn't seem to be a clear location for that kind of code either.
Is this kind of post-deployment setup to be done perhaps externally to my app's code, maybe through rake or some other means? Any suggestions?
Thank you!

Regarding http://guides.rubyonrails.org/initialization.html, sorry, we're working hard to rewrite it. For your problem, I would try with config.after_initialize in your application.rb
def after_initialize(&block)
ActiveSupport.on_load(:after_initialize, :yield => true, &block)
end

Add your code in the initializer directory.
http://guides.rubyonrails.org/configuring.html#using-initializer-files

You have two options really
1) add it into initializers directory and this should be ok.
2) add it at the very end of application.rb, this is less clean but it will have things like initializers ready at this point ;p so if 1) fails because of AR problems do 2)

Related

Getting Whenever to Work with RVM and Capistrano

I'm deploying an app that uses capistrano/whenever/rvm. Apparently, the whenever/rvm combo has a gotcha, as documented here. The wiki describes three ways of overcoming this. I've tried all of them and to no avail. These solutions include setting rvm_trust_rvmrcs_flag=1 in ~/.rvmrc, configuring schedule.rb to use the proper capistrano route, and using an alternative whenever gem. Again, none of these solutions have worked for me.
Checking crontab -e, whenever is successfully creating the cron jobs. According to the system logs, they're even being executed. However, they're not actually running in Rails. One debugging task reads like this:
every 1.minute do
runner "Company::Category.create(name: 'Shoe Cleaning')"
end
However, no Company::Category is created. Any advice for better debugging this? I've been on it for nearly 7 hours now and I'm struggling to move forward.

How to run a piece of code each time an ActiveRecord model is reloaded

So I have some code that rewrites paperclip file paths so that each developer on the project can have a path to their own uploads without clobbering each other, but this runs in development inside a
ActiveSupport.on_load(:after_initialize) do
loop. Which means its only loaded on initialize. The problem is that we're using the Active Reload gem (rails 3.1 so its okay), so once someone edits the a model it is reloaded and the old paperclip paths are used.
I was wondering how I could get this code to run each time a particular model was reloaded?
You could wrap it in a config.to_prepare block inside config/application.rb:
config.to_prepare do
# your code
end
This will reload upon every request in development, but only once in production.
So I tried Ryan's suggestion above, but just like I thought, it would run my code on every page load ... No Bueno.
What I wound up doing was using this piece of code that is given to you by Active Reloader, but I doubt it will work with Rails 3.2
ActiveSupport::Notifications.subscribe("active_support.dependencies.clear") do |*args|
my_code_block
end
And it worked a treat, I still had to keep the original
ActiveSupport.on_load(:after_initialize) do
block there too, so its a little ugly, but it works!
Still holding out for a cleaner solution, if one exists.

Rails execute script

I am building a script in on of my controllers to fill a database with an excel files data. I would build the function, then access it through a route. (That i guess i can protect with cancan) But i thought about it, and it doesn't seem very ... 'Railsy'.
I know the scripts folder exists, and it is probably for these kinds of tasks. I've tried googling stuff like 'rails execute script' and other stuff, but i can't find any good advice for what to do next.
I'm sorry if this seems kind of stupid, but in my apps i've been kind of hacking around stuff to make it work, so any advice on this task would be appreciated.
If you need to upload the file in the app and process it, it should probably go in the "lib"directory and be accessed like any other Ruby library/module/etc.
If it's something you need to run locally, "on demand", "scripts" is fine. If you need access to your rails environment when running it like any Rails models, you can run it from "rails console" or "rails runner".
As Aln said, there are a variety of ways it could be scheduled as well.
You could simply do
#!/usr/bin/env ruby
require 'rubygems'
# regular ruby code here
and have it running just like any other util. Of course you can always call any *.rb with simply
ruby somescript.rb
If you need some scheduled script, check into rufus-scheduler gem.

Where do you put an object call that is needed before your application loads?

I have an object call that is basically initiating a singleton that is needed all over my application. I thought the best place to put this was the environment.rb file, right after the Application.initialize! call. And it had worked with all my tests. But now that I'm running my code in the development environment, I'm finding that it is not getting called. Is there somewhere else I should be putting it, or is there something wrong with my development environment setup?
EDIT: I haven't looked at the answers yet, but I did find out that it's not working in development when I have the config.cache_classes set to false.
Try putting it in an initializer file.
See this link for configuring rails.
Basically, I do use config files written in yml and load these with an initializer.
If you don't want to go into details, use Ryan Bate's gem: nifty-generators
and type in console:
rails g nifty:config
It will install everything for you. Then edit your config/app_config.yml file.

Rails moving from 2.2.2 to 2.3.8 - rake not loading the environment same as the console or my app

I have an app that has been around a while that I'm migrating for
Rails 2.3.8. There have been a lot of interesting issues, but I'm on
the home stretch, but have now run into some very odd errors.
The gist is when I run a task with rake it fails, but when I run the
same code form the console it works fine. The 'fix' I devised was to
move my include ModuleNameA, include ModuleNameB, etc to the bottom of
the AR file.
I don't like this 'fix' as I don't understand it. Before I moved them
the AR object (we will call it Bob) kept throwing undefined method
errors when it was called through the rake invocation. It was invoked
in the rake task, but in another AR object.
So the rake task was running something like Worker.work, and it would
fail as described above. When I run Worker.work from the console it
would pass. Once I moved the includes to the bottom of the file both
would work.
Anyone ever seen anything like this? I feel like something
fundamental isn't correct. Like I have broken something basic to the
functionality and my 'fix' is some kind of weird patch.
thanks.
Erik
PS:
There is a module that I'm including in my AR object. It adds class and instance methods by doing:
def self.included(base)
base.extend(ClassMethods)
end
All of the methods in this module are available in the console, but not through rake tasks.
Update:
I noticed that if i take the :work => :environment part out of the
rake task and instead in the task do block require the environment
file by hand (e.g. require(File.join(RAILS_ROOT, 'config',
'environment'))) it works fine. All of a sudden all of my class
methods are available. this is very disturbing.
So I figured it out....
We had a directory under app/models called deals that was not included in the load path. That is where my module was that was giving me all the issues. Why it was being loaded OK from the console and not with rake...I don't know.
Once I added this to the config.load_path everything has started working fine. I never noticed this because in 2.2.2 everything worked fine, the app in production or dev mode, the console and the rake tasks in dev, test, and production mode.
I figured it was something just basic i was doing wrong as the error was obtuse and my 'fixes' looked like really bad ideas.

Resources