Как я могу использовать Mongoid и ActiveRecord параллельно в Rails 3? - PullRequest
22 голосов
/ 01 июля 2011

Я использую рельсы 3 и начал свое приложение с ActiveRecord. Теперь у меня есть много моделей, и отношения начинают усложняться, и некоторые из них могут быть проще выражены с помощью Document-Oriented структуры, поэтому я хотел бы попробовать перейти на 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 на документ Mongoid, чтобы мои элементы сохранялись в MongoDB, а мои Users и Products могли оставаться в моей базе данных SQL

Дело в том, что я не понимаю, как это сделать. Я иду об этом правильным путем?

Возможно, другой альтернативой является сохранение базового предмета 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

Спасибо!

Ответы [ 4 ]

14 голосов
/ 06 октября 2012

То, что я сделал, это просто высмеял отношения с методами в каждой модели 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

Конечно, у вас не будет всех методов AR в модели VisitSession Mongoid, но вы по крайней мере сможете довольно хорошо высмеивать отношения между ними.

Надеюсь, это поможет.

10 голосов
/ 04 июля 2011

Я не вижу причин, по которым вы не могли бы иметь обе модели ActiveRecord и Mongoid в одном приложении. При этом я почти уверен, что у вас возникнут проблемы, если вы попытаетесь создать отношения между вашими ActiveRecord и Mongoid моделями.

Если ваши модели ActiveRecord тесно связаны между собой, но лучше подходят для структуры документа, то я бы предложил просто прикусить маркер и преобразовать их все в документы Mongoid. Я должен был сделать это недавно на (крупномасштабном) проекте, и это значительно менее напряженно, чем вы думаете.

Если у вас есть хорошие юнит-тесты для ваших моделей, то это должно быть просто. Если вы этого не сделаете - сначала напишите свои модульные тесты, убедитесь, что они прошли с ActiveRecord, а затем начните переносить вещи в Mongoid.

0 голосов
/ 16 мая 2018

Я создал модуль для подмены отношения в моделях активных записей.

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 вместо XXX_id

Я также называю пространство имен всеми моими моделями Монго под 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
0 голосов
/ 31 января 2015

... только для целей отслеживания, Я хотел бы добавить кое-что, что я только что обнаружил в этом поле:

СУХОЙ проект SQL + NoSQL Rails

...