rails rake task with globally installed gem - ruby-on-rails

I'm trying to write a rake file to import data from csv, and I want to use smarter_csv gem. I have the gem installed globally (I don't want to add it to my Gemfile because it's a one-off task).
In my rake file I require 'smarter_csv' but when I run the task I get the following error:
rake aborted!
LoadError: cannot load such file -- smarter_csv
Every rake example I can find tells you to just require 'foo'. I can run the code manually in irb after requiring smarter_csv.
What am I missing?
(If it matters, I'm using rbenv on macOS Catalina)

If you do want to load a gem without having it in your Gemfile you can do the following in your rake task:
$: << '/Users/<user>/.rvm/rubies/ruby-
x.x.x/lib/ruby/gems/x.x.x/gems/smarter_csv-x.x.x/lib'
require 'smarter_csv'
I think the option to have the gem in your Gemfile with the require: false option is more suitable however. The gem won't be loaded until you specifically require it.

Rails uses bundler, and loads the gems mentioned in gemfile into memory. Doesn't look like you've any other option.
I had a similar use case, I tried putting it into a development group like so,
group :development do
gem 'smarter_csv'
end

Related

How do I get awesome_print to work without using ~/.irbrc file?

I want to use awesome print without putting it in my rails 5 app. Just in the console. The documentation for requiring it in irb is not working.
That's because bundler isolates the gems available to load to what's in your Gemfile.
The best way to get around this is to add the gem to your Gemfile
gem 'awesome_print', require: false, group: :development
And in your .irbrc, you can require it, so that it is only enabled for you:
begin
require 'awesome_print'
rescue LoadError => err
warn "could not require awesome_print: #{err}"
end
However, if you aren't permitted to add awesome_print to your repository for whatever reason, there are a few hacks to get gems installed, but not in your Gemfile to load in this GitHub Gist.
One such example that could be placed at the top of your .irbrc:
# Add all gems in the global gemset to the $LOAD_PATH so they can be used even
# in places like 'rails console'.
if defined?(::Bundler)
global_gemset = ENV['GEM_PATH'].split(':').grep(/ruby.*#global/).first
$LOAD_PATH.concat(Dir.glob("#{global_gemset}/gems/*/lib")) if
global_gemset
end
cd your/rails/project
irb
inside irb, run:
require 'awesome_print'
require './config/environment'
and you have both rails console and awesome_print gem while the gem is installed outside of the bundler.

Why is this gem not adding rake tasks to a Rails app?

We have a gem which runs via a Rake task. The task is defined in lib/tasks/<namespace>.rake. After reading Rake tasks inside gem not being found I confirmed that the .gemspec includes the file defining the task; there is also a railtie which should be including the tasks as suggested in including rake tasks in gems. And yet our Rails 4.1 application doesn't seem to load the Rake task.
What am I missing?
I just successfully tested your gem and I can see no problem with the rake tasks in it:
I added gem_fresh to the Gemfile and ran bundle, the gem installed
Immediately I could see the rake present in the list of rakes:
$ rake -T outdated
rake gem_fresh:outdated # outdated
Then I updated the railtie.rb file to use the load method to load the rake defined in lib/task/metrics.rake and searched the available rakes again:
# lib/gem_fresh/railtie.rb:
rake_tasks do
namespace :gem_fresh do
desc "outdated"
task :outdated => :environment do
GemFresh::Reporter.new.report
end
end
load "tasks/metrics.rake"
end
$ rake -T outdated
rake gem_fresh:outdated # outdated
rake metrics:outdated_gems # display outdated gem version metrics
So, I can see no problem with your gem. Both methods in railtie (inline rake as well as using the load method) seem to work OK. The only difference I noticed is that I tested this on rails 4.2 but I rather doubt that would make a difference.
Did you put the gem into your Gemfile? If I remove it from there, I indeed see no gem_fresh rakes defined.
The problem was not with the gem, but with the way it was included in the app.
In the Gemfile, this works and includes the rake task:
gem 'gem_fresh'
This works but doesn't include the rake task:
group :development do
gem 'gem_fresh'
end
This seems to be due to how Bundler requires gems in Rails apps. From the documentation:
By default, a Rails generated app calls Bundler.require(:default, Rails.env) in your application.rb, which links the groups in your Gemfile to the Rails environment.
If for some reason that Rails.env argument wasn't evaluating to include the :development group, which seems to be the case when I call rake -T, the gem wouldn't be Bundler.require-d, and the rake tasks wouldn't be loaded.
The fact that it isn't including the :development group seems to be an odd Bundler "gotcha", but at least now I know that moving it to the default group solves the issue and it's not a problem with the gem.
in my case, the project requiring the gem had a rake file, and the gem I was requiring had the same name when I changed the name of the rake file I could see the tasks in the project.
my_gem had lib/tasks/XXXX.rake and my_proj also had lib/tasks/XXXX.rake,
after I changed my_gem XXXX.rake to YYYY.rake I managed to list and use the tasks in YYYY.rake

Rake cannot load such file cucumber

I'm trying to setup an application on a ubuntu VPS with rvm installed. The thin webserver works fine, but all the rake commands fails with same error message.
LoadError: cannot load such file -- cucumber/rake/task
I've this on my Rakefile:
require 'cucumber/rake/task'
I've tried with
gem install cucumber
gem install guard-cucumber
gem install cucumber-rails
gem install rake
bundle exec rake db:migrate
Nothing seems to work
#which ruby
/home/ubuntu/.rvm/rubies/ruby-2.0.0-p353/bin/ruby
#which rake
/home/ubuntu/.rvm/gems/ruby-2.0.0-p353#search-demo/bin/rake
What else could be or how I can debug this?
You can check the load path printing the $: var. check if you have the cucumber gem there and if it match the version that you have on your local machine, where I suppose is working.
If the gem path is not there, be sure it is installed with
gem list | grep cucu
Also compare versions with your local environment.
Check your Gemfile, make sure you dont have those gems on a group :development block or similar, cause you have probably set RAILS_ENV in your vps to production.

Load gems inside scripts run from the shell outside our Rails application directory?

We have a mail gem installed in our vendor/cache directory inside a Rails application.
The script is called "test" and is not inside the Rails application directory.
#! /usr/local/rvm/wrappers/ruby-1.9.3-p194/ruby
require 'date'
require 'fileutils'
require 'openssl'
require 'yaml'
require 'mail'
require 'dalli'
I get the following error when I execute this script from outside the Rails application.
/usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mail (LoadError)
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
I simply re-installed these gems (mail, dalli) in the standard Ruby path and it worked, but that's not ideal.
What do we need to so that these installed gems are found when we try to run this script outside of a Rails app? In other words, how do we specify the path to these gems?
Be sure that your gem are all declared in your Gemfile:
gem 'mail'
If you don't want them to be loaded by default, and load them only when needed, you can use the require statement that you are already using, and in your Gemfile add :require => false:
gem 'mail', :require => false
When you call your script from outside your Rails environment, and want to load the gems, prefix your script by bundle exec:
bundle exec my_script.rb
If you need to run your script from another location than your rails's app root, you must run:
BUNDLE_GEMFILE=/path/to/your/app/Gemfile bundle exec your_script
Keep in mind though that this may cause path issues if your script or your gems are looking for file in the path of your rails app

Cannot load Gmail gem in console/app, but can in irb

I'm bewildered here. While I can run require "gmail" in irb and successfully load the Gmail gem, doing so in my rails console returns false. I made sure to include all the directories in $LOAD_PATH for irb in the $LOAD_PATH for my console, but still cannot get the gem to load in my console.
It may be that the gmail gem is conflicting with another gem that I have installed, but I don't know how to confirm this. It seems other people have had similar problems:
Why is autoload failing to load files for gems
Ruby autoload conflicts between gmail and parse_resource gems
Rails: Using ruby-gmail gem causes problems
I made sure to include 'gem "gmail"' in my Gemfile and run bundle install. Still no luck!
Stuck here, so would appreciate any help.
false doesn't mean that the gem is failing to load, it means that the gem is already loaded.
It the rails console could not find the gem you would get a LoadError. Here's an example of an app of mine that has gem 'haml' in the Gemfile.
1.9.2p320 :001 > require 'haml'
=> false
1.9.2p320 :002 > require 'foo'
LoadError: no such file to load -- foo
Another way to see this is to require 'gmail' a second time in your irb session.
You must add this line to your Gemfile:
gem 'gmail'
This is because the gems loaded by your application are restricted to just the ones specified inside the Gemfile, and their dependencies (and the dependencies of the dependencies, and so on).

Resources