简体   繁体   English

从Rails 3.1引擎访问模型

[英]Accessing a model from a Rails 3.1 Engine

I have been wrestling with this for the last day and it's driving me NUTS! 我在最后一天一直在和它搏斗,它正在驱使我努力!

As an learning exercise I decided that I would package up some of my code into a Rails Gem. 作为一个学习练习,我决定将一些代码打包成Rails Gem。 This code has a controller action, a route, a model and a helper so I decided that the most suitable method of creating a Gem would be to create it as a Rails Engine. 这段代码有一个控制器动作,一个路由,一个模型和一个帮助器,所以我认为最合适的创建Gem的方法是将它创建为一个Rails引擎。

Everything seems to be working well, except for one thing. 除了一件事,一切似乎都运作良好。 When I try to reference the Model from within a Controller or Views (of an application that uses the engine) eg: 当我尝试从Controller或Views(使用引擎的应用程序)中引用模型时,例如:

@su = Shortener::ShortenedUrl.generate("http://stackoverflow.com")

I get the following error: 我收到以下错误:

uninitialized constant Shortener::ShortenerHelper::ShortenedUrl

It's strange because the error doesn't happen when I execute the code from the projects console. 这很奇怪,因为当我从项目控制台执行代码时,不会发生错误。 I think that this is caused by the fact I have put all of the code into the "Shortener" namespace/module. 我认为这是因为我已将所有代码放入“Shortener”命名空间/模块中。 I did this so it would help avoid conflicts when used within other applications. 我这样做是为了避免在其他应用程序中使用时发生冲突。

The code file hierachy looks like this: 代码文件层次结构如下所示:

项目目录/文件列表的图像

And here is the class/module declaration code (with the guts removed) of the important files in question 这里是有问题的重要文件的类/模块声明代码(删除了内容)

app/controllers/shortener/shortened_urls_controller 应用程序/控制器/缩短器/ shortened_urls_controller

module Shortener
  class ShortenedUrlsController < ::ApplicationController

    # find the real link for the shortened link key and redirect
    def translate
      # convert the link...
    end
  end
end

app/models/shortener/shortened_urls 应用程序/模型/缩略服务/ shortened_urls

module Shortener
  class ShortenedUrl < ActiveRecord::Base

    # a number of validations, methods etc  

  end 
end

app/helpers/shortener/shortener_helper 应用程序/佣工/缩略服务/ shortener_helper

module Shortener::ShortenerHelper

  # generate a url from either a url string, or a shortened url object
  def shortened_url(url_object, user=nil)

    # some code to do generate a shortened url

  end

end

lib/shortener/engine.rb LIB /缩短器/ engine.rb

require "rails/engine"
require "shortener"

module Shortener

  class ShortenerEngine < Rails::Engine

  end

end

lib/shortener.rb LIB / shortener.rb

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"

shortener.gemspec shortener.gemspec

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

I have published the entire code of the engine on GitHub: 我在GitHub上发布了引擎的完整代码:

https://github.com/jpmcgrath/shortener https://github.com/jpmcgrath/shortener

NOTE: this engine has a generator to generate the required migration file. 注意:此引擎有一个生成器,用于生成所需的迁移文件。 Type: 类型:

rails g shortener

I have also created a rails 3.1 app that exhibits the problem (look at line 18 of the projects controller): 我还创建了一个展示问题的rails 3.1 app(查看项目控制器的第18行):

https://github.com/jpmcgrath/linky https://github.com/jpmcgrath/linky

Any ideas? 有任何想法吗? I have scoured the web, but have not been able to find any really definitive guide to making Engine Gems. 我已经在网上搜索过,但是还没有找到任何真正明确的制作引擎宝石的指南。 Any helpers would be much appreciated. 任何助手都会非常感激。

Thanks! 谢谢!

In your engine helper ( app/helpers/shortener/shortener_helper.rb ), replace both occurrences of ShortenedUrl with Shortener::ShortenedUrl . 在您的引擎助手( app/helpers/shortener/shortener_helper.rb )中,将ShortenedUrl两次出现替换为Shortener::ShortenedUrl

I found this error weird at the beginning, because ruby is supposed to look for constants in the enclosing module. 我在开始时发现这个错误很奇怪,因为ruby应该在封闭模块中寻找常量。 But helpers are included in another class, which could mean that the constant name resolution environment isn't the same as the one you see in the file. 但是帮助程序包含在另一个类中,这可能意味着常量名称解析环境与您在文件中看到的环境不同。

If you want to know more about namespaced engines and their behaviour, you can look at this excellent answer . 如果您想了解有关命名空间引擎及其行为的更多信息,可以查看这个优秀的答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM