Last week, we decided to remove sunspot
gem from this new version App. Therefore, I rolled out a simple and small solr
library.
I went through the ActiveRelation Walkthrough episode from RailsCasts long time ago, but now I have a chance to do something similar. I want the search response object lazy to load activerecord objects. I don’t want to call #results
method the same as sunspot
does. Actually, it’s a nice trick and simple to do it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
After sending the request to Solr, it will initialize the response object by passing solr response and the class to retreive the results.
The trick is to overwrite #inspect
method so that when in the console, you will see the objects back. #to_a
method is responsible loading the objects.
The question is that when to load? I want the caller be able to iterate through the collection by using standard Ruby enumerable methods such as each
, inject
, …… My solution is to overwrite method_missing
by sending any undefined methods to #to_a
method.
1 2 3 4 5 6 |
|
Everything works fine except when it renders the view. It shows this error [....] is not an ActiveModel-compatible object that returns a valid partial path.
1
|
|
After digging through google, it simply means it doesn’t know the partial path to render because it is my new object. Therefore, I just one more method in Solr::Response
class. It’s pretty simple, actually. ActiveModel
does the same thing, http://apidock.com/rails/v3.2.3/ActiveModel/Conversion/to_partial_path.
1 2 3 |
|
There is still one last tiny problem, it seems Rails
doesn’t know my new object is a collection object. It passes the whole object to each partial views. How does Rails
knows how the passed objects is collection or single object? I digged out the rails source code. Actually, it checks with to_ary
method, so I just alias
method.
1
|
|