join query in rails 4 - ruby-on-rails

i am developing a job portal using rails 4.
i have search box where job seeker can search jobs. currently i am able to do it for job title and description , as follows
scope :by_name_or_desc,lambda{|search| where(" title ilike (?) or description ilike(?)","%#{search}%","%#{search}%") if search.present?}
i want to use the same search box for skills also where seeker can search job using skill. i have skill_ids as a column in my Job model . which is array field. how can i modify above query to do the same.
i also tried doing this ,
scope :by_name_or_desc,lambda{|search| where(" title ilike (?) or description ilike(?) or '#{search}' = ANY (skill_ids)","%#{search}%","%#{search}%") if search.present?}

If you use PostgreSQL, you should take a look at Full Text Search feature. Otherwise i recommend you to use Elastic Search or Sphinx for this kind of stuff. Full-text search is not what RDBMS designed for. With project's growth your approach will be only a headache.

Related

Querying records based on max of subcollection

As the title says, for example we have a library system with two tables Books and RentalRecord with a one to many relationship. It looks like
Book1
--name
--RentalRecords
----record11
----record12
Book2
--name
--RentalRecords
----record21
----record22
----record23
----record24
Each record contains 2 time stamps for date rented, and date returned
and I want to query for the Books that hasn't been rented out in the past 2 weeks.
I'm new to Ruby and couldn't think of any way to do this without using multiple queries.
Using two queries sometimes is a viable option. If you prefer constructing a single query, use something along the lines of
Book.joins(:rental_records)
.where("max(rental_records.created_at) < ?", 2.weeks.ago)
Things to note:
You need to join the required tables explicitly (but by association name)
You can use a plain string in a Rails where statement
You can bind a Ruby value to a question mark within such a string
If your queries get out of hand or you don't like using plain SQL strings like that, then take a look at the gem squeel. It provides an fully-fledged SQL algebra for Ruby on Rails.
HTH

Rails Search One Column On Multiple Saved Terms (Saved Searches In Model)

One table, one column ('headline' in an RSS feed reader). On the front end, I want a text area in which I can enter a comma-separated list of search terms, some multi-word, like for 'politics':
rajoy, pp, "popular party", "socialist party", etc
This could either be stored as part of a separate search model or as a keyword column on the 'category' or 'story' models, so they can be edited and improved with different terms from the front end, as a story develops.
In the RSS reader, have a series of links, one for each story or category, that, on being clicked return the headlines that contain one (or more) of the search terms from the stored list.
In a later version, it would be good to find headlines containing several of the terms in the list, but let's start simple.
Have been doing lots of reading about postgres, rails, different types of searches and queries, but can't seem to find what I want, which I understand is basically "search 'headlines' column against this list of search terms".
Sounds like it might be an array thing that's more to do with controllers in Rails than postgres, or cycling through a giant OR query with some multi-word terms, but I'm not sure.
Does anyone have any better pointers about how to start?
Users
If this will be user specific, I would start with a User model that is responsible for persisting each unique set of search terms. Think logon or session.
Assuming you use the Category method mentioned before, and assuming there's a column called name. Each search term would be stored as a separate instance in the database. Think tags.
headlines that contain one (or more) of the search terms from the stored list
Categories
Since each Category has many terms, and all the queries are going to be OR queries, a model that joins the User and Category, storing a search term would be appropriate.
I'm also assuming you have a Story model that contains the actual stories, although this may not be persisted in the database. I'm predicting your story model has a heading and a body.
Terminal Console
rails generage model SearchTerm query:string user:references category:references && rake db:migrate
Models
On your existing User and Category models you would add:
# app/models/user.rb
has_many :search_terms
has_many categories, through: :search_terms
# app/models/category.rb
has_many :search_terms
has_many :stories
Rails Console
This will automatically make it possible for you to do this:
#user = User.last # this is in the console, just to demonstrate
#category = Category.find_by_name("politics")
#user.search_terms.create {query: "rajoy", category: #category}
#user.search_terms.create {query: "pp", category: #category}
#user.search_terms.where(category_id: #category.id).pluck(:query)
-> ['rajoy', 'pp']
Controllers
What you will want to do with your controller (probably the Category controller) is to parse your text field and update the search terms in the database. If you want to require commas and spaces to separate fields, you could do:
#user.search_terms.where(category: #category).delete_all
params[:search_term][:query].split(", ").map{|x| x.gsub("\"", "")}.each do |term|
#user.search_terms.create({category: #category, query: term})
end
Front End
Personally though, I'd make the front end a bit less complicated to use, like either just require commas, no quotes, or just require spaces and quotes.
Search
For the grand finale, for the Stories to be displayed that have search terms in their heading:
Story.where(#user.search_terms.where(category: #category).pluck(:query).map { |term| "heading like '%#{term}%'" }.join(" OR "))
I would recommend using pg_search gem rather than trying to maintain complicated queries like this.
Note: I'm sure there are errors in this, since I wasn't able to actually create the entire app to answer your questions. I hope this helps you get started with what you actually need to do. I encourage you as you work through this to post questions that have some code.
References
Rails guides: choosing habtm or has many through
gem 'pg_search'
Stack Overflow: Search a database based on query

how to implement advanced search in rails with form validation

I have a problem with this scenario in ruby on rails 4, hope you guys can help me out.
I have products, brands, prices and users tables:
products: name, description,user_id,...
brands: title
prices: value, shipping_fee,...
users: username, password,...
I need a search page that allows people search products based on:
prices (minimum, maximum)
brands
seller name (it would be a join to users table)
What's your suggestion for the best way implementing such scenario? (or I should say cleanest way)
ps1: I need to validate fields in the search form.
ps2: I've seen sunspot and I don't think if that kind of full-text search be a good option for my scenario
Have a look at has_scope gem.
It allows you implement a search in controller using the resource scopes.

Rails tokenized text search across fields with performance in mind

I have a Rails app on Heroku that I'm looking to increase the user-friendlyness of the search for. To do this, I'd like to allow them to text search across multiple fields on multiple models through associations. The input from the user could be a mix of text from any of these fields (and often might span multiple fields) in no particular order.
Example: if you had a car database and wanted to allow the user to search "Honda Fit 2011", where "Honda" came from the manufacturer table, "Fit" came from the model table, and "2011" came from the model_year table.
I'm thinking that I need to build a single field on the root record that contains the unique list of words from each of these fields, and then tokenize the user's input. But that would cause me to use an IN clause, which I'm not sure could benefit from full-text search plugins like pg_search.
So, my question is what's a good way to active a search like this in Rails?
I would take a look at Sunspot_rails. It uses Solr as it's search engine, but allows you index content in all sorts of fruity ways. For instance, I have models indexed with their associations pretty simply:
searchable do
text :description
text :category do
category.present? ? category.name : ''
end
end
You can then search with:
TYPES = [Asset,Product]
Sunspot.search(*TYPES) do |q|
q.fulltext search_str
end

Returning Search Results in Rails

I am having a problem implementing a special kind of search for my Rails application. I am working on an achievement system where you can search for a set of users in a search form (e.g., the query being "Ross, Adam, Jake") and it returns all of the common achievements that the users have unlocked (e.g., if users Ross, Adam, and Jake all had an achievement named "You are winner!"). I have three tables, one for achievements, one for users, and a join table. We have tested the associations and such, so we know that works.
My first idea was to put the search terms in an array and get the search results for each item in the array and place them into respective "search result arrays". Then, I was thinking to go through each item in search result array 1 to see if it appears in both of the other result arrays. The objects that appear in all three of the search result arrays would be returned and displayed on a page.
Is there an easy way to implement this without writing a bunch of my own code? Are there some functions I should know about? Any help will be appreciated!
Well, both Ransack and it's predecessor (MetaSearch) are useful gems for creating complex search forms.
In general I think you want to do something like select distinct achievement ids for user ids in an array. Off the top of my head I'm not quite sure how you should write it... others may know.
Look at the documentation on MetaSearch (more established) and see if you see a pattern that fits, if not check Ransack (more advanced).
You can use some autocomplete plugin for user names and convert the names to ids on the fly, that way you won't have to deal with converting user names to ids in backend later.
For common achievements, if a user can have a achievement only once, aggregating the results in join table and counting the results with achievement ids would be the way to go.
You can provide more details for a more detailed answer. :)
You can use Sunspot which is allows easy solr integration with Ruby and Rails

Resources