2016-08-24 64 views
0

我創建了一個叫做Collection從我的項目模型的所有對象的集合中持有的接口。我想要這個集合vs一個數組,因爲我想要Collection中的其他字段。Ruby接口的集合對象

module Collection 
     def self.included(klass) 
     klass.attr_writer :list, type: Array 
     klass.attr_writer :class_type, type: Class 
     # Other fields go in here, along with their validations 
     klass.validate :validate_list 

     def validate_list 
      self.list.each { |o| 
      if(!o.instance_of? self.class_type) 
       klass.errors.add :list, 'Objects in list must be of the same type' 
       return 
      end 
      } 
     end 
     end 
    end 

我想用這個Collection持有模式::公司的對象,除了從其他列表中,我將在未來加入到投資組合模型的列表。我希望這個公司名單只是投資組合模型的一部分。

class Portfolio 
    include Model::Collection 

    @schema = { 
     'type' => 'object', 
     'properties' => { 
      'id'      => { 'type' => 'string' }, 
      'title'     => { 'type' => 'string' }, 
      'description'    => { 'type' => 'string' }, 
      'companies_list'   => {'type' => '?'}, # 1. Should this be array or Collections? 
     } 
    } 
    @modelName  = 'portfolios' 
    @collectionName = 'portfolios' 


    store_in collection: 'portfolios' 

    field :title,      type: String 
    field :description,    type: String 
    field :companies_list,   type: Array # 2. Should this be array or array of Collections? 

    embeds_many :companies 

end 

任何幫助表示讚賞。

+0

在模塊中使用術語「摘要」真的會讓人困惑。這有一個特定的含義,它與類有關,儘管Ruby沒有真正使用這個術語,因爲沒有用於表示抽象基類的標準方法。此外,這裏的問題還不清楚。 – tadman

+0

@tadman:對不起,我應該把它改成'class'? – chipmunk

+0

不,我的意思是說這是一個mixin模塊,但稱它爲「抽象」是錯誤的。爲什麼不把它稱爲'Model :: CollectionMethods'或'Model :: CollectionValidations'或類似的東西? – tadman

回答

2

我看到你來自Java世界,我想你想使Java的泛型紅寶石。但是,首先,爲什麼Java有泛型?讓我們有一個歷史課。

在Java的早期(1.5)之前,沒有泛型類型,所以程序員編寫代碼是這樣的:

List list = new ArrayList(); 
// add some strings to the list 
list.add("foo"); 
list.add("bar"); 

// we have to iterate over each element as an Object 
for (Object obj : list) { 
    // and then cast it to String 
    String str = (String) obj; 
    // in order to call String methods on it. 
    String uppercased = str.toUpperCase(); 

    // ... 
} 

這肯定是不幹燥。爲了減輕投射的痛苦,Java 1.5引入了泛型。

List<String> list = new ArrayList<String>(); 
// add some strings to the list 
list.add("foo"); 
list.add("bar"); 

// now we can iterate over the elements as strings 
for (String str : list) { 
    // no more casting, yay! 
    String uppercased = str.toUpperCase(); 

    // ... 
} 

但是等等,非通用版本在哪裏出錯?

在Java中,變量的類型確定哪一個方法可以調用的對象上,而不是對象本身。如果以更通用的類型(即超類)聲明變量,則不能調用屬於更特殊類型(即子類)的方法。如果你想調用這些方法,你必須施放。

但如果對象本身可以決定哪些方法可以在它被稱爲?突然間仿製藥變得毫無用處。 Ruby和許多其他動態語言都遵循這種方式。 Rubyists稱之爲鴨子打字 - 如果某件東西像鴨子一樣走路,鴨子像鴨子一樣走,它就是一隻鴨子。

list = ['foo', 'bar'] 
list.each do |str| 
    # we don't care what type str is, 
    # as long as it has the method upcase. 
    str.upcase if str.respond_to?(:upcase) 
end 

所以rubyists通常不會定義容器類,它們只是使用數組。如果應用類型限制,則只在將對象添加到數組時應用它。

list = [] 
list << something if something.is_a? Portfolio 

另一個原因堅持陣列是陣列具有真棒文字像['foo', 'bar']%w(foo bar)%i(foo bar),其定製的容器類型沒有。

+0

謝謝,這確實有助於清理很多概念! – chipmunk