在Rails应用程序中使用模块的模型

时间:2010-09-23 18:13:04

标签: ruby-on-rails ruby coupling decoupling

我有一个模型需要从辅助源加载外部数据。我的模型可以从(可交换)中获取数据的许多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'目录有关吗?如果没有,最适合存储代码的地方在哪里?谢谢!

2 个答案:

答案 0 :(得分:27)

你是正确的,如果模块与特定模型紧密耦合,那么它不适合宝石/插件。

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

你可以把模块放在lib /中的一个地方。这适用于在app /中任何地方都不适合的代码,并且在将代码移动到插件之前通常是松散耦合代码的初始主页(但这不是一个硬性规则)。但是,由于您的模块与模型紧密耦合,因此lib /可能不适合它。

我知道37signals(和其他人)使用“关注点”的概念作为保持模块中相关模型代码组织的一种方式。这是通过创建app / concerns /并将模块放在那里来实现的。然后将该目录添加到app / 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

希望有所帮助。

答案 1 :(得分:2)

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

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

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

我还在application.rb

中添加了扩展路径
config.autoload_paths += %W(#{config.root}/app/models/extensions)