I want users to be able to use one search box to search for different objects. I would differentiate them on the results page. Both would be full text search.
Should I make a Search controller and load everything into the index action with something like:
#posts = Post.all
#groups = Group.all
Something tells me that would be fantastically inefficient.
I'm not really sure where to start, I haven't managed to find anything addressing this question on the interwebs, but if I have overlooked something let me know.
Thanks
EDIT:
here's my search bar that is available globally on my website:
-form_tag posts_path, :method => :get do
=text_field_tag :search, params[:search], :id => 'searchfield'
=submit_tag '',:name => nil, :id => 'searchbutton'
it only searches the "Post" model right now, and displays the results on the Post#index view
I want to be able to have queries typed into the search box be searched for in both the Post and Group tables, and the results be displayed in two separate columns on the same page. maybe through a search controller/view
If you want to search both types at once, you can use this form:
# Pass your models in by class constant
Sunspot.search(Post,Group) do |s|
s.fulltext(params[:search])
end
This is documented in the wiki:
https://github.com/sunspot/sunspot/wiki/Working-with-search#initiating-a-search
Add the searchable directive from sunspot solr to your models for indexing. For example:
class Post < ActiveRecord::Base
searchable do
text :title, :body
end
end
class Group < ActiveRecord::Base
searchable do
text :name
end
end
If you have existing data in DB make sure to run rake sunspot:solr:reindex for indexing. For new data the indexing will be done in a hook.
Now you can search:
#posts = Post.search {fulltext params[:search]}
#groups = Group.search {fulltext params[:search]}
Now you have the data for your two columns.
This is not the answer, but I found something useful. It is a gem that helps you searching across multiple tables:
https://github.com/toptierlabs/acts_as_fulltextable.
It helps you keeping all the searchable data (from different models) in one place.
Related
I am trying to implement a search field in Rails 4 to find data behind two models. I have two controllers: buildings and rooms, and two models: building and room. A building, naturally, has many rooms and a room belongs to a building, which I have stated in the respective models.
Basically, a user could type either a building or a room name into the search form and it would return a response with details about the building or room. Of course, a building needs to have an address, and a room needs to know in which building it is with the address as well. So I'd need to display different details according to the searched for instance. Both have the same String attribute name, so this could make things easier.
I have no luck in finding a relevant example on how to implement such a search form. This is the working basic search I have at the moment in views\buildings\index.html.erb, which can only search buildings:
<%= form_tag({controller: "buildings", action: "show"}, method: "get", class: "nifty_form") do %>
<%= label_tag(:name, "Search for a building (later also rooms):") %>
<%= text_field_tag(:name) %>
<%= submit_tag("Search") %>
<% end %>
This is the show method in controllers\buildings_controller.rb:
def show
#building = Building.where('lower(name) = ?', params[:name].downcase).first
end
And this is the route it refers to:
get 'buildings/:id' => 'buildings#show'
Any and all help is appreciated!
I would recommend you to add the search code in the index method of buildings controller, there are many things you can do but here is what i will recommend:
def index
#
if params.has_key?(:name)
#buildings = Building.joins(:rooms).
where([
'lower(buildings.name) like ? or lower(rooms.name) like ?',
"%#{params[:name].downcase}%",
"%#{params[:name].downcase}%"
])
else
# your normal code goes here.
end
end
Any other information you need such address ( is that a different model ) can he included in there.
Hope this helps,
PD: if necessary you can render a different view when a search is present inside your if block
render action: 'my_custom_view', status: :ok
Due to time restrictions, I decided to merge these models into one common model, Space. It holds all the information that a building and a room needs. Thanks anyways!
I've managed to build a simple search model and have four attributes that can be searched; name, age, location and gender. The problem I am having is I can't seem to find the right code to search multiple attributes.
For example a search for "adam" should produce all users named adam, whereas a search for london should display all users from london. I can only search one attribute individually (name) so if I type in "london" it displays a blank result page.
/people/index.html.erb (search form)
<%= form_tag people_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search]%>
<%= submit_tag "Search" %>
<% end %>
models/person.rb
class Person < ActiveRecord::Base
attr_accessible :age, :gender, :location, :name
def self.search(search, id)
if search
where(['name LIKE ?', "%#{search}%"])
else
scoped
end
end
end
people_controller.rb
def index
#people = Person.search(params[:search], params[:id])
end
The following code worked fine.
where('name LIKE ? OR location LIKE ?', "%#{search}%","%#{search}%")
#meagar, I fail to understand how that simple line of code "is outside the scope of Stack Overflow".
You can checkout Sunspot_rails gem for your problem, it integrate Solr search engine platform into Rails and is a battle proved solution for Rails app. In my company's website Fishtrip.cn we use solr to search for both House, Transportation retailer and tours. It might be a little bit heavy for your project, but if are looking for a powerful solution then Sunspot definitely would be one of it.
I'm creating an application that tracks users and achievements (think, xbox live, etc.) These tables are linked via a join table. I would like to have a search form on my index that lets users type in a users name and a new page is loaded with a list of all achievements that user has earned. I'm not entirely sure how to set up this search form, on the index, to actually search the user table and return the results on a new page. Any help would be greatly appreciated. If you require more information then I'll be happy to provide it.
Here's a bit of skeleton code to get you started based off what I think you need from what you have said. I hope this is useful.
For the search bit you could do something like this in your index view:
<%= form_for User.new, :url => "search" do |f| %>
<%= f.label :name %>
<%- f.text_field :name %>
<%- end %>
In your controller:
def search
q = params[:user][:name]
#users = User.find(:all, :conditions => ["name LIKE %?%",q])
end
and in your search view:
<%-#users.each do |user| %>
Name: <%=user.name %>
<%- user.achievements.each do |achievement| %>
<%= achievement.name %>
<%- end %>
<%- end %>
You would, of course, need to ensure the users and achievement models are correctly linked:
class User << ActiveRecord::Base
has_many :achievements
end
There are plenty of tutorials and things about this e.g.:
http://blog.devinterface.com/2010/05/how-to-model-a-custom-search-form-in-rails/
Look the thing is every basic explanation in Rails3 starting with the Initial Tutorial provided by them explains you how to setup a new Controller/Model. The example was only one of thousands explaining the same problem.
It is a very broad range of different things you can do to achieve this. Basically you have to put some code in the controller:
which handles the search (including the activerecord stuff or whichever technique you use to access your model)
which sets some variables necessary for the search form
Setup two routes etc... Its to broad and completely covered even by the basic official rails3 tutorial.
Here is an application based on searchlogic is very useful and you can search by whatever you want
https://github.com/railscasts/176-searchlogic
You may want to check out the Ransack gem. https://github.com/activerecord-hackery/ransack
I am using Ernie Miller's Metasearch in a rails 3 app and have run into a problem.
In my Model
class Prospect < ActiveRecord::Base
has_many :steps
In my controller
#search=Prospect.search(params[:search])
In my view (search form)
<%= f.date_select :steps_updated_at_greater_than%>
This works such that I get all the Prospects where steps have been updated since date_select. My problem is that if there has been multiple updated steps, I get duplicates in #search, which I do not want when I go to format my search results in a view.
My question is what is the best way to remove the duplicates from #search? Or prevent duplicates from being added to #search in the first place?
#search=Prospect.search(params[:search]).select('DISTINCT step_id')
#search = Prospect.search(params[:search])
#prospects = #search.relation.uniq
You want:
#search = Prospect.search(params[:search])
#search.relation.select("DISTINCT(step_id), prospects.*")
I built a basic search form that queries one column in one table of my app. I followed episode 37 Railscast: http://railscasts.com/episodes/37-simple-search-form
Here's my problem. I want to display the search query that the user makes in the view that displays the search results. In my app, the search queries the zip code column of my profile model, and returns a list of profiles that contain the right zip code. On the top of the list of profiles returned from the search, I want it to say "Profiles located in [zip code that was queried]."
I'm sure I can do this because the queried zip code gets passed into the url displaying the results. So if the url can pick it up, there must be some way to display it in the view on the page as well. But I don't how.
Please keep in mind that I'm not using any search pluggins and I don't want to use any for now. This is my first app, so I don't want to add complexity where it's not needed.
Per Ryan's instructions in the Railscast, here's my setup:
PROFILES CONTROLLER
def index
#profiles = Profile.search(params[:search])
end
PROFILE MODEL
def self.search(search)
if search
find(:all, :conditions => ['zip LIKE ?', "%#{search}%"])
else
find(:all)
end
end
PROFILE/INDEX.HTML.ERB
<% form_tag ('/profiles', :method => :get) do %>
<%= text_field_tag :search, params[:search], :maxlength => 5 %>
<%= submit_tag "Go", :name => nil %>
<% end %>
The search itself is working perfectly, so that's not an issue. I just need to know how to display the queried zip code in the view displaying the results.
Thanks!
Just set it to an instance variable and use that.
def index
#search = params[:search]
#profiles = Profile.search(#search)
end
In your view, you can reference #search.
Also, as a friendly tip, please use an indent of 2 spaces for Rails code. It's the standard way to do it, and others who are reading your code will appreciate it.