![](/img/trans.png)
[英]Rails 3.1 - Accessing Parent Application Models from Mountable Engine
[英]Accessing a model from a Rails 3.1 Engine
我在最后一天一直在和它搏斗,它正在驱使我努力!
作为一个学习练习,我决定将一些代码打包成Rails Gem。 这段代码有一个控制器动作,一个路由,一个模型和一个帮助器,所以我认为最合适的创建Gem的方法是将它创建为一个Rails引擎。
除了一件事,一切似乎都运作良好。 当我尝试从Controller或Views(使用引擎的应用程序)中引用模型时,例如:
@su = Shortener::ShortenedUrl.generate("http://stackoverflow.com")
我收到以下错误:
uninitialized constant Shortener::ShortenerHelper::ShortenedUrl
这很奇怪,因为当我从项目控制台执行代码时,不会发生错误。 我认为这是因为我已将所有代码放入“Shortener”命名空间/模块中。 我这样做是为了避免在其他应用程序中使用时发生冲突。
代码文件层次结构如下所示:
这里是有问题的重要文件的类/模块声明代码(删除了内容)
应用程序/控制器/缩短器/ 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
应用程序/模型/缩略服务/ shortened_urls
module Shortener
class ShortenedUrl < ActiveRecord::Base
# a number of validations, methods etc
end
end
应用程序/佣工/缩略服务/ 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 /缩短器/ engine.rb
require "rails/engine"
require "shortener"
module Shortener
class ShortenerEngine < Rails::Engine
end
end
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
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上发布了引擎的完整代码:
https://github.com/jpmcgrath/shortener
注意:此引擎有一个生成器,用于生成所需的迁移文件。 类型:
rails g shortener
我还创建了一个展示问题的rails 3.1 app(查看项目控制器的第18行):
https://github.com/jpmcgrath/linky
有任何想法吗? 我已经在网上搜索过,但是还没有找到任何真正明确的制作引擎宝石的指南。 任何助手都会非常感激。
谢谢!
在您的引擎助手( app/helpers/shortener/shortener_helper.rb
)中,将ShortenedUrl
两次出现替换为Shortener::ShortenedUrl
。
我在开始时发现这个错误很奇怪,因为ruby应该在封闭模块中寻找常量。 但是帮助程序包含在另一个类中,这可能意味着常量名称解析环境与您在文件中看到的环境不同。
如果您想了解有关命名空间引擎及其行为的更多信息,可以查看这个优秀的答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.