rbenv:没有宝石的幸存

Noa*_*man 43 ruby rubygems ruby-on-rails bundler rbenv

TL; DR

  • 不要打扰宝石; 可以同时安装多个版本的gem.
  • 必要时,使用$ gem-based-binary _version_ args表示法指定要执行的版本.
  • 使用bundle exec指定版本的Gemfile时使用.
gem install rails -v 3.2.13
rails _3.2.13_ new Project2
cd Project2
bundle exec rails server
Run Code Online (Sandbox Code Playgroud)

更新时间: 2015-06-04

我三年前写过这个问题.部分地,它是基于错误的假设,部分情况从那时起发生了变化.感谢@indirect的原始答案,我想提请注意@kelvin的更新(不太热烈)的答案,如上所述.

我的错误假设:一次只能安装一个gem的单个版本,因此需要gemsets来隔离命名空间.不对.可以同时安装多个版本的gem.从命令行调用时将使用最新的一个,除非您有一个Gemfile指定版本约束并通过命令调用命令bundle exec,或指定版本作为其第一个参数.

另请参阅如何从命令行调用旧版本的gem?re:下划线版本表示法.


原始问题:

我有多个项目正在使用不同版本的Rails.我有一个工作流程(如下所述),用于使用特定版本的rails创建项目,并保持项目彼此隔离.我想尝试其他工作流程,特别是使用rbenv而不是RVM,但目前尚不清楚如何这样做.

问题:当使用rbenvbundler而不是rbenv-gemset或rvm 时,创建多个rails项目 的最佳当前实践是什么,每个项目使用不同版本的rails .

用例: 我有两个rails项目,名为ProjectA和ProjectB.ProjectA是使用一个版本的rails("RailsA")开发的,而ProjectB使用不同的版本("RailsB").如何安装两个版本?

GEMSETS方法: 当我第一次开始使用Rails开发时,我使用了RVM.除了支持多个并发安装的ruby之外,RVM还支持具有多个命名宝石集.每个项目都有自己独立的宝石集合(包括rails本身),称为gemset:

rvm gemset create RailsA
rvm gemset use RailsA
# RailsA.  Note: My question is not version-specific.
gem install rails --version 3.0
rails new ProjectA
cd ProjectA
rvm --rvmrc use `rvm current`
vi Gemfile
bundle install
cd ..
## Now do the same for ProjectB
rvm gemset create RailsB
rvm gemset use RailsB
gem install rails --version 3.2
rails new ProjectB
cd ProjectB
rvm --rvmrc use `rvm current`
vi Gemfile
bundle install
Run Code Online (Sandbox Code Playgroud)

注意:项目文件夹的创建应该由rails new使用所需版本的rails 的命令完成(IMHO),因为框架文件从版本更改为版本.(也许我应该重温这个前提?)

BUNDLER方法:我一直在玩rbenv而不是RVM,但我不明白工作流程.在README.md中,Sam Stephenson写道"rbenv不管理gemsets .Bundler是管理应用程序依赖性的更好方法." 有一个插件(rbenv-gemset)可以获得与rvm的gemsets相同的结果,但Sam显然更喜欢使用Bundler.不幸的是,他没有详细说明工作流程的样子.甚至Bundler网站也没有明确地将如何将一个项目与另一个项目隔离开来.几个博客 要点来救援,建议以下~/.bundle/config文件:

---
BUNDLE_PATH: vendor/bundle
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,我不确定"---"是什么.文档没有提到它,它似乎没有什么区别.)

这有效地为每个rails项目提供了自己的gemset,将gem存储在ProjectX/vendor/bundle /中.实际上,rails(自动)将在那里(重新)安装,一旦我运行,使项目完全独立于我的环境的其余部分bundle install.

房间里大象首先创建rails项目文件夹的鸡蛋问题! 为了使用RailsA创建项目A文件夹,我需要安装导轨(及其众多依赖)第一.但是当我想创建ProjectB时,我必须切换到使用RailsB.没有gemsets,我必须做一些严肃的升级/降级.不酷.

一个可能的解决方案是不要担心我用来创建ProjectX文件夹的rails版本.如果我然后使用rails 3.0创建一个3.2项目,我可以手动创建app/assets树.但那只会让我感到烦恼.有没有更好的方法?

ind*_*ect 42

大多数人通过首先安装rails gem来解决这个问题gem install rails.如果由于某种原因拒绝这样做,您可以选择退出Rails尝试为您执行的自动捆绑.无论您的ruby管理系统如何,这都将完全有效.

mkdir myapp
cd myapp
echo "source :rubygems" > Gemfile
echo "gem 'rails', '3.2.2'" >> Gemfile
bundle install --path vendor/bundle
bundle exec rails new . --skip-bundle
Run Code Online (Sandbox Code Playgroud)

出现提示时,键入"y"将Gemfile替换为默认的Rails(根据需要,不是).然后,一旦完成:

bundle install
Run Code Online (Sandbox Code Playgroud)

你已经完成了,你已经使用你选择的版本增加了一个新的rails应用程序而无需将rails gem安装到rubygems中.

  • 与此解决方案无关,但从不编辑.bundle/config文件.如果要隔离项目的gem,请使用`bundle install --path vendor/bundle`. (3认同)
  • 现在你可以调用`rails _3.1.2_ new ... blablabla ...`. (3认同)
  • `〜/ .bundle/config`是Bundler的内部实现细节.我们用它来记住传递给安装的标志,比如`--path vendor/bundle`.您不应该自己编辑它,因为如果您这样做,可能会发生不受支持的事情.:)三重破折号是因为它存储为YAML文件.我特意建议使用--skip-bundle,以便跳过`bundle install`的失败自动运行.我相信它失败了,因为这些命令如何引导rails gem. (2认同)

Kel*_*vin 12

假设您已安装rails 3.1.0,但您想使用未安装的rails 3.2.13创建新项目.

假设您想要新项目~/projects/Project2.

gem install rails -v 3.2.13
cd ~/projects
rails _3.2.13_ new Project2
Run Code Online (Sandbox Code Playgroud)

这将为Gemfile您创建,锁定您在命令行上指定的rails版本.

我故意省略了为新项目保留单独的宝石副本的想法,因为这违背了Bundler哲学,即将所有宝石安装在一个地方.当您运行rails时,Bundler将从该中心位置自动选择正确的gem版本.这意味着项目可以共享宝石,而不是为自己安装新的副本.(请注意,您安装的每个版本的ruby都有自己的gem.这是一件好事,因为原生扩展可能无法在ruby版本中运行.)

您必须要更加清楚,因为大多数命令rake都会加载rake您安装的最新版本.您需要运行bundle exec rake ...以确保加载了正确的版本.通常我会运行bundle exec所有命令,除了rails.你可以创建一个别名来缩短它(我使用bex).要使用gem可执行文件自动执行此操作,您可以使用rbenv-binstubs,但仍需要注意运行非gem可执行文件,ruby并且irb不会自动使用Gemfile.

旁注:rails new将运行bundle install,它将检查最新版本的依赖项.如果您希望bundler尝试使用满足依赖性要求的当前安装的gem,则可以跳过bundle installwith rails new --skip-bundle,然后bundle check在app dir中运行.

旁注2:假设您要使用Project2的ruby版本(例如2.1.8),它与默认版本不同(例如2.3.0).在这种情况下,gem install按照上面的说明运行将在2.3.0下安装宝石,这是浪费时间,因为你需要在2.1.8下再次安装宝石.要解决该问题,可以强制命令通过环境变量使用首选版本:

RBENV_VERSION=2.1.8  gem install rails -v 3.2.13
cd ~/projects
RBENV_VERSION=2.1.8  rails _3.2.13_ new Project2
echo 2.1.8 > Project2/.ruby-version
Run Code Online (Sandbox Code Playgroud)

可以使用rbenv shell设置变量,但我建议如果您不希望rbenv在.ruby-version该shell的持续时间内基于文件自动切换.很容易忘记你有变量集,当你cd到另一个项目时,它将不会使用你期望的版本.


Max*_*Max 8

关于gemsets/bundler的主题,最近有一篇很好的帖子http://rakeroutes.com/blog/how-to-use-bundler-instead-of-rvm-gemsets/您可以应用于rbenv设置的良好背景.