2012-11-11 33 views
5

我有一個Rails應用程序與幾個車型具有相同的結構:擴展Ruby類有一個獨立的代碼

class Item1 < ActiveRecord::Base 
    WIDTH = 100 
    HEIGHT = 100 
    has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"} 
    validates_attachment :image, :presence => true 
end 


class Item2 < ActiveRecord::Base 
    WIDTH = 200 
    HEIGHT = 200 
    has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"} 
    validates_attachment :image, :presence => true 
end 

實際的代碼更復雜,但是這足以讓簡單。

我想我可以把代碼的公共部分放在一個地方,然後在所有模型中使用它。

這裏是我腦海:

class Item1 < ActiveRecord::Base 
    WIDTH = 100 
    HEIGHT = 100 
    extend CommonItem 
end 

module CommonItem 
    has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"} 
    validates_attachment :image, :presence => true 
end 

很明顯,它不適合,原因有二:

  1. CommonItem沒有關於類方法調用我的想法。
  2. WIDTHHEIGHT常數在CommonItem而不是Item1中查找。

我試圖用include代替extendclass_eval和類繼承的一些方法,但沒有工作。

看來我失去了一些明顯的東西。請告訴我什麼。

+2

http://api.rubyonrails.org/類/ ActiveSupport/Concern.html是爲這樣的東西。 – jdoe

回答

3

這是我會怎麼做:當它包含

class Model 
    def self.model_method 
    puts "model_method" 
    end 
end 

module Item 
    def self.included(base) 
    base.class_eval do 
     p base::WIDTH, base::HEIGHT 
     model_method 
    end 
    end 
end 

class Item1 < Model 
    WIDTH = 100 
    HEIGHT = 100 
    include Item 
end 

class Item2 < Model 
    WIDTH = 200 
    HEIGHT = 200 
    include Item 
end 

included方法被稱爲模塊。

我想我已經設法創建了一個類似的問題結構。該模塊正在調用由Model類的項目類繼承的方法。

輸出:

100 
100 
model_method 
200 
200 
model_method 
+0

不錯!使用'self.included'鉤子並沒有出現在我的腦海中。這是一個肯定的解決方案。 – Ivan

2

在Ruby,構建體使用以提取重複的代碼到一個單一的單元是方法

class Model 
    def self.model_method 
    p __method__ 
    end 

    private 

    def self.item 
    p self::WIDTH, self::HEIGHT 
    model_method 
    end 
end 

class Item1 < Model 
    WIDTH = 100 
    HEIGHT = 100 
    item 
end 

class Item2 < Model 
    WIDTH = 200 
    HEIGHT = 200 
    item 
end 
+1

下載者請解釋一下嗎?該代碼完美地解決了OP的問題,它具有與@ Dogbert代碼完全相同的行爲,而且更簡單,不需要任何形式的元編程,反射或掛鉤。 –