我有以下定義的類,它們有許多具有較小變化的通用代碼。爲類似的句柄提取常見的ActiveRecord代碼
class ThirdPartyComponent < ActiveRecord::Base
belongs_to :prev_version, :class_name => 'ThirdPartyComponent', :foreign_key => 'prev_version_id'
has_one :next_version, :class_name => 'ThirdPartyComponent', :foreign_key => 'prev_version_id'
attr_accessible :name, :version, :installer, :install_script
mount_uploader :installer, ComponentFileUploader
mount_uploader :install_script, ComponentFileUploader
validates :name, :presence => true
validates :version, :presence => true, :format => { :with => /\A\d{1,3}\.\d{1,2}\z/ }
validates :installer, :presence => true
validates :install_script, :presence => true
validate :increased_version
def increased_version
# Check to ensure that version number is greater than the previous version number for the same component set
unless prev_version.nil?
version > prev_version.version
end
end
def all_previous_versions
prev_versions = all_versions
prev_versions.shift
prev_versions
end
def all_versions
current_version = self
all_versions = [current_version]
while !current_version.prev_version.nil?
all_versions << current_version.prev_version
current_version = current_version.prev_version
end
all_versions
end
end
class RegistryComponent < ActiveRecord::Base
belongs_to :prev_version, :class_name => 'RegistryComponent', :foreign_key => 'prev_version_id'
has_one :next_version, :class_name => 'RegistryComponent', :foreign_key => 'prev_version_id'
attr_accessible :name, :version, :registry_file
mount_uploader :registry_file, ComponentFileUploader
validates :name, :presence => true
validates :version, :presence => true, :format => { :with => /\A\d{1,3}\.\d{1,2}\z/ }
validates :registry_file, :presence => true
validate :increased_version
def increased_version
# Check to ensure that version number is greater than the previous version number for the same component set
unless prev_version.nil?
version > prev_version.version
end
end
def all_previous_versions
prev_versions = all_versions
prev_versions.shift
prev_versions
end
def all_versions
current_version = self
all_versions = [current_version]
while !current_version.prev_version.nil?
all_versions << current_version.prev_version
current_version = current_version.prev_version
end
all_versions
end
end
我也在尋找在未來添加一些其他組件,再次具有非常相似的功能。
我想從這些類中提取通用代碼到單個文件(包括ActiveRecord方法調用,如驗證等),然後在具體的類中引用它們。
到目前爲止,我已經試過了,
- 繼承 - 我創建了一個從ActiveRecord的繼承了基類,然後從基類繼承的每個類。結果:Rails抱怨說找不到名稱與基類相匹配的數據庫表。
- 繼承 - 我認爲在創建基類如無表模型代替(見http://railscasts.com/episodes/219-active-model),但是然後我意識到具體的類也將缺乏完整的ActiveRecord功能
組合物 - 我試圖在一個模塊中定義的通用代碼然後使用包含或擴展在具體的類來訪問它,如下所示。
module ComponentBase belongs_to :prev_version, :class_name => self.class.name, :foreign_key => 'prev_version_id' has_one :next_version, :class_name => self.class.name, :foreign_key => 'prev_version_id' attr_accessible :name, :version validates :name, :presence => true validates :version, :presence => true, :format => { :with => /\A\d{1,3}\.\d{1,2}\z/ } validate :increased_version def increased_version # Check to ensure that version number is greater than the previous version number for the same component set unless prev_version.nil? version > prev_version.version end end def all_previous_versions prev_versions = all_versions prev_versions.shift prev_versions end def all_versions current_version = self all_versions = [current_version] while !current_version.prev_version.nil? all_versions << current_version.prev_version current_version = current_version.prev_version end all_versions end end class RegistryComponent < ActiveRecord::Base include ComponentBase attr_accessible :registry_file mount_uploader :registry_file, ComponentFileUploader validates :registry_file, :presence => true end
這導致錯誤,該
belongs_to
方法沒有用於ComponentBase
定義。這看起來是最有希望的解決方案,但有什麼方法可以在包含它們的類的上下文中執行ActiveRecord類方法嗎?或者,有沒有更好的方式來達到同樣的目標?
請參閱我對以下答案的評論 – richard