0

在我的 rails 模型Post.rb中,我设置了以下方法:

  def category_names(seperator = ", ")
    categories.map(&:name).flatten.join(seperator).titleize
  end

  def publish_date
    read_attribute(:publish_date).strftime('%A, %b %d')
  end

我想将这些移到PostsHelper助手下的模块中。但是当我这样做时会出现无方法错误,因为我猜对的引用self丢失了。

那么我该如何解决这个问题呢?辅助模块是这些方法的错误位置吗?

4

2 回答 2

2

如果我没记错的话,辅助方法主要用于视图。

我确定的是您的辅助方法超出了模型的范围,这意味着您需要将要使用的属性传递给它们。例子:

  def category_names(categories, seperator = ", ")
    categories.map(&:name).flatten.join(seperator).titleize
  end

并在您看来:

category_names @post.categories

如果您发现自己编写的“帮助”方法并非专门用于您的视图,您可以创建一个服务对象并将它们包含在您的模型中。

编辑:服务对象

你可以在“app”目录下创建一个“services”目录并在那里创建你的类。

让我给你举个例子。我有一个 User 模型类,我想将所有与密码相关的方法分组到 UserPassword 服务对象中。

用户等级:

class User < ActiveRecord::Base
  include ::UserPassword
  ...
end

UserPassword 服务对象:

require 'bcrypt'

module UserPassword
  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end

  module ClassMethods
    def authenticate(email, password)
      user = find_by_email email
      if user and user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
        user
      end
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

所以我的用户实例对象(即u = User.first)可以调用u.encrypt_password,我的用户可以调用User.authenticate

也许还有其他方式,但我发现它灵活且易于编写和维护:)

于 2013-03-04T10:33:59.907 回答
1

助手总是用来帮助视图,但是如果你希望你的模型是干净的并且保持不相关的方法是分开的,请尝试在 Rails 3 中使用关注点。默认情况下,关注目录将存在于 Rails 4 中。

DHH 也有一篇不错的博文。

http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns

于 2013-03-04T10:55:06.493 回答