2017-11-13 4 views
0

내 웹 응용 프로그램의 백엔드 서버로 rails/mongodb를 사용하고 있습니다.레일 몽고드 다이나믹 모델 실패

데이터베이스가 매우 유연해야합니다. 런타임 중에 새 테이블을 정의하고 수정할 수 있어야합니다. 그래서 모델 엔티티와 모델 컬럼 (엔티티에 속함)을 작성하여 동적 컬럼으로 새 모델을 동적으로 작성할 수 있습니다.

내가 엔티티 기록으로 호출 할 수 있습니다 내가 함수를 쓴 레코드를 업데이트/읽기/만들려면 및 요청 된 모델의 클래스 반환 : 나는 엔터티 레코드와 기능으로 getObject를 호출

:

entity = Entity.find_by(name: obj) 
datarecord = getObject(entity) 

이 기능을 사용 :

def getObject(entity) 

    obj= Class.new() do 
     include Mongoid::Document 
     include Mongoid::Attributes::Dynamic 
     store_in collection: entity.name.pluralize.downcase 

     entity.columns.each do |column| 
      field column[:fieldNameOrPath] 
     end 

     entity.relationships.each do |relationship| 
     if relationship.typ =='Belongs To' 
      e = Entity.find(relationship.relationship_id) 
      belongs_to e.name.downcase 
      default_scope { includes(e.name.downcase)} 
     end 
     if relationship.typ =='Has Many' 
      e = Entity.find(relationship.relationship_id) 
      has_many e.name.pluralize.downcase 
     end 
     if relationship.typ =='Has And Belongs To Many' 
      e = Entity.find(relationship.relationship_id) 
      has_and_belongs_to_many e.name.pluralize.downcase 
     end 
     end 

#  def as_json(options={}) 
#  attrs = super(:include => [:user]) 
#  attrs["user"]["id"] = attrs["user"]["_id"].to_s 
#  attrs 
#  end 
    end 
    end 
    obj 
end 

를 내가 검색 반환 된 객체의 OBJ를 사용할 때이 작품 데이터 :

render json: { result: datarecord.all()} 

새 레코드를 만들고 업데이트하는데도 사용됩니다. 그러나 곧 나의 실체 관계 '에 속한'것처럼 나는 런타임 오류를 얻을 :

NoMethodError (undefined method `demodulize' for nil:NilClass): 

또는

NoMethodError (undefined method `constantize' for nil:NilClass): 

내가 문제를 생각 나는 관련 모델에 대해 정의 된 클래스가 없다는 것입니다?

두 번째 문제점은이 레코드가 자동으로로드되는 다른 레코드를 갖고 싶다는 것입니다. 정적 구현에서이 definde as_json 메서드는 관련된 레코드를 포함 할 수 있습니다 (내 코드에서 주석 처리 된 행 참조). 그러나 나는 동적 인 모델에서 이것을 어떻게 할 수 있는지 모른다.

어떤 아이디어가 여기에 잘못 가고 어떻게 해결할 수 있습니까? 어쨌든이 방법을 올바르게 구현하는 방법이 확실하지 않습니다. 아마도 더 좋은 방법이있을 것입니다.

감사합니다, 마이클

답변

0

최종 솔루션 :

동적 모든 클래스를 만듭니다.동적으로 클래스를 생성/instatiating하는 동안 나는 그들에게 새로운 이름 (모델의 접두사 + 이름)을 주었고 그래서 나는 db를 시드 (seed)하기 위해 필요한 초기 클래스 정의를 덮어 쓰지 않았다. 연관성을 포함하여 모든 클래스에 대한 메타 데이터를 읽고 관련된 모든 모델이나 상속에 대한 클래스를 동적으로 생성합니다. 따라서 모델을 변경 (필드 또는 연결/상속 조작) 할 때마다 동적으로 클래스를 만들고이를 일정하게 유지합니다. 다른 모든 경우에 대해 이미 정규화된 경우 기존 클래스를 사용합니다.

0

Mongoid의 관계 코드 않는 이름을 기반으로 추측 많은 (active_model_serializer 또는 무엇 -이 - 당신 같은 레일 또는 보석의 많은 다른 부분처럼). 당신이 클래스 사용자가 있다면 그래서,이 라인을 따라 뭔가 수행하여가, 수집 users에 저장되어야한다, 추가 구성없이, 가정합니다 : I는 전체 스택 추적을 볼 수 없습니다

user.class.name.tableize 

당신의 오류, 그래서 난 정확히에서오고 말할 수 없지만,이 근본적인 원인은 동적 클래스에 이름이 없다는 것입니다.

datarecord.name # => nil 

클래스는 상수에 할당 됨으로써 이름을 얻습니다. (어쩌면 다른 방법으로,하지만 지금은 기억이 안.)

datarecord.name # => nil 
FooBar = datarecord 
datarecord.name # => 'FooBar' 
+0

관련 항목 : https://stackoverflow.com/q/4113479/125816 –

+0

안녕하세요. 참고로 : 사용자가 약간의 의문의 여지가 있습니다. 나는 모든 'belongs_to'관계를 포함하는 as_json 함수를 원했습니다. 저는이 이전 코드에서 as_json 함수를 잘라내어 정적 클래스 User가있는 곳에 붙여 넣습니다. 현재 내 주요 문제는 belongs_to가 제대로 작동하지 않는다는 것입니다. 이 코드를 사용하여 레코드를 올바르게 검색 할 수는 있지만 레코드를 쓰거나 작성할 수는 없습니다. 난 항상 오류가 발생합니다 : NoMethodError (정의되지 않은 메서드 'nil : NilClass에 대한 constantize') : 그리고 저는 익명의 클래스 만 가지고 있기 때문입니다. –

+0

@MichaelH .: 네, 그렇게 생각합니다. –