Working with Third party yummly api in rails 4 - ruby-on-rails

I've searched all over the web for decent explanations of how to do what I want to do, but cannot find any.
What I want to do is have the user be able to search through the yummly api and return some results back...
Here is some code.
index.html.erb
<% #results.each do |r| %>
<%= r.name %>
<% end %>
home_controller.rb
class HomeController < ApplicationController
def index
#results = Yummly.search('Onion')
#recipe = #results.map(&:to_s)
end
end
I've installed the Yummly gem which allows me to call Yummly.search
How can I allow the user to search for the term instead of hard coding it? It returns just fine hard coded but I cannot figure out how to allow the user to search.
Thank you!

Ideally, you would have a form that allows the user to enter a search term, and then pass that term to the Yummly API.
Something like (substitute your own route name):
<%= form_tag({controller: 'home', action: 'index'}, {method: :get}) do %>
<%= text_field_tag 'search' %>
<% end %>
And in your controller:
Yummly.search(params[:search])

Related

How to minimize/refactor my events controller

Context: this is the 1st rails app I've built and it is fully deployed with fly.io
In the spirit of DRY, I feel like I am definitely repeating myself alot with my current configuration, but due to my lack of Rails knowledge, I'm not sure of a better way.
I have an app where I'm listing dance events around the world and I created individal pages for individual cities.
The first thing I did was create a scope in the event.rb:
scope :in_austin, -> { where(city: "Austin").or(where(city: "Pflugerville")).where(state: "Texas") }
Next, I created a page for the city in the events folder atx_index.html.erb and in that file I applied the scope:
<%= render 'events/local_search_form', { url: atx_index_path } %>
<h3>Upcoming Events</h3>
<div class="event-list-wrapper">
<% #events.upcoming_events.in_austin.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
<h3>Past Events</h3>
<div class="event-list-wrapper past-event">
<% #events.past_events.in_austin.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
On the local city page I'm also pulling in a separate partial for a search form for local pages modified from the main seach form partial I'm using on my main event index page:
<% if local_assigns.has_key? :url %>
<%= search_form_for #q, { url: url } do |f| %>
[Local Search Form]
<% end %>
<% end %>
I added the route to the local page:
get '/atx', to: 'events#atx_index', as: 'atx_index'
I also found out I needed to add an exception to my before_action in the events controller to not require a user:
before_action :require_user, except: %i[show index atx_index ]
as well as duplicate my index method for the local city since I'm using Ransack to search on my main index page as well as the individual city page:
def atx_index
if params[:q]
params[:q][:combinator] = "and"
params[:q][:groupings] = []
[ Bunch of Ransack parameters ]
end
#q = Event.ransack(params[:q])
#events = #q.result(distinct: true).order(event_start_date: :asc)
end
So once I added the above I was able to get my local city view to display and function correctly with Ransack.
The issue I have now is that I have about 20 more cities (and scaling wise this list of cities could grow 100+) I've followed this process with and now my controller is 500+ lines long as I'm duplicating the index method for each city as well as the before_action array getting longer and longer.
My app is working, but I'm pretty sure there's a way to refactor this, especially my controller.
Any insights or resources I could look into would be appreciated!

Using ransack to search from different controller action

I have a PagesController that contains two actions
def search
#q = Listing.ransack(params[:q])
#listings = #q.result(distinct: true)
#listings = #listings.where(active: true).order("created_at DESC").page(params[:page]).per(12)
end
and
def home
end
now what I would like to achieve is that I could fire a search from the home path to the search path like
home.html.erb
<%= search_form_for #q, url: search_path do |f| %>
<%= f.search_field :listing_name_cont %>
<%= f.submit 'Search' %>
but this returns No Ransack Search object was provided to search_form_for which It should since there is no q param passed to the home action. The only way I can get this to work is that if I modify the home action as follows
def home
#q = Listing.ransack(params[:q])
end
but this doesn't seem reasonable since I'm not displaying any of the listings on the home page so I can imagine this will just slow down the page by quite a lot If I'm fetching a lot of listings. Is there any other way I could achieve this?
You can do <%= search_form_for #q, url: 'home' do |f| %>
'home' can be whatever you want the URL extension to be.

Cleaning up view ruby logic and separating concerns into model/controller

I want to display a random assortment of 6 tools from my database on my home page. I have created a Pages controller with a home action.
This is my Pages controller:
class PagesController < ApplicationController
def home
#tools = Tool.all
end
end
Then in my home.html.erb view I use the .sample method to grab random tools from my database as such(I repeat this 6 times using tool1, tool2, tool3, etc variables for each):
<% tool1 = #tools.sample %>
<%= image_tag tool1.tool_image.url(:medium) %>
<%= tool1.name %>
<%= tool1.description %>
I am wondering if there is a better way to do this. It seems that I have logic in my view and there must be a way to move that logic somewhere else? My model, controller, etc. How would one go about cleaning this code up so that it's good rails code? Or maybe this is good rails code and I just don't know it since I am a beginner.
Your controller doesn't need to extract everything from the tools_table, so I'd first remove the .all. Your example makes it seem like you just need 6 random objects from the database, here's one way to do that:
class PagesController < ApplicationController
def home
#tools = Tool.order("RANDOM()").first(6)
end
end
Then in your view you can just loop through those:
<% #tools.each do |tool| %>
<%= image_tag tool.tool_image.url(:medium) %>
<%= tool.name %>
<%= tool.description %>
<% end %>
In addition to Anthony's answer.
To clear up the view with some rails magic you can also add a partial to your app/views/tools called:
_tool.html.erb
Looking like:
<%= image_tag tool.tool_image.url(:medium) %>
<%= tool.name %>
<%= tool.description %>
And then change your view to
<%= render #tools %>
And Rails will know what to do if #tools is a collection of tools 😄

Show Ransack search results on different page

I am using Ransack to add a simple search form on my homepage. I would like the results of the search to show on a different page, instead of on the homepage.
The HomeController has an index action with the #search variable set as follows
def index
#search = User.search(params[:q])
#users = #search.result
end
The view contains
<%= search_form_for #search do |f| %>
<fieldset>
<legend>User</legend>
<ul>
<li>
<%= f.label :first_name_or_last_name_cont %>
<%= f.text_field :first_name_or_last_name_cont %>
</li>
<li>
<%= f.label :email_cont %>
<%= f.text_field :email_cont %>
</li>
</ul>
</fieldset>
<fieldset>
<legend>User's Posts</legend>
<ul>
<li>
<%= f.label :posts_title_cont %>
<%= f.text_field :posts_title_cont %>
</li>
</ul>
</fieldset>
<%= f.submit %>
<% end %>
<%= render 'results' %>
How can I set up the controller so that I can use <%= render 'results' %> in a different view for a different action, say a search action? How can I do this so that when I submit the search form I am directed to a new page for the search action which displays the search results?
Great question! To answer your question, you can create a private method with a redirect_to a different page (that has <%=render 'results' %>) IF search params are passed in your HomeController.
class HomeController < ApplicationController
before_action :search
def index
#search = User.search(params[:q])
#users = #search.result
end
private
def search
if params[:q]
search_params = CGI::escapeHTML(params[:q])
redirect_to (url --> see below how to get the url)
end
end
end
However, if you want to start building out your app, you want your search results to display on that dedicated page, no matter where you are at in the app. I am pasting in a full answer from a small rails app. The code is only slightly different (form_tag instead of search_form_for), but I know it works, so hopefully it will help you.
Below, is a nav bar partial that is displayed across the app and then the relevant code for the home page and the ListingController index action. If search params are passed, then index.html.erb renders the #listings partial (_listing.html.erb) and nothing below the <% else %> tag on the home page.
_navigation.html.erb
<%= form_tag search_path, :method => :get do %>
<div class="form-group">
<%= text_field_tag :search, params[:search], class: "form-control", placeholder: "Search" %>
</div>
<%= submit_tag "Submit", :name => nil, :class => "btn btn-primary" %>
<% end %>
index.html.erb
<% if params[:search] %>
<h2>Search Results</h2>
<%= render #listings %>
<% else %>
...what usually shows up on my home page with no search results.
<% end %>
listings_controller
def index
#listings = Listing.search(params[:search])
end
routes.rb
get 'search' => "listings#search"
This works great. However, if I am in a different view/controller, like the one showing all the categories, and try to search, then it basically searches the current page. So, I added the following to the categories controller:
categories_controller
before_action :search
......
private
def search
if params[:search]
search_params = CGI::escapeHTML(params[:search])
redirect_to ("/listings?utf8=%E2%9C%93&search=#{search_params}")
end
end
BUT, for your specific app, to get the search to redirect to the home page and display the search results, first do a search on your home page and see what is generated in the url. Let's say I typed 'cheese' (/listings?utf8=%E2%9C%93&search=cheese). Notice the %E2%9C%93...you may not see this b/c this normally displays as a check in the url on your browser (http://unicode-search.net/unicode-namesearch.pl?term=mark)...so just paste it into text wrangler or stackoverflow text area to get the 'full url' like above. Then at the end of the url, just replace what you typed into the search box with #{search_params}.
This passes whatever was typed into the search box to your dedicated search results page (in my case index.html.erb)!
Here is some documentation on CGI escapeHTML (for security reasons): http://ruby-doc.org/stdlib-2.0/libdoc/cgi/rdoc/CGI.html#method-c-escapeHTML

parse JSON from url using Eniro search API in Rails

I am trying to use an external API from eniro http://api.eniro.com/ for my rails application.
They have provided a code snippet to use for ruby as a working example, but I need further assist on how I can use it. The code below is my controller.
My Controller
class ListanController < ApplicationController
require 'open-uri'
require 'rubygems'
require 'json'
def get_json
#json = JSON.parse( open('http://api.eniro.com/partnerapi/cs/search/basic?profile=[*******]&key=[**********]&country=se&version=1.1.3&search_word=pizza').read )
#json['adverts'].each do |advert|
puts advert['companyInfo']['companyName']
end
end
def index
#json = JSON.parse(open('http://api.eniro.com/cs/search/basic?profile=mrshawn191&key=5582158511111471396&country=se&version=1.1.3&search_word=pizza').read )
end
end
My view
<h1><center>Test site</center></h1>
<center>
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag :index, params[:index] %>
<%= submit_tag("Search") %>
<% end %>
</center>
<% #json['adverts'].each do |advert| %>
<%= advert['companyInfo']['companyName'] %>
<% end %>
How do I interact with this controller in my view?
I want simply to create a search form in my view that is connected to the external API, so whenever I search for something it will redirect me to a new page and display the result from the api.I don't know much but what I'm guessing is that I have to
In my controller, specify a method where I parse url into json object
In my view puts that json objekt? depending on what the keyword is?
Configure routes.rb to match the search path
I'm lost, can anyone give any guidelines where to start? How would the code look in my view?
The code parts
#json['adverts'].each do |advert|
puts advert['companyInfo']['companyName']
end
merely print it to the console. Since you want it showing in your view, you can just remove those.
In your view (if you're using ERB), add
<% #json['adverts'].each do |advert| %>
<%= advert['companyInfo']['companyName'] %>
<% end %>
which should then do the same as your putscode, just for the HTML rendered on page. Format as appropriate.

Resources