Rails associations and Thinking Sphinx index to refactor search method in controller.

183 views
Skip to first unread message

Mike C.

unread,
Nov 5, 2012, 9:20:56 AM11/5/12
to thinkin...@googlegroups.com
I posted this over on StackOverflow a little while ago and thought I might try here as well:


I'm working with a old database and drawing blank on how to set up the association and index it with Thinking Sphinx. I want to index the People and Group's skill.

I have Users. Users can create People and Groups. People and Groups have a single skill through Sharing_Skill.

people and groups tables: ID field, Name field

sharings_skills table: ID field, Skill_ID field, Marker_ID(which is the person/group_id), Marker_Type ("Group" or "Person")

skills table: ID field, Name field

How do I setup the rails association and index the skills of the person or group in the Person model or Group model.

my main goal is to refactor my search by indexing the person skills in the person model and searching the name, tags and skills together, instead of searching skills, sharing_skills and people separate like this:

This is in my Person model.

class Person < ActiveRecord::Base
  acts_as_taggable
  acts_as_taggable_on :tags

  attr_accessible :name, :tag_list

  validates_presence_of :name

  belongs_to :marker_image, :class_name => "Photo", :foreign_key => "marker_image_id"
  belongs_to :user

  extend FriendlyId
  friendly_id :name, use: [:slugged, :history]

  define_index do
    indexes name
    indexes tag_taggings.tag(:name), :as => :tags
    has :id
    has created_at
  end

This is in my Search Controller

#PERSON SEARCH
if params[:marker_type].nil? or params[:marker_type].empty? or params[:marker_type] == "Person"
  #SEARCH NAME, TAGS, (Need to fix skills)
  conditions = {}
  %w(name tags).each do |i|
    i = i.to_sym
    next unless params[i]
    conditions[i] = params[i]
  end

  person = Person.search_for_ids(params[:search], :conditions => conditions, :per_page => 999999)
  if !person.empty?
    person_ids << person
  end

  #SEARCH SKILLS IN PERSON MODEL
  skills = Skill.search_for_ids(params[:search], :per_page => 99999)
  check_skills_available_persons = SharingsSkill.search(:conditions => {:marker_type => 'Person'}, :with => {:skill_id => skills}, :per_page => 99999)
  if !check_skills_available_persons.empty?
    check_people_by_skills = Person.search(:with => {:id => check_skills_available_persons.collect{|x|x.marker_id}})
    if !check_people_by_skills.empty?
      check_people_by_skills.each do |p_skill|
        person_ids << p_skill.id
      end
    end
  end
end

Mike C.

unread,
Nov 5, 2012, 6:19:27 PM11/5/12
to thinkin...@googlegroups.com
I almost have the associations fixed, although kinda stuck on how to add it for groups? I might need to make it a polymorphic association? Also another problem is in console if I find a record, person = Person.find(1), I can now do person.skills and it lists the skill of that person. But if I do person.skills.name it gives me "Skill" and not the actual skill name for the person.

person.rb
  has_many :sharing_skills, :foreign_key => "marker_id", :conditions => ['marker_type = ?', 'Person']
  has_many :skills, :through => :sharing_skills

group.rb
  has_many :sharing_skills, :foreign_key => "marker_id", :conditions => ['marker_type = ?', 'Group']
  has_many :skills, :through => :sharing_skills

sharing_skill.rb
  belongs_to :marker, :class_name => "Person"
  group?
  belongs_to :skill

skill.rb
  has_many :sharing_skills
  has_many :people, :through => :sharing_skills, :source => :marker
  has_many :groups, :through => :sharing_skills, :source => :marker

Mike C.

unread,
Nov 5, 2012, 7:24:37 PM11/5/12
to thinkin...@googlegroups.com
Studied Rails associations today and think I got a better grasp of it now =) Fixed up the search function. Now I can add the filters to search by View Counts etc...

person.rb
  has_one :sharing_skill, :as => :marker, :conditions => ['marker_type = ?', 'Person']
  has_one :skill, :through => :sharing_skill

group.rb
  has_one :sharing_skill, :as => :marker, :conditions => ['marker_type = ?', 'Group']
  has_one :skill, :through => :sharing_skill

sharing_skill.rb
  belongs_to :marker, :polymorphic => true
  belongs_to :skill

skill.rb
  has_one :sharing_skill
  has_one :person, :through => :sharing_skill, :source => :marker
  has_one :group, :through => :sharing_skill, :source => :marker

and now my search method in controller is thus:

      conditions = {}
      %w(name tags skill).each do |i|
        i = i.to_sym
        next unless params[i]
        conditions[i] = params[i]
      end

      person = Person.search_for_ids(params[:search], :conditions => conditions, :per_page => 999999)
Reply all
Reply to author
Forward
0 new messages