Skip to content

Instantly share code, notes, and snippets.

@agibralter
Created September 25, 2010 15:16
Show Gist options
  • Select an option

  • Save agibralter/596934 to your computer and use it in GitHub Desktop.

Select an option

Save agibralter/596934 to your computer and use it in GitHub Desktop.
1.rb represents a situation I have now... 2.rb proposes an addition to the ThinkingSphinx DSL for handling association attribute updates.
# This example allows users to search through their memberships (to groups).
# The Membership index has a number of attributes that depend on both the
# membership itself and the group to which it belongs.
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# Attributes:
# * user_id
# * group_id
# * delta
# * state ("pending", "active", "suspended")
define_index do
has user_id, group_id
indexes group(:name)
indexes group(:description)
has "memberships.state = 'pending'", :as => :is_pending, :type => :boolean
has "memberships.state = 'active'", :as => :is_active, :type => :boolean
has "memberships.state = 'suspended'", :as => :is_suspended, :type => :boolean
has "groups.state = 'pending'", :as => :is_group_pending, :type => :boolean
has "groups.state = 'active'", :as => :is_group_active, :type => :boolean
has "groups.state = 'archived'", :as => :is_group_archived, :type => :boolean
# This would probably be a ts-delayed-delta (or ts-resque-delta), but for
# the sake of this example let's make it synchronous.
set_property :delta => true
end
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
# Attributes:
# * name
# * description
# * state ("pending", "active", "archived")
end
# Now, if a group's state is updated, it is necessary to update all the Sphinx
# attributes of its associated memberships. If a group's name or description
# are updated, it is necessary to update all associated memberships to have
# delta = 1 and then run the delta indexer for the memberships index.
class Membership < ActiveRecord::Base
# ...
define_index do
# ...
has "(groups.state = 'active' AND groups.memberships_count > 1000)", :as => :is_big_group, :type => :boolean do
# A class to watch (in the case of associations), default is watching
# self.
watch :group
# A list of attributes which should be watched for "changed?" If none is
# listed, updating a group will always update all the group's
# memberships' attributes in searchd with the latest value of the
# "value" block in an after_commit hook.
attributes :state, :memberships_count
# A ruby block equivalent to the SQL snippet to be evalutated in the
# scope of the watched instance.
value do
self.state == "active" && self.memberships_count > 1000
end
end
# ...
end
end
# I wonder if there's a way to use arel to avoid the duplication of specifying
# the SQL snippet and the value block in ActiveRecord 3.0.x...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment