Как сделать gemspec зависимостями autoload в приложении Rails 3, используя Gemfile
У меня есть приложение Rails 3, которое я превращаю в Rails engine/gem.
Этот движок имеет некоторые зависимости от gem, которые я вложил в него .gemspec.
Я создал новое "родительское" приложение Rails 3, и я хотел бы добавить свой жемчуг в Gemfile и автоматически загружать зависимости gem автоматически, но это не работает для меня! bundle install
устанавливает корректные зависимости gem, но когда я запускаю сервер, приложение выходит из строя, потому что оно не загружено.
Например, мой код gemspec содержит следующие строки:
s.add_runtime_dependency(%q<rails>, ["= 3.0.7"])
s.add_runtime_dependency(%q<acts_as_commentable>, [">= 3.0.1"])
s.add_runtime_dependency(%q<haml>, [">= 3.1.1"])
.. и родительское приложение Rails 3 имеет эти строки в своем Gemfile:
source 'http://rubygems.org'
gem 'my_engine', :path => "~/src/gems/my_engine"
Но я получаю следующую ошибку:
undefined local variable or method `acts_as_commentable'
from /home/user/src/gems/my_engine/app/models/account.rb:66:in `<class:Account>'
Но если я добавлю gem 'acts_as_commentable', '>= 3.0.1'
в Gemfile родительского Rails 3, то жемчуг будет загружен и ошибка исчезнет.
Я использую Rails 3.0.8.
Есть ли у кого-нибудь предложения? Нужно ли мне что-то менять в отношении загрузки моего двигателя?
Ответы
Ответ 1
Во время загрузки основного Rails-приложения Bundler потребует только зависимостей, непосредственно перечисленных в Gemfile, но не любых зависимостей. Обязанность вашей библиотеки/двигателя требовать ее зависимости, когда она сама понадобится. Вы можете сделать это с помощью инициализаторов в вашем Railtie.
class MyRailtie < Rails::Railtie
initializer "require stuff" do
require "stuff"
end
end
Ответ 2
В нашем Rails Engine мы использовали небольшой трюк, чтобы автоматически требовать зависимости. К сожалению, вы не можете указать, должны ли они загружаться в .gemspec, что позволит увеличить контроль.
Gem.loaded_specs["our_rails_engine"].dependencies.each do |d|
begin
require d.name
rescue LoadError => le
# Put exceptions here.
raise le if d.name !~ /factory_girl_rails/
end
end
Ответ 3
Я смотрю на Spree (супергерой Rails Engines!), и они делают это в spree_core-0.60.1/lib/spree_core.rb
:
require "rails/all"
require 'state_machine'
require 'paperclip'
require 'stringex'
require 'will_paginate'
require 'nested_set'
require 'acts_as_list'
require 'resource_controller'
require 'active_merchant'
require "meta_search"
require "find_by_param"
Итак, ответ заключается в том, что в вашем драгоценном камне вам нужно каждый раз использовать все его зависимости. Что ж, пока я это сделаю. Но прокомментируйте, если это произойдет в будущем.
Ответ 4
Кажется, он не работает, я создаю проект-хост и суб-проект с движком rails 3.
Добавлен драгоценный камень в двигатель gemspec
s.add_dependency 'simple_form'
то добавили require к engine_name.rb, как показано ниже
require 'simple_form'
Но если удалить строку [gem "simple_form" ] в файле проекта Gemfile, он будет показывать undefined немедленно