13

我有一个模型需要从辅助源加载外部数据。存在许多 Web 服务,我的模型可以从中获取数据(可交换),但我不想创建难以更改服务的代码(成本因可变和固定使用而显着不同,并且可能会发生变化将被要求)。

我想创建一个驱动程序来执行交互(如果服务需要切换,然后创建进一步的自定义驱动程序)。不幸的是,由于驱动程序和模型的紧密耦合,将代码提取到插件或 gem 中是没有意义的。我已将所有代码提取到一个模块中(参见示例),并且目前在我的模型上方声明了代码。

module Synchronize
  def refresh
    self.attributes = ...
    self.save
  end
end

class Data < ActiveRecord::Base
  include Synchronize
end

Rails (3.0.0) 是否有存储模块与模型紧密耦合的约定?我应该使用插件来做到这一点吗?这与“app/helpers”目录相关联吗?如果不是,最适合存储代码的位置在哪里?谢谢!

4

2 回答 2

27

您是正确的,如果模块与该特定模型紧密耦合,那么它不是 gem/plugin 的良好候选者。

app/helpers/ 用于查看辅助方法,不应包含仅用于混合到模型中的模块。

您可以放置​​模块的一个地方是 lib/. 这适用于实际上不适合 app/ 中任何位置的代码,并且通常是松散耦合代码在移至插件之前的初始位置(但这不是硬性规定)。但是,由于您的模块与模型紧密耦合,因此 lib/ 可能不是它的最佳位置。

我知道 37signals(和其他人)使用“关注”的概念作为将相关模型代码组织在模块中的一种方式。这是通过创建 app/concerns/ 并将模块放入其中来实现的。然后将该目录添加到 config/application.rb(Rails 2 的 config/environment.rb)中的应用程序加载路径:

config.load_paths += %W(#{Rails.root}/app/concerns)

然后可以像往常一样将模块混合到模型中。

这是 Jamis Buck 关于此的原始博客文章 - http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord

我个人更喜欢的另一个变体,虽然它不涉及模块,但使用这个插件:http: //github.com/jakehow/concerned_with

希望有帮助。

于 2010-09-28T10:06:50.027 回答
2

这个链接帮助我解决了这个问题。

http://ander.heroku.com/2010/12/14/concerns-in-rails-3/

我一直把它放在模型/扩展目录中。关注目录是有道理的,但“关注”这个词对我来说并不明显。也许它会在我身上生长。

我还在 application.rb 中添加了扩展路径

config.autoload_paths += %W(#{config.root}/app/models/extensions)
于 2011-11-04T03:19:37.707 回答