I have a rails app where a user can enter keywords into a search box. From there, I find the id's of those matching keywords, then I do more processing until i arrive at an array of items that fulfill that criteria.
EXAMPLE:
A user searches for people who have a JD degree. I look up the id in the Degrees database, then I look up all companies/firms from my Companies db that employ people who have JDs. Finally i collect the employees with JDs of those companies. Assume that there is no way to start by searching people.
Once I have an array of individuals that meet the requirement, how can I paginate through this array? It seems paginating in the Employee model isn't giving me what i want.
When the user who performs the search hits the 'Next' button, the array of results is gone and i would ideally like to preserve that array appropriately, or get rid of it if the user performs a new search. Thoughts?
In a file in your config/initializers, add this:
require 'will_paginate/array'
Then you can use it on arrays:
my_array.paginate(:page => x, :per_page => y)
The will_paginate gem is definitely a simple solution. The README has a few examples on how to implement it: https://github.com/mislav/will_paginate. The :per_page property takes care of retaining the array when you go to the next page of results.
Related
I'd like to add the ability to filter products by multiple categories to a Rails ecommerce application. I currently allow filtering products by category, but now I'd like to provide the ability to filter further.
For example, I'd like to allow a user to select "Men's" and "Outerwear" to display only products in both of those categories.
Knowing that supplying an array of category IDs in my Product query will find products in any of the specified categories, and hoping for a nice ActiveRecord-y type solution, I first tried adding multiple categories.id conditions in the query, but this didn't work out.
Product.joins(:categories).where(:'categories.id' => 123, :'categories.id' => 456)
The result here was that the first category ID was overwritten by the second.
And, of course, this will find products in either of the categories, rather than only products in both:
Product.joins(:categories).where(:'categories.id' => [123, 456])
Additionally, the solution I need should work with an arbitrary number of categories. It could be two, it could be three, or more.
After doing some research, I don't think there's a nice Rails-y way to do this, but I'm stuck on finding the actual correct solution.
My application is running Rails 5.2 with MariaDB.
Based on #muistooshort's comment above, I found this SO post with the solution I needed:
Selecting posts with multiple tags
Updating my query like so gave the products I wanted, those in ALL of the specified categories (lines wrapped for readability):
Product.joins(:categories).where(:categories => { :id => category_ids })
.having('count(categories.name) = ?', category_ids.size)
.group('products.id')
I am creating a website that allows users to evaluate their coworkers. My boss would like the averages to be displayed from best to worst on a static page that she can print and hang up in our store, so the employees can see their results compared to other employees. I have been searching for awhile now on how to easily sort a column. I found a Railscast on sorting columns, but it seems a lot more detailed than I truly need. I found the order API, but I don't think I'm implementing it the way I need to. I am hoping that maybe there is a one-liner that can help me solve this problem, such as:
#user = User.all.order(average: :asc)
Where I can load a static page that prints the user's name and their score. Thank you in advance!
Have you tried that code of yours? It should do exactly what you're asking except from lowest score to highest score.
You could simplify it a little and sort from highest to lowest by doing:
#users = User.order(average: :desc)
Like MarsAtomic said, this assumes that you actually have a column in your users table called average. If not we need more information on how your database is set up.
I have a Rails Model with a relatively small number of entries (Currently at ~ 300 and will probably never go past 1000).
It currently paginates items on its index page to show 20 results a page.
I have just added Twitter Typeahead to the search field, and I'm using the record's names to supply the autocomplete suggestions. The problem is that as I'm paginating the results, I'm only able to offer suggestions for the 20 items from the current paginated batch.
The only thing I need from each model is its name, and I don't want to load/parse every record as this will undo most of the advantages from pagination.
So how can I retain sensible pagination, but also access the names of all records in an efficient manner?
You could fetch the names separately with pluck.
#names = MyModel.pluck(:name)
Note that in Rails 3 you can only provide 1 column name as argument for pluck.
Pagination usually resorts to LIMIT, so the only way to still retrieve all records, is to do another query.
With pluck you're only retrieving the field that you want from the database, and you won't have the overhead that ActiveRecord brings when you would go through a complete collection of all your models.
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
I have a little example Rails app called tickets, which views and edits fictional tickets sold to various customers. In tickets_controller.rb, inside def index, I have this standard line, generated by scaffolding:
#tickets = Ticket.find(:all)
To sort the tickets by name, I have found two possible approaches. You can do it this way:
#tickets = Ticket.find(:all, :order => 'name')
... or this way:
#tickets = Ticket.find(:all).sort!{|t1,t2|t1.name <=> t2.name}
(Tip: Ruby documentation explains that sort! will modify the array that it is sorting, as opposed to sort alone, which returns the sorted array but leaves the original unchanged).
What strategy do you normally use? When might you use .sort! versus the :order => 'criteria' syntax?
Use :order => 'criteria' for anything simple that can be done by the database (ie. basic alphabetical or chronological order). Chances are it's a lot faster than letting your Ruby code do it, assuming you have the right indexes in place.
The only time I could think you should use the sort method is if you have a complex attribute that's calculated at run-time and not stored in the database, like a 'trustworthiness value' based off number of good/bad responses or something. In that case it's better to use the sort method, but be aware that this will screw things up if you have pagination in place (each page will have ITS results in order, but the set of pages as a whole will be out of order).
I specify an order in the ActiveRecord finder or in the model association because sorting using SQL is faster. You should take advantage of the features offered by the RDBMS when you're able to do so.