3

How can I create an app in Rails that will let me input search parameters, which are then passed to an external API to perform the search, and then display those results in my app. I'm trying to use HTTParty to achieve this but I'm a bit lost. I've tried creating a class method in app/services and accessing it in my controller, and then calling the instance variable in my view. At the moment it's throwing a Routing Error uninitialized constant ResultsController::Api. Would be super grateful for some help.

services/Api.rb

class Api
  include HTTParty
  base_uri "search.example.com"
  attr_accessor :name

  def initialize(name)
    self.name = name
  end

  def self.find(name)
    response = get("/results&q=#{name}")
    self.new(response["name"])
  end

results_controller.rb

class ResultsController < ApplicationController
  include Api

  def index
    @results = Api.find('test')
  end
end

Routes:

Rails.application.routes.draw do
  resources :results
  root 'results#index'
end
Vasilisa
  • 4,604
  • 3
  • 20
  • 25
  • what is the purpose of the statement `include Api` in `ResultsController`? – Vlatko Ristovski Jan 22 '19 at 13:53
  • Yeah, it's not actually necessary now that I look at it –  Jan 22 '19 at 13:57
  • There is where your error lies actually. `Api` is not a module to include it, and it needs to be under `app/services/api.rb` ( keep in mind, Ruby files have a convention of naming with lower case underscore names ) so Rails can autoload it. – Vlatko Ristovski Jan 22 '19 at 14:02

1 Answers1

3

You're almost right, just need some changes here. At first, rename Api.rb to api.rb - by convention, all files should be named in lower snake_case

class Api
  include HTTParty
  base_uri "http://search.spoonflower.com/searchv2"

  def find(name)
    self.class.get("/designs", query: { q: name }).parsed_response
  end
end

class ResultsController < ApplicationController    
  def index
    # here you get some json structure that you can display in the view
    @results = Api.new.find('test')['results']
  end
end
Vasilisa
  • 4,604
  • 3
  • 20
  • 25
  • thanks very much :) That's solved the error problem. What format should be returned if I call `@results` in my view? I'm getting lots of html and css rather than the search results of the query. –  Jan 22 '19 at 15:20
  • 1
    Feel free to accept the answer if it helped :) Your API should be able to return search results in JSON format. Check the documentation for api, maybe you need `get("/results.json", query: { q: name })` – Vasilisa Jan 22 '19 at 15:42
  • It doesn't seem to be returning json, just lots of html tags for the "The page you were looking for doesn't exist (404)" oage weirdly. Adding .json also didn't work and threw an error. There is no api documentation sadly :( –  Jan 22 '19 at 16:12
  • Status 404 means that you're hitting the wrong url. I can try to help if you post the real API url – Vasilisa Jan 22 '19 at 17:15
  • It returns very nice [JSON](http://search.spoonflower.com/searchv2/designs?utf8=%E2%9C%93&q=rose&lang=en&availability=for_sale&substrate=all&sort=classic&view=design&offset=0&limit=30&color_family1=&color_family2=&commit=Search). Why do you try to hit "/results"? It should be "/designs" if `base_uri` is http://search.spoonflower.com/searchv2 – Vasilisa Jan 22 '19 at 17:47
  • @Steve, check the updated answer, looks like I understood, what you need :) – Vasilisa Jan 22 '19 at 17:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/187138/discussion-between-steve-and-vasilisa). –  Jan 22 '19 at 18:00