Comments (8)
Hi, there's no elegant solution for this problem with associations, in the current version.
The wrapper
is set to the model, and obviously, the model inicialization fails with NoMethodError
(or other) error when being passed the hash, which was returned from ElasticSearch.
First, I have anticipated the issue. As you can see in commit 5d89dd1, Tire was initializing the collection from the records retrieved from the database, originally (via MyModel.find [list of IDs]
). This, however, had many issues. The performance was unnecesarilly dumped by roundtrips to the database. The sort order was not preserved (a huge bug). So I decided against it.
Second, the problem can be immediately solved. Let's simplify your situation (because that's really a M to N relation, with videos and categories).
The Article
model has many Comment
associations:
class Article < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
index_name 'articles-with-comments'
has_many :comments
end
The Comment
is simple:
class Comment < ActiveRecord::Base
belongs_to :article
end
Now, obviously, when you have the Article
indexed as:
def to_indexed_json
{ :id => id,
:title => title,
:content => content,
:comments => comments.map { |c| { :id => id, :author => c.author, :content => c.content } },
}.to_json
end
it would break on Article#comments=
being given wrong type of objects on initialization.
You can temporarily, and in a quite ugly way, solve it like this:
class Article < ActiveRecord::Base
# ...
alias :original_comments= :comments=
def comments=(comments)
# Are the objects returned from ElasticSearch?
if comments.all? { |c| c.is_a? Hash }
comment_ids = comments.map { |c| c['id'] }
else
send :original_comments=, comments
end
end
end
So, when we are initializing the comments from ElasticSearch, set the ID (an retrieve the records from database), otherwise, perform the original method.
Of course, this could be isolated into completely different model, like this:
class SearchedArticle < Article
index_name 'articles-with-comments'
def comments=(comments)
comment_ids = comments.map { |c| c['id'] }
end
end
You'll then search via this fake model: SearchedArticle.search 'love'
. Of course, this is an ugly, and temporary way of dealing with the issue. The underlying issue is, of course, blocking for advanced production usage.
When I have discussed this with another Tire users, the real, and elegant, solution seems to me like this:
- Do not wrap the results in the real model class, but wrap them in
Tire::Results::Item
, as usual - Add a proxy object to every result, let's say
object
, which would point, via the ID, to the underlying record (and model instance)
In this way, we would keep the awesome performance of ElasticSearch, for most cases. Where you'd need or like to get the original model instance, you'd just write result.object.comments.first.my_complicated_method
, instead of result.comments.my_complicated_method
.
Thank you for the report, and I'll definitely have a look at this issue.
from retire.
Cool. I'll give that a try. Thanks for the detailed response.
from retire.
@russ, any luck with the proposed solution?
from retire.
The solution did work. But for the time being I went back to sunspot. I will definitely give Tire another try in the future.
from retire.
Understood. Thanks for the report!
from retire.
Hi @russ, I've tried to solve this issue with ActiveRecord associations -- see the closing commit.
Could you test it against your use-case, if you still have the code handy? The only thing you need is to define Git as endpoint in the gemfile:
gem "tire", :git => "git://github.com/karmi/tire.git", :branch => "activerecord"
from retire.
This looks very cool :D
from retire.
@aaronchi: It looks, but let's see how it works in real world :)
from retire.
Related Issues (20)
- empty array HOT 2
- Elasticsearch 1.2.1, empty hash should be removed. HOT 5
- T
- Can I use regexp query via tire? HOT 1
- Persistence module does not provide updating a record. HOT 2
- "uninitialized constant" error on import rake task HOT 3
- Sort by field value other model (table)
- How can we use tire with multitenant app?
- Timeout option on activerecord? HOT 1
- Boost hits based on date HOT 2
- is there a way to use tire with zeus-parallel_tests?
- Custom Mapping on Hstore Columns
- Elasticsearch(0.90.9) failed to download 230K records(~80mb), with Tire gem(0.4.2).Below was the error message
- Elasticsearch(0.90.9) failed to download 230K records(~80mb), with Tire gem(0.4.2).Below was the error message
- import:all tasks: models load HOT 1
- Regarding nested query
- Support to `search_type: scan` HOT 1
- Ordering doesn't work without RoR shutdown HOT 1
- d
- Querying Association Trouble? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from retire.