Rails search functionality - ruby-on-rails-3

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.

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.

I am new on rails i not sure what is going on my code but I want to filter data from database by searching using id how can i do it

I am trying generate a code that tracks for documents that revolve within the organisation. I have done other codes for adding employees, adding document types and logging in now I am struggling on creating a document form and search from the document that I have created. This code is for searching:
controller#show
def show
#generate_documents = GenerateDocument.where('Reciever LIKE?',"%#{params[:search]}%")
# #generate_documents = GenerateDocument.all
end
views/show
<%= form_tag generate_document_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search" %>
</p>
<% end %>
<!-- end of seaerch form -->
<!-- loading data from database and displaying then in a list format BEGIN -->
<ul>
<% #generate_documents.each do |generate_document| %>
<li>
<%= link_to generate_document.Reciever, edit_generate_document_path(generate_document) %>
</li>
<% end %>`enter code here`
</ul>
<!--
END LISTING -->
<%= link_to 'New Generate Document', new_generate_document_path %>
Even Iam new to rails, but i can help you with basics that you need to pass the parameters from the view to the controller, therefore you can use:
:url => {:controller => "name_of_your_controller", :action => "action_to_be_perforemed", :id => "whatever id you want"}
or else you can also pass the object within the url like we do while edit request
<%= link_to "Edit", edit_post_path(#edit)%>
which will give the :id of the particular post.
Hope this may help you.

Passing an instance variable into a form - rails

This is likely an error due to my minimal understanding of Rails and how to use variables across models, so if there is more code needed to answer it or if my terminology is incorrect, let me know and I will gladly update the question.
I have a feed of posts that I want a user to be able to "like." While the following code allows likes to work on an individual post's page - site.com:3000/posts/*post.id* - with the form data being passed of like[liked_post_id]:*post.id*, when I try to submit a like on a profile - site.com:3000/users/*user.id* - which contains a feed of posts, the form data being passed is like[liked_post_id]: (blank value)
How can I pass the post's ID within a feed of posts to the liked_post_id variable in _like.html.erb?
I have noticed that the action of the like form is /likes across the board. Would this will only work when you are on the page site.com:3000/posts/*post.id*? I'm curious if I need to modify the it so that the action of the form is /posts/*post.id*/likes when you are on the page site.com:3000/users/*user.id*
From my post view:
#views/posts/_post.html.erb:
...
<%= render 'posts/like_form' if signed_in? %>
...
Route to proper form:
#views/posts/_like_form.html.erb:
<div id="like_form">
<% if current_user.likes_this?(#post) %>
<%= render "posts/unlike" %>
<% else %>
<%= render "posts/like" %>
<% end %>
</div>
Like from:
#views/posts/_like.html.erb
<%= form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :liked_post_id, :value => #post.id %>
<%= f.submit "Like" %>
<% end %>
From profile (feed of posts):
#views/users/show.html.erb
...
<%= render #posts %>
...
Likes controller:
#controllers/likes_controller.rb
class LikesController < ApplicationController
before_filter :signed_in_user
def create
#post = Post.find(params[:like][:liked_post_id])
current_user.like!(#post)
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
end
...
User model:
#models/user.rb
...
def like!(post)
likes.create!(liked_post_id: post.id)
end
...
#frank-blizzard has pointed out that my form markup is an issue. On a post's page the generated markup is:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" value="73" />
While on the feed page:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" />
You can do something like this:
<% form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :post_id, :value => #post.id %>
<%= f.submit %>
<% end %>
The current_user.likes.build(...) part should get out of your view and inside your controller. You are using a current_user.like! method so I guess you have implemented already some method in user model to accomplish this. If not build your like in the create action of LikesController where you can access params[:like].
def create
#post = Post.find(params[:like][:post_id])
current_user.likes.build(#post)
# ...
end
EDiT
You might need to pass your #post variable correctly into your _like_form partials, like so:
#views/posts/_post.html.erb:
...
<% if signed_in? %>
<%= render 'posts/like_form', :post => #post %>
<% end %>
...
This will give you acceess to a post variable inside the partial so you can prepopulate your forms value with its id. See this questions as well Pass a variable into a partial, rails 3? and make sure to read up on how to pass variables correctly to partials. you can debug your views using <%= debug <variablename> %>

Rails 3 ActiveRecord::UnknownAttributeError "unknown attribute: _destroy" for nested records

Let's say I have a schema in which an apple crate contains zero or more apples. While editing the apple crate in a form, I want to list the apples and provide a checkbox next to each apple, for deleting it when the form is submitted.
There is nothing going wrong that I can see. In my model I say
class AppleCrate < ActiveRecord::Base
has_many :apples
accepts_nested_attributes_for :apples, :allow_destroy => true
...
end
I have the form working, so far as I can tell. The checkboxes appear in the form html and when the form is processed by the controller each apple in the list has an attribute called "_destroy" which is set to either "1" or "0" depending on whether or not I checked the box before submitting.
According to the Rails API, when I set _destroy to 1 and save, the apple should be deleted. But when I submit the form I get
ActiveRecord::UnknownAttributeError in AppleCrateController#update
unknown attribute: _destroy
...
"apple_crate"=>{"id"=>"10101", "apples"=>{"1"=>{"id"=>"1",
"variety"=>"granny smith",
"apple_crate_id"=>"10101",
"_destroy"=>"1"},
"2"=>{"id"=>"2",
"variety"=>"fuji",
"apple_crate_id"=>"10101",
"_destroy"=>"1"},
"3"=>{"id"=>"3",
"variety"=>"macintosh",
"apple_crate_id"=>"10101",
"_destroy"=>"0"},
...
and so on.
I must be missing something obvious but after several days of futzing around I can't figure it out. I can successfully do everything else -- update, edit, index, etc -- so long as I leave out the :_destroy attribute. Any ideas?
(For what it's worth, I'm running rails 3.2.2 on Windows.)
Updated:
This is what I'm looking at in the documentation. (See the subsection "One-to-many".)
Updated:
As requested in comments, here is the view:
<%= form_for #apple_crate do |f| %>
<% #apples = #apple_crate.apples %>
<% #apples.each do |apple| %>
<%= fields_for "apples[]", apple do |apple_fields| %>
<%= apple_fields.text_field :variety %>
<%= apple_fields.hidden_field :apple_crate_id %>
<%= apple_fields.hidden_field :id %>
<%= apple_fields.check_box :_destroy %>
<% end %>
<% end %>
<%= f.submit "Save" %>
<% end %>
You should generate nested forms and forms with rails helpers, don't do it by your hands. So I think that's where your error at.
Try:
<%= form_for #apple_crate do |f| %>
<%= f.fields_for :apples do |apple_fields| %>
<%= apple_fields.text_field :variety %>
<%= apple_fields.hidden_field :apple_crate_id %>
<%= apple_fields.hidden_field :id %>
<%= apple_fields.check_box :_destroy %>
<% end %>
<% end %>
something like this, did not check if it's correct, but idea should be clear enough

How do I link to the particular ID of a model?

I have a search controller and index page:
# search/index.html.erb
<% #user_prices.each do |up| %>
# This needs to go to particular ID of UserPrice.
<%= link_to show_user_price_path do %>
<%= up.product_name %>
<% end %>
<% end %>
----------------------------------------------------------
class SearchController < ApplicationController
def index
#search = UserPrice.search do
fulltext params[:search]
paginate(:per_page => 5, :page => params[:page])
end
#user_prices = #search.results
end
end
Above you can see on my search form I am trying to link the product name to that particular UserPrice.How would I do this?
Thanks.
<%= link_to up.product_name, show_user_price_path(up) %>
That should do?
Not exactly sure why you're using the block form of link_to, if you check the link_to documentation there is an easier way to use the function to get what you want.
<% #user_prices.each do |up| %>
<%= link_to up.product_name, show_user_price_path(up) %>
<% end %>