I'm trying to set up a search-as-you-type form with Tokeninput, with help from Ryan Bates' Railscast. Unfortunately, I'm having trouble figuring it out with a self-referential association.
In my models:
class Skill < ActiveRecord::Base
attr_accessible :skill_relationship_attributes, :prereq_tokens
attr_reader :prereq_tokens
has_many :skill_relationships
has_many :prereqs, :through => :skill_relationships
has_many :inverse_skill_relationships, :class_name => 'SkillRelationship', :foreign_key => "prereq_id"
has_many :inverse_prereqs, :through => :inverse_skill_relationships, :source => :skill
accepts_nested_attributes_for :skill_relationships, :allow_destroy => true
def prereq_tokens=(ids)
self.prereq_ids = ids.split(",")
end
end
class SkillRelationship < ActiveRecord::Base
attr_accessible :skill_id, :prereq_id, :skill_attributes, :prereq_attributes
belongs_to :skill
belongs_to :prereq, :class_name => 'Skill'
end
And I feebly put together a form:
<%= form_for skill do |f| %>
<%= f.label :prereq_tokens, "Prerequisites" %><br/>
<%= f.text_field :prereq_tokens, data: {load: Skill.all} %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I do get a nicely styled text field, but it doesn't find anything when it searches and I'm not really sure where to go from here. Any ideas?
I figured this one out! First, I removed "data: {load: Skill.all}" from the form, because I wanted it to work through thinking_sphinx rather than my entire database. Then - and here was the key - I specified propertyToSearch and queryParam in my coffeescript:
jQuery ->
$('#skill_prereq_tokens').tokenInput '/skills.json'
theme: 'facebook'
propertyToSearch: 'title' // :title is the attribute in my Skill model that I want to show up in the list
queryParam: 'search' // :search is the parameter that gets passed to thinking_sphinx
And voila! It turned out to be more a thinking_sphinx issue than anything to do with my self-referential associations.
It's important to note that specifying the title attribute with propertyToSearch only determines which attribute gets to represent each skill and does not prevent thinking_sphinx from using other attributes from its index.
It doesn't work exactly like a Facebook input field though, since thinking_sphinx by default only does whole-word search. In other words, if I'm looking for a skill called "Boxing" and I type in "box" or even "boxin", I'll get nothing. Only when I finally type in the full word boxing "boxing" will the skill be returned in the list. It's possible to configure thinking_sphinx to index prefixes, so that it'll return results from partial words, like Facebook does - but if you're indexing a large database, you probably don't want to do that, because your index will blow up crazy fast. That's probably a significant part of the reason why Facebook caps everyone at 5000 friends, apart from the fact that no one has 5000 friends.