Вопрос

When working with ruby on rails it is common to use terminal commands like rake db:migrate or rails g devise:install. But what exactly does the : in these commands mean? In rake db:migrate is migrate a parameter or something else? It doesn't seem like a hard question, but after several hours researching on Google and not finding an answer, I would really like someone to explain that to me, please.

Это было полезно?

Решение 2

Like Philip explained in his answer when using rake the colon defines the seperator between namespaces/tasks

When using rails g(enerate) it's basically the same. The difference is that Rails generators aren't defined with rake's DSL, instead they're classes.

But to answer your initial Questions: The Colon works as seperator, in both cases, that's it.

In the code the only thing what it's important for is splitting up the string: https://github.com/rails/rails/blob/4-0-stable/railties/lib/rails/generators.rb#L124

You can find some more infos about generators and how to create your one ones (which definetley will help you understanding the mechanics behind it) in the official Ruby on Rails Guides

//EDIT Ok, let's take a closer look at the generator lookup process:

First of all there is Rails::Generators.invoke

It receives the namespaces passed on the CLI and split's it up (using the colon)

  names = namespace.to_s.split(':')

then it get's the according class by passing the last part of the passed namespace (the actual generator name) and the remaining part joined with a colon again (the namespace path, in our case it's devise) to Rails::Generators::Base.find_by_namespace

  if klass = find_by_namespace(names.pop, names.any? && names.join(':'))

This method again will join the base (namespace path) and name (generator name) and push it to an array:

lookups = []
lookups << "#{base}:#{name}"    if base

after that it calls Rails::Generators.lookup which will lookup the classes to invoke for the called generator:

lookup(lookups)

which will again will call Rails::Generators.namepaces_to_paths

There's no big magic in that method, it'll simply return an array of two possible source paths for the invoked generator in our case these two are "devise/install/install" and "devise/install".

Whereby those aren't the actual paths rails will check, they are only the part's of it that are depend on the namespace:generator construct.

The lookup method will now take those two, let's call them subpaths, and check for files to require at the following places:

  1. rails/generators/devise/install/install_generator
  2. generators/devise/install/install_generator
  3. rails/generators/devise/install_generator
  4. generators/devise/install_generator

in our case the second path is the desired file, rails require's it and through that the inherited (more about that callback callback on Rails::Generators::Base will get called since Devise::Generators::InstallGenerator inherits from it.

This will add the Class to the subclasses array of Rails::Generators which is mapped to an Hash which will have the format { namespace => klass } and so rails is finally able to get the desired Generator Class

klass = namespaces[namespace]

and start it

klass.start(args, config)

Другие советы

You can think of the colon as a namespace. Somewhere within Rails there is a rake task file that looks similar to this:

namespace db
  task :migrate do...
    ....
  end
end

It's a way to group related tasks together and prevent them from colliding with other tasks. This way you could potentially have devise:migrate, db:migrate, foobar:migrate, etc.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top