Run script in Rails console and have access to objects created? - ruby-on-rails

I recently found you can run an arbitrary Ruby file in the Rails console using load or require, as in:
load 'test_code.rb'
This is great as far as it goes, but using either load or require (what's the difference?) I don't seem to have access to the objects created in the script after it completes.
For example, in my script I might have something like:
u = User.where('last_name = ?', 'Spock').first
If I start rails console and run that script using load or require, I see it working, I see the query happen, and I can 'put' attributes from the object inside the script and see them in the console output. But once the script is done, the variable u is undefined.
I'd like to run some code to set up a few objects and then explore them interactively. Can this be done? Am I doing something wrong or missing something obvious?

Variables defined in your script will go out of scope once the file is loaded. If you want to use the variables in console, define them as instance variables or constants
#u = User.where('last_name = ?', 'Spock').first
or
USER = User.where('last_name = ?', 'Spock').first

As explained in http://www.ruby-doc.org/core-2.1.2/Kernel.html#method-i-load:
In no circumstance will any local variables in the loaded file be propagated to the loading environment.
An option is to eval the file:
eval(File.read 'your_script.rb')
and the local variables will be there afterwards.

Related

Scope of Models(?) in Rails

I'm new to Ruby on Rails and am trying to access my site's database. I generated and set up a model and controller called Machine, and noticed that in places like the Machine view I could iterate through all the machines in my database simply using #machines.each. However, this doesn't appear to be universal, as when I created a new Ruby file directly in my project's outermost directory, both #machines.each and the attempted assignment #machines = Machine.all threw errors (a NoMethodError and NameError respectively). Here's an example of code I could try to run:
#machines = Machine.all
#machines.each do |machine|
puts machine.created_at
end
Perhaps I need some kind of import statement?
If you are writing a script in plain Ruby -- then yes, you'll have to import everything manually, establish a connection to the DB, etc.
The code would roughly look like this:
require 'active_support'
require 'active_record'
your_db_config = {
# your DB config goes here
}
ActiveSupport::Dependencies.autoload_paths += File.join(__dir__, "app/models")
ActiveRecord::Base.establish_connection(your_db_config)
machines = Machine.all
Consider creating a task if you want Rails to take care of all that and don't want to be doing all that stuff manually.
When you start a rails server (or a rails console) it preloads your Rails application so that your models, constants, etc. are automatically in scope. If you want to access your application's resources from a separate script you still need to load the app. The simplest way to do that is with the rails runner command, which loads your app and then executes a script. So if your script above is in lib/show_machines you'd run:
$ bin/rails runner lib/show_machines
If you like self-executing scripts you can also use runner as a 'shebang' line:
#!/usr/bin/env <your_project_path>/rails/runner
#machines = Machine.all
#machines.each do |machine|
puts machine.created_at
end

How to store values that result from executing an app using system(" ") on ruby on rails 4?

I'm using system(" ") on the rails console to execute an application that takes inside a file, processes it and outputs another file.
The application also logs statistics for said file on the terminal before closing.
My objective is to save those logged statistics as variables inside rails, although I'm not exactly sure how I can do that.
How can I save the logged statistics inside rails variables?
I don't think the system method is the best method to use here, as I think this would either return true or false. However to get back the value, you should try to use the backticks
statistics = `method to call on computer`
let me know if that works

Rails environment variables failing to load in model

I have an environment variable that I'm using in two places, one is in a rake task, the other is in a model method. When I call it from the rake task, everything is fine and the variable loads, but when I call it from the model it doesn't find anything. It's not a nil error or any other error, it just returns an empty string.
Is there any reason the environment variables would be overridden or inaccessible to the model?
It's being used to build a url:
http://#{AppEnv['env_var_1']}/this/is/#{AppEnv['env_var_2']}/a/path
--one more thing, myabe it's relevant, the model method is called after_create
EDIT:
thanks for the responses, but my question isn't how to access or use env vars, as you can see I'm already using them above. My question is why they are not loading in my model.
EDIT 2:
I have 4 relevant AppEnv variables, and [this is really weird so bear with me] when I check them on running the rake task (puts all 4 of them to the log), they are as expected. When I run the exact same class method, but called after_create in a model, 3 of the variables are empty, and one of them holds the value of a different variable. That is:
AppEnvVar1 is empty
AppEnvVar2 has the value of AppEnvVar4
AppEnvVar3 is empty
AppEnvVar4 is empty
If I change the method to self.method (allowing me to run it from the console), and run it, it works. So I'm pretty sure I've narrowed this down to an issue with the AppEnv during an after filter.
any ideas on where to dig?
Rails sets a global constant hash ENV that should be available anywhere in your app after it's initialized, including in your models. So you should be able to refer to any enviroment variable like this (assuming the relevant env variables has been set):
"http://#{ENV['ROOT_DOMAIN']}/this/is/#{ENV['SECONDARY_DOMAIN']}/a/path"
I restarted the server and everything worked fine. Mysterious...

data driven ios-Calabash automated testing using xml or css or global variables

i am doing automated testing using calabash-ios. I want to be able to run cucumber once and have it run x times for x user names and run through the gamut of test scenarios.
i want to use this:
Given I login as [#{country-name}] user using id [#{Login-name}] and pwd "PASSWORD"
and have a global variable that can store the values for both country and user name.
i had hoped to use scripts to run cucumber x times and set the value for the global variables each time. is this possible? and if so, could someone point me in the right direction?
i tried using :
##Loginname=value
but got this error:
features/step_definitions/common.rb:1: warning: class variable access from toplevel
uninitialized class variable ##Login in Object (NameError)
failing which, will it be possible to access data stored in a xml or css file using calabash?
If you want to run the same cucumber run many times with some different variables you can just use environment variables.
Given I login as "ENV['COUNTRY_NAME']" user using id "ENV['LOGIN_NAME']" and pwd "PASSWORD"
And then when you run the tests
LOGIN_NAME='login name' COUNTRY_NAME=country bundle exec cucumber
And then of course you can put all of the lines you want to run into a bat or sh script.
One thing to be careful of is to use the environment variables or another one to change the path for the outputs so you don't overwrite them.
However, a more elegant solution would be to handle it with a rake task that ran all of the other tasks. The most efficient way to write that would depend on how many different runs you need.
task :all => [:task1, :task2, :task3]
EDIT: To make your scenarios more readable, you should use a generic placeholder in the scenario and hide the environment variables in the step definition.
Given I login as a user
Might have a step definition that looked like:
Given /^I login as a user$/ do
... set up your page object here ...
login_page.login(ENV['COUNTRY_NAME'], ENV['LOGIN_NAME'])
end

Passing custom arguments into rails console (2.2.2)

I have a rails 2.2.2 app. I'd like to be able to start the console by passing in a custom variable, which i can then retrieve inside my environment. Something like
#i start console like so
rails/console production -uid 1182
Then, anywhere in my code, i would be able to access this "uid" variable in the same sort of way that i can access ENV['HOME'] or things like that. (it doesn't need to be in ENV, just so long as i can access it reliably).
Anyone know how i can do this? thanks, max
Try this:
uid=1182 rails/console production
This way you set env variable, accessible from Ruby with:
ENV['uid']

Resources