[英]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.