Calling an external rake task from Rails: dependency issues - ruby-on-rails

I am currently developing a standalone ruby application alongside a Rails application that works as its frontend. I am managing the dependencies of the Ruby app with Bundler, so there are two gemfiles.
I have a problem trying to execute the Ruby application from the Rails frontend via a system call to a rake task.
When I call the rake task from a standard IRB, it works; but if I try to call the task from a Rails controller or the rails console, dependency issues arise.
As a workaround I can add all the gems not present in the Rails application to the Rails Gemfile, but I guess this approach is wrong.
I think it might be a problem with the scope of Bundler. How could I work around this problem?
Thanks.

fork do
Dir.chdir("/your/project/dir")
ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', __FILE__)
Bundler.setup
exec "rake -T"
end

Related

What is the difference between rails console and bundle console?

Can anyone explain me or give me a resource where I can learn the differences between rails console and bundle console? Is there way to load all the gems automatically in irb instead of require gem?
Here is a good explanation: What's the Difference Between irb, bundle exec irb, bundle console, and rails console?
irb is the basic Ruby console. It ignores your Gemfile, and only core
Ruby classes are accessible without require-ing them. It can’t easily
load gems that Bundler installs outside of RubyGems’ load path.
bundle exec irb is like irb, if you also required bundler/setup. You
can only easily require gems that are in your Gemfile.lock, but you
can load those gems no matter where Bundler put them.
bundle console is like bundle exec irb, if you also called
Bundler.require. All of the gems in your Gemfile, except the ones
marked require: false, can be used without requiring them. It’s really
convenient when you’re writing your own gems, or working on non-Rails
code.
rails console is like running bundle console inside a Rails app, if
you also required config/environment.rb. You can play with your entire
Rails app, autoloads and database connections work, and everything’s
hooked up the way you’d expect. If you’re working in a Rails app, this
is the most helpful kind of console.
The answer from Aleksandr is great.
I just wanted to add there is also the option for running
bundle exec rails console
which combines everything from rails console and bundle exec irb answer from Aleksandr's answer.

Upgrade from Rails 3 to Rails 4 - Issues with activerecord-sqlserver-adapter 4.1.0 and rails 4.1.4 "Rake Tasks Not Supported"

I'm trying to run rake tasks such as db:reset and getting the error "Rake tasks not supported by 'sqlserver' adapter."
I'm running ruby 2.1.2, rails 4.1.4, rake 10.3.2, and activerecord-sqlserver-adapter 4.1.0.
I've been using the adapter with Rails 3 and running db:reset without trouble, but now I'm trying to upgrade an app to Rails 4 and running into this problem. To isolate, I created an empty new Rails 4 app, added the adapter to the Gemfile, and updated database.yml to point to my SQL Server. I get the error above when I run rake db:reset.
I've tried setting up the workaround described in https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/wiki/Rails-DB-Rake-Tasks, with a minor adjustment to make it work with the latest versions of rake, but I still get the same error.
Am I doing something wrong, or is it just not possible to use tasks like db:reset with version 4 of rails and activerecord-sqlserver-adapter?
"As of 2.3.6 of the adapter, we are now compliant with the rake task interfaces in the :db namespace of rails. That means for new unix-based developers that are working with a non-legacy DB, accurately reflected by schema.rb, can now use the standard rake tasks for just about everything except actually creating the development/test databases.
The only problem is that the we have not yet committed patches upstream to rails to remove Windows specific command interpolation from their databases.rake task. So, we have to do two things to get you up and running. First, here is an extension to Rake that allows us to method chain tasks."
https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/wiki/rails-db-rake-tasks

What does the term "vendoring" or "to vendor" mean for Ruby on Rails?

Examples:
"Vendoring Rails application at test/dummy"
"What is the recommended way of vendoring Rails for production?"
Vendoring is the moving of all 3rd party items such as plugins, gems and even rails into the /vendor directory.
This is one method for ensuring
that all files are deployed to the production server the same as the dev environment.
Best way to do this is either:
rake gems:unpack
Or
rake rails:freeze:gems
Use rake -T to see a full list of rake tasks.

What is the logic behind tasks in Rake versus under `rails`

I try to grasp the logic behind some tasks being "rails" whereas others, the majority, is found as rake task. Why rails server and not rake server for example?
I can understand that the bootstrapping cannot be done in rake: after all, you first need a rakefile and other requirements before you can start using rake. So creating the project with a rails binary seems only practical.
But why generate, server, console, yet not migrate or assets? I don't see the logic. Is there any?
IMO the rails scripts are for "live" console usage, like during development.
The rake tasks are more "automated" tasks, for example, that might be run as part of a build or deploy cycle, like by a CI server. Some rake tasks might group rails/etc. commands together (like tests).
A rake script is a utility/build tool for some common tasks when developing. For example, you need to do deployment, run test, database stuffs, truncate log files, compile assets .... You can create your own custom rake scripts.
A rails script is ruby file located under script directory for the purpose of the gem rails. This is what the gem does. Rails is a ruby web framework, so the command rails is for starting the rails apps, go to rails console, generate files. It's bundled when you install the gem.
You can think of rails command like bundle command for bundler. bundle install, bundle update ... all are related to resolving gem dependencies. rspec command for running tests...
Some gems has an executable script such as rails, bundler, capistrano, whenever, rspec. Some other gems doesn't have such as builder, will_paginate....
You can check this out for how to add executable to a gem, http://guides.rubygems.org/make-your-own-gem/#adding-an-executable

Kernel.system call from rails

I am invoking a shell script using Kernel.system from my Rails controller. The shell script might invoke another Ruby script based on some conditions. This Ruby script requires the twitter gem. My Rails app is running in apache using Passenger. Now when this Ruby script is invoked from my Rails app, I get the following error in apache logs.
/var/www/webapps/test/twitter/twitter_post.rb:2:in `require': no such file to load -- twitter (LoadError)
from /var/www/webapps/test/twitter/twitter_post.rb:2
The same Ruby script runs fine from the Linux shell. Now, if I list the twitter gem in my Gemfile, it works perfectly. Kernel.system is supposed to invoke the commands in a subshell, so is Rails modifying any environment variables in its execution shell?
A subshell has the same environment as the process that spawned it, so the right thing is occurring here, since Bundler overwrites Ruby's load path with its own to ensure only the gems in the Gemfile get loaded.
If your app depends on this process running, and that process depends on the twitter gem, why is it not in your Gemfile anyway? Further, why are you executing Ruby in a subshell from Ruby in the first place? There's usually no reason you shouldn't just have that Ruby code within your app.
you should not be making a system call to another ruby script, you should require or include the contents of the other ruby script.
That being said, your current rubygems environment when you invoke the rails server will be that of the rails application's bundle. If the rails application's bundle does not include the gems that your other ruby script requires, then your other ruby script will not be able to require that library.
So, add to your rails app's Gemfile the the library that the other script is complaining it is missing and I think that should do ya.
In your external ruby script try:
require 'bundler/setup'
taken from bundler setup docs

Resources