2011-08-09 19 views
1

我將ActiveRecordA的肉分解成模塊M,以便我能夠複製某些數據管道。原始A有AR宏方法,如belongs_to :X。雖然我能夠將非AR事物細分爲模塊並將其混合回A,但該模塊並不瞭解belongs_toB開箱即用的任何信息。我如何使這些模塊可用,然後將它們混合回新的淺A(現在只有include s M)和B,這是A的克隆,並帶有其自己的基礎AR表?或者我應該寫一些像acts_as插件(對吧?)而不是M?保留belongs_toA並複製它在B工程,但打敗了幹...將belongs_to分解爲一個公共模塊

+0

whats B?它是否與A類相似,其中包括M,A的一個子類,它很難遵循這樣的抽象要求。 –

+0

B是A的一個克隆,坐在同一個表的頂部,只有表名是不同的。 – Alexy

回答

3

當創建一個模塊,並在使用繼承? 問題came up today讓我想到Ruby on Rails開發人員真正瞭解他們使用的工具。

與重構共享功能的兩個模型有關的問題。一個普遍的要求和一個非常明智的想要做的事情,但意見和解決方案引起了我的眉毛一些什麼。 這是問題,有些編輯和重新格式化,以使其更清晰

我分解出一個ActiveRecord類A的肉到一個模塊男, 讓我能夠複製某些數據管道。

原始A模型具有ActiveRecord宏方法,如belongs_to :X。

儘管我能夠將非AR事物細分爲模塊 並將其混合回A,但模塊並不知道任何有關 belongs_to的內容或關於AR模型B的任何開箱即用功能。

如何使那些提供給模塊,然後將其混回 新淺淺,只包括男和B,這是一個克隆一個與自己的潛在AR表 ?或者我應該寫些類似於acts_as插件的東西 (對嗎?)而不是M?保留在 一個belongs_to的和B中的作品複製,但違背了DRY原則

我不明白的是,爲什麼問這個問題的人是把這個代碼放到一個模塊,而不是插入類的模型可能會從中下降。

在Rails中(幾乎)每個類都是從另一個類下降的權利? 您看到的代碼如

class MyModel < ActiveRecord::Base 

到處都是。很好,基地似乎有點神祕,我可以看到這種隱藏在這裏發生的事情,讓我們看看控制器的例子

當第一次生成正確時,所有控制器從ApplicationController下降? 所以,你得到

class MyController < ApplicationController 

你們有多少人把代碼放到應用程序控制器像以前一樣過濾器和電流)用戶的方法和最終使用在你的控制器和視圖代碼? 一旦你花時間考慮一下,那麼你可以看到,如果你把代碼放在公共的或者受保護的ApplicationController中,那麼從ApplicationController派生出來的所有控制器都能正確地獲得這些功能?

ApplicationController的僅僅是從的ActionController :: Base的定義是這樣的

class ApplicationController < ActionController::Base 

現在看起來很熟悉上面的使用是如此普遍,我開始思考下降的一類,很多Rails開發人員努力看到樹木的木材。

這是關於繼承。

的Rails把一堆方法爲ActionController::BaseActiveRecord::Base類(這就是他們,一個模塊內部類),這樣你就可以從這些類,從而繼承這些基類提供的方法和功能下降自己的類。

那麼爲什麼不創建一個抽象的ActiveRecord :: Base類來解決這個問題。在我看來,這是最明顯和最自然的做法。

我想出了這個解決方案

In a_base_class.rb 

class ABaseClass < ActiveRecord::Base 
    abstract true 
    has_many :whatevers 
    belongs_to :whatevers 

    def common_methods 
    #some code here 
    end 

end 

Then class a 

class A < ABaseClass 
    # Whatever 
end 

這可以被放置在模塊內部的命名空間的目的

如果你想要把一個模塊中,然後從WhateverModule下降:: ABaseClass那麼這是一個很酷的名稱間隔新的基類,以便類名不衝突,這是使用模塊的主要目的之一。命名空間類。

顯然使用任何真正的類名對你有意義。

@Rishav Rastogi爲使用模塊提供了一個很好的答案,這就是爲什麼人們真的想知道爲什麼這個解決方案對別人不那麼清楚,爲什麼這個問題甚至首先被問到,我開始得到印象人們真的不知道這樣的代碼確實

class SomeController < ApplicationController 

class MyModel < ActiveRecord::Base 

當這種東西,Rails開發者每天都在使用?

這完全是關於繼承。

抽象類和非抽象類都是從一個類繼承的嗎?從繼承的類可能很好地繼承了許多其他構成單一繼承鏈的類,但它仍然是單一繼承。每個班級只能從另一個班級下降。

那麼模塊可以做些什麼來提供幫助? 模塊有點混淆用於2個目的。 1)如前所述命名空間事物 2)提供多繼承場景。多重繼承在開發世界中是一個骯髒的詞。事情最終會陷入混亂,但模塊提供了一個很好的解決方案。

的你爲什麼會想多繼承的例子

的ActiveRecord :: Base提供像find_by_something和find.all返回的ActiveRecord的數組方法:: Base的對象(類代碼對象是實際的東西)

認識到這一點,將基類從數組類繼承是有意義的,但如果它這樣做,那麼它將無法從任何其他更合適的類繼承。解決方案是混合一個模塊。如果模塊包含數組類,那麼您可以獲得諸如.each和.empty之類的數組功能的所有功能?加上ActiveRecord :: Base使用的其他類的所有果汁。

那麼何時使用模塊以及何時繼承?

使用名稱空間模塊(類可以在一個模塊內)

使用繼承一個類

所以在同一時間一起使用這兩個,除非你想在這種情況下,只需要使用多重繼承模塊

+0

不錯 - 它是否適用於AR 2.3.12? – Alexy

+0

這只是標準的OO ruby​​代碼。不具體到任何版本的Rails或Ruby,所以是的,如果它不會,那麼你將無法做MyClass jamesc

+0

合作,完全改造了我的答案,使其成爲社區維基。希望它是有道理的,隨時可以貢獻。這是一個相當沉重的問題,我可能錯過了一些東西或沒有足夠清楚 – jamesc

1

基本上belongs_to是一種類方法。所以你可以隨時。你通常可以編寫一個插件acts_as以及

 

module ActiveRecord 
module Acts 
    module M 
    def self.included(base) 
     base.extend M::ClassMethods 
    end 

    module ClassMethods 
     def acts_as_m 
     class_eval <<-CLASS_METHODS 
      belongs_to :X 
     CLASS_METHODS 
    end 
    end 
end 
end 

ActiveRecord::Base.send(:include, ActiveRecord::Acts::M) 

class A 
acts_as_m 
end 
 

它只是運行class_eval

+0

爲什麼?根本沒有意義!問題是關於活動記錄。模塊M應該是一個抽象的ActiveRecord類,那麼你所要做的就是從Acts :: M而不是ActiveRecord :: Base – jamesc

+0

下載模型對不起,如果我最後的評論聽起來有點關閉。我現在只是爲什麼有人想要以這種方式擴展課程而感到困惑?而且似乎提問的人可能會按照同樣的思路思考。對於什麼是非常簡單的面向對象問題,這只是一個非常奇怪的方法。 – jamesc

+0

對不起,我已經改變了一點點的代碼。您通常不需要下載到Acts :: M,但是它可以用來組織插件,否則可能會干擾其他ActiveRecord :: *模塊和類。 –

相關問題