【发布时间】:2015-07-09 16:16:50
【问题描述】:
我想在我的 Rails 应用程序的 2 个(将来可能更多)之间共享一个模型。我找不到任何明确的建议,但我收集了一些我读过的问题和答案,得出的结论是必须使用“gemmed”插件引擎来完成。 我决定使用插件,因为我读到该引擎只是一种“完整”插件。
所以我创建了一个插件,使用:rails plugin new my_models --skip-active-record --skip-test-unit --dummy-path=spec/dummy(选项是跳过 activerecord 作为 ORM 并使用 rspec 进行测试)。
创建插件后,我得到以下文件:
my_models.gemspec Gemfile Gemfile.lock lib MIT-LICENSE Rakefile README.rdoc spec
我尝试使用以下方法包含模型:
- 只需创建一个
app/models目录并将我的模型放入其中 - 按照this tutorial 中的建议(我可以在devise's github 中看到),我创建了一个生成器来尝试生成模型。
他们都失败了,然后我决定采用引擎建议(只需将 --mountable 添加到“rails new”命令的选项列表中),我得到了完整的 rails 应用程序结构(带有 app、bin , db 和其他目录),将我的模型放在 app/models 目录中,它就像魔术一样工作!
因为我相信我是程序员而不是魔术师,所以我不会做这种魔术,所以你能告诉我我的两个瘦插件解决方案(使用生成器/创建模型)有什么问题吗?此外,使用这些生成器有什么好处?
我正在附上我的生成器的代码,也许我错过了什么:
require 'rails/generators/named_base'
require 'mongoid'
module Mongoid
module AttackGenerator
def generate_model
invoke "mongoid:model", [name] unless model_exists? && behavior == :invoke
end
def inject_field_types
inject_into_file model_path, migration_data, after: "include Mongoid::Document\n" if model_exists?
end
def migration_data
field :link_url, type: String
field :token, type: String
end
def model_exists?
File.exists?(File.join(destination_root, model_path))
end
def model_path
@model_path ||= File.join("app", "models", "#{file_path}.rb")
end
end
end
【问题讨论】:
-
对于非完整引擎/插件,您可能需要
require来自父应用程序的文件。如果它们已经在加载路径上,您可以执行require 'my_engine/whatever,否则为require MyEngine::Engine.root.join('app', 'models', 'whatever')。 -
我同意您关于成为程序员而不是魔术师的观点,但是当您使用 Rails 时,您已经完全投降于魔术领域。你必须学习咒语和咒语,如果你试图理解它们太过分,那就像盯着太阳一样。
-
我可能错了,但插件的概念是“遗留”的东西,在 rails 2 中有效(不确定在 3 中是否仍然有效),也许生成器只是为了这个目的。目前,创建一个引擎就像在一个简单的 gem 中使用 Railtie 一样简单,该 gem 由
bundle gem gem_name、app目录和一些小东西构建。虽然我必须承认,在你的具体情况下,感觉你不需要引擎,你可以用一个简单的 gem -
@Fire-Dragon-DoL 引擎和简单的 gem 有什么区别?如何创建既不是引擎也不是插件的 gem?
-
其实我忘了迁移,你需要一个引擎。我添加了一个包含更多细节的答案。 gem 基本上是一个库,引擎仍然是一个 gem,但带有一个文件
engine.rb(加载在 gem 中),它通过自动加载应用程序目录和其他内容来增强 gem 功能。有关详细信息,请参阅我的答案。它很长,需要你学习各种各样的东西,但它们非常有趣,一旦你理解了它,你就会明白更多的“rails magic”;)
标签: ruby-on-rails ruby-on-rails-plugins rails-engines