Доступ к модели из движка Rails 3.1 - PullRequest
5 голосов
/ 01 сентября 2011

Я боролся с этим в последний день, и это сводит меня с ума!

В качестве учебного упражнения я решил, что я собираюсь упаковать часть своего кода в Rails Gem.В этом коде есть действие контроллера, маршрут, модель и помощник, поэтому я решил, что наиболее подходящим методом создания Gem было бы создать его как Rails Engine.

Кажется, все работает хорошо,кроме одной вещи.Когда я пытаюсь сослаться на Модель из Контроллера или Представлений (приложения, использующего движок), например:

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

, я получаю следующую ошибку:

uninitialized constant Shortener::ShortenerHelper::ShortenedUrl

Это страннопотому что ошибка не возникает, когда я выполняю код из консоли проектов.Я думаю, что это связано с тем, что я поместил весь код в пространство имен / модуль "Shortener".Я сделал это, чтобы избежать конфликтов при использовании в других приложениях.

Иерархический файл кода выглядит следующим образом:

An image of the project directory/file listing

А вот класс /код объявления модуля (с удаленными кишками) важных файлов, о которых идет речь

приложение / контроллеры / укорачивающее устройство / shorten_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

приложение / модели / укорачивающее устройство / shorten_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"

укорочение.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, в котором обнаружена проблема (см. Строку 18 контроллера проектов):

https://github.com/jpmcgrath/linky

Anyидеи?Я просмотрел сеть, но не смог найти ни одного по-настоящему точного руководства по созданию Engine Gems.Любые помощники будут очень признательны.

Спасибо!

1 Ответ

3 голосов
/ 01 сентября 2011

В вашем помощнике по движку (app/helpers/shortener/shortener_helper.rb) замените оба вхождения ShortenedUrl на Shortener::ShortenedUrl.

. Сначала я обнаружил эту ошибку странной, потому что ruby ​​должен искать константы вограждающий модуль.Но помощники включены в другой класс, что может означать, что среда с постоянным разрешением имен отличается от той, что вы видите в файле.

Если вы хотите узнать больше о механизмах пространства имен и их поведении,Вы можете посмотреть на этот отличный ответ .

...