使捆绑商使用不同的平台不同的gem

我正在将我们的Rails 2.3.8应用程序之一升级到Rails 3,并且已经遇到了捆绑器和部署的恼人的问题。 我在Windows机器上开发应用程序,但生产环境正在运行Ubuntu Linux。 现在,我的问题是bundler忽略了生产环境中的mysql gem,而Passenger吐出来: “!!!缺lessmysql gem。将它添加到你的Gemfile:gem'mysql','2.8.1'”

这是我的Gemfile

 # Edit this Gemfile to bundle your application's dependencies. # This preamble is the current preamble for Rails 3 apps; edit as needed. source 'http://rubygems.org' gem 'rails', '3.0.0' gem 'net-ldap', :require => 'net/ldap' gem 'highline', :require => 'highline/import' gem 'mysql', '2.8.1' gem 'net-ssh', :require => 'net/ssh' # Bundle gems for the local environment. Make sure to # put test-only gems in this group so their generators # and rake tasks are available in development mode: group :development, :test do gem 'fakeweb', :require => 'fakeweb' gem 'flexmock', :require => 'flexmock/test_unit' end 

正如你所看到的, mysql gem是指定的。 但是,在部署时,捆绑器会忽略它。 为什么? 原因是Bundler生成以下Gemfile.lock (仅包括相关部分):

 .... mime-types (1.16) mysql (2.8.1-x86-mingw32) net-ldap (0.1.1) .... 

请注意,它包含平台特定的gem。 这显然不是我想要的,因为在Linux下运行时,gem是不合适的(而且显然被忽略)。

那么Bundler有没有办法解决这些问题呢? 或者我必须记得手动更改生成的Gemfile.lock每一次我的开发机器上运行软件包安装的MySQL gem版本?

先谢谢你!

更新

捆绑商团队似乎知道这个问题 。

这是Bundler中的一个已知问题 。 解决方法是:

  • 在与生产环境相似的系统上生成Gemfile.lock,以获得与生产平台匹配的结果。 实际上,这意味着如果生产系统是Windows,则只能在Windows上生成Gemfile.lock文件。
  • 根本不要提交Gemfile.lock文件,并在部署时确定生产计算机上的依赖关系(不使用–deploy进行bundle install )。 虽然通常不推荐,但这是一个经常使用的解决方法,直到错误被修复。 例如,这是Heroku提供的推荐解决scheme。
  • 切换到JRuby,它将在Windows和Linux( java )上具有相同的平台string。 我不推荐这个认真的,但我相信它会解决这个问题。
  • 修复Bundler源代码中的问题,即帮助Bundler团队修复这个bug。 🙂

我有一个类似的问题。 我想能够在我的Gemfile中写下这样的东西:

 platforms :ruby do # linux gem 'nokogiri', "1.5.0.beta.2" end platforms :mswin do gem 'nokogiri', "1.4.4.1" end 

但是,捆绑商告诉我,我不被允许。 所以,我的解决方法,在这个特定的情况下工作是指出一系列的版本:

 gem 'nokogiri', ">= 1.4.4.1", "<=1.5.0.beta.2" 

其中 – 目前 – 给我的Windows计算机上的1.4.4.1版本和我的Linux计算机上的1.5.0.beta.2。 也许你可能会写一个类似丑陋的解决方法;-)

我们Engine Yard的工程师已经向Bundler提交了一个补丁来解决这个问题,并且在不同的平台上解冻这些gem。 在运行RailsInstaller演示教程之后,我们遇到了很多Windows试图部署的问题。 我们发现的最好的解决方法是执行以下操作:

  1. 在你的开发机器上像正常一样bundle install
  2. 检查Gemfile.lock ,如果有-x86-mingw32任何行,请删除该部分。
    • bcrypt-ruby (3.0.1-x86-mingw32)变成bcrypt-ruby (3.0.1)
  3. Gemfile.lock的“Platforms”部分下添加ruby
  4. 确保使用平台标志在Gemfile明确指定所需的gem。 (不知道这是否需要,但不会伤害)
    • Gemfile :` Gemfile -ruby','〜> 3.0',:platform =>'ruby'
  5. 再次bundle install ,保留bcrypt-ruby (3.0.1)行,并重新添加到bcrypt-ruby (3.0.1-x86-mingw32)

如果你对Bundler补丁很好奇,你可以在https://github.com/carlhuda/bundler/pull/1451

希望这可以帮助任何人仍然在寻找答案。

我认为这个问题是MySQL的gem没有正确发现所需的标题。 你可以通过转移到使用mysql2 gem来解决这个问题,你只需要在database.yml更新你的数据库适配器以便ActiveRecord集成。

此外,如果绝对必要,您可以将构build标志传递给C扩展gem:

bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

我之前遇到过这个问题,并且使用mysql2 gem确实可以解决这个问题。 我知道那不是你要找的答案,而是把它和迭戈的答案结合起来,你是金。

你有没有尝试使用rvm ( 链接在这里 )? 它可以安装孤立的Ruby虚拟机和Gemset,所以你可以使用一个更像你在生产环境中的环境。 我真的不知道这是否能解决你的问题,但值得一试。

无论如何,我知道这不是你想听到的答案,但恕我直言,Windows不是在Rails中开发的最好的平台。 我最近买了一台MacBook,主要是为了开发Rails应用程序,这让您免于很多麻烦。 你也可以在你的开发机器上安装Linux并使用它,比使用Windows端口或Cygwin更好。

不要提交Gemfile.lock和你的gem生产。 您必须在生产环境中再次运行bundler install

你可以做这样的事情:

 platforms :ruby do gem "sqlite3-ruby", :require => "sqlite3", :group => [:development, :test] end platforms :jruby do gem 'activerecord-jdbc-adapter', :require => false gem "jdbc-sqlite3", :require => false end 

顺便说一句,你应该把你的Gemfile.lock到版本控制,因为这样所有的机器将运行相同的gem版本的应用程序。

我遇到了这个问题,最后写了脚本来完成这个痛苦的任务。 http://gouravtiwari.blogspot.com/2011/03/development-on-windows-deploying-to.html