rails search multiple attributes of multiple modules - ruby-on-rails

I'm trying to search all columns in my Ticket model. Most columns are assocaited with a belongs_to association so I have to search the attributes of the info in my columns because people won't know the IDs.
These articles helped:
Search multiple db columns in Rails 3.0
Rails: Search in has_one association
So far I have the below code, but it only searches the top param. How can I get it so that if it doesn't find anything in the top search, it tries the next. I'll be adding more to this.
Thanks
def self.search(search)
if search
Ticket.joins(:submitter).where('first_name LIKE ?', "%#{search}%")
elsif
Ticket.joins(:issue).where('name LIKE ?', "%#{search}%")
else
all
end
end
I figured it out, updated correct code here:
def self.search(search)
case search
when /^[-+]?[0-9]*\.?[0-9]+$/
Ticket.find(:all, :conditions => ['id LIKE :search', {:search => "%#{search}%"}])
else
Ticket.joins(:submitter,:issue).find(:all, :conditions => ['name LIKE :search OR first_name LIKE :search', {:search => "%#{search}%"}])
end
end

Updated code above - answer found

Related

Rails5: filtering with sunspot_solr

I have a search implemented with the gem sunspot_solr. I would like to add links in the search results to be able to filter the search by alphabetical order and other parameters.
my controller is
class SearchController < SuperSiteController
def index
#sunspot_search = Sunspot.search User, Post do |query|
query.keywords #search_query
query.paginate(:page => params[:page], :per_page => 30)
end
#posts = #sunspot_search.results
end
I wish I could filter for older, recent, and alphabetical order within your search has already been completed. I did not find anything in the documentation about this.
Has anyone worked with this type of search before, and if so, do you know the best practice for doing this?
I think you aim to order results based on a property (data field) of documents.
For example, to sort the results of Post model by created_at, you have to add this field to the index definition in app/models/post.rb as below:
class Post < ActiveRecord::Base
searchable do
...
time :created_at
...
end
end
And then in you SearchController sort the result as below:
class SearchController < SuperSiteController
def index
Post.search do
fulltext #search_query
paginate(:page => params[:page], :per_page => 30)
order_by :created_at, :desc #:desc for descending, :asc for ascending
end
#posts = #sunspot_search.results
end
In order to order results alphabetically you just have to add the field to you index definition as what mentioned above with text function instead of time and use order_by in SearchController.

Sunspot rails: include associated models when calling .results and how to correct syntax for it

A similar question has already been asked
Sunspot rails: include associated models when calling .results
search = Sunspot.search(ArticlePost, Post, User, Group) do
fulltext query
with(:api_search_shared, true)
paginate :page => page, :per_page => 100
end
what i want to do is include a few other tables with the query something like that:
include [{:user => [:user_job_title, :user_departments], :group => []}]
How would you go about go about putting the include in for when you are searching multiple models?
This is an example of a Single one:
Event.search(:include => [:user]) do...
this solution works for me :
search_in = [Post, Tweet]
search = Sunspot.search search_in do
search_in.each{|m|data_accessor_for(m).include = [:user]}
[...]
end
Hope this solution help.
Have a nice day :)

Rails search through associated models in HABTM relation

All,
I have a database of courses, programmes and staffMembers. A course has and belongs to many staffMembers and a course has and belongs to many programmes.
I want to make a search function that returns all courses that match the input keywords. Currently, I only search through all of the courses' fields, but I also want to return courses of a certain programme and of a certain staffMember if those match the search keywords. In other words, I want to search trough the associated models' fields as well. This is my code:
class Course < ActiveRecord::Base
has_and_belongs_to_many :programmes
has_and_belongs_to_many :staffMembers
def self.search(search)
# wild cards in front and back
search_condition = "%" + search + "%"
find(:all, :conditions => ['name LIKE ? OR description LIKE ? OR goals LIKE ?',
search_condition, search_condition, search_condition])
end
end
And in the CoursesController:
class CoursesController < ApplicationController
def search
#courses = Course.search params[:search]
end
end
All help appreciated!
This should work:
def self.search(search)
# wild cards in front and back
search_condition = "%" + search + "%"
includes(:programmers, :staffMembers).find(:all, :conditions => ['name LIKE :search_condition OR description LIKE :search_condition OR goals LIKE search_condition OR programmers.name LIKE :search_conditions ...',
:search_condition => search_condition])
end

Rails ActiveRecord: Multiple conditions in find

This might be more of a Ruby syntax thing than anything else. I'm having difficulty getting two limiting conditions on a SomeObject.find going.
Separated, the conditions seem to work:
if search != ''
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all, :conditions => ['active', 1]).shuffle
end
What I'm going for for the first case is this:
find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1])
But the line throws syntax error, unexpected ')', expecting tASSOC.
Rails 2
find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) isn't the proper syntax for passing hashes to a method. You can leave the curly braces off of a hash if it is the last argument to a method, but in this case you are passing an array as the last argument.
Use the following instead:
find(:all, :conditions => ["name LIKE ? AND active = ?", "%#{search}%", 1])
or
params = {:search => "%#{search}%", :active => 1}
find(:all, :conditions => ["name LIKE :search AND active = :active", params])
Rails 3 and 4
You would probably want to do something more like the following for recent Rails versions:
scope :active, -> { where(active: true) }
scope :name_like, ->(search) { where("name LIKE ?", "%#{search}%") }
And then you'd call it like this:
YourModel.active.name_like("Bunnies")
That allows you to reuse those specific queries in different combinations throughout the application. It also makes the code retrieving the data super easy to read.
If you don't like the scope syntax, you can also define these as class methods:
def self.active
where(active: true)
end
def self.name_like(search)
where("name LIKE ?", "%#{search}%")
end
You can also chain scopes on the fly. That will allow you to start building a chain of relation objects and then choose to include others based on conditions. Here's what it could look like when applied to the original question to achieve the same results:
results = active
results = results.name_like(search) if search.present?
Instead of using if-else which would involve a redundancy for checking on active = 1, a simpler syntax would be something like this:
result = where(:active => 1)
result = result.where('name like ?', "%#{search}%") unless search.blank?
As far as the error your seeing, it wouldn't appear to be caused by the code that you are posting. A stack trace may help narrow it down further...
i think you are using rails 2
try this.
find(:all, :conditions => ['name LIKE ? and active = 1', "%#{search}%"])
rails 3 syntax
where('name LIKE ? and active = 1', "%#{search}%")
For Rails 4, In rails new find_by and find_by! methods are introduced
Read answer

Is there such a thing as a 'nested find' in Rails?

I've got the hang of nested includes—they're great for performance—but what I'd really like is a 'nested find'. What's the best way to achieve something like:
#matchingProducts = Batch.find(:all,
:conditions => 'product.name LIKE ?', "%#{search}%",
:include => :product)
As you can see, Product is a nested attribute of Batch, but I want to find a batch based on Product.name.
Rails 3 I would use the AREL syntax:
#matches = Batch.where('product.name LIKE ?', "search").includes(:product)
Your idea was right, you can do matchingProducts = Batch.find(:all, :include => 'products', :conditions => ["products.name LIKE ?", whatever_you_want], :order => order_as_you_want)

Resources