I'm fairly new to Ruby on Rails, making a directory type of website as a personal project to learn.
In my app, I implemented Geocoder search so the user can search for places/locations near them, the search worked perfect. But then when I added tabbed menus to categorize what type of places are available it broke the search.
I think I know why it's broken but not sure how to fix it. The tabs are showing the @schools, @restaurants, and @businesses variables, how can I get the tabs to show the search results and not those variables? Those variables should only show up when there is no search executed, but they also show up when the search is executed.
Here's my code:
Places Controller:
class PlacesController < ApplicationController
before_filter :authenticate_user!, except: [:index]
def index
if params[:search].present?
@places = Place.near(params[:search], 50, :order => :distance)
else
@places = Place.all
end
@schools = Place.where("category = ?", "School")
@restaurants = Place.where("category = ?", "Restaurant")
@businesses = Place.where("category = ?", "Business")
end
Places Index.html.erb:
<% if user_signed_in? %>
<div class="row">
<h2>Newly Added Places</h2>
<%= form_tag places_path, :method => :get do %>
<%= text_field_tag :search, params[:search], placeholder: "Enter your zipcode or city", class: "search-query" %>
<%= submit_tag "Search Nearby", :name => nil, class: "btn"%>
<% end %>
<ul class="nav nav-tabs">
<li><a href="#tab1" data-toggle="tab">Schools</a></li>
<li><a href="#tab2" data-toggle="tab">Restaurants</a></li>
<li><a href="#tab3" data-toggle="tab">Businesses</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<%= render :partial => "places", :locals => {:places_container => @schools} %>
</div>
<div class="tab-pane" id="tab2">
<%= render :partial => "places", :locals => {:places_container => @restaurants} %>
</div>
<div class="tab-pane" id="tab3">
<%= render :partial => "places", :locals => {:places_container => @businesses} %>
</div>
</div>
</div>
<br />
<% else %>
<%= render 'static_pages/home' %>
<% end %>
Places partial(_places.html.erb):
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Address</th>
<th>State</th>
<th>City</th>
<th>Type</th>
<th>Website</th>
</tr>
</thead>
<% places_container.each do |place| %>
<tr>
<th><%= image_tag place.image(:medium)%></th>
<th><%= link_to place.name, place %></th>
<td><%= place.address %></td>
<td><%= place.state %></td>
<td><%= place.city %></td>
<td><%= place.category %></td>
<td><%= place.website %></td>
<% if current_user.admin? %>
<td><%= link_to 'Edit', edit_place_path(place) %></td>
<td><%= link_to 'Destroy', place, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>
Your tabbed results are ignoring the search parameter because you aren't using the @places
relation built from the search parameter. To fix, change this code:
def index
if params[:search].present?
@places = Place.near(params[:search], 50, :order => :distance)
else
@places = Place.all
end
@schools = Place.where("category = ?", "School")
@restaurants = Place.where("category = ?", "Restaurant")
@businesses = Place.where("category = ?", "Business")
end
to:
def index
if params[:search].present?
@places = Place.near(params[:search], 50, :order => :distance)
else
@places = Place.scoped # use 'scoped', not 'all', to avoid triggering the query immediately
end
@schools = @places.where("category = ?", "School")
@restaurants = @places.where("category = ?", "Restaurant")
@businesses = @places.where("category = ?", "Business")
end