142

Is there a way to pass ruby file, foo.rb to rails console. Expected results would be after console starts rails environment to run file.

Or any other way which would allow me to execute file in rails environment, triggered from command prompt.

ddavison
  • 28,221
  • 15
  • 85
  • 110
Haris Krajina
  • 14,824
  • 12
  • 64
  • 81
  • Possible duplicate of [How do I run a Ruby file in a Rails environment?](http://stackoverflow.com/questions/9757261/how-do-i-run-a-ruby-file-in-a-rails-environment) – Nick Roz Sep 07 '16 at 17:27

7 Answers7

199

Actually, the simplest way is to run it with load inside the rails console

 load './path/to/foo.rb'
Adrian
  • 9,102
  • 4
  • 40
  • 35
  • 6
    This works great. But unless I'm doing something wrong, you do not have access to objects created inside the script. Any way to do that? The use case is to set up some objects, then interactively explore them. Is that possible? – Dan Barron Jan 21 '14 at 15:33
  • 1
    @DanBarron you can put in a debugger or binding.pry – grant Apr 19 '16 at 20:35
  • This is just like a Lisp REPL +1 – zeitue Jan 13 '17 at 07:52
  • 2
    Noob help : ./path - is path relative to your rails project where your file resides. – Darpan Nov 14 '18 at 08:15
97

You can use

bundle exec rails runner "eval(File.read 'your_script.rb')"

UPDATE:

What we also have been using a lot lately is to load the rails environment from within the script itself. Consider doit.rb:

#!/usr/bin/env ruby

require "/path/to/rails_app/config/environment"

# ... do your stuff

This also works if the script or the current working directory are not within the rails app's directory.

moritz
  • 25,477
  • 3
  • 41
  • 36
  • Thanks a lot that does a job! I am using Sublime Text 2 so now I will be able to trigger builds of rails classes and see output directly in IDE :) – Haris Krajina Apr 25 '12 at 15:04
  • 2
    script/runner "eval(File.read 'your_script.rb')" for rails 2.3 :) – valk Nov 20 '12 at 10:30
  • 2
    you can use a similar pattern to run files inside the console: `f=File.new('path/to/file')` to run use: `f.rewind; eval f.readlines.join("\n");` – semiomant Jun 28 '13 at 14:08
  • 3
    FYI you don't need the `eval(File.read ...)` part anymore. Rails accepts a Ruby file as an argument to `rails runner`: `Usage: rails runner [options] [<'Some.ruby(code)'> | ]` – Ajedi32 Jul 06 '16 at 21:07
  • Update- as per @HarisKrajina's answer below, looks like `rails r path/to/filename.rb` is functionally equivalent to the `bundle exec rails runner` command mentioned above. – Richie Thomas Aug 22 '18 at 19:51
  • See the last subsection under 1.6 for documentation here: https://guides.rubyonrails.org/command_line.html#rails-runner. – CFitz Nov 21 '18 at 20:54
95

In the meantime, this solution has been supported.

rails r PATH_TO_RUBY_FILE

Much simpler now.

Haris Krajina
  • 14,824
  • 12
  • 64
  • 81
6

Consider creating a rake task.

For code that I need to create records or support migrations, for example, I often create a rake task like that from this answer. For example:

In lib/tasks/example.rake:

namespace :example do
  desc "Sample description you'd see if you ran: 'rake --tasks' in the terminal"
  task create_user: :environment do
    User.create! first_name: "Foo", last_name: "Bar"
  end
end

And then in the terminal run:

rake example:create_user
ddavison
  • 28,221
  • 15
  • 85
  • 110
Matt
  • 5,800
  • 1
  • 44
  • 40
5
script/console --irb=pry < test.rb > test.log

simple, dirty, and block the process at the end, but it does the job exactly like I wanted.

StarsSky
  • 6,721
  • 6
  • 38
  • 63
hari seldon
  • 51
  • 1
  • 1
1

Of these approaches mentioned earlier, none seemed clean and ideal like you would expect a standalone script to run (not get eval-ed or piped via < redirection), but finally this works perfect for me:

(for Rails 3)

Insert at the top of your script:

#!/usr/bin/env ruby

APP_PATH = File.expand_path(appdir = '/srv/staging/strat/fundmgr/config/application',  __FILE__)
require File.expand_path(appdir + '/../boot',  __FILE__)
require APP_PATH
# set Rails.env here if desired
Rails.application.require_environment!

# your code here...

Of course, set your own Rails app path in the APP_PATH line.

That way, I can avoid having to enter any interactive irb or rails c and can test my script.rb from the shell prompt, before eg. scheduling it in crontab.

It smoothly supports command-line parameters, too, and minimizes the levels of wrappers before getting to your code.

CREDIT (also shows a Rails 2 example)

http://zerowidth.com/2011/03/18/standalone-script-runner-bin-scripts-in-rails.html

Marcos
  • 4,796
  • 5
  • 40
  • 64
0

Here's the hack I'm using:

rr() {
    rails_root="$(bundle exec rails runner "puts Rails.root")"
    rp="$(relpath "$1" "$rails_root")"
    bundle exec rails runner "eval(File.read '$rp')"
}
relpath() {python -c "import os.path; print os.path.relpath('$1','${2:-$PWD}')";}

Example:

cd ~/rails_project/app/helpers
rr my_script.rb

Based on @moritz's answer here. I changed it, since the working directory for File.read is the Rails project root.

I know this is some serious heresy, using python to help a ruby script. But I couldn't find a relpath method built into ruby.

Credit: relpath() was taken from @MestreLion, Convert absolute path into relative path given a current directory using Bash

Community
  • 1
  • 1
Chaim Leib Halbert
  • 2,194
  • 20
  • 23