Search code examples
rubysearchactiverecordsinatra

Basic Search in Ruby Sinatra ActiveRecord


I'm trying to make a basic search function for a simple product inventory app on Sinatra, but don't know how to make the controller and view to properly output all the products which have similar names to a results page.

SearchPage.erb:

<form action="/search", method="post"> <input type="text" name="product[name]">

Controller:

post '/search' do
@Products = Product.find_by(name: params[:product][:name])
@Products = Product.all(:name.like => "%#{params[:name]}%") #found this on another question
erb :"result"
end

Result.erb

<% @Products.each do |product| %>
<%=product.name %>
<%=product.details %>

EDIT: I was able to make search work based on the suggestion with the following code. Thanks!:

Search.erb View

<form action="/search", method="get">
<input type="text" name="search">

Controller

get '/search' do
@products = Product.all
if params[:search]
  @products = Product.search(params[:search])
else
  @products = Product.all
end
erb :'results'
end

Model

class Product < ActiveRecord::Base
def self.search(search)
where("name like ?", "%#{search}%")
end

Results.erb View

<% if @products.present? %>
<table>
<td>Product Name</td><td>Company</td>
<% @products.each do |product| %>
<tr><td><a href="/products/<%= product.id %>"><%=h product.name %></a>   </td>
<td><%=h product.company.name %></td>
<% end %>
<% else %>
<p>There are no Products containing the term(s) <%= params[:search] %>.</p>
<% end %>
</table>

Solution

  • I notice off the bat you're using a POST method. There is an easier way to do create search functionality for your products. Try this:

    Posts Controller:

    @products = Product.all
    if params[:search]
      @products = Product.search(params[:search]).order("created_at DESC")
    else
      @products = Product.all.order('created_at DESC')
    end
    

    Posts Model (note: If you are using SQLite keep it as LIKE. If you are using Postgres, change LIKE to ILIKE)

    def self.search(search)
      where('name like :pat or content like :pat', :pat => "%#{search}%")
    end
    

    Search Form (Put into your Result.erb and edit as needed but keep as get method. I personally like using form helpers but you can create a normal form if you'd like)

    <%= form_tag(products_path, :method => "get", id: "search-form") do %>
    <%= text_field_tag :search, params[:search], placeholder: "Search Posts" %>
    <%= submit_tag "Search" %>
    <% end %>
    

    Render Results

    <% if @products.present? %>
      <%= render @products %>
    <% else %>
      <p>There are no posts containing the term(s) <%= params[:search] %>.</p>
    <% end %>
    

    Let me know if this works for you. If not, i'll try help some more.