mongoid/mongoid-geospatial

Feature request: Programmatic index creation

Closed this issue · 2 comments

I've been using this gem in an engine. Unfortunately I can't run the Mongoid rake tasks from within an engine spec suite, only from within a real Rails app it seems :(

From https://github.com/mongoid/mongoid/blob/master/lib/mongoid/railties/database.rake

      engines_models_paths = Rails.application.railties.engines.map do |engine|
        engine.paths["app/models"].expanded
      end
      root_models_paths = Rails.application.paths["app/models"]
      models_paths = engines_models_paths.push(root_models_paths).flatten

      models_paths.each do |path|
        ::Rails::Mongoid.create_indexes("#{path}/**/*.rb")
      end

Would be nice to encapsulate this in a method that is easy to use even outside of Rails, perhaps just sending it a list of paths:

module Mongoid
  module Indexing
    class << self
      def create_indexes models_paths = nil
        models_paths ||= rails_models_paths

        raise ArgumentError, "No model paths for creating mongoid indexes" if models_paths.blank?
        puts "CREATE INDEXES: #{models_paths}"

        models_paths.each do |path|
          ::Rails::Mongoid.create_indexes("#{path}/**/*.rb")
        end
      end

      def remove_indexes models_paths = nil
        models_paths ||= rails_models_paths

        raise ArgumentError, "No model paths for creating mongoid indexes" if models_paths.blank?
        puts "REMOVING INDEXES: #{models_paths}"

        models_paths.each do |path|
          ::Rails::Mongoid.remove_indexes("#{path}/**/*.rb")
        end
      end

      def rails_models_paths
        engines_models_paths = Rails.application.railties.engines.map do |engine|
          engine.paths["app/models"].expanded
        end
        root_models_paths = Rails.application.paths["app/models"]
        engines_models_paths.push(root_models_paths).flatten
      end          
    end
  end
end

Used this in my engine and it works beautifully :)

What do you think?

Here a snapshot of my code to generate random data in the vicinity in order to test a near search ;)

    def base_pos
      [longitude, latitude]
    end

    def longitude
      55.6760968
    end

    def latitude
      12.5683371
    end

    def random_point_within distance
      vector = random_vector(distance)
      (base_pos.geo_point + vector).to_lng_lat
    end

    def random_vector distance
      [distance, 0].vector.random_vector
    end

    # RANDOM PROPERTIES
    before :all do
      10.times do
        SearchableProperty.create type: 'apartment', 
          rooms: rand(6)+1, size: rand(100)+10, country_code: 'DK', 
          position: random_point_within(10.kms)
      end

      Mongoid::Indexing.create_indexes
      # puts SearchableProperty.all.map(&:inspect)
    end

Going to check out this better, but as a first thought: shouldn't this be something mongoid should support, and not us?
As for a quick way to workaround this, I got some indexes I need on workers and such but I just define 'em on the rails app too. Indexes need to be run just once anyway.