0

I am making a model in ruby like the one I have shared below. The problem is that I need to reference the key-value pairs in locations for my filters. So how should I go about in doing that?

class User
 include Mongoid::Document
 store_in collection: "user"

 field :name, type: String
 field :number, type: String
 field :locations #is an array of locations with key-value pairs
end

for example, the user object is like

db.user.findOne()
{
 "name" : "ABC",
 "number" : "1234567890",
 "locations" : [
    {
        "state" : "X",
        "district" : "AY",
    },
    {
        "state" : "V",
        "district" : "BZ",
   }
 ],
}

Using filters I need to find all users who are in say state = "X". Mongo query will use locations.state but how to define a field that can help in querying such states. For querying in filters I am using Active Admin like below:

filter :locations, label: 'Locations', as: :select,
     collection: {
         'x': 'X',
         'v': 'V',
     }

So, I need a way to query states in locations rather than locations. Any help in how to approach this problem will be really helpful.

Let me know if any other details are needed.

Thanks in Advance!

1 Answers1

0

There are several ways to do this:

1. Use an array type

class User
  include Mongoid::Document
  store_in collection: "user"

  field :name, type: String
  field :number, type: String
  field :locations, type: Array
end

2. Use embedded documents

class User
  include Mongoid::Document
  store_in collection: "user"

  field :name, type: String
  field :number, type: String
  embeds_many :locations
end

class Location
  include Mongoid::Document
  field :state, type: String
  field :district, type: String
  embedded_in :user  
end

The key advantage here is that you can place the appropriate business logic on the Location model instead of swelling your User model.

3. Use referenced documents

class User
  include Mongoid::Document
  store_in collection: "user"

  field :name, type: String
  field :number, type: String
  has_and_belongs_to_many :locations
end

class Location
  include Mongoid::Document
  field :state, type: String
  field :district, type: String
  has_and_belongs_to_many :users
end

This is somewhat like #2 but lets you use normalized documents for location instead of duplicating them for each user. This was a bit of a performance problem in earlier versions of Mongoid (and MongoDB) since there was no join support.

Community
  • 1
  • 1
max
  • 96,212
  • 14
  • 104
  • 165
  • after doing this how do I reference these locations in the filter that I mentioned? The User model doesn't provide any option to refer to locations. – user1575044 Mar 07 '18 at 15:42
  • https://stackoverflow.com/questions/18148166/find-document-with-array-that-contains-a-specific-value – max Mar 07 '18 at 15:45
  • https://stackoverflow.com/questions/22473391/custom-search-with-ransacker http://nikhgupta.com/code/activeadmin/custom-filters-using-ransacker-in-activeadmin-interfaces/ The above 2 links helped – user1575044 Mar 08 '18 at 08:43