How to know which rails environment is running in delayed job - ruby-on-rails-3

I have a delayed job which is working perfectly fine. I want to know which environment is this. Is it production or development or staging. Check the code please. ENV["RAILS_ENV"] is nuil?
class SendMessageJob < Struct.new(:message_id)
def perform
p ENV["RAILS_ENV"] // printing nil :(
p "hello world"
end
end
I tried including
require "#{File.dirname(__FILE__)}/../config/environment.rb"
on the top the file still nothing..

You can try RAILS_ENV (constant defined within Rails) or the newer one Rails.env (a wrapper for this).

Related

Rails 3.2.5 in `eval': wrong number of arguments (0 for 2..3) (ArgumentError)

I wrote a runner (saved in lib folder). When starting the runner with: rails runner lib/test.rb
def aaa
puts "aaa"
end
aaa
it dumps:
in `eval': wrong number of arguments (0 for 2..3) (ArgumentError)
why?
rails runner is intended to run code from your app codebase as in
(from the guide)
rails runner "Model.long_running_method" # parses the string and executes
# the (hypothetical) method [long_running_method]
# from (hypothetical) model [app/models/model.rb]
the error raises from the fact that in your call you don't provide a string to evaluate
anyway to make it work this way (with a function from lib) you should
enclose your method in some class and
make the class available requiring it someway during application boot
! pay attention: if you call rails runner 'MyClass.my_method' you're calling a class method which has to be defined properly
def self.my_method
# your code
end
if you want to call an instance method you need to do rails runner 'MyClass.new.my_method'
All that said, rails runner boots all the rails app.
If that is not required, may I suggest to investigate whether a rake task could be suited for your needs ?

How to refresh Rails / Sprockets to be aware of new manifest on production server after assets:precompile

We have a use case where we need to run assets:precompile outside of the deploy/restart process, and therefore preferably without having to restart the Rails server processes. Is this possible in a Passenger environment?
I've been banging my head trying a bunch of stuff within Rake tasks and fiddling with Rails.application.config.assets stuff, but nothing makes the application pickup the changes to the digests except restarting Passenger with /usr/bin/env touch ~/project/current/tmp/restart.txt
We ended up going with a 2 part solution:
Part 1 is to setup the app to hit redis to store an 'assets:version' (we just went with a timestamp). Then, whenever our process was done precompiling, we update this assets version with the latest timestamp.
Part 2 was that we added a before_filter :check_assets_version in our main application_controller that all our other controllers inherit from. This method looks something like this:
def check_assets_version
##version ||= 1
latest_version = get_assets_version # wrapped call to redis to get latest version
# clear assets cache if current version isn't the same as the latest version from redis
unless latest_version.blank? || latest_version.to_s == ##version
##version = latest_version
if Rails.env.production? || Rails.env.sandbox? || Rails.env.experimental?
nondev_reset_sprockets
else
dev_reset_sprockets ##version
end
end
end
And those two reset methods look like this:
def nondev_reset_sprockets
manifest = YAML.load(File.read(Rails.root.join("public","assets","manifest.yml")))
manifest.each do |key, value|
Rails.application.config.assets.digests[key] = value
end
end
The nondev reset "stuffs" each of the values into memory from the new generated manifest file
def dev_reset_sprockets(version)
environment = Rails.application.assets
environment = environment.instance_variable_get('#environment') if environment.is_a?(Sprockets::Index)
environment.version = version
end
The dev reset just kicks sprockets "version" value so that it thinks (correctly so) it needs to reparse and live recompile the latest assets.
Another way of updating the assets in production is as follows:
Rails.application.assets_manifest.instance_eval do
new_manifest = Sprockets::Manifest.new(manifest.dir, manifest.filename)
#data = new_manifest.instance_variable_get(:#data)
end
For Rails 4 (Sprockets 2.11), you can do:
Rails.application.assets_manifest = Sprockets::Manifest.new(Rails.env, Rails.application.assets_manifest.path)
# see sprockets-rails/lib/railtie.rb
ActionView::Base.assets_manifest = Rails.application.assets_manifest

How to prevent initializers from running when running `rails generate`

I want to prepopulate my cache with an initializer, but I don't need this code to run every time I run rake or rails g, etc. Rake and Bundler are easy to deal with, but a similar solution does not work for the generators:
# config/initializers/prepop_cache.rb
if !defined?(::Bundler) and !defined?(::Rake) and !defined(Rails::Generators)
# do stuff
end
This must be because rails/generators (or something similar) is requireed at runtime. How can I check to see if the command being run is rails g xyz?
Update:
Two solutions can be found here: Rails 3 initializers that run only on `rails server` and not `rails generate`, etc
Still would like to know if it's possible in the manner I've tried above.
In Rails 3, what you're looking to do is conceivably possible, but in a hacky way. Here's how:
When you make a rails generate call, the callpath looks like this:
bin/rails is called, which eventually routes you to execute script/rails
script/rails is executed which requires rails/commands
rails/commands is loaded, which is the main point of focus.
Within rails/commands the code that runs for generate:
ARGV << '--help' if ARGV.empty?
aliases = {
"g" => "generate",
"c" => "console",
"s" => "server",
"db" => "dbconsole"
}
command = ARGV.shift # <= #1
command = aliases[command] || command
case command
when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler'
require APP_PATH
Rails.application.require_environment! # <= #2
require "rails/commands/#{command}" # <= #3
The points of interest are numbered above. Namely, that at point #1 the command that you're running is shifting off of ARGV. Which in your case means generate is going to be removed from the command line args.
At point #2 your environment gets loaded, at which point your initializers are going to be executed. And herein is the tough part - because nothing indicating a specific command has been loaded at this point (this occurs at #3) there is no information to determine a generator is being run!
Let's insert a script into config/initializer/debug.rb to see what is available if we ran rails generate model meep:
puts $0 #=> "script/rails"
puts ARGV #=> ["model", "meep"]
As you can see, there is no direct information that a generator is being run. That said, there is indirect information. Namely ARGV[0] #=> "model". Conceivably you could create a list of possible generators and check to see if that generator has been called on ARGV[0]. The responsible developer in me says this is a hack and may break in ways you'd not expect so I'd use this cautiously.
The only other option is to modify script/rails like you suggested -- which isn't too bad a solution, but would likely break when you upgrade to Rails 4.
In Rails 4, you've got more hope! By the time the application environment is being loaded, the generators namespace has already been loaded. This means that in an initializer you could do the following:
if defined? Rails::Generators #=> "constant"
# code to run if generators loaded
else
# code to run if generators not loaded
end

undefined method 'path' for nil:NilClass using chargify_api_ares gem

I feel like this should be a simple problem, but I'm pulling my hair out trying to track it down. I'm installed the chargify_api_ares gem, but can't do even basic things such as
Chargify::Subscription.create
As I get this path error. I feel like this must be a gem issue somehow but don't know where to go from here.
UPDATE: bundle show chargify_api_ares shows the correct path, I just somehow can't access it. Still trying random environment related things.
Looks like this is the source of the problem, in active_resource\base.rb:
# Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>)
# This method is regenerated at runtime based on what the \prefix is set to.
def prefix(options={})
default = site.path
default << '/' unless default[-1..-1] == '/'
# generate the actual method based on the current site path
self.prefix = default
prefix(options)
end
As I understand it, Chargify.subdomain should be setting the site.path, but I don't understand activeresource well enough yet to know what's happening and will continue to dig.
I too had the same issue.
I executed the following on the console
Chargify.configure do |c|
c.api_key = "<<api_key>>"
c.subdomain = "<<subdomain>>"
end
After that performing any Chargify console commands went through fine.

Disable Rails SQL logging in console

Is there a way to disable SQL query logging when I'm executing commands in the console? Ideally, it would be great if I can just disable it and re-enable it with a command in the console.
I'm trying to debug something and using "puts" to print out some relevant data. However, the sql query output is making it hard to read.
Edit:
I found another solution, since setting the logger to nil sometimes raised an error, if something other than my code tried to call logger.warn
Instead of setting the logger to nil you can set the level of the logger to 1.
ActiveRecord::Base.logger.level = 1 # or Logger::INFO
To turn it off:
old_logger = ActiveRecord::Base.logger
ActiveRecord::Base.logger = nil
To turn it back on:
ActiveRecord::Base.logger = old_logger
This might not be a suitable solution for the console, but Rails has a method for this problem: Logger#silence
ActiveRecord::Base.logger.silence do
# the stuff you want to be silenced
end
Here's a variation I consider somewhat cleaner, that still allows potential other logging from AR. In config/environments/development.rb :
config.after_initialize do
ActiveRecord::Base.logger = Rails.logger.clone
ActiveRecord::Base.logger.level = Logger::INFO
end
For Rails 4 you can put the following in an environment file:
# /config/environments/development.rb
config.active_record.logger = nil
In case someone wants to actually knock out SQL statement logging (without changing logging level, and while keeping the logging from their AR models):
The line that writes to the log (in Rails 3.2.16, anyway) is the call to debug in lib/active_record/log_subscriber.rb:50.
That debug method is defined by ActiveSupport::LogSubscriber.
So we can knock out the logging by overwriting it like so:
module ActiveSupport
class LogSubscriber
def debug(*args, &block)
end
end
end
I used this: config.log_level = :info
edit-in config/environments/performance.rb
Working great for me, rejecting SQL output, and show only rendering and important info.
In Rails 3.2 I'm doing something like this in config/environment/development.rb:
module MyApp
class Application < Rails::Application
console do
ActiveRecord::Base.logger = Logger.new( Rails.root.join("log", "development.log") )
end
end
end
Just as an FYI, in Rails 2 you can do
ActiveRecord::Base.silence { <code you don't want to log goes here> }
Obviously the curly braces could be replaced with a do end block if you wanted.
I use activerecord 6.0.3.3 and I had to include ActiveSupport::LoggerSilence
include ActiveSupport::LoggerSilence
ActiveSupport::LoggerSilence.silence do
## everything you want to silence
end
This however did not work with anything related to creating or deleting SQL tables like ActiveRecord::Migration.drop_table. For this to be silenced I added:
ActiveRecord::Schema.verbose = false
I had to solve this for ActiveRecord 6, and I based my answer on fakeleft's response, but it wasn't quite right, since it was suppressing other logging such as the logging of nested views. What I did was created config/initializers/activerecord_logger.rb:
# Suppress SQL statement logging if necessary
# This is a dirty, dirty trick, but it works:
if ENV["ACTIVERECORD_HIDE_SQL"].present?
module ActiveRecord
class LogSubscriber
def sql(event)
end
end
end
end
The log subscriber in AR 6 has a sql event that we want to hide, so this is very narrowly targeted to skip that event.