我有一個傳統的數據庫(甲骨文),在那個數據庫中我有幾個表持有不同的數據,但結構相同。我不允許以任何方式更改數據庫模式!如何動態設置模型的table_name?
我想要一個DRY ActiveRecord模型從右表中獲取正確的數據。問題是我需要動態覆蓋self.table_name
才能使其工作。
這裏是我的代碼:
ActiveRecord的:將所有類似的表繼承基類
class ListenLoc < ActiveRecord::Base
@@table_name = nil
def self.table_name
@@table_name
end
default_scope { where(validated: 1).where("URL_OK >= 0") }
scope :random_order, -> { order('DBMS_RANDOM.VALUE') }
scope :unvalidated, -> { unscope(:where).where(validated: 0) }
def self.get_category(cat_id)
where("cat_id = ?", cat_id)
end
def self.rand_sample(cat_id, lim)
where("cat_id = ?", cat_id).random_order.limit(lim)
end
end
子類看起來像這樣:
一個
class ListenLocA < ListenLoc
@@table_name = 'LISTEN_ADDR_A'
self.sequence_name = :autogenerated
belongs_to :category, class_name: 'ListenLocCatA', foreign_key: 'cat_id'
belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
end
B.
class ListenLocB < ListenLoc
@@table_name = 'LISTEN_ADDR_B'
self.sequence_name = :autogenerated
belongs_to :category, class_name: 'ListenLocCatB', foreign_key: 'cat_id'
belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
end
上述的工作,但我已經注意到,做特定的選擇查找時有一些陷阱。
這是一個很好的方法嗎?有沒有更好的方式動態傳遞self.table_name
?
更新:
有人會認爲,這應該工作,但我得到的表不存在由於ActiveRecord的嘗試創建一個對象之前驗證表,self.table_name未設置錯誤在ListenLoc模型上動態。
class ListenLocB < ListenLoc
self.table_name = 'LISTEN_ADDR_B'
self.sequence_name = :autogenerated
belongs_to :category, class_name: 'ListenLocCatB', foreign_key: 'cat_id'
belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
end
就個人而言,我會爲您的案例中的每個表有不同的模型。您可以在'ListenLoc'中將相似的代碼解壓縮成 –