扩展模型以包括“帮助”方法

时间:2011-12-15 16:43:35

标签: ruby-on-rails

我有一种社交网站。

我有一个为用户创建路径的逻辑,并为UsersHelper方法user_path(user)和user_avatar(user)中描述的每个用户选择一个头像。

相反,我希望有像user.path和user.avatar这样的方法,但我不想在模型文件中包含该代码。

我尝试在帮助程序中扩展User类:

module UsersHelper
  class User
    def avatar
      ...
    end
  end
end

这不起作用 - 我添加的方法无法识别(我猜Rails会根据需要动态生成ActiveRecord类,所以我的方法不适用?)

我真的很感激想法

3 个答案:

答案 0 :(得分:1)

首先,帮助者与模型分离是有原因的。根据MVC模式,你的模型不应该对你的助手有所了解,反之亦然(后者通常在Rails中被忽略)。

但是,如果您想这样做,则需要在class ::User中执行model UsersHelper或以下操作:

module UsersHelper
end

class User
end

原因是Ruby命名空间类。因此,您定义了UsersHelper::User,而您的模型名为User。调用类::User或在模块外部定义它会强制它进入根命名空间。

然而,正如我所说,这不是“正确”的做法。更好的方法是你已经在做什么,或者使用装饰模式。

答案 1 :(得分:1)

Draper是一个非常棒的小宝石,可以很好地实现您正在寻找的功能(添加视图/演示文稿特定代码,同时仍然让它“感觉”像您正在使用的模型) 。在开始使用draper之后,我们删除了几乎所有特定于模型的助手。

基本上,它通过定义装饰器来工作,它就像模型的包装一样工作。装饰器看起来和感觉就像它正在装饰的模型,但可以在其上定义额外的功能。此外,如果您愿意,可以限制对某些字段的访问并锁定内容。

对于您的示例,添加装饰器将非常简单:

(在app / decorators / user_decorator.rb中)

class UserDecorator < ApplicationDecorator
  decorates :user

  def avatar
    # your implementation
  end

(在您的控制器中)

def index
  respond_with UserDecorator.decorate(User.all)
end

(在您的观点中)

<div class='avatar'><%= user.avatar %></div>
<div class='name'><%= user.name %></div>

答案 2 :(得分:0)

助手旨在与视图一起使用,而不是与模型一起使用。

如果您希望使用user.avatar之类的内容,则必须将其添加到模型中。

如果您想将其粘贴在帮助者中,请在UsersHelper中添加user_avatar方法。