What is the logic behind tasks in Rake versus under `rails` - ruby-on-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

Related

Bundler is using a binstub that was created for a different gem.

When I run a rails console using
rails console
everything is fine.
When I run a rails console using
bundle exec rails console
I get the following warning
Bundler is using a binstub that was created for a different gem.
This is deprecated, in future versions you may need to `bundle binstub my_gem` to work around a system/bundle conflict.
my_gem happens to be a gem that I've created that is completely unrelated and not used in the current project directory.
I've tried every solution in this question with no luck:
Bundler is using a binstub that was created for a different gem
I would appreciate any guidance on removing this warning or help understanding how binstubs work so that I can figure out what's going on.
Nowadays it's common for projects to have "specialized" versions of tools. E.g. in some projects the "rails" command may be expected to be run using "spring" (to start up faster).
So it's not uncommon to generate files in your project's 'bin' directory, and then use those versions when running commands, so e.g. instead of
bundle exec rails console
or
bundle exec spring rails console
you could simply expect the following to work correctly
bin/rails console
and not care whether the project needs spring or bundler or zeus or whatever.
So if you don't have 'bin/rails' in your project, you should generate one that suits the project, e.g. using
bin/rake rails:update:bin
If you don't already have bin/rake, you might have to use
bundle exec rake rails:update:bin
(so your bin/rake commands will also get a speedup from using spring)
Some people even put ./bin in their paths, so whenever they run rake (or whatever) they are actually running ./bin/rake if it exists.
Troubleshooting
for project specific tasks, use bin/* files, creating them if needed (e.g. using special rake tasks like in Rails or using bundle binstub <gemname>) - usually those have Bundler specific lines that will make Bundler happy.
for non-project gems (like your gem), find out where it is (e.g. which mygem) and check out it's contents - it's probably using e.g. "bundler/setup" which is confusing Bundler (because bundler expects a local Gemfile file). Maybe your gem is using bundler (it shouldn't if it's a "global" kind of tool and not a "project" tool).
Also, if you're using them, check if tools like RVM and .rbenv are correctly adding their stuff to your bin files (they usually need to setup specific paths)
If you still have questions, it's best to post the contents of the bin file causing problems - it's meant to be a plain Ruby file, so if there's something wrong, it's usually because of the file contents (and not anything else).
More info: https://github.com/sstephenson/rbenv/wiki/Understanding-binstubs
It happened in a project of mine. Because I ran bundle install with another ruby version.
Make sure your rvm is the correctly ruby version.

Running bin/rails generate don't work

Im following a rails tutorial, and when im supposed to run the command: 'bin/rails generate model Article'. An error occurs saying that there isnt such a command.
I'm using 'command prompt with ruby on rails' and in the rails project i can find a Bin folder. Am also using windows 7.
Also What is the difference between running only 'rails generate' instead of running 'bin/rails generate'?
Using rails generate is fine if you have no bin stubs (binaries in the root /bin folder of your project). If you do have bin stubs then it's preferred to use them because they may do additional things specific to your project. But even then, it's (probably) fine to just use rails generate still. The other bin stubs may be a little more necessary to use, though (again, if present) because they tend to be shortcuts to e.g. bundle exec rake.
Rails 4.1 ships with bin stubs. That is, when you generate a Rails 4.1 project it generates bin stubs for you. So this is probably why your tutorial mentioned using them -- they're now there by default. But if you're on an older version of Rails that won't help you much.
The big reason Rails 4.1 includes bin stubs is because Rails uses spring by default now. Spring is an application preloader... that makes it so that when you call e.g. bin/rake ... it will load and keep a running rails environment in the background and then, the 2nd time you call bin/rake it will fork from the running environment giving you almost instantaneous response. So this is an example of "additional things specific to your project" that you get from using bin/rake over just rake and bin/rails over just rails.

difference between running rake command with and without bundle exec

What is the major difference between running the rake command with and without bundle exec?
I have seen few posts stated that when you run the command with bundle exec then it will be run on scope of the gems version defined in the gem file. If that is the case, then it should be mandatory to run rake command with bundle exec?
bundle exec rake some:task runs the rake task within the context of your bundle.
You didn't explicitly mention Rails but i see you're post is tagged with Rails so a contrived example of this in action might be the following:
You have version 2.0 of the fictitious whateva-whateva gem installed on your system for some valid reason.
You decide you want to pull down an old Rails project from somewhere to check it out and run bundle install within the cloned project's root folder. That command will install all of the gems that the Rails app requires and one of them happens to be verison 1.0 of the fictitious whateva-whateva gem.
So the current state is this: your old rails app has a gem bundle that includes an older version of the whateva-whateva and your systemwide gems include a newer version of the whateva-whateva gem.
When you run rake tasks associated with your Rails app, which version do you want loaded? The older one of course.
In order to do this you can use bundle exec rake the:task and it runs the rake command within the context of your bundle -- the older version of the gem plus whatever other stuff was specified in the old rails app's Gemfile.
So yeah after all that, i think it's safe to say that BEST practice would be that you should always prepend bundle exec but to be honest I'm pretty lazy and rarely do it unless I see problems.
In other news, if you use Bundler's binstubs you don't need to add it. Here's a link to setting that up: https://thoughtbot.com/blog/use-bundlers-binstubs
BUNDLE_GEMFILE=/path/to/gemfile bundle exec can be used to precede any command (if BUNDLE_GEMFILE is not specified it searches up the file system and uses the first one it finds), not just rake.
Any command you run may invoke executable Ruby commands (such as rake) or require code from Ruby libraries (such as the Rake::Task class), and these things are typically provided by gems. gem env tells you where the gem-provided libraries and executables are. However if you use bundle exec it restricts the available gems to those specified in the Gemfile.lock file associated with the Gemfile your bundle exec context is using.
Using all the available gems on your machine (which can happen if you don't do bundle exec) can be undesirable for a couple reasons:
You may have incompatibilities in your full gem set.
It's harder to tell exactly what gems you're using, adding some unpredictability to your working environment.
Here's a quick way to see the difference.
gem install thin
Create a directory foo with two files: an empty Gemfile and a file foo.rb with the contents:
#! /usr/bin/ruby (or whatever the path to your system Ruby is)
require 'thin'
Make foo.rb executable.
Note that running thin and ./foo.rb from the command line both work, but preceding either with bundle exec will not work.
If you use bundle exec before any command in rails, It will search for the Gems Which are mentioned in our Gemfile, in application home folder.
Suppose, You have 2 applications, and using different ruby versions for each of them.
Without bundle exec the command might be failed to run, as it may take different version Gem to run that task. But If you start using bundle exec It will take the exact gem version to run the task/application.
I recommend you to use **bundle exec** before any command.
bundle-exec - Execute a command in the context of the bundle
This command executes the command, making all gems specified in the Gemfile(5) available to require in Ruby programs.
It's not for the only rake, instead applicable for rails, rspec, rackup command too.
Essentially, if you would have normally run something like rspec spec/my_spec.rb, and you want to use the gems specified in the Gemfile(5) and installed via bundle install(1), you should run bundle exec rspec spec/my_spec.rb.
Note that bundle exec does not require that an executable is available on your shell's $PATH.
For more detail, have a look to bundle exec doc.

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.

Rake vs. Warbler in Ruby?

I have used Warble to make .war files. That worked pretty well.
Some of the tutorials online suggest using the "rake" command at various times. If rake is for compilation, I thought Ruby didn't need compilation. Is it a substitute for Warble? Or do these two play different functions?
When is rake meant to be used?
Rake is a tool written in Ruby for automating tasks, which you also write using a Ruby syntax. Ruby program's don't have to be built, but there are still plenty of other tasks involved in development that you can automate instead of doing yourself each time.
Some examples from Rails include migrating your database to a new schema or creating a new database.
Rake lets you write tasks with a Ruby syntax, and you can also specify dependencies between tasks, so that running one task will cause all of its dependencies to be ran first.
Think of rake as a make for Ruby. For example for one of the gems I develop, the Rakefile includes several tasks, like running all the tests (rake test) or building the gem (rake gem:build). More info on the web site:
http://rake.rubyforge.org/

Resources