从Ruby on Rails开始。在指定要下载的版本时,Gemfile以及gems如何工作?

时间:2012-03-20 04:05:26

标签: ruby-on-rails ruby rubygems gem version

我试过阅读文档,但这对我来说还不清楚:

假设我的Gemfile中有以下语句:

source 'https://rubygems.org'

gem 'rails', '3.2.2'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'

gem 'json'

...

我正在尝试学习如何在这个网站上使用Ruby on Rails:http://ruby.railstutorial.org/并且它说我需要为此版本的rails(3.2.2)拥有sqlite3 gem。

我的问题是:如果我在运行sqlite3时没有为系统指定bundle install gem的确切版本,那么它是否会安装适用于版本的最新版本我正在使用的rails和ruby(假设它分别是3.2.2和1.8.7 p-352)或者它是否只是下载最新版本的sqlite3 gem,无论它是否与我安装的内容一起使用?

我不确定Gemfile的这个方面是如何运作的,文档还不清楚,或者我没有找到明确说明这个或其他的地方。

3 个答案:

答案 0 :(得分:3)

因此,它将安装最新版本的sqlite3,它与您列出的其他gem指定的依赖项兼容。

比如说,rails表示只能使用大于1.0但小于4.0的sqlite3,它可能会安装3.9.5。我正在制作所有这些数字,只是一个例子。

实际上,我不知道rails 是否指定了它需要的任何特定版本的sqlite3。据推测,'json'也没有,因为它与数据库无关。如果您列出的其他任何宝石都没有指定sqlite3的任何要求,那么它只会安装最新版本。

'bundle install'正在使用bundler,有关它如何解析依赖关系的更多信息是here

因此,bundler将下载符合您列出的所有其他宝石要求的最新宝石。假设您列出了一个需要早于2.0的sqlite3的宝石A和一个需要2.1之后的sqlite3的宝石B - '捆绑安装'会抱怨并说它不能满足所有要求。

这依赖于宝石自己对他们所依赖的其他宝石的每个要求的广告。有时他们可能是错的,或者是错过的。可能是rails实际上没有指定它需要的sqlite3版本 - 因为它实际上并不是需要 sqlite3(你不必使用带有rails的sqlite),这可能非常好。在这种情况下,捆绑包不能做太多但是获得最新版本的sqlite3。这并不能保证版本能够正常运行。但它只能做这么多。

您还提到了与特定版本的ruby兼容的问题,例如1.8.7-p352。 Bundler在那里的能力较差,你不能指望它知道什么版本与特定版本的ruby兼容(因为没有很好的方式让宝石以捆绑者可以使用的方式来表达这一点,唉)。

但是在 general 中,事情就会成功。如果你不知道或不关心你想要什么版本的sqlite3(或任何其他宝石),但知道你想要一个 - 做你做的,运行'bundle install',看它是否有效。它可能会。如果没有,请查看错误消息,您可能会找到某人解释为什么不这样做以及您需要做什么。

PS:如果那还不够。 sqlite3有点奇怪,因为虽然Rails设计用于它,但它不是必需的。但是Rails默认情况下,在创建具有最新版本的rails rails new my_app的新应用程序时,已经已经将sqlite3放入您的Gemfile中。它就像你一样,没有版本约束。这是有理由相信它能很好地工作。请注意,在rails 3.2.2中,rails new my_app会在您的Gemfile中添加一些列出更多特定版本的内容,例如gem 'sass-rails', '~> 3.2.3',因为虽然这些不是Rails绝对需要(或者它们表示为需求而不需要在应用程序的Gemfile中明确表示),rails安装程序知道只有某些版本才能运行。

答案 1 :(得分:1)

Rails相当新,所以如果我错了,请纠正我。

Gemfile在gems目录中查找列出的gem,并且对实际“安装”它们没有影响。执行不带版本的“gem install”命令将获取列出的最新版本,无论您的Gemfile是什么。当您“捆绑安装”时,即在您的gems目录中发生特定于版本的查找。

答案 2 :(得分:1)

当您正在执行Gemfile.lock时,Bundler会始终首先查看您的bundle install文件。如果您打开该文件,您将看到宝石以及您的应用程序使用的版本。这对于现有项目来说非常方便,因为您始终确保参与该项目的所有其他开发人员都将使用相同的gem版本。

如果找不到该文件(即执行rails new projectname),或Gemfile中的指定gem或版本与Gemfile.lock不一致,则会下载最新或指定版本的gem。