Как сделать маршруты из движка Rails 3 доступными для хост-приложения? - PullRequest
23 голосов
/ 05 декабря 2010

У меня есть приложение Rails 3 с несколькими движками, содержащими дополнительную функциональность. Каждый движок - это отдельный сервис, доступ к которому клиенты могут приобрести.

Однако у меня проблема с маршрутами от двигателей, которые не всегда доступны для контроллеров и представлений.

Контроллер:

class ClassroomsController < ApplicationController
  ..
  respond_to :html

  def index
    respond_with(@classrooms = @company.classrooms.all)
  end

  def new
     respond_with(@classroom = @company.classrooms.build)
  end

  ..
end

app/views/classrooms/new.html.haml

= form_for @classroom do |f|
  ..
  f.submit

config/routes.rb в двигателе:

MyEngineName::Engine.routes.draw do
  resources :classrooms
end

config/routes.rb в приложении:

Seabed::Application.routes.draw do
  mount MyEngineName::Engine => '/engine'
  ...
end

lib/my_engine_name.rb в двигателе:

module MyEngineName
  class Engine < ::Rails::Engine
  end
end

попытка перейти к /classrooms/new приводит к

NoMethodError in Classrooms#new

Showing app/views/classrooms/_form.html.haml where line #1 raised:
  undefined method `hash_for_classrooms_path' for #<Module:0x00000104cff0f8>

и попытка вызова classrooms_path из любого другого представления приводит к той же ошибке. Я могу, однако, позвонить MyEngineName::Engine.routes.url_helpers.classrooms_path и заставить его работать. Я думаю, что, возможно, определил маршруты неправильно, но не могу найти другой способ, который работает.

Попробовал запустить приложение с Passenger (автономный модуль и модуль Apache) и WEBrick (сервер rails). Использование последних Rails из Git (7c920631ec3b314cfaa3a60d265de40cba3e8135).

Ответы [ 3 ]

26 голосов
/ 06 сентября 2012

У меня была такая же проблема, и я нашел ее в документации :

Поскольку теперь вы можете монтировать движок внутри маршрутов приложения, у вас нет прямого доступа к url_helpers Engine внутри приложения. Когда вы монтируете движок в маршруты приложения, создается специальный помощник, который позволяет вам это делать. Рассмотрим такой сценарий:

# config/routes.rb
MyApplication::Application.routes.draw do
  mount MyEngine::Engine => "/my_engine", :as => "my_engine"
  get "/foo" => "foo#index"
end

Теперь вы можете использовать помощник my_engine внутри вашего приложения:

class FooController < ApplicationController
  def index
    my_engine.root_url #=> /my_engine/
  end
end
25 голосов
/ 06 декабря 2010

Измените config.routes в вашем двигателе на:

Rails.application.routes.draw do  # NOT MyEngineName::Engine.routes.draw
  resources :classrooms
end

Как вы понимаете, маршруты доступны только в пространстве имен MyEngineName::Engine, а не в остальной части приложения host rails.

Раньше был пост в блоге с дополнительной информацией, но, к сожалению, он больше недоступен:

2 голосов
/ 10 октября 2011

Для меня также помогите добавить

require 'engine' if defined?(Rails)

в мой основной файл gem (lib / .rb).

Хороший пример - https://github.com/mankind/Rails-3-engine-example/blob/master/lib/dummy.rb

...