如何在带有别名的模型类中包含模块?

时间:2016-12-05 06:03:19

标签: ruby-on-rails mongoid

我目前正在使用RailsMongoid。 假设我有以下模型:

class User
  include Name
end

Name模块:

module Name
  included do
    field :name, type: String

    #other methods here...
  end
end

问题

现在我希望User有两个字段:namenickname,两者都使用Name模块。我该怎么做?谢谢。

修改

要知道,namenickname分享一些方法,但昵称本身也有一些特殊的方法。 例如,namenickname都可以执行以下操作:

def greeting(name)
  p "hello #{name}!"
end

但是,只有nickname才能执行以下操作:

def friendly_greeting(name)
  p "hello #{name}! You can call me #{nickname}"
end

我的第一个想法是创建2个模块NameNickname,让Nickname成为Name的子类。但它们都是模块,所以我不知道这是否有效。

1 个答案:

答案 0 :(得分:1)

模块不是类,因此不能使用经典的分层继承。但是,模块可以包含其他模块 - 这意味着您可以使用并行继承。

module Name
  extend ActiveSupport::Concern

  included do
    field :name, type: String
  end

  def greeting(name)
    p "hello #{name}!"
  end
end

module Nickname
  extend ActiveSupport::Concern

  include Name

  included do
    field :nickname, type: String
  end

  # if you named this method greeting it would
  # overwrite the implementation from the Name module
  def friendly_greeting(name)
    p "hello #{name}! You can call me #{nickname}"
  end
end

class Foo 
  include Name
end

class Bar
  include Nickname
end

Foo.new.name # nil
Foo.new.nickname # NoMethodError

Foo.fields.keys # ['_id', 'name']
Bar.fields.keys # ['_id', 'name', 'nickname']

Foo.new(name: 'Max').greeting # "hello Max!"
Foo.new(name: 'Max').friendly_greeting # NoMethodError

bar = Bar.new(name: 'Richard', nickname: 'Dick')
bar.greeting # "hello Richard!"
bar.friendly_greeting # "hello Richard! You can call me Dick"