我將ActiveRecord
類A
的肉分解成模塊M
,以便我能夠複製某些數據管道。原始A
有AR宏方法,如belongs_to :X
。雖然我能夠將非AR事物細分爲模塊並將其混合回A
,但該模塊並不瞭解belongs_to
或B
開箱即用的任何信息。我如何使這些模塊可用,然後將它們混合回新的淺A
(現在只有include
s M
)和B
,這是A
的克隆,並帶有其自己的基礎AR表?或者我應該寫一些像acts_as
插件(對吧?)而不是M
?保留belongs_to
在A
並複製它在B
工程,但打敗了幹...將belongs_to分解爲一個公共模塊
回答
當創建一個模塊,並在使用繼承? 問題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::Base
和ActiveRecord::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使用的其他類的所有果汁。
那麼何時使用模塊以及何時繼承?
使用名稱空間模塊(類可以在一個模塊內)
使用繼承一個類
所以在同一時間一起使用這兩個,除非你想在這種情況下,只需要使用多重繼承模塊
基本上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
爲什麼?根本沒有意義!問題是關於活動記錄。模塊M應該是一個抽象的ActiveRecord類,那麼你所要做的就是從Acts :: M而不是ActiveRecord :: Base – jamesc
下載模型對不起,如果我最後的評論聽起來有點關閉。我現在只是爲什麼有人想要以這種方式擴展課程而感到困惑?而且似乎提問的人可能會按照同樣的思路思考。對於什麼是非常簡單的面向對象問題,這只是一個非常奇怪的方法。 – jamesc
對不起,我已經改變了一點點的代碼。您通常不需要下載到Acts :: M,但是它可以用來組織插件,否則可能會干擾其他ActiveRecord :: *模塊和類。 –
- 1. 想要將模式分解爲一個公共部分+「私人」部分。如何?
- 2. 導入一個公共模塊的包中的幾個模塊
- 3. 共享一個公共源文件夾的多個MAVEN模塊
- 4. 瞭解一個基本的模塊化模式的私人和公共職能
- 5. 多個angular4模塊的公共代碼
- 6. 將角度模塊分解爲組件
- 7. Maven多模塊:聚合公共依賴在一個單一的?
- 8. python多個導入一個公共模塊
- 9. 將大型python文件拆分爲具有公共依賴關係的模塊
- 10. 使用公共模塊將多個文件回溯登錄
- 11. 從多個公共塊中創建多個模塊fortran 77
- 12. 添加公共代碼到一個角度過濾器模塊
- 13. 在模塊中聲明一個公共變量
- 14. 將數組分解爲塊
- 15. 作爲一個包含所有模塊的文件的公共python程序
- 16. 如何將此代碼分解爲兩個RequireJs模塊
- 17. 私人和公共包模塊?
- 18. A模塊不看公共變量
- 19. 如何使用Revealing模塊模式將一個JS模塊的公共方法調用到另一個模塊中?
- 20. 如何將python數據分析代碼分解爲模塊?
- 21. 公共部分
- 22. 在JavaScript中用一個公共分隔符解析一個字符串
- 23. 在matlab中將一個n * m圖像分解爲p * q塊
- 24. ZeroRPC:如何公開一個模塊
- 25. 爲什麼要將Maven項目分解爲子模塊?
- 26. 爲github創建一個公共git repo的分支
- 27. 將一個向量拆分爲R塊
- 28. 爲zend模塊化結構創建公共控制器類
- 29. 獨立的公共部分爲公共控制器
- 30. AngularJs從單獨的文件注入多個指令到一個公共模塊
whats B?它是否與A類相似,其中包括M,A的一個子類,它很難遵循這樣的抽象要求。 –
B是A的一個克隆,坐在同一個表的頂部,只有表名是不同的。 – Alexy