Ruby on rails 从Rails 3.1引擎访问模型

Ruby on rails 从Rails 3.1引擎访问模型,ruby-on-rails,ruby-on-rails-3,rubygems,ruby-on-rails-plugins,Ruby On Rails,Ruby On Rails 3,Rubygems,Ruby On Rails Plugins,最后一天我一直在和这个摔跤,它快把我逼疯了 作为一个学习练习,我决定将我的一些代码打包成Rails Gem。这段代码有一个控制器操作、一个路由、一个模型和一个助手,因此我决定创建Gem的最合适方法是将其创建为Rails引擎 除了一件事,一切似乎都很顺利。当我尝试从控制器或使用引擎的应用程序视图中引用模型时,例如: @su = Shortener::ShortenedUrl.generate("http://stackoverflow.com") 我得到以下错误: uninitialized c

最后一天我一直在和这个摔跤,它快把我逼疯了

作为一个学习练习,我决定将我的一些代码打包成Rails Gem。这段代码有一个控制器操作、一个路由、一个模型和一个助手,因此我决定创建Gem的最合适方法是将其创建为Rails引擎

除了一件事,一切似乎都很顺利。当我尝试从控制器或使用引擎的应用程序视图中引用模型时,例如:

@su = Shortener::ShortenedUrl.generate("http://stackoverflow.com")
我得到以下错误:

uninitialized constant Shortener::ShortenerHelper::ShortenedUrl
这很奇怪,因为当我从项目控制台执行代码时,错误没有发生。我认为这是因为我将所有代码都放在了较短的名称空间/模块中。我这样做是为了避免在其他应用程序中使用时发生冲突

代码文件层次结构如下所示:

下面是类/模块声明代码,其中删除了所讨论的重要文件

应用程序/控制器/缩短器/缩短的URL\u控制器

module Shortener
  class ShortenedUrlsController < ::ApplicationController

    # find the real link for the shortened link key and redirect
    def translate
      # convert the link...
    end
  end
end
lib/shortener/engine.rb

require "rails/engine"
require "shortener"

module Shortener

  class ShortenerEngine < Rails::Engine

  end

end
珍珠岩

require File.expand_path("../lib/shortener/version", __FILE__)

# Provide a simple gemspec so you can easily use your enginex
# project in your rails apps through git.
Gem::Specification.new do |s|
  s.name                      = "shortener"
  s.summary                   = "Shortener makes it easy to create shortened URLs for your rails application."
  s.description               = "Shortener makes it easy to create shortened URLs for your rails application."
  s.files                     = `git ls-files`.split("\n")
  s.version                   = Shortener::VERSION
  s.platform                  = Gem::Platform::RUBY
  s.authors                   = [ "James P. McGrath" ]
  s.email                     = [ "gems@jamespmcgrath.com" ]
  s.homepage                  = "http://jamespmcgrath.com/projects/shortener"
  s.rubyforge_project         = "shortener"
  s.required_rubygems_version = "> 1.3.6"
  s.add_dependency "activesupport" , ">= 3.0.7"
  s.add_dependency "rails"         , ">= 3.0.7"
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
  s.require_path = 'lib'
end
我已经在GitHub上发布了引擎的全部代码:

注意:此引擎有一个生成器来生成所需的迁移文件。类型:

rails g shortener
我还创建了一个rails 3.1应用程序,展示了projects controller第18行的问题:

有什么想法吗?我在网上搜索过,但没有找到任何真正权威的引擎宝石制作指南。任何助手都将不胜感激

谢谢

在引擎助手应用程序/helpers/shortener/shortener_helper.rb中,用shortener::ShortenedUrl替换两个出现的ShortenedUrl

我在开始时发现这个错误很奇怪,因为ruby应该在封闭模块中查找常量。但是助手包含在另一个类中,这可能意味着常量名称解析环境与您在文件中看到的环境不同


如果您想了解更多有关名称空间引擎及其行为的信息,可以查看。

这里应该有一些迁移,没有它们我无法测试您的引擎。我一直在github测试您的代码,它似乎工作得很好,我只添加了一个迁移。您在rails应用程序中使用了什么版本的rails?我用了最后的3.1,也许这就是区别。谢谢贝诺特。github代码有一个生成器,用于创建迁移。只需输入g短缩器。我将修改我的问题,将其包括在内。至于rails版本,我认为这可能是问题所在,但我的gem文件中有gem'rails','3.1.0'。我将创建另一个github项目,我将把我的测试应用程序推到其中。Benoit,这就成功了,你是一个传奇,让我的一天变得美好!这很奇怪,因为当从应用程序调用帮助程序时,它的代码工作正常。我猜在这一过程中,有些地方事情变得很混乱。我应该专注于ruby名称解析:-如果你知道这里到底发生了什么,这将是对答案的极好补充-行。希望一些过路的名称空间/名称解析/引擎大师碰巧路过,能够提供启示,而不是我在寻找一条简单的出路或其他什么:-
require "active_support/dependencies"

module Shortener

  # Our host application root path
  # We set this when the engine is initialized
  mattr_accessor :app_root

  # Yield self on setup for nice config blocks
  def self.setup
    yield self
  end

end

# Require our engine
require "shortener/engine"
require File.expand_path("../lib/shortener/version", __FILE__)

# Provide a simple gemspec so you can easily use your enginex
# project in your rails apps through git.
Gem::Specification.new do |s|
  s.name                      = "shortener"
  s.summary                   = "Shortener makes it easy to create shortened URLs for your rails application."
  s.description               = "Shortener makes it easy to create shortened URLs for your rails application."
  s.files                     = `git ls-files`.split("\n")
  s.version                   = Shortener::VERSION
  s.platform                  = Gem::Platform::RUBY
  s.authors                   = [ "James P. McGrath" ]
  s.email                     = [ "gems@jamespmcgrath.com" ]
  s.homepage                  = "http://jamespmcgrath.com/projects/shortener"
  s.rubyforge_project         = "shortener"
  s.required_rubygems_version = "> 1.3.6"
  s.add_dependency "activesupport" , ">= 3.0.7"
  s.add_dependency "rails"         , ">= 3.0.7"
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
  s.require_path = 'lib'
end
rails g shortener