problems in using search function in rails - ruby-on-rails-3

I am trying to do a simple search function. This is the function in the module. I have two columns: title and description. But I get an error. Instead of posts I need to have select "title" in there.
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
The error I get is:
SQLite3::SQLException: no such column: name: SELECT "posts".* FROM "posts" WHERE (name LIKE '%first%')
UPDATE:
Here is my index.html.erb file. I have essentially used a form and listed all the posts along with their content. How do I change the file to display only the searched item? Initially all should be listed. I am not able to understand how to do this. Any ideas?
<h1>Our Blog</h1>
<%= form_tag posts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<% #posts.each do |post| %>
<h2><%= link_to post.title,post %></h2>
<p><%= post.content %></p>
<hr />
<%= link_to "Add a new post", new_post_path %>
<% end %>

You have no column name in your table posts i think you want search on title & description so try following
find(:all,
:conditions => ['title LIKE ? OR description like ?', "%#{search}%", "%#{search}%"])

Related

Rails search form for multiple column in a table

I have a simple rails search form that will select rank on a column in which 3 different ranks in a table. But I cannot extend plural ranks.
Table Food: value1, rank_value1, value2, rank_value2, value3, rank_value3
View /foods/index.html:
<%= form_tag foods_path, :method => 'get' do %>
<p>
rank_value1
<%= text_field_tag :rvalue1, params[:rvalue1] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
Model food.rb:
def self.search(search)
if search
Food.where(["rank_value1= ?", "#{search}"])
else
Food.all
end
end
Controller foods_controller.rb:
def index
#foods = Food.search(params[:rvalue1])
end
To extend two ranks, I tried codes below but it did not work.
View /foods/index.html:
<%= form_tag foods_path, :method => 'get' do %>
<p>
rank_value1
<%= text_field_tag :rvalue1, params[:rvalue1] %>
<%= text_field_tag :rvalue2, params[:rvalue2] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
Model food.rb:
def self.search(search1,search2)
if search
Food.where(["rank_value1= ? and rank_value2=?", "#{search1}", "# {search2}"])
else
Food.all
end
end
Controller foods_controller.rb:
def index
#foods = Food.search(params[:rvalue1], params[:rvalue2])
end
Any suggestions as to search with data in multiple columns?
Hey for searching with multiple values you can use Ransack gem. Here you can see the video tutorial and github link for implementation.
github: https://github.com/activerecord-hackery/ransack
video : http://railscasts.com/episodes/370-ransack
Hope you are looking for this only.

Rails 3 using ransack to search and sort and trying to limit options in sort select

I have a page in my rails application that shows a list of listings (paginated using will_paginate). I am trying to find a good gem to implement searching and sorting with the list on this page. The Ransack gem looked like what i needed but i'm running into an issue with it. This is what my code looks like right now with the Ransack gem.
My model (didn't include the whole model, didn't want the validations and extra code to get in the way):
UNRANSACKABLE_ATTRIBUTES = ["id", "state", "show_email", "email", "show_phones", "primary_phone", "secondary_phone", "updated_at", "user_id"]
def self.ransackable_attributes auth_object = nil
(column_names - UNRANSACKABLE_ATTRIBUTES) + _ransackers.keys
end
My controller action:
def index
#search = Listing.search(params[:q])
#listings = #search.result.paginate(page: params[:page], per_page: 20, joins: "LEFT OUTER JOIN attachments ON listings.id = attachments.attachable_id", select: "listings.*, COUNT(attachments.id) AS photos", group: "listings.id", order: "listings.created_at DESC, listings.title ASC, listings.id DESC")
#search.build_sort if #search.sorts.empty?
end
My search form on the page:
<div class="advanced-search">
<%= search_form_for #search do |f| %>
<div class="search-by">
<div class="search-field">
<%= f.label :title_cont, "Title Contains" %>
<%= f.text_field :title_cont %>
</div>
<div class="search-field">
<%= f.label :description_cont, "Description Contains" %>
<%= f.text_field :description_cont %>
</div>
<div class="search-field">
<%= f.label :price_gteq, "Price Between" %>
<%= f.text_field :price_gteq %>
<%= f.label :price_lteq, "and" %>
<%= f.text_field :price_lteq %>
</div>
</div>
<div class="sort-by">
<%= f.sort_fields do |s| %>
<%= s.sort_select %>
<% end %>
</div>
<div class="search-actions">
<%= f.submit "Search" %>
</div>
<% end %>
</div>
My route:
resources :listings do
collection do
match 'search' => 'listings#index', via: [:get], as: :search
end
end
With everything i have in place now i have been able to get the application to successfully search and sort the listings.
My question: The sort_select field is showing everything option that is "ransackable". Is there a way to make one attribute available for the searching, but not the sorting? For example i want the ability to search on the description attribute but it doesn't make any sense to include that attribute in the sorting. How can i use an attribute in one and not the other? Thanks for any help and let me know if my question is not clear enough.
Couldn't figure out how to get the values i wanted into the dropdown so i just used links instead. Here's what i ended up with for the sorting.
Sort by <%= sort_link #search, :title %> | <%= sort_link #search, :price %> | <%= sort_link #search, :created_at, "Date Listed" %>

Weird undefined method 'all' and collection_select error

I've got a form like this (simplified, but you get the idea):
<%= form_for(#brand, :html => { :class => "form-horizontal" }) do |f| %>
<%= f.fields_for :prices do |price| %>
<%= price.collection_select(:price, :template_id, Template.all, :id, :name) %>
<% end %>
<%= f.submit "Save", :class => 'btn btn-primary' %>
<% end %>
Which when rendered gives me this error
undefined method `all' for ActionView::Template:Class
on the collection_select line.
Template.all works from the controller and the console. If I write a #templates = Template.all and use #templates in the collection_select line then I get this error:
undefined method `merge' for :name:Symbol
Any thoughts?
You can do it by prefixing with two colon. e.g,
<%= price.collection_select(:price, :template_id, ::Template.all, :id, :name) %>
but I believe, you should avoid using Template as model name as it is rails Action View Template
Solved it. It was annoyingly simple.
<%= price.collection_select(:template_id, #templates, :id, :name) %>
Duplication. Eugh.

Rails search functionality

I am taking a rails class at my University and I am trying to create a search form which will show the results on the same page rather than show a different page of results. Is this something simple to do? I am creating a museum app with artifacts for each museum but I want the user to search artifacts from either page.
On my routes.rb I have
resources :artifacts do
collection do
get 'search'
end
end
On my museum index I have the code below that he gave us but not sure how to tweak the get routes for the same page.
<%= form_tag search_artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
<% if #artifacts %>
<p> <%= #artifacts.length %> matching artifacts. </p>
<h2> Matching Artifacts </h2>
<% #artifacts.each do |a| %>
<%= link_to "#{a.name} (#{a.year})", a %><br />
<% end %>
<% end %>
Yes, this is easy. Just have the index page return the search results if params[:search_text] is present - this way you don't need a new route or a different page.
class ArtifactsController < ApplicationController
def index
#artifacts = Artifact.search(params[:search_text])
end
end
class Artifact < ActiveRecord::Base
def self.search(query)
if query
where('name ILIKE ?', "%#{query}%")
else
all
end
end
end
So then your form looks like:
<%= form_tag artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
Edit:
So what you really want to do is any page you want to search, include a form which makes a request to that same page.
Then in each of those controller methods just put this line of code:
#artifacts = Artifact.search(params[:search_text])
and that will populate the #artifcats array with only artifacts that match the search query.
Try using "Ransack" gem. It can also perform some more powerful searches.

Passing Rails Parameters into Form

I'm trying to pass in two variables for a Nested Model form to use, but I'm getting an error. It's probably an easy syntax error that someone experienced could see right away, but I don't see it.
I have a template showing users, if you click one, it should take the user_id and community _id for use in the form. Both community and user are properly declared in the controller.
link to form:
<%= link_to "award badge", award_badge_badges_path, :user_id => user.id, :community_id => #community.id %>
The form uses two models - badge and badge winners. The user_id and community_id are needed for badge_winners which is nested in badges. The error I'm getting is "undefined local variable or method 'user_id' for #<#<Class:0x77544c0>:0x7714230>" so I think that something is wrong with the 2nd and 3rd lines in the form. Here's the form:
<%= form_for(#badge) do |f| %>
<%= f.hidden_field :user_id ,:value => user_id %>
<%= f.hidden_field :community_id ,:value => community_id %>
<%= f.label :Description %>
<%= f.text_area :description %>
<%= f.fields_for :badge_winners do |builder| %>
<%= render "badge_winner", :f => builder, :locals => {:user_id => user_id, :community_id => community_id} %>
<% end %>
<%= f.submit "Give Badge" %>
<% end %>
the show template in the controller:
def award_badge
#badge = Badge.new
badge_winners = #badge.badge_winners.build
end
the badge winner partial
<%= f.hidden_field :user_id ,:value => user_id %>
<%= f.hidden_field :community_id ,:value => community_id %>