Boenne
Boenne

Reputation: 616

Save inherited object to separate collection in Mongoid

I read up to inheritance in mongoid and it seems that all inherited classes will save in the base class, e.g.

class BaseClass
end

class ChildClass1 < BaseClass
end

class ChildClass2 < BaseClass
end

It seems that all these store in the BaseClass collection.

I actually want them to store in separate collections, e.g. ChildClass1 - collection and ChildClass2 - collection.

Upvotes: 9

Views: 2633

Answers (5)

Harsh2000
Harsh2000

Reputation: 11

From Mongoid v8.1 onwards (Maybe v8.0 as well, haven't tested it in that version), you can use store_in collection: "collection_name" for this.

class Shape
  include Mongoid::Document
  store_in collection: :shapes
end

class Circle < Shape
  store_in collection: :circles
end

This will create the documents in 2 different collections (shapes and circles).

Reference: https://www.mongodb.com/docs/mongoid/current/reference/inheritance/#persistence-contexts

Upvotes: 0

Assaf Faybish
Assaf Faybish

Reputation: 41

I encountered the same problem and did not find a good solution on the web. After few attempts, I developed a solution:

class A
  include Mongoid::Document
  include Mongoid::Timestamps
  ...
end


class B < A
  def self.collection_name
    :your_collection_name_1
  end
  ...
end


class C < A
  def self.collection_name
    :your_collection_name_2
  end 
  ...
end

Before any access to mongo collection, mongoid gets the collection name from 'collection_name' method.

This way, I override the method 'collection_name' of mongoid class, which returns the collection name (instead of the name of the base class with 's': 'As')

So, all the write (or read) commands from class B will insert (select) into 'your_collection_name_1' collection and class C will insert into 'your_collection_name_2' collection.

Upvotes: 4

Slavik Shynkarenko
Slavik Shynkarenko

Reputation: 386

Please try this approach:

module Base
  extend ActiveSupport::Concern

  include Mongoid::Document
  include Mongoid::Timestamps

  included do
    # Common code goes here.
  end
end

class ChildClass1
  include Base
end

class ChildClass2
  include Base
end

I do this in my Rails 5 app and it works for sure.

Upvotes: 4

Ronna
Ronna

Reputation: 1190

I realise this was posted a year ago, but this might be what you were looking for:

class BaseClass
  include Mongoid::Document
  def self.inherited(subclass)
    super
    subclass.store_in subclass.to_s.tableize
  end
end

class ChildClass1 < BaseClass
end

class ChildClass2 < BaseClass
end

Upvotes: 4

shingara
shingara

Reputation: 46914

It's impossible to do that. Because it's the concept of the STI In Mongoid like explain by Durran the Mongoid creator

If you really want save in several collection you need use Module include like :

class BaseClass
  include MyModule
end

class ChildClass1
  include MyModule
end

class ChildClass2
  include MyModule
end

Upvotes: 3

Related Questions