2011-08-05 14 views
11

Tôi có ứng dụng Rails 3 mà tôi đang chuyển thành công cụ Rails/gem. Công cụ này có một số phụ thuộc đá quý mà tôi đã đặt bên trong tệp .gemspec của nó.Làm cách nào để tạo phụ thuộc gemspec tự động tải trong ứng dụng Rails 3, sử dụng Gemfile

Tôi đã tạo ứng dụng Rails 3 mới cho phụ huynh và tôi muốn thêm gem gem của mình vào Gemfile và có phụ thuộc của gem tự động được 'tải', nhưng điều này không hiệu quả đối với tôi! bundle install cài đặt phụ thuộc vào đá quý, nhưng khi tôi khởi động máy chủ, ứng dụng bị treo vì chúng không được tải.

Ví dụ, gemspec động cơ của tôi chứa những dòng này:

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"]) 

.. và Rails mẹ 3 ứng dụng có những dòng này trong Gemfile của nó:

source 'http://rubygems.org' 

gem 'my_engine', :path => "~/src/gems/my_engine" 

Nhưng tôi nhận được lỗi sau:

undefined local variable or method `acts_as_commentable' 
from /home/user/src/gems/my_engine/app/models/account.rb:66:in `<class:Account>' 

Nhưng nếu tôi thêm gem 'acts_as_commentable', '>= 3.0.1' vào Gemfile của phụ huynh Rails 3 ứng dụng, sau đó đá quý được tải và lỗi biến mất.

Tôi đang sử dụng Rails 3.0.8.

Có ai có bất kỳ đề xuất nào không? Tôi có cần phải thay đổi điều gì đó về cách động cơ của tôi đang tải không?

Trả lời

12

Trong khi khởi động ứng dụng Rails chính, Bundler sẽ chỉ yêu cầu các phụ thuộc được liệt kê trực tiếp trong Gemfile nhưng không yêu cầu bất kỳ phụ thuộc phụ nào. Đó là trách nhiệm của Thư viện/Động cơ của bạn để yêu cầu các phụ thuộc của nó khi bản thân nó được yêu cầu. Bạn có thể làm như vậy bằng cách sử dụng initializers trong Railtie của bạn.

class MyRailtie < Rails::Railtie 
    initializer "require stuff" do 
    require "stuff" 
    end 
end 
+0

Cảm ơn bạn đã xác nhận rằng đây là hành vi mong đợi. Có một vấn đề bị đóng (bị từ chối) đối với người đóng gói với ý tưởng 'đệ quy Gemfiles', có vẻ như nó có thể hữu ích: https://github.com/carlhuda/bundler/issues/49 – ndbroadbent

+0

Đối với tôi, tôi cần phải yêu cầu /lib/my_engine.rb. Ví dụ: https://github.com/krisleech/qwerty/commit/c1e82cef27013afc6a540412e101cc2b6aeb4898 – Kris

2

Tôi nhìn vào Spree (các siêu anh hùng của Rails cơ!), Và họ làm điều này trong 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" 

Vì vậy, câu trả lời là rằng trong vòng ngọc của bạn, bạn phải yêu cầu tất cả đó là đá quý phụ thuộc từng cái một. Vâng, đó là cách tôi sẽ làm điều đó ngay bây giờ. Nhưng xin vui lòng bình luận nếu điều này bao giờ thay đổi trong tương lai.

1

Dường như nó không hoạt động, tôi tạo một dự án máy chủ và một tiểu dự án với động cơ ray 3.

Added viên ngọc để động cơ gemspec

s.add_dependency 'simple_form'

sau đó thêm vào các yêu cầu để engine_name.rb như dưới đây

require 'simple_form'

Nhưng nếu xoá dòng [đá quý 'simple_form'] trong host project của Gemfile, nó sẽ hiển thị undefined ngay lập tức

3

Trong Rails Engine của chúng tôi chúng tôi đã sử dụng một mẹo nhỏ để yêu cầu phụ thuộc tự động. Rất tiếc, bạn không thể chỉ định có nên tải trong .gemspec, điều này cho phép kiểm soát tốt hơn hay không.

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 
+0

Điều đó hoạt động thực sự tốt, mặc dù tôi đang làm 'runtime_dependencies' thay thế. –