ruby on rails - ¿Cómo puedo usar Mongoid y ActiveRecord en paralelo en Rails 3?
ruby-on-rails ruby-on-rails-3 (4)
Estoy usando Rails 3 y comencé mi aplicación con ActiveRecord. Ahora, tengo muchos modelos, y las relaciones se empiezan a complicar, y algunas podrían expresarse más simplemente con una estructura orientada a documentos, así que me gustaría intentar migrar a MongoDB y usar Mongoid.
Siempre he oído que no tienes que usar todo MongoDB o nada, pero que puedes usar los dos en paralelo mientras migras. Sin embargo, no veo cómo hacerlo con los documentos.
Por ejemplo, tengo:
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
Me gustaría comenzar reemplazando idealmente mi modelo Activerecord con un documento de Mongoid, para que mis elementos se almacenen en MongoDB y mis Users
y Products
puedan permanecer en mi base de datos SQL.
La cosa es que no veo cómo hacer esto. ¿Voy por esto de la manera correcta?
Quizás otra alternativa es mantener un elemento 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
¡Gracias!
... solo para el seguimiento, me gustaría agregar algo que acabo de descubrir en este campo:
Creé un módulo para suplantar la relación en los modelos de registro activos.
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
En mi tabla de SQL, nombro mis relaciones de mongo usando la convención mongo_XXX_id, en lugar de XXX_id
También uso el nombre de todos mis modelos mongo en Mongo ::
en mi modelo de registro activo
class Foo < ActiveRecord::Base
belongs_to_mongo :XXX
end
Que permite
Foo.new.XXX = Mongo.find(''123'')
Foo.XXX
o
Foo.new.XXX_id = ''123''
Foo.XXX
Lo que hice fue burlarme de la relación con los métodos en cada modelo AR y Mongoid.
# 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
Por supuesto, no tendrá todos los métodos AR en el modelo VisitSession Mongoid, pero al menos podrá burlarse de la relación entre los dos bastante bien.
Espero que esto ayude.
No veo ningún motivo por el que no pueda tener los modelos ActiveRecord y Mongoid en la misma aplicación. Una vez dicho esto, estoy casi seguro de que se encontrará con problemas si intenta crear relaciones entre sus modelos ActiveRecord y Mongoid.
Si sus modelos ActiveRecord están estrechamente interrelacionados, pero se adaptan mejor a la estructura de un documento, entonces le sugiero que solo muerda la viñeta y los convierta a todos en documentos de Mongoid. Tuve que hacer esto recientemente en un proyecto (grande) y es significativamente menos estresante de lo que piensas.
Si tiene buenas pruebas unitarias para sus modelos, entonces debería ser un complemento total. Si no lo hace, primero escriba las pruebas de su unidad, asegúrese de que pasen con ActiveRecord y luego comience a migrar a Mongoid.