1

I'm still new to rails and APIs. I'm trying to sort my incoming values from an API using sort_by but I can't really figure out why is not working.

as you can see bellow @results contains an array of objects in my case listings. When I click on the drop-down button for params[:sort], eg price it seems like I'm loosing what my params listings are so then @results in an empty array.

I'm not sure how to fix this if anyone can help I'll be deeply grateful.

listings_controller

class ListingsController < ApplicationController
  require 'will_paginate/array'

  def index
    listings = params[:listings]
    beds = params[:beds]
    baths = params[:baths]
    min_price = params[:min_price]
    max_price = params[:max_price]
    sub_type = params[:sub_type]
    min_area = params[:min_area]
    max_area = params[:max_area]
    residential = params[:residential]
    rental = params[:rental]
    multifamily = params[:multifamily]
    condominium = params[:condominium]
    garage_spaces = params[:garage]

    search_options = [ beds, baths, min_price, max_price, sub_type, min_area, max_area, residential, rental, multifamily, condominium, garage_spaces ]

    if params[:sort] == 'price'
      @results = Listing.find_listings(listings).sort_by { |listing| listing.price }
    elsif params[:sort] == 'date'
      @results = Listing.find_listings(listings).sort_by { |listing| listing.list_date }
    elsif params[:sort] == 'beds'
      @results = Listing.find_listings(listings).sort_by { |listing| listing.beds }
    elsif params[:sort] == 'sqft'
      @results = Listing.find_listings(listings).sort_by { |listing| listing.area }
    elsif search_options.any? { |option| option.present? }
      @results = Listing.find_listings_wo_subtype(listings, beds, baths, min_price, max_price, residential, rental, multifamily, condominium, sub_type, min_area, max_area, garage_spaces).paginate(page: params[:page], per_page: 20)
    else
      @results = Listing.find_listings(listings).paginate(page: params[:page], per_page: 20)
    end
  end

_listing_card.html.erb

<div class="container">
  <div class="dropdown">
    <button class="btn btn-info dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      Sort by:
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
      <li><%= link_to 'Price', listings_path(sort: 'price') %></li>
      <li><%= link_to 'Listing Date', listings_path(sort: 'date') %></li>
      <li><%= link_to 'Beds', listings_path(sort: 'beds') %></li>
      <li><%= link_to 'SQFT', listings_path(sort: 'sqft') %></li>
    </ul>
  </div>
</div>


<% @results.each do |listing| %>
  <div class="item">
    <div class="card-image">
      <% if listing.listing_images.present? %>
        <%= link_to image_tag(listing.listing_images[0], class: 'listing-photo'), listing_path(listing.mls_id) %>
      <% else %>
        <%= link_to image_tag('Image_not_available.png', class: 'listing-photo'), listing_path(listing.mls_id) %>
      <% end %>
    </div>
    <ul class="card-details">
      <li class="list-unstyled price"><%= number_to_currency(listing.price, precision: 0) %></li>
      <li class="list-unstyled bold"><%= listing.street_number %> <%= listing.street %> <br></li>
      <li class="list-unstyled bold"><%= listing.city %> <%= listing.state %> <%= listing.postal_code %><br></li>
      <li class="list-unstyled bold"><%= listing.beds %> beds | <%= listing.baths_full %> baths | <%= listing.area %> sqft </li>
      <li class="list-unstyled bold"><%= "Listing Date:  #{ format_date(listing.list_date) }"%></li>
    </ul>
  </div>
<% end %>

listing_service.rb

class ListingService

  attr_reader :listings,
              :residential,
              :rental,
              :multifamily,
              :condominium,
              :sub_type,
              :min_price,
              :max_price,
              :min_area,
              :max_area,
              :baths,
              :beds,
              :garage_spaces

  def initialize(listings, beds = '', baths = '', min_price = '', max_price = '', residential = '', rental = '', multifamily = '', condominium = '',
                  sub_type = '', min_area = '', max_area = '', garage_spaces = '' )
    @listings    = listings
    @beds        = beds
    @baths       = baths
    @min_price   = min_price
    @max_price   = max_price
    @residential = residential
    @rental      = rental
    @multifamily = multifamily
    @condominium = condominium
    @sub_type    = sub_type
    @min_area    = min_area
    @max_area    = max_area
    @garage_spaces = garage_spaces

    @conn = Faraday.new(url: "https://api.simplyrets.com") do |faraday|
      faraday.basic_auth(ENV['SIMPLY_RETS_API_KEY'], ENV['SIMPLY_RETS_API_SECRET'])
      faraday.adapter Faraday.default_adapter
    end
  end

  def find_listings
    get_url("/properties?q=#{@listings}&limit=200")
  end

  def get_url(url)
    response = @conn.get(url)
    JSON.parse(response.body, symbolize_names: true)
  end

  def self.find_listings(listings)
    new(listings).find_listings
  end

end

listing.rb

class Listing

  attr_reader :beds,
              :baths_full,
              :baths_half,
              :baths,
              :area,
              :street_number,
              :street,
              :city,
              :postal_code,
              :state,
              :price,
              :latitude,
              :longitude,
              :id,
              :mls_id,
              :listing_images,
              :roof,
              :cooling,
              :style,
              :stories,
              :fireplaces,
              :flooring,
              :heating,
              :foundation,
              :laundry_features,
              :lot_description,
              :pool,
              :sub_type,
              :interior_features,
              :lot_size,
              :area_source,
              :maintenance_expense,
              :additional_rooms,
              :exterior_features,
              :water,
              :view,
              :lot_size_area,
              :subdivision,
              :construction,
              :parking,
              :parking_leased,
              :parking_spaces,
              :parking_description,
              :lot_size_area_units,
              :type,
              :garage_spaces,
              :baths_three_quaters,
              :accessiblity,
              :year_built,
              :terms,
              :showing_instructions,
              :schools,
              :middle_school,
              :high_school,
              :elementary_school,
              :tax_year,
              :tax_anual_amount,
              :remarks,
              :association_fee,
              :association_name,
              :association_amenities,
              :list_date


  def initialize(listing)
    @beds            = listing[:property][:bedrooms]
    @baths_full      = listing[:property][:bathsFull]
    @baths_half      = listing[:property][:bathsHalf]
    @baths           = listing[:property][:bathrooms]
    @area            = listing[:property][:area]
    @street          = listing[:address][:streetName]
    @street_number   = listing[:address][:streetNumberText]
    @city            = listing[:address][:city]
    @postal_code     = listing[:address][:postalCode]
    @state           = listing[:address][:state]
    @price           = listing[:listPrice]
    @latitude        = listing[:geo][:lat]
    @longitude       = listing[:geo][:lng]
    @id              = listing[:listingId]
    @mls_id          = listing[:mlsId]
    @list_date       = listing[:listDate]


    # for property details
    @listing_images        = listing[:photos]
    @roof                  = listing[:property][:roof]
    @cooling               = listing[:property][:cooling]
    @style                 = listing[:property][:style]
    @stories               = listing[:property][:stories]
    @fireplaces            = listing[:property][:fireplaces]
    @flooring              = listing[:property][:flooring]
    @heating               = listing[:property][:heating]
    @foundation            = listing[:property][:foundation]
    @laundry_features      = listing[:property][:laundryFeatures]
    @lot_description       = listing[:property][:lotDescription]
    @pool                  = listing[:property][:pool]
    @sub_type              = listing[:property][:subType]
    @interior_features     = listing[:property][:interiorFeatures]
    @lot_size              = listing[:property][:lotSize]
    @area_source           = listing[:property][:areaSource]
    @maintenance_expense   = listing[:property][:maintenanceExpense]
    @additional_rooms      = listing[:property][:additionalRooms]
    @exterior_features     = listing[:property][:exteriorFeatures]
    @water                 = listing[:property][:water]
    @view                  = listing[:property][:view]
    @lot_size_area         = listing[:property][:lotSizeArea]
    @subdivision           = listing[:property][:subdivision]
    @construction          = listing[:property][:construction]
    @parking               = listing[:property][:parking]
    @parking_leased        = listing[:property][:parking][:leased]
    @parking_spaces        = listing[:property][:parking][:spaces]
    @parking_description   = listing[:property][:parking][:description]
    @lot_size_area_units   = listing[:property][:lotSizeAreaUnits]
    @type                  = listing[:property][:type]
    @garage_spaces         = listing[:property][:garageSpaces]
    @baths_three_quaters   = listing[:property][:bathsThreeQuarter]
    @accessiblity          = listing[:property][:accessibility]
    @year_built            = listing[:property][:yearBuilt]
    @terms                 = listing[:property][:terms]
    @showing_instructions  = listing[:property][:showingInstructions]
    @schools               = listing[:school]
    @middle_school         = listing[:school][:middleSchool]
    @high_school           = listing[:school][:highSchool]
    @elementary_school     = listing[:school][:elementarySchool]
    @tax_year              = listing[:tax][:taxYear]
    @tax_anual_amount      = listing[:tax][:taxAnualAmount]
    @remarks               = listing[:property][:remarks]
    @association_fee       = listing[:association][:fee]
    @association_name      = listing[:association][:name]
    @association_amenities = listing[:association][:amenities]
  end


  def self.find_listings(listings)
    listings = ListingService.find_listings(listings)
    listings.map do |listing|
      new(listing)
    end
  end
end
Community
  • 1
  • 1
Chantal
  • 33
  • 4
  • 1
    Does the index request work the first time? And the result gets emptied when you click the sort options? It seems like the listing variable is being set to nil when you click any of the sort options so you end up with Listing.find_listings(nil) which might be resulting in the empty result set – Dan Hilton Jul 24 '18 at 02:33
  • yes! correct. I just don't know how to fix it – Chantal Jul 24 '18 at 19:17
  • Does the listing parameter get set in the original request? I'm not seeing how it will ever get set – Dan Hilton Jul 24 '18 at 21:04
  • yes listings = params[:listings] at the top of the file on the index action of listings_controller.rb – Chantal Jul 24 '18 at 21:19
  • right, but is params[:listings] set to any value when it first hits the index endpoint? – Dan Hilton Jul 24 '18 at 21:21
  • uhm, well no. params[:listings] gets set on user input so it's dynamic – Chantal Jul 25 '18 at 17:00

0 Answers0