Search code examples
ruby-on-railsgeokit

Error while using Geokit-Rails in model instance method


I am trying to use geokit-rails' .within helper method in a model instance method. Take a look here:

def self.crunch
        users = User.all

        users.each do |user|
            last_movement = Movement.where(user_id: user.id).try(:last)

            if last_movement
                users_near = Movement.where("user_id != ?", user.id).within(5, :origin => last_movement.user_lat, last_movement.user_lng)
            else
                next
            end

            if users_near.first
                users_near.each do |near|
                    #Make sure they don't exist in MB table

                    #Check for interests
                end
            end
        end
    end

I keep getting the error when I try to run the method: "SyntaxError: /Users/arsood/Documents/Consulting/SweetGlue_Service/app/models/matchbox.rb:10: syntax error, unexpected ')'"

Line 10 is:

users_near = Movement.where("user_id != ?", user.id).within(5, :origin => last_movement.user_lat, last_movement.user_lng)

When I remove the line it works fine. Is there a different way I need to call Geokit methods inside of a model rather than a controller?


Solution

  • I think the point is that origin needs a point or an array of lat and lng, you're passing 2 arguments so the synatx is wrong

    This should work without problems

    users_near = Movement.where("user_id != ?", user.id).within(5, :origin => [last_movement.user_lat, last_movement.user_lng])
    

    Allow me to add a few notes on your code

    • where always returns an active record relation, and running last on that would return nil if there's no records, no need to use try

      Movement.where(user_id: user.id).last
      
    • if you are using rails 4, there's a nice not method for active record, so you can change your query to something like this

      Movement.where.not(user_id: user.id).within(5, origin: [last_movement.user_lat, last_movement.user_lng])
      
    • if you add an instance method that returns a point array that would be helpful

      class Movement < ActiveRecord::Base
         def point
           [ user_lat, user_lng ] 
         end
      end
      

      The query would be simpler

      users_near = Movement.where.not(user_id:user.id).within(5, origin: last_movement.point)
      
    • I'm not sure what the users loop does, but i think it could be improved, if you explain what it's intended to do i could help with that too.