2017-03-13 14 views
0

私はモデルのためにこれを試してみましたMVCをメタプログラミングを通じて必要なあらゆる種類のデータを作成するための動的なアプリケーションを作成しようとしています:RoRとmongodbでモデルを動的に作成する方法は?

class DynamicRecord 

    attr_accessor :name, :attributes 

    def initialize(name, attributes = []) 
     raise "Error: Constant #{name} already in namespace" if name.in? Object.constants 
     a_new_class = Class.new(Object) do |clazz| 
      include Mongoid::Document 
      attributes.map do |attribute| 
       field attribute[:name], type: attribute[:type] 
      end 
     end 
     Object.const_set(name, a_new_class) 
    end 
end 

DynamicRecord.new('Person', [{name: :name, type: String}, {name: :email, type: String}]) 

person = Person.new(name: "Foo", email: "[email protected]") 
person.save 

その後、私はこのエラーを取得する:

Mongo::Error::OperationFailure: Invalid ns [mongodb_divcad_development.] (16257) 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/operation/result.rb:256:in `validate!' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/operation/write/insert.rb:60:in `block in execute_message' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/server/connection_pool.rb:107:in `with_connection' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/server.rb:242:in `with_connection' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/operation/write/insert.rb:59:in `execute_message' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/operation/write/write_command_enabled.rb:39:in `execute' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/collection.rb:365:in `block in insert_one' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/retryable.rb:112:in `write_with_retry' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongo-2.4.1/lib/mongo/collection.rb:356:in `insert_one' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/query_cache.rb:182:in `insert_one_with_clear_cache' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:79:in `insert_as_root' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:27:in `block in insert' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:118:in `block (2 levels) in prepare_insert' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:373:in `_run__4510143668266298615__create__callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:80:in `run_callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/interceptable.rb:138:in `run_callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:117:in `block in prepare_insert' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:373:in `_run__4510143668266298615__save__callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:80:in `run_callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/interceptable.rb:138:in `run_callbacks' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:116:in `prepare_insert' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/creatable.rb:23:in `insert' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/mongoid-5.2.0/lib/mongoid/persistable/savable.rb:23:in `save' 
    from (irb):70 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start' 
    from /home/cassiano/.rvm/gems/ruby-2.3.3/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>' 
    from bin/rails:4:in `require' 
    from bin/rails:4:in `<main>' 

この缶終わり?エンティティ属性値モデルに陥ることなく、より良いアプローチがありますか?

答えて

2

動的モデルを使用しようとすると、Mongoidは名前空間について認識しません。私はこの試みた

class DynamicCollection 
    def self.create(collection, fields) 
    klass = Class.new do 
     include Mongoid::Document 
     store_in collection: collection.downcase 

     fields.each do |item| 
     field item[:name], type: item[:type] 
     end 
    end 

    Object.const_set(collection, klass) 
    end 
end 

fields = [ 
    {name: 'name', type: String}, 
    {name: 'email', type: String} 
] 

DynamicCollection.create('Demo', fields) 

Demo.create!(name: 'SomeValue', email: 'SomeValue') 
0

私はローカルでこれをしようとしなかったが、これはダムの答えかもしれない...しかし、私はattributes.eachに

attributes.mapを変更しますマップは、配列を返すとエラーになりますように思えます。 mongoidのソースを見ると

また... https://github.com/mongodb/mongoid/blob/master/lib/mongoid/fields.rb#L335

。おそらく利用できるadd_fieldというメソッドがあります。

+0

:それを修正するためには、store_in

例で名前空間を設定する必要があり 'a_new_class = Class.new(Object)を はMongoid ::ドキュメント を含まないMongoidが含まれています。 :フィールド attributes.each do | attribute | フィールド属性[:name]、タイプ:属性[:type] add_field属性[:name] end end' 同じエラー... =/'.map'も同様に動作します – Cassiano

関連する問題