Rails 3/ActiveRecord:如何在动态请求期间切换/更改表名?

kao*_*obo 6 ruby ruby-on-rails

我想动态地在请求期间更改ActiveRecord模型类的表名.


例如,有许多表具有相似的结构(列):

mydb:
  sample_data_12222
  sample_data_12223
  sample_data_12224
  sample_data_12225
  ...
Run Code Online (Sandbox Code Playgroud)

那么,我想要做的是......

_1.定义基本模型类,如:

class SampleData < ActiveRecord::Base
Run Code Online (Sandbox Code Playgroud)

_2.在请求期间更改目标表,如:

def action_method
  SampleData.set_table_name "sample_data_#{params[:id]}"
  @rows = SampleData.all
Run Code Online (Sandbox Code Playgroud)

如果它在非线程环境(如Passenger/mod_rails)上运行,那么上面的代码似乎是正确的.但它不是线程安全的,因此它可能不适用于线程环境(如JRuby-Rack).

我也尝试像这样创建一个deliverd类:

def action_method
  @model_class = Class.new(SampleData)
  @model_class.set_table_name "sample_data_#{params[:id]}"
  @rows = @model_class.all
Run Code Online (Sandbox Code Playgroud)

但是它会导致内存泄漏,尽管在请求完成后不再使用deliverd模型类.:(


有没有更好的方法呢?

Veg*_*ger 6

我会使用类变量:

class SampleData < ActiveRecord::Base
  class << self
    @@model_class = {}

    # Create derived class for id
    @@model_class[id] = Class.new(SampleData)
    @@model_class[id].set_table_name "sample_data_#{id}"
    # Repeat for other IDs
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,您可以反复使用派生类,而不会导致内存泄漏.

根据您的实际情况(例如,您事先不知道ID),您可以检查ID是否已经动态地存在于Hash中,如果没有则添加它.