-
-
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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