2012-08-28 3 views
0

Datamapper를 사용하여 동적으로 테이블을 만들고 싶습니다.테이블 이름을 중간 애플리케이션으로 지정 Ruby-Datamapper

Datamapper를 사용하면 레거시 테이블과 스키마로 작업 할 수 있으며이 방법으로 테이블 이름을 설정하면 응용 프로그램이 아닌 초기화하는 동안에 만 사용할 수 있습니다.

Datamapper가 응용 프로그램에서 할당 된 테이블 이름으로 모델을 마이그레이션/업그레이드하고이 테이블을 쿼리하도록 알리는 쉬운 방법이 있습니까?

답변

0

후드에서 변경하지 않고 가장 쉬운 방법은 테이블 대신 별도의 데이터베이스를 사용하는 것입니다 (모든 관계가 별도의 데이터베이스에 저장된다고 가정). 블록의 추가 리포지토리에 대한 연결을 엽니 다.

DataMapper.setup(:external, "adapter://username:[email protected]/dbname") 
DataMapper.repository(:external) do...end 
1

이것은 문제가되지 않습니다.

모든 Ruby 클래스를 만들고 런타임에 다시 정의 할 수 있습니다. 초기화도 실행시입니다. 초기화는 다른 코드가 실행되기 전에 먼저 실행됩니다.

그래서 원숭이 패치는 쉽게 작동합니다. 그것은 그냥 추가 메서드, 변수 등을 추가하는 클래스를 다시 정의하는 초기화에서 추가 코드입니다.

"특수"라는 루비 코드는 컴파일시에만 실행된다는 의미는 없습니다. 루비는 이며, 언어는입니다.


동적으로 클래스를 만들려면 Dynamically creating class in Ruby을 참조하십시오.

문자열 배열에서 클래스를 동적으로 생성 할 필요가 없다고 가정하면 define_method으로 추가 메서드를 정의하거나 런타임에 Datamapper 메서드를 호출하여 특성을 추가 할 수 있습니다.

클래스에 새로운 메소드를 정의하려면 :

class Post 
    include DataMapper::Resource 
    property :title, String # the static way 
end 

Post.send :property, :title, String # add property the dynamic way (at run-time) 

어떤 테이블이나 속성을 사용하면 런타임에 정의주의 마십시오

Post.send :define_method, :new_method_name do 
end 

는 Datamapper 속성을 사용하여 새 속성을 정의하려면 동적으로 코드를 생성하는 코드가 다시 실행되지 않는 한 서버를 다시 시작하면 사용할 수 없습니다.


런타임에 테이블을 업데이트하려면, 당신은 단순히 정상으로 같은 일을, 즉, 호출된다

DataMapper.auto_upgrade! 

는 하나의 테이블을 업그레이드하려면, 당신은 또한 수행 할 수 있습니다

Post.auto_upgrade! 

2 경고 : 여러 프로세스가있는 경우, 동적 코드는 N 것 각 프로세스에서 실행할 수 없거나 추가 테이블의 모델 및 등록 정보를 사용할 수 없습니다.

생산 과정에서 발생할 수있는 것처럼 여러 작업자 프로세스가있는 경우이 문제가 발생합니다 (예 : 여러 명의 Unicorn 작업자가있는 Nginx 또는 Ha_proxy 뒤에 여러 잡동사니 노동자).

단일 프로세스 서버가있는 경우에는 문제가되지 않습니다.그러나 여러 작업자 프로세스가있는 경우 동적 코드를 실행하여 각 프로세스에서 이러한 추가 클래스 및 속성을 생성하여 사용 가능하게해야합니다.

각 프로세스가 초기화를 거치거나 (포크 된 경우 초기화를 상속하므로) 실제로 초기화와 동일합니다.

+0

답변을 추가해 주셔서 감사합니다. 나는 DataMapper 모델이 사용하는 레거시 스키마와 그것을 평가할 필요가있을 때'auto_upgrade'를 간단히 변경할 수 있다고 생각하지만, 런타임에이 속성을 지정하는 쉬운 방법이 있었으면 좋겠다. 'auto_upgrade' 또는'auto_migrate'를 피할 필요가있다. 프로덕션 환경에서는 그렇게하지 않을 것입니다. – djlumley