Batman
Batman

Reputation: 6353

Get user coordinates within model

I've created my search and I'm trying to add conditionals for when certain parameters aren't provided.

This is what it looks like:

Controller:

@search = Availability.search(params)

Availability.rb:

  # Scopes for search filters
  scope :close_to, -> (venues) {where{facility.venue_id.in venues}}
  scope :activity, -> (activity) {where{facility.activities.id == activity}}
  scope :start_date, -> (datetime) {where{start_time >= datetime}}
  scope :end_date, -> (datetime) {where{end_time <= datetime}}
  scope :not_booked, -> {where(booking: nil)}
  scope :ordered, -> {order{start_time.desc}}
  scope :join, -> {joins{facility.activities}}

  # Main search function
  def self.search params
    # Check if date is nil
    def self.date_check date
      date.to_datetime if date
    end

    search = {
      venues: Venue.close_to(params[:geolocation]),
      activity: params[:activity].to_i,
      start_date: date_check(params[:start_time]) || DateTime.now,
      end_date: date_check(params[:end_time]) || 1.week.from_now
    }

    result = self.join.not_booked
    result = result.close_to(search[:venues])
    result = result.activity(search[:activity])
    result = result.start_date(search[:start_date])
    result = result.end_date(search[:end_date])
    result.ordered
  end

Venue.rb

  # Scope venues near geolocation
  scope :close_to, -> (coordinates) {near(get_location(coordinates), 20, units: :km, order: '').pluck(:id)}

  # If given coordinates, parse them otherwise generate them
  def self.get_location coordinates=nil
    if coordinates
      JSON.parse coordinates
    else
      location = request.location
      [location.latitude, location.longitude]
    end
  end

Everything works great except when I don't provide params[:geolocation]

I'd like to be able to return Availabilities which are in proximity to the user if the user doesn't enter the name of a city for example.

My url looks like this: localhost:3000/s?activity=1

From there, in the Venues model, I want to return Venues that are close to the users location.

I've been looking at Geocoder and using request.location but that doesn't work at the model level. Any suggestions?

I also considered adding the IP address to the url dynamically but if I did that, if a url was shared, it would return incorrect results.

Upvotes: 0

Views: 96

Answers (1)

Ryan Bigg
Ryan Bigg

Reputation: 107728

You'll need to be passing in the location from the controller to the model. Models do not have access to the request, because they are designed to be accessed in more than just the request cycle.

You should pass it to your search method as another argument.

Upvotes: 1

Related Questions