2017-03-16 5 views
1

클래스를 동적으로 만들고 각 클래스에 여러 데이터베이스 연결 중 하나를 할당하려고합니다.ActiveRecord 연결을 사용하여 Ruby 클래스를 동적으로 생성

나는 시간이 지남에 따라 변경되는 2 개 또는 3 개의 데이터베이스 사이에서 작업하므로, 각 연결 문자열을 별도의 클래스에 저장하고 ActiveRecord :: Base 대신 상속받는 것을 주저합니다.

다음은 "RuntimeError : 익명 클래스가 허용되지 않습니다."라는 오류가 발생하지만이를 해결하는 방법이나 더 좋은 대안이 있는지 확신 할 수 없습니다.

database.yml을

development: 
    adapter: mysql 
    username: root 
    password: 
    database: example_development 

oracle_development: 
    adapter: oracle 
    username: root 
    password: 
    database: example_oracle_development 

을 그리고 코드의 어떤 장소에서 당신은 당신의 모델의 DB 연결 변경 될 수 있습니다 :

class ClassFactory 
    def self.create_class(new_class, table, db_connection) 

     c = Class.new(ActiveRecord::Base) do 
     db = db_connection 
     self.table_name = table 
     establish_connection(:adapter => db.database_type, :host => db.host, :database => db.database, :username => db.username, :password => db.password).connection 
     end 

     Module.const_set new_class, c 
    end 
    end 

답변

0

동적 모델 establish_connection를 설정할 수 있습니다

User.establish_connection "oracle_#{RAILS_ENV}".to_sym 

또한 동적으로 모델 클래스를 만들 수 있습니다.

class ClassFactory 
    def self.create_class(new_class, table, connection_name) 

    Object.const_set(new_class, Class.new(ActiveRecord::Base) {}) 
    new_class.constantize.table_name = table 
    new_class.constantize.establish_connection(connection_name) 

    end 
end 

ClassFactory.create_class('NewUser', 'users', :development) 

그 후 NewUser 클래스를 사용할 수 있습니다.

이 버전은 Rails 5.0 및 3.2에서 작동합니다.

+1

소스를 읽음으로써 이것이 작동하지 않아야합니다. 'ActiveRecord :: ConnectionHandling # establish_connection'의 첫 줄은'raise "익명 클래스가 허용되지 않습니다." 이름이없는 한, 전달한 매개 변수를 한 번 살펴보기 전에. 내가 잘못 이해 한 적이 있습니까? – philomory

+0

코드는 Rails 3.2 이전 버전에서만 작동합니다. [연결 원본 설정] (http://apidock.com/rails/v4.0.2/ActiveRecord/ConnectionAdapters/ConnectionHandler/establish_connection). 잠시만 기다려주세요. 새로운 레일즈에서 작동하도록 노력하겠습니다. –

+0

흥미롭게도'ActiveRecord :: ConnectionHandler # establish_connection'이 아닌'ActiveRecord :: ConnectionHandling # establish_connection'을보고있었습니다. 혼동을 일으킬 정도로 비슷한 이름을 좋아해야합니다. – philomory

2

ActiveRecord::ConnectionHandling#establish_connection's source에 대해 name이 진실 값을 반환하지 않는 클래스에서 연결을 설정할 수 없습니다.

이제는 const_set을 사용하여 상수에 클래스를 할당하면 이름이 부여됩니다. 하지만 당신은 전에 establish_connection을 부르는 수행해야합니다 또한

class ClassFactory 
    def self.create_class(new_class, table, db_connection) 
    c = Class.new(ActiveRecord::Base) do 
     db = db_connection 
     self.table_name = table 
    end 

    Module.const_set new_class, c 
    c.establish_connection(:adapter => db.database_type, :host => db.host, :database => db.database, :username => db.username, :password => db.password).connection 
    end 
end 

, 당신은 정말 Module.const_set(...)을 원하는가? 그러면 Module::Foo이라는 클래스가 생성됩니다. 아마도 Object.const_set(...) (단지 Foo)을 원할 수도 있습니다. 심지어는 const_set(...) 이니 ClassFactory::Foo이 나옵니까?

+0

감사합니다. 도움이되었습니다. 네 말이 맞아, 나는 그걸 원하지 않았다. – martinmsf

관련 문제