Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3/ActiveRecord: How to switch/change table name during request dynamically?

I want to change the table name of the ActiveRecord model class during request dynamically.


For example, there are many tables having similar structure(columns):

mydb:
  sample_data_12222
  sample_data_12223
  sample_data_12224
  sample_data_12225
  ...

So, what I want to do is...

_1. Defining the base model class like:

class SampleData < ActiveRecord::Base

_2. Changing the target table during request like:

def action_method
  SampleData.set_table_name "sample_data_#{params[:id]}"
  @rows = SampleData.all

It seems that above code is right if it's run on non-threaded environment (like on Passenger/mod_rails). But it's not thread-safe, so it may not work on threaded-environment (like on JRuby-Rack).

Also I tried creating the delived class like this:

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

But it cause memory leaks, though the delived model class is not used any more after request was completed. :(


Is there a better way to do that?

like image 567
kaorukobo Avatar asked Sep 08 '11 11:09

kaorukobo


1 Answers

I would use class variables:

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

Now you can use the derived classes over and over, without causing memory leaks.

Depending on your actual situation (eg you do not know the IDs on beforehand), you could check whether the id is already present in the Hash dynamically and add it if not.

like image 51
Veger Avatar answered Sep 21 '22 17:09

Veger