Ruby on rails 如何在gem中运行Rails应用程序?

Ruby on rails 如何在gem中运行Rails应用程序?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我不确定这类事情是否很常见,但我一直在尝试创建gem,这些gem只是Rails应用程序的包装 我的gem将有一个生成器来创建config.ru,但是Rails应用程序将位于gem的lib目录中。我需要知道如何“嵌入”Rails应用程序并对其进行配置,以便它可以在gem中运行 例如: $ mygem new project mygem created a directory called "project" with the following files: project/config.ru

我不确定这类事情是否很常见,但我一直在尝试创建gem,这些gem只是Rails应用程序的包装

我的gem将有一个生成器来创建
config.ru
,但是Rails应用程序将位于gem的lib目录中。我需要知道如何“嵌入”Rails应用程序并对其进行配置,以便它可以在gem中运行

例如:

$ mygem new project

mygem created a directory called "project" with the following files:

project/config.ru
project/widgets/
project/foobars/
我的gem还将生成一些需要以某种方式添加到Rails中的目录,以便我可以从gem中的Rails应用程序访问这些目录中的代码

如果您能给我任何帮助或建议,我将不胜感激

为了澄清这一点,我没有尝试创建Rails引擎或Rails应用程序的插件。我正在尝试创建一个成熟的Rails应用程序,但将其打包为gem,这样我的gem用户就可以运行gem(Rails应用程序),而无需知道它在幕后使用Rails

更新:好的,我现在有点工作。我已经创建了gem,并在gem的lib目录中生成了rails项目

$ bundle gem my_gem && cd my_gem/lib
$ rails new my_gem --skip-bundle
这给我留下了:

my_gem/
  my_gem.gemspec
  bin/my_gem
  lib/
    my_gem.rb
    my_gem/
      version.rb # generated by bundler
      # the rails app:
      app/
      config/
      Gemfile
      ...etc
由于这个gem需要Rails,我开始在gem的gempec中将Rails Gemfile中定义的gem作为依赖项添加到gem中,但是对于如何处理Gemfile中的
assets
组,我有点困惑

# Rails Gemfile
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'therubyracer', :platforms => :ruby
  gem 'uglifier', '>= 1.0.3'
end

# gemspec
Gem::Specification.new do |gem|
  gem.name          = "my_gem"
  # ...
  gem.add_dependency 'rails', '3.2.8'
  gem.add_dependency 'sqlite3'
  gem.add_dependency 'jquery-rails'
  # how to add the assets group gems?
end

试试这个,看看它是否有助于你取得进步

gem只是文件的目录,你可以把你想要的任何文件放到gem中

创建: 创建一个空白的gem完整Rails项目:

$ bundle gem my_gem
然后是Rails应用程序:

$ rails new my_app --skip-bundle
$ cd my_gem
$ bundle install --binstubs --path vendor/bundle
$ cd -
将Rails文件复制到gem中:

$ cp -R my_app/* my_gem
将所有内容捆绑到Rails应用程序中:

$ rails new my_app --skip-bundle
$ cd my_gem
$ bundle install --binstubs --path vendor/bundle
$ cd -
使Rakefile具有gem任务和Rails设置:

#!/usr/bin/env rake
require "bundler/gem_tasks"
require File.expand_path('../config/application', __FILE__)
MyApp::Application.load_tasks
# Rails.root/config.ru
require "config/environment"

use Rails::Rack::LogTailer
use ActionDispatch::Static
run ActionController::Dispatcher.new
验证它是否启动:

$ rails server
加载路径: 要控制Rails查找文件(如“外部”配置文件)的位置,您可以将config/application.rb文件与以下目录路径一起使用:

# Add additional load paths for your own custom dirs
# config.load_paths += %W( #{config.root}/../customdir )
请注意“.”,这意味着转到Rails目录上方。这将为您提供一条相对于宝石的路径

如果愿意,您可以指定一个绝对路径,例如,如果您知道用户将始终将其外部文件保存在“~/myfiles/”中。您还可以选择使用ENV vars在您想要的任何目录中发送

如果您阅读了有关加载路径功能的内容,请查找用于在加载路径前面添加目录的简写行,因为您可能希望将外部目录放在第一位:

$:.unshift File.dirname(__FILE__)
宝石建造: 编辑my_gem.gemspec以添加您自己的描述、主页、摘要等。然后构建:

$ gem build my_gem.gemspec
Successfully built RubyGem
Name: my_gem
Version: 0.0.1
File: my_gem-0.0.1.gem
现在,您的Rails应用程序已打包为gem

config.ru应该是典型的Rails文件。没什么特别的变化

当您的用户想要安装您的应用程序时:

$ gem install my_gem
gem将安装在用户的典型gem目录中。如果要调整此值,请参阅rubygems上的此页:

机箱: 您可能还想调查板条箱项目:

  • 板条箱:打包独立的Ruby应用程序
机架: 要使用config.ru,以下是典型的Rails设置:

#!/usr/bin/env rake
require "bundler/gem_tasks"
require File.expand_path('../config/application', __FILE__)
MyApp::Application.load_tasks
# Rails.root/config.ru
require "config/environment"

use Rails::Rack::LogTailer
use ActionDispatch::Static
run ActionController::Dispatcher.new
对于您的项目,您希望在Rails之前需要一些文件。您将想了解Ruby“require”以及它如何使用LOAD_PATH查找文件

简单的方法:

# Rails.root/config.ru
require_relative 'filename'
require "config/environment"
或者将用户的自定义目录设置为两个目录级别:

require './../../filename'  # not the best for security
或者要使用绝对路径,请阅读关于File.expand\u path的内容:

File.expand_path(__FILE__)
或使用当前目录并将其放在加载路径上:

$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'filename'
你可以考虑很多选择。希望这有帮助

关于“如何在gem中运行Rails应用程序”的问题呢

Rails应用程序具有运行web服务器的控制器和视图。您需要的是创建、列出、更新和销毁的操作。在没有web服务器的情况下公开这些操作本质上就是在类中包含这样的方法。首先,这是一种普通的标准宝石

所以也许你的问题是,我如何在有ActiveRecord和其他Rails的地方写一个gem呢

首先,您需要使gem依赖于所需的Rails gem。您可以在gempec文件中为您的gem执行此操作


那么,这实际上只是你的gem代码需要你所需要的正确的Rails gem的问题。

我不确定这是否会有帮助,因为我通读了所有内容,我找不到你这样做的动机。我想到的一个原因是制作一些可以在桌面环境中使用的东西。在这种情况下,您可以尝试使用类似的方法。如果你只是想提供一个其他人可以下载、使用和安装自己的应用程序,那么你可以假设他们至少可以遵循基本的开发人员指导,你可以在github上提供整个应用程序或作为zip文件。请参阅其他人在上做类似操作的示例。

比如rails引擎?引擎可以提供路线、模型、资源等。。并被包含在宝石中。它基本上是一个rails应用程序,可以安装在另一个rails应用程序中。就像可以独立运行的rails引擎(无需安装)。或者有一种方法可以运行rails应用程序,而不需要通常创建的所有目录(app、config、lib、test等)因为widget和foobars目录将取代它们。gem用户将与web服务器交互吗?或者只有应用程序的代码才会这样做?如果是这样的话,运行的轨道可能会被过度使用。请描述“幕后”使用rails应用程序的实际情况。@Kelvin我不知道我是否完全理解你两个问题的区别。我想像其他Rails应用程序一样在gem中开发代码。当用户使用my gem的可执行文件生成新应用程序时,他们应该会得到一个rackup文件,该文件在my gem中运行Rails应用程序。谢谢!这会有帮助的。我还在想…假设您使用我的gem生成一个带有
config.ru