Autocomplete Vs Pagination - ruby-on-rails

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.

Related

Rails 4 - Ordering by something not stored in the database

I am using Rails 4. I have a Room model with hour_price day_price and week_price attributes.
On the index, users are able to enter different times and dates they would like to stay in a room. Based on these values, I have a helper method that then calculates the total price it would cost them using the price attributes mentioned above.
My question is what is the best way to sort through the rooms and order them least to greatest (in terms of price). Having a hard time figuring out the best way to do this, especially when considering the price value is calculated by a helper and isn't stored in the database.
You could load all of them and do an array sort as is suggested here, and here. Though that would not scale well, but if you've already filtered by the rooms that are available this might be sufficient.
You might be able to push it back to the database by building a custom sql order by.
Rooms.order("(#{days} * day_price) asc")

rails 3.1 How to retrieve in a query those elements with the maximum number of relationships in a many to many?

I have tried different combinations but it seems that I cannot work this out.
I want to retrieve, from an Event model, those events which have the biggest number of users.
For example, I retrieve users of an event like this
#users = Event.find(x).users
They can be counted using this
Event.find(x).users.count
So, How should be done to order the list by the number of users each event has. And then retrieve the 8 first?
The same issue was resolved in: How to get highest count of associated model (Rails)?
Event.order("events.users_count DESC")

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

If sorting records by a number in the record, but some records have the same number, the order is not gauranteed but shouldn't be random?

Let's say if we are sorting some records by a number in record:
Name Number_of_Language_Known
John 3
Mary 2
Peter 3
Mike 1
...
If we are not also sorting by Name, then the order of John and Peter is not guaranteed, but it shouldn't be random if the records never changed? I think it should be true in most environment (that is, nothing else changed, and the sorting is done twice).
That is, if we sort it one time, it won't be Peter before John and the second time, John before Peter.
This is because in a Ruby on Rails environment, if the records are fetched from DB and then sorted by a Ruby function, and printed as the original page content, the order is one way, but if the data is requested through AJAX afterwards, then the sorted array elements can have a different order, for records with the same number in that number field, and that seems strange.
Update: if the data is from the db, then maybe the db can have unpredictable order when records are fetched. But what if the records are sorted by primary ID in the first place? Also if the data is right inside the data structure already, I don't know any common sorting algorithm that will produce different sorting order each time. That is, order not guaranteed but not random.
"not guaranteed" means it can change whenever it likes (depending on the current memory layout, the garbage collector, the time, ...) if you need the sort order of another attribute to be stable you have to sort it by both attributes (by id and then by name - in your case)
Assuming these values are coming from an Active Record model, the ordering is coming from the database itself. Different databases handled ordering in different ways, so you will probably need to check the docs for your specific db.

Sort by ranking algorithm using will-paginate

I'm creating a digg-like site using Ruby on Rails that ranks the item (based on this algorithm). I'm using the will-paginate gem list the items in pages.
The problem is, will-paginate only allows me to insert ':order =>' based on the table data. I would like to make will-paginate to sort by a number which is calculated using a function based on different fields on the table (e.g number of votes, age hours).
How can I do that?
According to the comments/documentation in the code, you can use
Post.paginate_by_something
in order to use
Post.find_all_by_something
to get the collection of items you want to use paginate for. The :order option is required to set the order of the items.
So for your problem you can create a custom find method, adding a rank column using your algorithm. Use the :order option to sort on this ranking.
You can also use the paginate method on named scopes. If you make a scope for the ordering you could just do Article.ordered.paginate.

Resources