2012-05-18 32 views
2

我正在開發一個由兩部分組成的應用程序:一個ruby命令行應用程序和一個用於前端的Rails應用程序。在Rails中包含用戶模型時未定義的方法'devise'

我一直在使用ActiveRecord和Rails車型在Ruby應用程序包括通過其個人方式如下:

Dir[File.dirname(__FILE__) + '/../../RailsApp/app/models/*.rb'].each do |file| 
    filename = File.basename(file, File.extname(file)) 
    require_relative "../../RailsApp/app/models/" + filename 
end 

而且通過手動mantaining兩個幾乎相同的Gemfile文件的依賴關係(的做法,我認爲是不是最好的)

昨天我添加了Devise到Rails應用程序,現在當ruby應用程序試圖包含用戶模型時,出現消息undefined method devise for class <xxxxx>

我在我的紅寶石應用程序的Gemfile中添加了設計寶石,但錯誤仍在繼續。如果我理解正確,Devise是一個Rails引擎,這就是爲什麼它不僅僅是通過需要寶石加載。

,我讀了一個更好的方法,包括Rails的模型內的另一個應用是通過要求environment.rb文件,但是當我試過了,我得到的ActionMailer一個錯誤:

undefined method `action_mailer' for #<Rails::Application::Configuration:0xbbb54bc> 

我該如何解決這個問題與設計?有沒有更好的方法來將Rails模型包含在另一個應用程序中,而不是我目前用來避免保留兩個gemfiles的應用程序?謝謝

回答

5

即使這個架構必須在不久的將來發生變化,我們設法通過在devy應用程序中包含devise及其初始化程序來解決這個錯誤。

# FIXME: Dependency needed in Rails but not in the engine. 
require 'devise' 
require_relative "../../RailsApp/config/initializers/devise.rb" 

#Load all the models 
3

在調用模型之前,您可以嘗試使用require 'devise',但我不確定這是否會起作用?

我同意這個一般的架構感覺不對。

我會將這兩個應用程序通用的代碼提取到單獨的庫中,然後將這個庫包含在這兩個應用程序中。最簡單的做法是將自己的圖書館製作成寶石,然後將其包含在Gemfiles中。常見的寶石將在共享庫中指定。製作寶石非常簡單。在http://asciicasts.com/episodes/245-new-gem-with-bundler(或關聯的Railscast)上可以找到很好的說明。

您的命令行應用程序可能不需要關心設計。如果你同時需要一個用戶模型,你可以將它包含在共享庫中,然後在Rails應用程序中添加任何額外的功能(例如Devise)。

這有幫助嗎?

+0

謝謝你的迴應。我們都同意這種架構必須在不久的將來改變,以便更正交。 Upvote將關於將通用功能移至單獨的寶石的建議。現在我通過要求設計和它的初始化器來解決這個問題。 – bruno077

0

您可以將您的模型加載到父應用初始化步驟的時間,而不是在您的寶石加載時。

按照其他答案的建議構建一個shared_code gem。

移動你的shared_code裝載區到初始化文件(如需要「用戶」)在shared_code gemspec你的模型

列表中的gem依賴(如色器件)。

在您的shared_code gem中,包含一個生成器以將初始化程序文件安裝到使用shared_code gem的應用程序中。

然後使用您的共享代碼在父應用程序,

的Gemfile:

gem 'shared_code' 

控制檯:

rails generate shared_code:install 

這是相同的圖案色器件和其他寶石使用自我配置在父應用程序的初始化序列中的正確時間。

如果您在user.rb文件本身的設計初始值設定項中使用了require_relative,在shared_code gem中,您將刪除使用您的shared_code的兩個不同父應用程序可能需要初始化設計(或另一個gem應用程序和你的寶石都依賴於)。在發電機

詳情:

您可以創建shared_code:通過創建這樣的發電機安裝命令:

的lib /發電機/ shared_code/install_generator.rb

module SharedCode 
    class InstallGenerator < Rails::Generators::Base 
    source_root File.expand_path('../templates', __FILE__) 
    def copy_initializer_file 
     copy_file "shared_code.rb", "config/initializers/shared_code.rb" 
    end 
    end 
end 

把你的模型加載代碼到lib/generators/shared_code/templates/shared_code.rb

相關問題