【问题标题】:How can I use Mongoid and ActiveRecord in parallel in Rails 3?如何在 Rails 3 中并行使用 Mongoid 和 ActiveRecord?
【发布时间】:2011-09-26 07:09:18
【问题描述】:

我正在使用 rails 3,并使用 ActiveRecord 开始我的应用程序。现在,我有很多模型,并且关系开始变得复杂,有些可以用面向文档的结构更简单地表达,所以我想尝试迁移到 MongoDB 并使用 Mongoid。

我一直听说您不必使用全部 MongoDB 或什么都不使用,但您可以在迁移时并行使用这两者。不过,我看不到如何从文档中解决这个问题。

例如,我有:

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

理想情况下,我希望先将我的 Item activerecord 模型替换为 Mongoid 文档,因此我的项目存储在 MongoDB 中,而我的 UsersProducts 可以保留在我的 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

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord mongodb mongoid


    【解决方案1】:

    我创建了一个用于在活动记录模型中欺骗关系的模块。

    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
    

    【讨论】:

      【解决方案2】:

      ...仅用于跟踪目的, 我想添加一些我刚刚在该字段中发现的内容:

      DRY up your SQL+NoSQL Rails projects

      【讨论】:

        【解决方案3】:

        我所做的只是像这样模拟 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 方法,但您至少能够很好地模拟两者之间的关系。

        希望这会有所帮助。

        【讨论】:

        • 我喜欢你天真的方法!你在生产中有类似的东西吗?它是否通过了时间的探测?
        【解决方案4】:

        我看不出为什么您不能在同一个应用程序中同时拥有 ActiveRecord 和 Mongoid 模型。话虽如此,我几乎可以肯定,如果您尝试在 ActiveRecord 和 Mongoid 模型之间创建关系,您会遇到问题。

        如果您的 ActiveRecord 模型高度相互关联,但更适合文档结构,那么我建议您只管硬着头皮将它们全部转换为 Mongoid 文档。我最近在一个(大型)项目上必须这样做,而且压力比你想象的要小。

        如果您对模型进行了良好的单元测试,那么它应该是一个整体。如果你不这样做 - 首先编写你的单元测试,确保它们通过 ActiveRecord,然后开始将东西迁移到 Mongoid。

        【讨论】:

          猜你喜欢
          • 2016-10-22
          • 1970-01-01
          • 2011-07-21
          • 1970-01-01
          • 1970-01-01
          • 2015-02-28
          • 1970-01-01
          • 1970-01-01
          • 2011-09-29
          相关资源
          最近更新 更多