Comment puis-je utiliser Mongoid et ActiveRecord en parallèle dans Rails 3?

J'utilise rails 3 et j'ai commencé mon application avec ActiveRecord. Maintenant, j'ai beaucoup de modèles, et les relations commencent à se compliquer, et certains pourraient être plus simplement exprimés avec une structure orientée Document, donc j'aimerais essayer de migrer vers MongoDB et utiliser Mongoid.

J'ai toujours entendu dire que vous n'aviez pas besoin d'utiliser tout MongoDB ou Rien, mais que vous pouviez utiliser les deux en parallèle lors de la migration. Je ne vois pas comment s'y prendre avec les docs bien.

Par exemple, j'ai:

class User < ActiveRecord::Base
   has_many :items
   has_many :products, :through => :items
end

class Product < ActiveRecord::Base
   has_many :items
end

class Item < ActiveRecord::Base
   belongs_to :user
   belongs_to :product

   # alot of data that fits a hierarchical document-oriented structure
end

Je voudrais idéalement commencer par remplacer mon modèle d'élément activerecord par un document Mongoid, donc mes éléments sont stockés dans MongoDB, et mes Users et Products peuvent rester dans mon SQL DB

La chose est, Je ne vois pas comment faire cela. Je vais sur ce la bonne manière?

Peut-être une autre alternative est de garder un élément AR de base

class Item < ActiveRecord::Base
   has_one :mongodb_item  ?? # I know this is wrong
end

class MongodbItem
   include Mongoid::Document
   belongs_to AR_Item ???    # I know this is also wrong
end

Merci!

21
demandé sur noli 2011-07-01 00:08:28

4 réponses

Je ne vois aucune raison pour laquelle vous ne pourriez pas avoir les deux modèles ActiveRecord et Mongoid dans la même application. Cela étant dit, je suis presque certain que vous rencontrerez des problèmes si vous essayez de créer des relations entre vos modèles ActiveRecord et Mongoid.

Si vos modèles ActiveRecord sont fortement interreliés, mais mieux adaptés à une structure de document, alors je suggère de mordre la balle et de les convertir tous en documents Mongoïdes. Je devais le faire récemment sur un (grand-ish) projet, et il est beaucoup moins stressant que vous ne le pensez.

Si vous avez de bons tests unitaires pour vos modèles, cela devrait être un snap total. Si vous n'écrivez pas d'abord vos tests unitaires, assurez - vous qu'ils passent avec ActiveRecord, puis commencez à migrer les choses vers Mongoid.

10
répondu theTRON 2011-07-04 00:34:17

Ce que j'ai fait était juste de me moquer de la relation avec les méthodes dans chaque modèle AR et le modèle Mongoid comme ça.

# visit_session.rb
class VisitSession
  include Mongoid::Document
  include Mongoid::Timestamps

  field :user_id, type: Integer
  index({user_id: 1},{name: :user_id_index})

  # Mock a belongs_to relationship with User model
  def user
    User.find(self.user_id)
  end
end

# user.rb
class User < ActiveRecord::Base

  # Mock a has_many relationship with VisitSession Mongoid model
  def visit_sessions
    VisitSession.where(user_id: self.id)
  end
end

Bien sûr, vous n'aurez pas toutes les méthodes AR sur le modèle MongoId de VisitSession, mais vous pourrez au moins bien vous moquer de la relation entre les deux.

J'espère que cela aide.

14
répondu Marc 2012-10-05 22:08:16

... juste à des fins de suivi, Je voudrais ajouter quelque chose que je viens de découvrir sur ce champ:

Séchez vos projets SQL + NoSQL Rails

0
répondu Luca G. Soave 2015-01-31 11:59:26

J'ai créé un module pour usurper la relation dans les modèles d'enregistrements actifs.

module MongoRelations
  def belongs_to_mongo(name, options = {})
    id_name = "mongo_#{name}_id".to_sym
    mongo_model = options[:through] || "Mongo::#{name.to_s.camelize}".constantize

    define_method(name) do
      id = send(id_name)
      mongo_model.find(id) if id.present?
    end

    define_method("#{name}=") do |value|
      send("#{id_name}=".to_sym, value.try(:id).to_s)
    end
  end
end

Dans ma table SQL, je nomme mes relations mongo en utilisant la convention mongo_XXX_id, au lieu de XXX_id

J'ai aussi l'espace de noms Tous mes modèles mongo sous Mongo::

Dans mon modèle d'enregistrement actif

class Foo < ActiveRecord::Base
    belongs_to_mongo :XXX
end

Qui permet

Foo.new.XXX = Mongo.find('123')
Foo.XXX

Ou

Foo.new.XXX_id = '123'
Foo.XXX
0
répondu David Chan 2018-05-16 14:58:41