2016-12-05 74 views
0

我现在使用的是RailsMongoid。 假设我有以下型号:如何在带别名的模型类中包含模块?

class User 
    include Name 
end 

而且一个Name模块:

module Name 
    included do 
    field :name, type: String 

    #other methods here... 
    end 
end 

问题

现在我想User有两个字段:namenickname,都通过使用Name模块。我应该怎么做?谢谢。

编辑

要carify,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,让NicknameName的一个子类。但他们都是模块,所以我不知道这是否有效。

+0

将'field:nickname,type:String'添加到'Name'。你不明白的是什么? – max

+0

你好@max,问题是不是所有的模型都需要'昵称'字段。 说'Car'类,它可以包含'Name'模块,但'nickname'字段不适合这种情况。 'name'和'nickname'字段也有类似的地方,但它们也有不同的实现。请检查我编辑的问题。 –

+0

你不能像在Python中那样用Ruby导入模块的一部分。相反,你需要使用不同的模块和组合。 – max

回答

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" 
+0

感谢您解决我的问题最大!这种设计模式非常有用,一切都松散耦合。 –