Rails is continually running in test mode - ruby-on-rails

After upgrading to rails 2.3.5 I got things working again and the tests were passing. Then all of a sudden when I run the script/server command it now always runs in Test mode which is seen by a simple > puts RAILS_ENV
I have restarted my machine as well as run the script/server command manually setting the environment via -e, but still have no luck.
Does anyone have any idea what the cause of this would be?
** I should note that even when the RAILS_ENV constant is shows up as "test", the database config that is used is the development.
update
by adding puts RAILS_ENV statements throughout the code I can see that when I add a puts outside the Rails::Initializer.run do |config| block within the environment.rb class that at that point the RAILS_ENV becomes set to "test". Right before the end of the block it is still set to development.

The reason for the environment change was that, without thinking, I loaded the rspec gem in the development.rb file.

Related

Ruby on Rails: Difference between behaviour within the console / in a .rb file

I would like to use information stored within a the credentials.yml.enc file for a Rails 5.2 app. However, I am struggling to get a command which works perfectly within the console to behave in the same way when inserted into a .rb file.
In the Rails console (on my local development computer) Rails.application.credentials.username returns "my_username"
If I insert this line within a very simple db_backup.rb file as shown below, I get the error:
NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails
db_backup.rb:
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = Rails.application.credentials.username
end
end
Please could you explain why I get the different behaviour when using exactly the same line of code in the Rails console / within a .rb file?
The context in which the code is executed is not the same. One is the rails console and the other is the backup command
What happens when you load the Rails console
Launching the rails console means you launch all of the rails stack before executing your code against it. The Rack applications like Sinatra, Rails etc. use the config.ru file as a convention for which file should be run to boot. (You can explore the rabbit hole if you want to have a deep understanding of this)
It means that the vast majority of errors you can encounter when will occur during the console boot, preventing you from executing anything in the console (because boot failed). Instead it will print the stack trace errors for you to figure out what went wrong so you can correct and give it another try.
TL; DR Rails.application.credentials.username in console is executed after all of the Rails stack (models, dependencies, initializers) has loaded in a particular order
What happens when you run the backup command
The backup command is defined here in the bin repo of the backup repo
It goes like this
#!/usr/bin/env ruby
# encoding: utf-8
require File.expand_path("../../lib/backup", __FILE__)
Backup::CLI.start
If you open the required file lib/backup.rb and look around in the Gemfile, you won't fine a place where you have a dependency or a define for the Rails constant.
Thus when you run the backup command and execute your db_backup.rb, the constant Rails called here is ... not defined. Ruby being kind will try to find a nested version of this constant in the current scope which is the Model.new do; end block.
It is still not defined which ruby tells you about with NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails.
#giglemad gives a great explanation of the issue of class resolution in the execution context (rails console vs. running of the backup ruby file).
To fix your error, just let the code know to use the top-level class lookup (::Rails):
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = ::Rails.application.credentials.username
end
end
If you're still seeing the missing Rails constant, you'll need to put your script in either a rake task, or require your rails environment.
I ended up resolving this by simply adding the line below to the top of my db_backup.rb:
require './config/environment' # added to enable credentials to be read from Rails environment

How can I test my production environment instead of my test environment Rails

I've been struggling with a problem for a few days right now and I want to know how I can force my Rails app to run in environment and then I want to be able to test the images to ensure that they are http or https.
I'm getting closer and closer to solving the problem but now I want to test my production site instead of my test. The reason being is that when I run my rake tests to check to see if the images have either http or https, it only gives me a relative link such as
/images/9995/0007/company_logo.png
This is not helpful to me at all. In order to assert_match /http:/ patten, I need it to grab the images on the production site not in test. How can I do this? I've been researching this for a very long while now and I still feel that I'm no where close to figuring this out.
I've tried to force the Rails environment into production by placing this line of code into config/environments.rb
ENV["RAILS ENV"] ||= 'production'
THe problem is, when I run my tests, doesn't it still refer to the test database? How do I know that when I run rake test TEST=test/functional/ect_test.rb its running production?
I've also tried to have my database.yml file to "point" to production but I made a huge mess of this and to quite frankly I don't really know how that works (It was a recommendation from another stack overflow site). Anyways, some help would be greatly appreciated.
*FYI I am running on Rails 2.3. We are in the middle of upgrading our database. Any input would be greatly appreciated. Thanks.
It's just a matter of starting your server or running your tests with the environment set to production. To do this just prepend RAILS_ENV=production to the commands rails server or rake test or whatever you run you server or tests with. The line:
ENV["RAILS ENV"] ||= 'production'
Is misspelled (just mentioning in case). There's an underscore missing in it. Also, it won't set the RAILS_ENV to production if that ENV value is already set. Make it:
ENV["RAILS_ENV"] = 'production'
To ensure you overwrite any value. Although the aforementioned command prepend technique should work.
Also, if your site runs in https you can be sure the images with relative paths will be served via https as well.

What is the correct way to run Rails tests without invoking the development environment?

I have an Rails app, with some initializer code which must be executed when the app is running in development mode. However, this initializer code must not be executed when running tests.
I have established that
$ rake test
causes the app to be run in development mode, which invokes the initializer code and therefore breaks my tests. This is expected behaviour apparently (see: https://github.com/rails/rails/issues/9801).
What is the correct command to run my Rails app tests without starting the app in development mode?
Does your test_helper.rb file look like the default? It should start with:
ENV["RAILS_ENV"] = "test"
Try running the rake task with an explicit environment:
rake test:units RAILS_ENV=test
If you don't specify an environment, development is assumed, in my experience. And while the test database still gets the fixture data inserted into it, stuff from the development environment still gets referenced for some reason.
You need to have a line at the start of the test_helper.rb file that says
Rails.env = "test"
You can't use
ENV["RAILS_ENV"] = "test"
because it will fail to clear the cached value that returns from calls to Rails.env.

Log your SQL in Rails application inside unit test

I want to install a logger so that I can dump all executed SQL of my rails application. Problem is, such logger is associated with AbstractAdapter which initialized very soon under test mode, and thus cannot be set by my initializer code.
I try to put
ActiveRecord::Base.logger = MyCustomLogger.new(STDOUT)
in the end of environment.rb like someone advised but it only works when being run in console environment (kicked by script/console), not when run under test mode.
I wonder if there is any way to config such logger so that I will sure to be invoked under any environment (test, development, production, console)
Creating the logger in config/environment.rb should work. I get SQL logging on standard output when I run unit tests if I put the following line in either config/environment.rb or config/environments/test.rb:
ActiveRecord::Base.logger = Logger.new(STDOUT)
Does your MyCustomLogger class do anything special that causes it to fail during tests? Does it work better if you use Logger.new(STDOUT) instead?
In test/test_helper.rb, before loading config/environment.rb, add:
RAILS_DEFAULT_LOGGER = MyCustomLogger.new(STDOUT)
Relevant code in railties for 2.3 railties/lib/initializer.rb#L35. Not sure how to do it with Rails 3.0 yet. It looks like you need to call Rails#logger=, but I can't find a good spot for it yet.
The best way as far as I can found is to put such code in initializers folder. This way, regardless of the running environment, the logger is always properly installed. And no, on my mac osx Rails 2.3.2 on ruby 1.8.7, if I put ActiveRecord::Base.logger=... inside environment.rb then the logger is not properly installed, since the logger that the Sql Connection used to dump SQL was installed and cached before that.

How do I force RAILS_ENV=development from within environment.rb or initializers?

Our host does not allow us to modify the passenger config file (i.e. the apache config OR the vhosts file), but we'd like to run rails in dev mode. So we have to specify the environment (prod/dev/test) in one of the files that rails loads AS the application is restarted. Anyone know how to do this?
We've tried the following with no luck:
#environment.rb (before any other code is executed)
`RAILS_ENV=development` # using back ticks
ENV['RAILS_ENV'] = 'development' # assigning to a constant
RAILS_ENV='development' # as suggested by one of the answers, unfortunately does not work.
Setting it right at the top of environment.rb with:
RAILS_ENV = 'development'
should do it. It's possible that passenger overrides this, though.
If you don't have access to the passenger config but you do have access to your virtual hosts then you can also just force it in there with:
RailsEnv development
Why don't you change your production.rb config to match the settings found in development.rb?
In envriornment.rb you could add:
RAILS_ENV="production"
RAILS_ENV.freeze
That way when it tries to get reset later, it will fail.
I'm not sure what other ramifications this will have later or if it will permeate everywhere within rails.
Instead of setting ENV["RAILS_ENV"] in environment.rb, do so in boot.rb.
See here for details.
RAILS_ENV="production"
RAILS_ENV.freeze/ENV
That way when it tries to get reset later, it will fail.
I'm not sure what other ramifications this will have later or if it will permeate everywhere within rails.

Resources