I'm making an app with three model objects, Team
, Users
and Member
, Member
is a join table between Team
and Users
. So each Team
can have many members, and each User
can be a member of multiple teams.
The relationship looks like this:
# Team.rb
has_many :members
has_many :users, through: :members
# User.rb
has_many :members
has_many :teams, through: :members
What I want to do is to search for members that are in a specific team. Currently I get no
results.
My indexes looks like this:
# user_index
ThinkingSphinx::Index.define :user, :with => :real_time do
indexes name
indexes email
indexes about
has team_id, type: :integer
has created_at, type: :timestamp
has updated_at, type: :timestamp
indexes members.team.name, :as => :teams
end
# team_index
ThinkingSphinx::Index.define :team, :with => :real_time do
indexes name
has created_at, type: :timestamp
has updated_at, type: :timestamp
indexes members.user.name, :as => :members
end
# member_index.rb
ThinkingSphinx::Index.define :member, :with => :real_time do
has user_id, type: :integer
has team_id, type: :integer
has created_at, type: :timestamp
has updated_at, type: :timestamp
end
My members_controller
index action (where I perform the search) - looks like this:
def index
@team = Team.find_by_id(params[:team_id])
@users = @team.users.search(params[:search], :page => params[:page], :per_page => 10)
end
I have checked that the team actually has users, but @users always returns 0. Any ideas on how I should do to make it work as I want?
Update
I use Rails: 4.1.4 And thinking-sphink: 3.1.1
My Sphinx query looks like this:
Sphinx Query (0.7ms) SELECT * FROM `member_core` WHERE MATCH('Anders') AND `team_id` = 2 AND `sphinx_deleted` = 0 LIMIT 0, 10
Sphinx Found 0 results
With slightly updated controller code:
@members = @team.members.search(params[:search], :page => params[:page], :per_page => 10)
So, the original cause of this issue was that there was a search query being provided, but no fields to match against. Adding fields fixed that, which is great.
The second issue, noted in the comments above, is that when you search for an email address, a query error is raised. This is because the @ character signifies a field name in the query (to limit searches to a specific field - for example "@name Anders"
to search for Anders within a field called name).
You have two ways around this... either you escape the query by wrapping it in ThinkingSphinx::Query.escape(params[:query])
, or if you're searching for a specific email address, then I would suggest using ActiveRecord instead (given you're almost certainly going to have a unique constraint on email addresses in your database, hence there should only be zero or one matching records). The latter approach also means there's no need to have email as an indexed field, which is a bit more secure if you're letting anyone define your search queries via parameters. Letting someone search for 'gmail' and they get back all your users with gmail addresses is probably not a wise idea.