I tried:
after_initialize do
#code
end
But: (documentation)
Some parts of your application, notably observers and routing, are not
yet set up at the point where the after_initialize block is called.
I need routing and logger in my code
Any ideas?
See section 3.1 from http://guides.rubyonrails.org/configuring.html
I believe you would put this code in config/application.rb
config.after_initialize do
# ....
end
# config.after_initialize takes a block which will be run after Rails has finished initializing the application.
# That includes the initialization of the framework itself
Also http://guides.rubyonrails.org/initialization.html
#house9's answer is correct, as pointed out by the comments, this will also execute when running rake tasks, console, etc. I used the following to recognize when a server was actually being executed:
# application.rb
if defined?(Rails::Server)
config.after_initialize do
# Do stuff here
end
end
Another option is to create a custom initializer. It's just a ruby file that lives under config/initializers/ and is executed exactly "on_server_start" event :)
Lines added to config.ru will be run by the Rails server, but not by Rails console or Rake tasks that load the environment.
# config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path("../config/environment", __FILE__)
# your code here (after environment is loaded)
run Rails.application
Since Rails 5 the default server is Puma, so code in config/puma.rb will be run just once, and only if the server is started.
Related
I'm trying to run a method immediately on startup in my rails project. Previously I used the following for running locally
# application.rb
if defined?(Rails::Server)
config.after_initialize do
# Do stuff here
end
end
While this works locally, we are now running on prod with bundle exec rackup, which returns false for the above statement. Is there something I can call in my Rails project to execute a method immediately on start from Rackup?
Here's a layup for someone...
Back in Rails <= 4 days we'd run our test suite by simply typing $ rake at the command line, thanks to defaults in Rakefile:
task default: [:rubocop, :spec, :teaspoon]
but in Rails 5 it's not so apparent how to run default rake tasks now that rake has been replaced by rails. rails alone gives a list of possible commands rails responds to but doesn't run the specs. rails test seems logical but it tries to run minitest which we don't use. rails spec will run Rspec but not teaspoon or rubocop.
Where did this go? And why is something so apparently simple so hard for me to look up myself?
rails default
executes those tasks for me on Rails 5.2.1, though I couldn't find it documented anywhere.
Just create a new rake task that runs the other ones:
lib/tasks/my_extensions.rake
task :my_test do
Rake::Task[:foo].invoke
Rake::Task[:bar].invoke
end
# or the short version:
# task my_test: [:foo, :bar]
task :foo do
puts "FOO"
end
task :bar do
puts "BAR"
end
Run rails my_test and you will see FOO and BAR printed in your console.
If you don't know where to place the file to write the code above, check your /Rakefile:
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
Rails.application.load_tasks
It says to write them inside lib/tasks and end them with .rake, you don't need to require them. In your specific question, change my code from :foo and :bar to your specific tasks :rubocop :spec :teaspoon.
However, it looks like you are doing some BDD or TDD cycle. Check out rails Guard, it might help you better. I use it in my project and it works perfectly.
I have some rake tasks that I only perform locally. However since I refer to the some gem classes in rake tasks, this seems to require that the gem be installed and loaded on the production server. Among other things this increases deploy time and memory usage on the server.
This may or may not have to do with my setting:
config.autoload_paths += Dir["#{config.root}/lib/**/"]
I have a number of lib files and subdirectories.
I guess my options are to
move all my lib files somewhere else and add that path to autoload_paths
try to exclude the tasks dir from autoload_paths
do something fancy in the rake tasks themselves (if possible) to avoid the need to have the gems present.
configure rake tasks to live somewhere else (seems like a bad idea)
This seems like a pretty common issue and probably has a common way to solve it or avoid it. What am I missing?
Maybe not the most exciting answer but I just moved the require 'dev_gem' inside the rake task block for that task.
namespace :elasticbeanstalk do
desc 'Creates a new web & worker environment pair for testing'
task :create do
require 'aws-sdk-elasticbeanstalk'
# Do stuff with beanstalk that we wouldn't from a production env
end
end
This way the library only gets loaded when the rake task is invoked rather than when the rake task is defined.
doing something like this may work
require "prod_gem_name"
unless Rails.env.production?
require 'dev_gem_name'
desc "Task that run something with a dev gem"
# code that uses the gem on dev group
end
or another solution maybe will be to add those .rake files to the gitignore. maybe it wouldn't work on all cases but it's another option.
I'm folowing this link to put ruby on rails start automatically.
But I cant understand its ruby code
#!/usr/bin/env ruby
require File.expand_path("../../config/environment", __FILE__) #1.what is this path?
STDOUT.sync = true
Stalker::job 'user.fetch_details' do |args| #2.what is this user?
begin
user = User.find(args['id']) #3.what is this id?
user.fetch_user_details!
rescue ActiveRecord::RecordNotFound # too fast
Rails.logger.warn "Unable to find user ##{args['id']} - suspect too fast, requeuing"
Stalker.enqueue('user.fetch_details', :id => args['id'])
end
end
jobs = ARGV.shift.split(',') rescue nil
Stalker.work jobs
and conf file code in /etc/init/
description "TweetedLinks Ruby Worker"
# automatically start
start on filesystem
# working directory
chdir /var/www/TweetedLinks/current #4.should I change this to my own dir?ie home/usr/Trail/test-app
# command to run, with Bundler support!
env RAILS_ENV=production
exec bundle exec ruby script/worker.rb >> log/worker.log #5.do i need to create this worker.log? and this script folder can be put anywhere?
respawn
I have my rails app under home/usr/Trail/test-app
I have create a script folder under home/usr/script
I have my rvm generated under home/usr/.rvm/wrapper/test-app
How to modify this code according to my situation.
and the 5 question in code comments I also very confuse.
Thanks in advance!have been stuck for month!
The easiest way would be to use foreman gem that can export Procfile to upstart, see http://ddollar.github.io/foreman/#UPSTART-EXPORT
I am trying to precompile the assets while deploying to production environment. I am also trying to automate it for first time installation on a server using capistrano. It looks like none of the initializer's are getting loaded during the assets precompile process.
I am facing these two problems
For the first time installation I am generating a initializer file(initializers/freshinstall.rb) on the fly with the below content
config.assets.initialize_on_precompile = false
so that precompile doesn't check the database which doesn't exist yet
I also have some vendor files, and their locations are set in the asset pipeline, and are placed in separate initializer file initializers/vendor.rb
MyApp::Application.config.assets.paths << "#Rails.root}/vendor/assets/images/xxxx" << "# {Rails.root}/vendor/assets/images/xxxx/helpers"
MyApp::Application.config.assets.paths << "#{Rails.root}/vendor/assets/stylesheets/xxxx"
MyApp::Application.config.assets.paths << "#{Rails.root}/vendor/assets/stylesheets/yyyy" << "#{Rails.root}/vendor/assets/images/yyyy"
When capistrano runs the assets precompile task, its not able to find the vendor paths or stopping it from looking into the database. This brings me to a conclusion that the initializer's are not getting loaded. After going through some stackoverflow questions. I even added a railtie to config/application.rb
module AssetsInitializers
class Railtie < Rails::Railtie
initializer "assets_initializers.initialize_rails",
:group => :assets do |app|
require "#{Rails.root}/config/initializers/freshinstall.rb"
require "#{Rails.root}/config/initializers/vendor.rb"
end
end
end
But I still don't see any initializers getting loaded. Can I get some info on the internals of the boot process of an rail application, and also why the initializers are not getting loaded during the assets precompile process.
Some documentations would be really helpful to understand this. The Rails documentation is very minimal with respect to railtie and the initializer method.
http://guides.rubyonrails.org/configuring.html
Thank you in advance
Finally was able to figure out how to do it. This works for my single server capistrano deployment. Below is the capistrano task for my new_deploy on to a fresh server.
set :fresh_install, false
task :new_deploy do
set :fresh_install,true
deploy.setup
#The assets:precompile process is part of the deploy.update. Before the precompile process, we will create database.
deploy.update
deploy.migrate
run_seed
#load unicorn server
end
Dont do any configuration setting mentioned below
config.assets.initialize_on_precompile = false # no need of this in application.rb
Instead just before assets:precompile create your database
before "deploy:assets:precompile" , "yourapp:create_database"
See that you check if the fresh install flag is set, then only create the database.This method will also be called during regular deploy when ever you are updating the server with latest revision. During that scenario fresh_install flag will be false.
desc 'Create a new database'
task :create_database, :roles => :app do
if fresh_install
run "cd #{release_path}; bundle exec rake db:create RAILS_ENV=#{rails_env}"
end
end