change rails environment from within ruby file then change back - ruby-on-rails

I have a test-automation app that runs tests against user params against a rails app.
The tests execution in the Ruby app looks like this:
config = RSpec.configuration
json_formatter = RSpec::Core::Formatters::JsonFormatter.new(config.out)
reporter = RSpec::Core::Reporter.new(json_formatter)
config.instance_variable_set(:#reporter, reporter)
RSpec::Core::Runner.run(["#{Rails.root}/spec/features/example_spec.rb"])
puts json_formatter.output_hash
This works great but runs in the current environment, i.e. development.
I want to change the Rails environment so that this code is executed in the test environment and then change it back.
Does anyone know how to do this?
thanks
Richard

You can always change the environment for a single (or set of) commands like this in unix-like environments:
RAILS_ENV=testing bundle exec rspec
or whatever you need to execute. You could, for example, define a custom rake task that contains your spec-running logic and call that as I outlined above.
Using this concept and taking it a step further, you could execute shell commands directly from Ruby and have a custom environment variable set for only this command. In this shell commands you could execute arbitrary Ruby code (e.g. via ruby -e ...) or even call another Ruby file that properly initializes whatever you need within your desired environment.
I think it would be really bad practice to try to change the current environment from within your code, even if it is somehow possible. I would personally stick with a custom, dedicated, rake task which I can call from my command line with whatever environment I need.

Related

Ruby on Rails - Can I call a Controller:Method from a batch routine in windows?

I'm relatively new to RoR working on Windows. I built a simple app in Rails that sends email using ActionMailer. I'd like to add a task to my windows scheduler to run a batch routine that calls my email method inside of my controller. The web app will not be running when I do this, so I can't do a CURL or something similar. Is there a way to run Ruby.exe with some args to launch a rails app (similar to irb) and call a controller:method?
Update: I took the advice in the answer I marked correct, but I thought I'd elaborate in case a RoR newbie like myself needs a bit more guidance.
I created a folder app\classes and I created a .rb file for my class
I had to create an initialize method to handle some setup
Created a few methods that simple return variables
I made sure I could run the steps in rails console
Created a file in lib\tasks with the code below
Ran this in DOS in the project folder - rake runMe --trace
task :runMe => :environment do
#s = ScrapeTools.new
#bears = #s.getBears
#bulls = #s.getBulls
UserMailer.stock_email(#bears,#bulls).deliver
end
Please let me know if you see any errors
There is. rails runner <path to script> will run the given script under your Rails app. Have some docs
This is a good example of why you don't want to put logic in your controller. Much better than putting that functionality in a controller method, refactor it to a method in a module or class. Then you call that method from your controller as well as from a rake task that is straight-forward to execute in your batch routine.

run ruby script in rails application

This may be a stupid question but I was just wondering where, or if its possible to run a ruby script which is kind of unrelated to the rails application I would like it to run in. To clarify, I am working on an automation test suite that is written mainly in bash, but I want to create a front end (my rails application) that allows other users to run automated tests not through the command line. So I guess basically I want a user to select certain parameters, from a database or form fields, then take those parameters and pass them to a ruby script which calls my bash automation script.
I hope this is clear. Thanks!
If you want to call a script from a rails app it gets complex. You would want to use a background job or some sort of queue to run these jobs because they do block the server and your users would be waiting for the call to complete and the results to load, most likely hitting a timeout.
See delayed_job
and you might want to try creating a small wrapper script in ruby that can interface with your application.
Good luck!
for short tasks you should use system or popen
when tasks are longer then they are still needed in case of delayed_job
You can add a script to your scripts folder in the root of your rails app. Start your script like this:
your script can be [name here].rb
The reason why we load in the environment is so we can use rails models and rails related things in your script:
#!/bin/env ruby
ENV['RAILS_ENV'] = "production" # Set to your desired Rails environment name
require '/[path to your rails app on your server]/config/environment.rb'
require 'active_record'
If you want to run this on your server, then you have to edit your crontab on your server. Or you can use the whenever gem (which I''m having trouble with, but the entire universe doesn't). Conversely, if you have heroku, then there's the heroku scheduler that makes running scripts easy.
You can run Ruby code with rails runner.
… let us suppose that you have a model called “Report”. The Report model has a class method called generate_rankings, which you can call from the command line using
$ rails runner 'Report.generate_rankings'
Since we have access to all of Rails, we can even use the Active Record finder method to extract data from our application.
$ rails runner 'User.pluck(:email).each { |e| puts e }'
charles.quinn#highgroove.com
me#seebq.com
bill.gates#microsoft.com
obie#obiefernandet.com
Example taken from The Rails 5 Way by Obie Fernandez.

If you modify code in the Rails console will that affect a server running in parallel?

Is it possible to run "rails console" in one shell and then "rails server" in another and then have code changes in the console permeate to the running application? Presumably this isn't possible, but I'd just like to check if there is a way.
Edit: Both are running in the same environment. And by code changes I mean changes to class definitions (e.g. rewriting a method on the Post model).
If you modify any data, that will indeed permeate. However modifications to methods done on the fly by opening classes and "monkey-patching" them will not affect your running application - unless your modified method modifies data.
However, it is always advisable to run the console in a different environment with different data to avoid harming a running application.
If you are changing data in your console IN THE SAME ENVIRONMENT then it will be changed in the browser.

Is the rails console dynamic?

is the console in rails (~ rails c) dynamic? For example; if I open the console and then make changes to a model will it pick these changes up or do I have to exit out of the console and run rails c again for it to pick up the changes in the model?
You will need to call the reload! method in the console to reload the changes. This method's magic is automatically called by rails server in development mode.
As a comment's pointed out beneath and another answer here, if you change things to do with the environment of the application, such as adding new gems to the Gemfile, making changes to anything in config or adding a new plugin then you'll need to restart the console. Any changes to app will be reloadable with reload!
If you were using this particular way to test that a method was working, I wouldn't. Tests (as in, the Test::Unit or RSpec) variants are much nicer because you have a reproducible way of running them again and again. rails console is great for one-off testing, but if you want to write a maintainable application then write tests.

Rails console: Run a Ruby file several times

Rails provides a very useful console ('script/console').
I write a ruby file and run it in the console using require foo.rb.
It works fine the first time, but the second and next require foo.rb does not run my script (require does not reload it).
Do you have any tips/tricks?
require is used to load extensions - so the code will execute once, to get the extensions to be present in your environment, but subsequent requires won't do anything, because the job has already been done.
load, on the other hand, loads and executes the code every time.
As already mentioned, if you just want to run your script and you need the Rails environment, then consider using script/runner
You should probably try either loading your rails environment in a script or using rake. Also consider using script/runner.
Here is an old and possibly outdated example of using your rails environment in a script. A more recent and detailed version here.
A stack overflow answer

Resources