如何在Rails 3中并行使用Mongoid和ActiveRecord?
我正在使用rails 3,并使用ActiveRecord开始我的应用程序。 现在,我有很多模型,关系开始变得复杂,有些可以用Document-Oriented结构更简单地表达,所以我想尝试迁移到MongoDB并使用Mongoid。
我一直听说你没有必须使用所有MongoDB或者没有任何东西,但你可以在迁移时并行使用这两个。 我不知道如何从文档中解决这个问题。
例如,我有:
class User :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
我想在理想情况下首先用Mongoid文档替换我的Item activerecord模型,这样我的项目就存储在MongoDB中,我的Users
和Products
可以保留在我的SQL DB中
事情是,我不知道该怎么做。 我是以正确的方式来做这件事的吗?
也许另一种选择是保留基础AR项目
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
谢谢!
我没有看到为什么你不能在同一个应用程序中同时拥有ActiveRecord和Mongoid模型的原因。 话虽如此,我几乎可以肯定,如果你试图在ActiveRecord和Mongoid模型之间建立关系,你会遇到问题。
如果您的ActiveRecord模型是相互关联的,但更适合文档结构,那么我建议只是咬住子弹并将它们全部转换为Mongoid文档。 我最近不得不在一个(大型)项目上做到这一点,它的压力比你想象的要小得多。
如果您对模型进行了良好的unit testing,那么它应该是完全快速的。 如果你不这样做 – 首先编写你的unit testing,确保它们通过ActiveRecord,然后开始将东西迁移到Mongoid。
我所做的只是模仿每个AR模型和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
当然,你不会在VisitSession Mongoid模型上拥有所有的AR方法,但你至少能够很好地模拟两者之间的关系。
希望这可以帮助。
…仅仅为了追踪目的,我想在这个领域添加我刚刚发现的东西:
干掉你的SQL + NoSQL Rails项目
我创建了一个欺骗活动记录模型中关系的模块。
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
在我的SQL表中,我使用约定mongo_XXX_id命名我的mongo关系,而不是XXX_id
我还将所有mongo模型命名为Mongo ::
在我的活跃记录模型中
class Foo < ActiveRecord::Base belongs_to_mongo :XXX end
这使得
Foo.new.XXX = Mongo.find('123') Foo.XXX
要么
Foo.new.XXX_id = '123' Foo.XXX