SImple Rails Search - ruby-on-rails

I generated a search_contoller and view for my rails app.
My Controller:
class SearchController < ApplicationController
def index
if params[:commit] == "Search"
# Great, now lets figure out what sort of query we're after
#searchQuery = params[:q]
#resultsReceived = true
if
#sqlResults = Product.where("title like ? OR categories like ?", "%" + params[:q] + "%", "%" + params[:q] + "%").order("published DESC")
end
else
#resultsReceived = false
#sqlResults = []
end
# Render the page when we're done.
respond_to do |format|
format.html
end
end
end
My View
<%= form_tag("/search", :method => "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
<% if #resultsReceived == true %>
<b><%= #sqlResults.length %> Results Found For: </b><%= #searchQuery %>
<br>
<table>
<tr>
<th>Publish</th>
<th>Product</th>
<th></th>
</tr>
<% #sqlResults.each do |product| %>
<tr class="<%= cycle('oddrow', 'evenrow') %>">
<td><%= check_box_tag "product_ids[]", product.id, product.published, {:id => product.id, :class => "publish_checkbox"} %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, confirm: 'Are you sure you want to KILL this product?', method: :delete %></td>
<td>
<div>
<b>Title:</b> <%= product.title %>
</div>
<div class="float_left prod_image">
<img src='<%= product.image_url %>' class='product_image'></img>
</div>
<div class="float_left prod_description">
<div><b>Product is Published: </b> <%= product.published %></div>
<div><b>Category Names:</b> <%= product.category_names %></div>
<div><b>Categories:</b> <%= product.categories %></div>
<div><b>Rating:</b> <%= product.rating %></div>
<div><b>Wow:</b> <%= product.is_curated %></div>
<div><b>Age:</b> <%= product.pr_attributes['ag_type'] %></div>
<div><b>Gender:</b> <%= product.pr_attributes['gender_type'] %></div>
<div>
<b>Description:</b>
<% if product.long_descr.length < 200 %>
<%= product.long_descr %>
<% else %>
<span id="short_desc_<%= product.id %>"><%= product.long_descr[0..199] %>...</span>
<span class="long_description", id="long_desc_<%= product.id %>"><%= product.long_descr %> </span><a id="<%= product.id %>" class="toggle">toggle</a>
<% end %>
</div>
<div><b>Backfill Male:</b> <%= product.backfill_text['male'] %></div>
<div><b>Backfill Female:</b> <%= product.backfill_text['female'] %></div>
<div><b>Backfill Unisex:</b> <%= product.backfill_text['unisex'] %></div>
<div><b>MP Seller Name:</b><%= product.mp_seller_name %></div>
<div><b>Price:</b> Current: $<%= product.curr_item_price %> / Base: $<%= product.base_item_price %></div>
<div><b>ID STR:</b> <%= product.id_str %></div>
<div><b>Stock:</b> <%= product.stock_status %></div>
<div><b>Last Updated by <%= product.updated_by_name %> at <%= product.updated_at %></b></div>
</div>
</tr>
<% end %>
<% end %>
I need the search to be more specific, and would like to break up the sql statement, so I can search for other additional attributes. For example, I would like search for either TITLE (and get results that match only the string entered by the user) or search by GENDER (and get back only the gender I user is searching for). How can I do this? Should I create new form_tags for each type of search I want to perform? Is it possible to have just one search box in the view, and have the user select between radio buttons as to what they want to search for?

With MySQL, your options are pretty limited to self constructing the LIKE clauses. Most Rails apps on MySQL will use other search options, like SOLr (sunspot), ElasticSearch, or Sphinx.
On PostgreSQL, you have many more options to use the built in full text search capabilities, like Texticle.
A lot of links to the above: https://www.ruby-toolbox.com/categories/rails_search

Related

Form_tag routing error after unsuccessful submit

I have an index page with a partial form to submit new records to Package model. I keep this form in the index page, so the user doesn't need to leave the page when repeating this action, several times.
In the same page I have a form_tag fir multiple updates for the same controller, namely packages_controller.
Everything works fine, except the following: when hit the update button, going to the form BUT instead of submitting I go back (with the browser) and try to select other records to be updated then I have a routing error:
Routing Error
No route matches [PUT] "/projects/47/orderlines/18/packages"
My index page looks like this:
<% if current_user %>
<%= render "packages/form" %>
<% end %>
<% if #packages.count >= 1 %>
<table class="table table-striped">
<thead>
<tr>
<th> <input type="checkbox" id="selectAll" value="selectAll"></th>
<th>Packed </th>
<th>#No.</th>
<th>Type</th>
<th>Gross weight</th>
<th>Length</th>
<th>Width</th>
<th>Height</th>
<th></th>
<th>Container</th>
</tr>
</thead>
<%= form_tag edit_multiple_project_orderline_packages_path, method: :get do %>
<tbody>
<% for package in #packages %>
<% if package.packed== true %>
<% #label_type="success" %>
<% else %>
<% #label_type="default" %>
<% end %>
<tr>
<td><%= check_box_tag "package_ids[]", package.id %></td>
<td><span class="label label-<%= #label_type %>"><% if package.packed==true %>Packed<% else %>Unpacked<% end %></span></td>
<td><%= package.package_no %></td>
<td><%= package.package_type %></td>
<td><%= package.gross_weight %></td>
<td><%= package.length %></td>
<td><%= package.width %></td>
<td><%= package.height %></td>
<% if #orderline.packages.count >= 1 %>
<td><%= link_to 'Delete', [package.orderline.project, package.orderline, package],
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<td><%= #containers.find(package.container_id).container_id if package.packed %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Add to container", class: "btn btn-primary" %>
<% end %>
<br />
<%= will_paginate %>
<br>
And the multiple_edit form
<div class="col-sm-4">
<%= form_tag update_multiple_project_orderline_packages_path, method: :put do %>
<ul>
<% #packages.each do |package| %>
<li>
<%= hidden_field_tag "package_ids[]", package.id %>
<%= package.package_no %>
<%= package.container_id %>
<% package.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</li>
<% end %>
</ul>
<%= fields_for :package do |f| %>
<div class="field">
<%= f.label :package_no %><br />
<%= f.text_field :package_no, :class => "form-control" %>
</div>
<br />
<div class="field">
<%= f.label :container_id %><br />
<%= select_tag 'package[container_id]', options_from_collection_for_select(#project.containers, 'id', 'container_id', default_blank: true), prompt: "- Select container -", :class => "form-control" %>
</div>
<br />
<div class="field">
<%= f.label :packed %><br />
<%= f.select :packed, [["Packed", true], ["Unpacked", false]],{ prompt: "- Packing -"},{ :class => "form-control" } %>
</div>
<% end %>
<div class="actions">
<br />
<%= submit_tag "Update", :class => "btn btn-primary" %>
</div>
<% end %>
</div>
And the packages controller edit_multiple actions:
def edit_multiple
#project = Project.find(params[:project_id])
#packages = Package.find(params[:package_ids])
end
def update_multiple
#packages = Package.find(params[:package_ids])
#packages.reject! do |package|
package.update_attributes(package_params.reject { |k,v| v.blank? })
end
if #packages.empty?
redirect_to project_orderline_packages_url
else
#package = Package.new(package_params)
render "edit_multiple"
end
end
packages_controller create action:
def create
project = Project.find(params[:project_id])
orderline = project.orderlines.find(params[:orderline_id])
#package = orderline.packages.new(package_params)
#package.save
if #package.save
flash[:success] = "Package(s) was successfully added."
redirect_to :back
else
render 'new'
end
And my routes:
resources :projects do
resources :containers
resources :orderlines do
resources :packages do
collection do
put :packed
get :edit_multiple
put :update_multiple
end
end
end
end
I just added my routes here:
edit_multiple_project_orderline_packages_path GET /projects/:project_id/orderlines/:orderline_id/packages/edit_multiple(.:format)
packages#edit_multiple
update_multiple_project_orderline_packages_path PUT /projects/:project_id/orderlines/:orderline_id/packages/update_multiple(.:format)
packages#update_multiple
project_orderline_packages_path GET /projects/:project_id/orderlines/:orderline_id/packages(.:format)
packages#index
POST /projects/:project_id/orderlines/:orderline_id/packages(.:format)
packages#create
new_project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/new(.:format)
packages#new
edit_project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/:id/edit(.:format)
packages#edit
project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#show
PATCH /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#update
PUT /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#update
DELETE /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
your form_tag code is update_multiple_project_orderline_packages_path
I think it should be update_multiple_project_orderline_package_path(project_id, orderline_id, package_id)
I am not 100% sure with my statement above, because you gave scrambled Rails Routes, hard to read
and your form action seems goes to packages#edit_multiple controller
so paste your edit_multiple method, not create method
are you implementing your scenario above with javascript, or just plain HTML?

use check_box_tag in facet instead of link_to sunspot

I'm using sunspot for search , and i have implemented a fecet search for company this is my view for facet
<% for row in #search.facet(:company_id).rows %>
<li>
<% if params[:company_id].blank? %>
<%= link_to row.instance.name, :company_id => row.value %> <%= row.count %>
<% else %>
<strong><%= row.instance.name %></strong> (<%= link_to "remove", :month => nil %>)
<% end %>
</li>
<% end %>
but instead of using link_to i want to use check_box_tag, i have tried something like this but it didn't work <%= check_box_tag row.instance.name, :company_id => row.value %> <%= row.count %>

Block in rails 3

My view:
<%= form_tag(rate_url) do %>
<%= hidden_field_tag :prod_id, params[:product_id] %>
<%= hidden_field_tag :rating_set_id, params[:rating_set_id] %>
<span class = "heading"> Recommendations </span>
<div><%= submit_tag 'Submit Ratings', :class => " btn right" %></div>
<span id = "rate_more_link">
<%= link_to "Rate More Products", products_path(:rating_set_id => params[:rating_set_id])%>
</span>
<br/>
<div id ="prods_container">
<% #recommendations.each do |rec| %>
<% url_raw = URI.parse("url_to_parse") %>
<% url = Net::HTTP.get_response(url_raw).body %>
<% if url.empty? %>
<% #title = "Product Unavailable via API" %>
<% #url = "#{rec.wmt_id}" %>
<% #cover_img = "_180X180.jpg" %>
<% #price = "Product Unavailable via API" %>
<% else %>
<% begin %>
<% #response1 = JSON.parse(url) %>
<% #title = #response1["ProductName"]%>
<% #url = "{#response1["ProductUrl"]}"%>
<% #cover_img = #response1["ImagePath"]%>
<% #price = #response1["currentItemPrice"]%>
<% rescue %>
<% end %>
<% end %>
<div id ="prod">
<span class = "radio_button">
<%= hidden_field_tag "recommendation_ratings[#{rec.id}][recommendation_id]", rec.id %>
<%= radio_button_tag "recommendation_ratings[#{rec.id}][rating]", '3'%> Good
<%= radio_button_tag "recommendation_ratings[#{rec.id}][rating]", '2'%> Fair
<%= radio_button_tag "recommendation_ratings[#{rec.id}][rating]", '1'%> Bad
<%= radio_button_tag "recommendation_ratings[#{rec.id}][rating]", '0'%> N/A
</span>
<div>
<a href='<%= #url %>' target="_blank">
<img src='<%= #cover_img %>' class='product_image_rec_table'></img>
</a>
</div>
<div class = "rec-desc">
<div class = "small"><b>Wmt ID: </b><%= rec.wmt_id %></div>
<div class = "small"><b>Title: </b><%= #title %></div>
<div class = "small"><b>Price: </b>$<%= #price %></div>
<div class = "em">
<b>Current Rating: </b>
<% rec.ratings.each do |rating_phin| %>
<%= rating_phin.label %>
<% end %></div>
<br/>
</div>
<div id="rec_note_text">
<%= text_field_tag "recommendation_ratings[#{rec.id}][notes]", "#{rec.notes}" ,:id => "rec_note_text", :placeholder => 'Enter Notes..'%>
</div>
</div>
<% end %>
<% end %>
</div>
I'm trying to move the <% end %> from the Current Rating block to the end so that I can call the rating_phin variable in my text_field_tag, however when I move the <% end %> to the end of my view, everything after the Current Rating block is not being rendered. What am I doing wrong? How can I update the rating_phin.notes instead of rec.notes in my text_field_tag at the end of my view?
That rating_phin variable only exists within the scope of that each loop.
If you require it later, you will have to loop again:
<div id="rec_note_text">
<% rec.ratings.each do |rating_phin| %>
<%= text_field_tag "recommendation_ratings[#{rec.id}][notes]", "#{rec.notes}" ,:id => "rec_note_text", :placeholder => 'Enter Notes..'%>
<% end %>
</div>
I'm not sure why you would expect that moving the <% end %> tag would be the right thing to do.
If you're getting lost inside of ERB, which is not especially difficult considering how fussy and convoluted HTML can get, especially when there's live Ruby in it, you might want to try HAML. It would reduce this down to about half the number of lines and remove a lot of the <% %> and closing tag debris that tends to make ERB hard to read.

Form in Ruby on Rails

I can't sort out the forms. I'm going along with tutorial (Agile Web Development with Rails) and I'm trying to simply add the field Quantity to my line_items table. Can't figure this out. Please help. How can I change button_to to pass extra value?
<% if notice %>
<p id="notice" ><%= notice %></p>
<% end %>
<h1>Your Pragmatic Catalog</h1>
<% #products.each do |product| %>
<div class="entry" >
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%=sanitize product.description %>
<div class="price_line" >
<span class="price" ></span>
<%= button_to 'Add to Cart', line_items_path(:product_id => product) %>
</div>
</div>
<% end %>
Could you do something like:
<%= button_to 'Add to Cart', { :action => "delete", :id => #image.id, :locals => {:quantity => quantity} } %>
?

Display array element in rails

I try to make the two columns list of products, this is my code
<table>
<% (0..#products.length-1).step(2) do |i| %>
<tr><td><div id="product_left">
<%= image_tag #products[i].photo.url(:small) %>
<%= #products[i].name %><br/>
Price: <%= #products[i].price %><br/>
<%= link_to "details", :action=>"show", :id=> #products[i].id %>
<%= link_to "add to card", {:controller=> "carts", :action=>"add", :id=> #products[i].id}, :remote=> true %>
</div> </td>
<% if #products.length > i %>
<td><div id="product_right">
<%= image_tag #products[i+1].photo.url(:small) %>
<%= #products[i+1].name %><br/>
Price: <%= #products[i+1].price %><br/>
<%= link_to "details", :action=>"show", :id=> #products[i+1].id %>
<%= link_to "add to card", {:controller=> "carts", :action=>"add", :id=> #products[i+1].id}, :remote=> true %>
</div></td>
<% end %>
</tr>
<% end %>
</table>
the problem is in the second div, rails give me an error on #products[i+1]. How can I solve it?
<table>
<% #products.each_slice(2) do |products| -%>
<tr>
<% products.zip(["left", "right"]).each do |product, side| -%>
<td>
<div id="product_<%= side %>">
<%= image_tag product.photo.url(:small) %>
<%= product.name %><br/>
Price: <%= product.price %><br/>
<%= link_to "details", product %>
<%= link_to "add to card", [:add, :carts, product], :remote=> true %>
</div>
</td>
<% end %>
</tr>
<% end -%>
</table>
Also you shouldn't use not uniq id. Here you have got multiple product_left and product_right ids. That's not good

Resources