在使用ruby on rails时,通常使用像rake db:migrate或rails g devise:install这样的终端命令,但是这些命令中的:到底是什么意思?在rake db:migrate中,migrate是一个参数还是其他什么?
rake db:migrate
rails g devise:install
:
migrate
332nm8kg1#
你可以把冒号看作是一个命名空间,在Rails的某个地方有一个rake任务文件,看起来像这样:
namespace db task :migrate do... .... end end
这是一种将相关任务组合在一起并防止它们与其他任务冲突的方法,这样你就可以使用devies.migrate,db.migrate,foobar.migrate等。
g2ieeal72#
就像Philip在他的答案中解释的那样,当使用rake时,冒号定义了名称空间/任务之间的分隔符当使用rails g(enerate)时,基本上是相同的,不同的是Rails生成器不是用rake的DSL定义的,而是类。但要回答你的第一个问题:在这两种情况下,结肠都起分隔作用,就是这样。在代码中,它唯一重要的作用就是拆分字符串:https://github.com/rails/rails/blob/4-0-stable/railties/lib/rails/generators.rb#L124你可以在官方的Ruby on Rails Guides中找到更多关于生成器和如何创建一个生成器的信息(这将帮助你理解它背后的机制//EDIT好了,让我们仔细看看生成器的查找过程:首先是Rails::Generators.invoke它接收CLI上传递的名称空间并将其拆分(使用冒号)
rails g(enerate)
Rails::Generators.invoke
names = namespace.to_s.split(':')
然后,它通过将所传递的名称空间的最后一部分(实际的生成器名称)和再次用冒号连接的剩余部分(名称空间路径,在我们的示例中为 * device *)传递到Rails::Generators::Base.find_by_namespace来获取相应的类
Rails::Generators::Base.find_by_namespace
if klass = find_by_namespace(names.pop, names.any? && names.join(':'))
这个方法将再次连接base(命名空间路径)和name(生成器名称),并将其推送到数组中:
lookups = [] lookups << "#{base}:#{name}" if base
之后,它调用Rails::Generators.lookup,Rails::Generators.lookup将查找要为调用的生成器调用的类:
Rails::Generators.lookup
lookup(lookups)
它将再次调用Rails::Generators.namepaces_to_paths这个方法没有什么特别的,它只是返回一个数组,其中包含了被调用的生成器的两个可能的源路径,在我们的例子中,这两个路径是“device/install/install”和“device/install”。因此,这些不是rails要检查的实际路径,它们只是依赖于namespace:generator构造的部分路径。lookup方法现在将接受这两个路径,我们称之为subpath,并在以下位置检查需要的文件:1.轨道/生成器/设计/安装/安装_生成器1.生成器/设计/安装/安装_生成器1.轨道/生成器/设备/安装_生成器1.发生器/设备/安装_发生器在我们的例子中,第二个路径是所需的文件,rails需要它,通过它inherited(更多关于Rails::Generators::Base上的callback的信息)将被调用,因为Devise::Generators::InstallGenerator是从它继承的。这将把类添加到Rails::Generators的subclasses数组中,该数组被Map到格式为{ namespace =〉klass }的哈希,因此rails最终能够获得所需的生成器类x1米11米1x然后启动它klass.start(args, config)
Rails::Generators.namepaces_to_paths
lookup
inherited
Rails::Generators::Base
Devise::Generators::InstallGenerator
Rails::Generators
subclasses
klass.start(args, config)
2条答案
按热度按时间332nm8kg1#
你可以把冒号看作是一个命名空间,在Rails的某个地方有一个rake任务文件,看起来像这样:
这是一种将相关任务组合在一起并防止它们与其他任务冲突的方法,这样你就可以使用devies.migrate,db.migrate,foobar.migrate等。
g2ieeal72#
就像Philip在他的答案中解释的那样,当使用rake时,冒号定义了名称空间/任务之间的分隔符
当使用
rails g(enerate)
时,基本上是相同的,不同的是Rails生成器不是用rake的DSL定义的,而是类。但要回答你的第一个问题:在这两种情况下,结肠都起分隔作用,就是这样。
在代码中,它唯一重要的作用就是拆分字符串:https://github.com/rails/rails/blob/4-0-stable/railties/lib/rails/generators.rb#L124
你可以在官方的Ruby on Rails Guides中找到更多关于生成器和如何创建一个生成器的信息(这将帮助你理解它背后的机制
//EDIT好了,让我们仔细看看生成器的查找过程:
首先是
Rails::Generators.invoke
它接收CLI上传递的名称空间并将其拆分(使用冒号)
然后,它通过将所传递的名称空间的最后一部分(实际的生成器名称)和再次用冒号连接的剩余部分(名称空间路径,在我们的示例中为 * device *)传递到
Rails::Generators::Base.find_by_namespace
来获取相应的类这个方法将再次连接base(命名空间路径)和name(生成器名称),并将其推送到数组中:
之后,它调用
Rails::Generators.lookup
,Rails::Generators.lookup
将查找要为调用的生成器调用的类:它将再次调用
Rails::Generators.namepaces_to_paths
这个方法没有什么特别的,它只是返回一个数组,其中包含了被调用的生成器的两个可能的源路径,在我们的例子中,这两个路径是“device/install/install”和“device/install”。
因此,这些不是rails要检查的实际路径,它们只是依赖于namespace:generator构造的部分路径。
lookup
方法现在将接受这两个路径,我们称之为subpath,并在以下位置检查需要的文件:1.轨道/生成器/设计/安装/安装_生成器
1.生成器/设计/安装/安装_生成器
1.轨道/生成器/设备/安装_生成器
1.发生器/设备/安装_发生器
在我们的例子中,第二个路径是所需的文件,rails需要它,通过它
inherited
(更多关于Rails::Generators::Base
上的callback的信息)将被调用,因为Devise::Generators::InstallGenerator
是从它继承的。这将把类添加到
Rails::Generators
的subclasses
数组中,该数组被Map到格式为{ namespace =〉klass }的哈希,因此rails最终能够获得所需的生成器类x1米11米1x
然后启动它
klass.start(args, config)