sunspot_association 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sunspot_association (0.0.1)
4
+ sunspot_association (0.0.2)
5
5
  activerecord (~> 3.0)
6
- sunspot_solr
6
+ sunspot_rails
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
@@ -85,7 +85,6 @@ GEM
85
85
  sunspot_rails (1.3.3)
86
86
  nokogiri
87
87
  sunspot (= 1.3.3)
88
- sunspot_solr (2.0.0)
89
88
  sunspot_test (0.4.0)
90
89
  sunspot_rails (>= 1.2.1)
91
90
  terminal-table (1.4.5)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2013 YOURNAME
1
+ Copyright 2013 Arjen Oosterkamp
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,23 +1,39 @@
1
1
  # sunspot_association [![Gem Version](https://badge.fury.io/rb/sunspot_association.png)](http://badge.fury.io/rb/sunspot_association) [![Build Status](https://secure.travis-ci.org/Arjeno/sunspot_association.png?branch=master)](http://travis-ci.org/Arjeno/sunspot_association) [![Dependency Status](https://gemnasium.com/Arjeno/sunspot_association.png)](https://gemnasium.com/Arjeno/sunspot_association) [![Coverage Status](https://coveralls.io/repos/Arjeno/sunspot_association/badge.png?branch=master)](https://coveralls.io/r/Arjeno/sunspot_association)
2
2
 
3
- Automatically reindex ActiveRecord associations using Sunspot.
3
+ Automatic association (re)indexing for your searchable Sunspot models.
4
4
 
5
- ## Usage
6
-
7
- Add to your Gemfile:
5
+ ## Pure magic
8
6
 
9
7
  ```ruby
10
- gem 'sunspot_association'
8
+ class User < ActiveRecord::Base
9
+ belongs_to :company
10
+ searchable do
11
+ associate :text, :company, :name, :phone
12
+ end
13
+ end
11
14
  ```
12
15
 
13
- Add to your model:
16
+ ## What it does
17
+
18
+ The above example will convert to:
14
19
 
15
20
  ```ruby
16
- class Company < ActiveRecord::Base
17
- sunspot_associate :orders, :fields => :name
21
+ searchable do
22
+ text :company_name do; company.name end
23
+ text :company_phone do; company.phone end
18
24
  end
19
25
  ```
20
26
 
27
+ It will also hook into `Company` and watch it for changes
28
+
29
+ ## Usage
30
+
31
+ Add to your Gemfile:
32
+
33
+ ```ruby
34
+ gem 'sunspot_association'
35
+ ```
36
+
21
37
  ## Example
22
38
 
23
39
  ```ruby
@@ -25,50 +41,24 @@ class User < ActiveRecord::Base
25
41
  belongs_to :company
26
42
 
27
43
  searchable do
28
- text :company_name do; company.try(:name) end
29
- end
30
- end
44
+ associate :text, :company, :name, :phone
45
+ associate :string, :company, :address, :stored => true
31
46
 
32
- class Order < ActiveRecord::Base
33
- belongs_to :company
34
-
35
- searchable do
36
- text :company_name do; company.try(:name) end
47
+ # Converts to:
48
+ # => text :company_name do; company.name end
49
+ # => text :company_phone do; company.phone end
50
+ # => string :company_address, { :stored => true } do; company.address end
37
51
  end
38
52
  end
39
53
 
40
54
  class Company < ActiveRecord::Base
41
- has_many :orders
42
55
  has_many :users
43
56
 
44
- sunspot_associate :orders, :users
45
-
46
- # Or only track changes for the name field
47
- # => sunspot_associate :orders, :users, :fields => :name
57
+ # This configuration is automatically added by the searchable DSL
58
+ # => sunspot_associate :users, :fields => [:name, :phone, :address]
48
59
  end
49
60
  ```
50
61
 
51
62
  ## License
52
63
 
53
- Copyright (c) 2013 Arjen Oosterkamp
54
-
55
- MIT License
56
-
57
- Permission is hereby granted, free of charge, to any person obtaining
58
- a copy of this software and associated documentation files (the
59
- "Software"), to deal in the Software without restriction, including
60
- without limitation the rights to use, copy, modify, merge, publish,
61
- distribute, sublicense, and/or sell copies of the Software, and to
62
- permit persons to whom the Software is furnished to do so, subject to
63
- the following conditions:
64
-
65
- The above copyright notice and this permission notice shall be
66
- included in all copies or substantial portions of the Software.
67
-
68
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
71
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
72
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
73
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
74
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
+ sunspot_association is distributed under the MIT License, copyright © 2013 Arjen Oosterkamp
@@ -0,0 +1,107 @@
1
+ require 'active_record'
2
+
3
+ module SunspotAssociation
4
+ module Model
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## Attributes
11
+
12
+ cattr_accessor :sunspot_association_configuration
13
+
14
+ after_create Proc.new { |o| o.reindex_sunspot_associations!(:create) }
15
+ after_update Proc.new { |o| o.reindex_sunspot_associations!(:update) }
16
+ after_destroy Proc.new { |o| o.reindex_sunspot_associations!(:destroy) }
17
+
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ def sunspot_associate?
23
+ self.sunspot_association_configuration != {}
24
+ end
25
+
26
+ # Reindex associations when a model changes
27
+ #
28
+ # Options:
29
+ #
30
+ # :fields
31
+ # => Field(s) to watch for changes
32
+ #
33
+ # :on_create
34
+ # => Specifies if it should reindex associations when a record is created
35
+ #
36
+ # Examples:
37
+ #
38
+ # => sunspot_associate :orders, :fields => :name
39
+ # => sunspot_associate :orders, :users, :fields => [:name, :phone], :on_create => true
40
+ #
41
+ def sunspot_associate(*args)
42
+ options = args.extract_options!
43
+ fields = options.delete(:fields)
44
+
45
+ self.sunspot_association_configuration ||= {}
46
+
47
+ args.each do |object|
48
+ default = { :fields => [] }
49
+ config = self.sunspot_association_configuration[object] || default
50
+
51
+ # Fields
52
+ config[:fields] += Array(fields)
53
+ config[:fields].compact!
54
+ config[:fields].uniq!
55
+
56
+ config.merge!(options)
57
+
58
+ self.sunspot_association_configuration[object] = config
59
+ end
60
+ end
61
+
62
+ def reset_sunspot_associations!
63
+ self.sunspot_association_configuration = {}
64
+ end
65
+
66
+ end
67
+
68
+ # Main callback method, checks if it should reindex an association
69
+ def reindex_sunspot_associations!(event)
70
+ self.class.sunspot_association_configuration.each do |object, config|
71
+ case event
72
+ when :create
73
+ reindex_sunspot_association!(object) if config[:on_create]
74
+ when :update
75
+ reindex_sunspot_association!(object) if reindex_sunspot_association?(object)
76
+ when :destroy
77
+ reindex_sunspot_association!(object)
78
+ end
79
+ end
80
+ end
81
+
82
+ # Checks if an association should be reindexed
83
+ # => reindex_sunspot_association?(:orders) => true
84
+ def reindex_sunspot_association?(object)
85
+ if (config = (self.class.sunspot_association_configuration || {})[object]).present?
86
+ if config[:fields].present?
87
+ return ! (changed & (config[:fields] || []).map(&:to_s)).empty?
88
+ else
89
+ return changed.any?
90
+ end
91
+ end
92
+
93
+ false
94
+ end
95
+
96
+ # Reindexes an association using Sunspot.index
97
+ def reindex_sunspot_association!(object)
98
+ return false unless self.class.sunspot_associate?
99
+ return false unless self.respond_to?(object)
100
+
101
+ Sunspot.index self.send(object)
102
+ end
103
+
104
+ end
105
+ end
106
+
107
+ ActiveRecord::Base.send(:include, SunspotAssociation::Model)
@@ -0,0 +1,77 @@
1
+ require 'sunspot/rails'
2
+
3
+ module SunspotAssociation
4
+ module Searchable
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ # Index association fields
9
+ #
10
+ # Options:
11
+ #
12
+ # :inverse_name - see `setup_association_reindex`
13
+ #
14
+ # :index_on_change
15
+ # => Boolean or array
16
+ # => Defaults to `fields`
17
+ # => Set to false to disable automatic reindexing
18
+ # => Set to true to reindex for every update
19
+ # => Pass array of fields to specifically watch
20
+ #
21
+ # Examples:
22
+ #
23
+ # => associate :text, :company, :name
24
+ # => associate :text, :company, :name, :phone
25
+ # => associate :text, :company, :name, :phone, :inverse_name => :company_users
26
+ #
27
+ def associate(type, association_name, *fields)
28
+ options = fields.extract_options!
29
+
30
+ inverse_name = options.delete(:inverse_name)
31
+ index_on_change = options.delete(:index_on_change)
32
+
33
+ fields.each do |field|
34
+ name = [association_name, field].join('_')
35
+ self.send(type, name, options) do
36
+ self.send(association_name).send(field)
37
+ end
38
+ end
39
+
40
+ unless index_on_change == false
41
+ fields_to_watch = fields
42
+
43
+ if index_on_change.is_a?(Array)
44
+ fields_to_watch = index_on_change
45
+ elsif index_on_change == true
46
+ fields_to_watch = []
47
+ end
48
+
49
+ setup_association_reindex association_name, fields_to_watch, { :inverse_name => inverse_name }
50
+ end
51
+ end
52
+
53
+ # Set up automatic reindexing using `sunspot_associate`
54
+ #
55
+ # Options:
56
+ #
57
+ # :inverse_name
58
+ # => Name of inverse association to use, for example :company_users
59
+ #
60
+ # Examples:
61
+ #
62
+ # => setup_association_reindex :company, [:name]
63
+ # => setup_association_reindex :company, [:name], :inverse_name => :company_users
64
+ #
65
+ def setup_association_reindex(association_name, fields, options={})
66
+ searchable_class = @setup.clazz
67
+ association = searchable_class.reflect_on_association(association_name)
68
+ association_class = association.klass
69
+ inverse_name = options[:inverse_name] || searchable_class.name.pluralize.downcase.to_sym
70
+
71
+ association_class.sunspot_associate inverse_name, :fields => fields
72
+ end
73
+
74
+ end
75
+ end
76
+
77
+ Sunspot::DSL::Fields.send(:include, SunspotAssociation::Searchable)
@@ -1,3 +1,3 @@
1
1
  module SunspotAssociation
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,110 +1,6 @@
1
- require 'active_record'
2
1
  require 'sunspot_association/version'
2
+ require 'sunspot_association/model'
3
+ require 'sunspot_association/searchable'
3
4
 
4
5
  module SunspotAssociation
5
- module Model
6
-
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
-
11
- ## Attributes
12
-
13
- cattr_accessor :sunspot_association_configuration
14
-
15
- ## Callbacks
16
-
17
- after_create Proc.new { |o| o.reindex_sunspot_associations!(:create) }
18
- after_update Proc.new { |o| o.reindex_sunspot_associations!(:update) }
19
- after_destroy Proc.new { |o| o.reindex_sunspot_associations!(:destroy) }
20
-
21
- end
22
-
23
- module ClassMethods
24
-
25
- def sunspot_associate?
26
- self.sunspot_association_configuration != {}
27
- end
28
-
29
- # Reindex associations when a model changes
30
- #
31
- # Options:
32
- #
33
- # :fields
34
- # => Field(s) to watch for changes
35
- #
36
- # :on_create
37
- # => Specifies if it should reindex associations when a record is created
38
- #
39
- # Examples:
40
- #
41
- # => sunspot_associate :orders, :fields => :name
42
- # => sunspot_associate :orders, :users, :fields => [:name, :phone], :on_create => true
43
- #
44
- def sunspot_associate(*args)
45
- options = args.extract_options!
46
- fields = options.delete(:fields)
47
-
48
- self.sunspot_association_configuration ||= {}
49
-
50
- args.each do |object|
51
- default = { :fields => [] }
52
- config = self.sunspot_association_configuration[object] || default
53
-
54
- # Fields
55
- config[:fields] += Array(fields)
56
- config[:fields].compact!
57
- config[:fields].uniq!
58
-
59
- config.merge!(options)
60
-
61
- self.sunspot_association_configuration[object] = config
62
- end
63
- end
64
-
65
- def reset_sunspot_associations!
66
- self.sunspot_association_configuration = {}
67
- end
68
-
69
- end
70
-
71
- # Main callback method, checks if it should reindex an association
72
- def reindex_sunspot_associations!(event)
73
- self.class.sunspot_association_configuration.each do |object, config|
74
- case event
75
- when :create
76
- reindex_sunspot_association!(object) if config[:on_create]
77
- when :update
78
- reindex_sunspot_association!(object) if reindex_sunspot_association?(object)
79
- when :destroy
80
- reindex_sunspot_association!(object)
81
- end
82
- end
83
- end
84
-
85
- # Checks if an association should be reindexed
86
- # => reindex_sunspot_association?(:orders) => true
87
- def reindex_sunspot_association?(object)
88
- if (config = (self.class.sunspot_association_configuration || {})[object]).present?
89
- if config[:fields].present?
90
- return ! (changed & (config[:fields] || []).map(&:to_s)).empty?
91
- else
92
- return changed.any?
93
- end
94
- end
95
-
96
- false
97
- end
98
-
99
- # Reindexes an association using Sunspot.index
100
- def reindex_sunspot_association!(object)
101
- return false unless self.class.sunspot_associate?
102
- return false unless self.respond_to?(object)
103
-
104
- Sunspot.index self.send(object)
105
- end
106
-
107
- end
108
6
  end
109
-
110
- ActiveRecord::Base.send(:include, SunspotAssociation::Model)
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe SunspotAssociation::Model do
4
+
5
+ with_model :User do
6
+ table do |t|
7
+ t.belongs_to :company
8
+ t.string :name
9
+ t.timestamps
10
+ end
11
+
12
+ model do
13
+ belongs_to :company
14
+ end
15
+ end
16
+
17
+ with_model :Order do
18
+ table do |t|
19
+ t.belongs_to :company
20
+ t.string :number
21
+ t.timestamps
22
+ end
23
+
24
+ model do
25
+ belongs_to :company
26
+ end
27
+ end
28
+
29
+ with_model :Company do
30
+ table do |t|
31
+ t.string :name
32
+ t.string :number
33
+ t.timestamps
34
+ end
35
+
36
+ model do
37
+ has_many :orders
38
+ has_many :users
39
+ end
40
+ end
41
+
42
+ let(:company) { Company.create({ :name => 'Company name', :number => '1' }) }
43
+ let(:order) { Order.create({ :number => '1', :company => company }) }
44
+ let(:user) { User.create({ :name => 'John Doe', :company => company }) }
45
+
46
+ before(:each) do
47
+ Company.sunspot_associate :orders, :fields => :name
48
+ Company.sunspot_associate :users, :on_create => true
49
+ end
50
+
51
+ after(:each) do
52
+ Company.reset_sunspot_associations!
53
+ end
54
+
55
+ describe :sunspot_association_configuration do
56
+
57
+ it do
58
+ Company.sunspot_association_configuration.should == {
59
+ :orders => { :fields => [:name] },
60
+ :users => { :fields => [], :on_create => true }
61
+ }
62
+ end
63
+
64
+ context 'with multiple objects' do
65
+
66
+ before(:each) do
67
+ Company.sunspot_associate :orders, :users, :fields => :name, :on_create => true
68
+ end
69
+
70
+ it do
71
+ Company.sunspot_association_configuration.should == {
72
+ :orders => { :fields => [:name], :on_create => true },
73
+ :users => { :fields => [:name], :on_create => true },
74
+ }
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe :reindex_sunspot_association? do
82
+
83
+ subject { company }
84
+
85
+ context 'without changes' do
86
+
87
+ it { company.reindex_sunspot_association?(:orders).should be_false }
88
+ it { company.reindex_sunspot_association?(:users).should be_false }
89
+
90
+ end
91
+
92
+ context 'with changes' do
93
+
94
+ before(:each) { company.name = 'Name change' }
95
+
96
+ it { company.reindex_sunspot_association?(:orders).should be_true }
97
+ it { company.reindex_sunspot_association?(:users).should be_true }
98
+
99
+ end
100
+
101
+ context 'with any change' do
102
+
103
+ before(:each) { company.number = '5' }
104
+
105
+ it { company.reindex_sunspot_association?(:orders).should be_false }
106
+ it { company.reindex_sunspot_association?(:users).should be_true }
107
+
108
+ end
109
+
110
+ end
111
+
112
+ describe :callbacks do
113
+
114
+ context :after_create do
115
+
116
+ let(:company) { Company.new }
117
+ after(:each) { company.save }
118
+
119
+ it do
120
+ company.should_not_receive(:reindex_sunspot_association!).with(:orders)
121
+ company.should_receive(:reindex_sunspot_association!).with(:users)
122
+ end
123
+
124
+ end
125
+
126
+ context :after_update do
127
+
128
+ context 'with tracked change' do
129
+
130
+ after(:each) { company.update_attributes({ :name => 'name change' }) }
131
+
132
+ it do
133
+ company.should_receive(:reindex_sunspot_association!).with(:orders)
134
+ company.should_receive(:reindex_sunspot_association!).with(:users)
135
+ end
136
+
137
+ end
138
+
139
+ context 'with untracked change' do
140
+
141
+ after(:each) { company.update_attributes({ :number => '5' }) }
142
+
143
+ it do
144
+ company.should_not_receive(:reindex_sunspot_association!).with(:orders)
145
+ company.should_receive(:reindex_sunspot_association!).with(:users)
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
152
+ context :after_destroy do
153
+
154
+ after(:each) { company.destroy }
155
+
156
+ it do
157
+ company.should_receive(:reindex_sunspot_association!).with(:orders)
158
+ company.should_receive(:reindex_sunspot_association!).with(:users)
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+ end
@@ -0,0 +1,263 @@
1
+ require 'spec_helper'
2
+
3
+ describe SunspotAssociation::Searchable do
4
+
5
+ ## Shared examples
6
+
7
+ shared_examples_for 'a searchable field' do |searchable_field, type, stored|
8
+ stored ||= false
9
+
10
+ let(:field) { fetch_fields(searchable_field, model) }
11
+ let(:data) { field.build }
12
+
13
+ subject { field }
14
+
15
+ it { should be_present }
16
+ it { data.instance_variable_get(:@stored).should == stored }
17
+ it { data.type.class.should == type } if type
18
+ end
19
+
20
+ ## Methods
21
+
22
+ def fetch_fields(name, model)
23
+ fields = Sunspot::Setup.for(model).field_factories
24
+ fields += Sunspot::Setup.for(model).text_field_factories
25
+ fields += Sunspot::Setup.for(model).dynamic_field_factories
26
+
27
+ fields.flatten!
28
+
29
+ found_fields = fields.collect do |f|
30
+ f if f.name == name
31
+ end.compact
32
+
33
+ found_fields.count > 1 ? found_fields : found_fields.first
34
+ end
35
+
36
+ ## Models
37
+
38
+ with_model :User do
39
+ table do |t|
40
+ t.belongs_to :company
41
+ t.string :name
42
+ t.timestamps
43
+ end
44
+
45
+ model do
46
+ include Sunspot::Rails::Searchable
47
+ belongs_to :company
48
+ end
49
+ end
50
+
51
+ with_model :Company do
52
+ table do |t|
53
+ t.string :name
54
+ t.string :phone
55
+ t.timestamps
56
+ end
57
+
58
+ model do
59
+ has_many :users
60
+ end
61
+ end
62
+
63
+ describe :associate do
64
+
65
+ describe :setup_association_reindex do
66
+
67
+ after(:each) do
68
+ Company.reset_sunspot_associations!
69
+ end
70
+
71
+ subject { Company.sunspot_association_configuration }
72
+
73
+ describe 'default' do
74
+
75
+ before(:each) do
76
+ User.searchable do
77
+ associate :text, :company, :name
78
+ end
79
+ end
80
+
81
+ it { should == { :users => { :fields => [:name] } } }
82
+
83
+ end
84
+
85
+ describe :inverse_name do
86
+
87
+ before(:each) do
88
+ User.searchable do
89
+ associate :text, :company, :name, :inverse_name => :company_users
90
+ end
91
+ end
92
+
93
+ it { should == { :company_users => { :fields => [:name] } } }
94
+
95
+ end
96
+
97
+ describe :index_on_change do
98
+
99
+ context 'with true' do
100
+
101
+ before(:each) do
102
+ User.searchable do
103
+ associate :text, :company, :name, :index_on_change => true
104
+ end
105
+ end
106
+
107
+ it { should == { :users => { :fields => [] } } }
108
+
109
+ end
110
+
111
+ context 'with false' do
112
+
113
+ before(:each) do
114
+ User.searchable do
115
+ associate :text, :company, :name, :index_on_change => false
116
+ end
117
+ end
118
+
119
+ it { should == {} }
120
+
121
+ end
122
+
123
+ context 'with array' do
124
+
125
+ before(:each) do
126
+ User.searchable do
127
+ associate :text, :company, :pretty_address, :index_on_change => [:address]
128
+ end
129
+ end
130
+
131
+ it { should == { :users => { :fields => [:address] } } }
132
+
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
139
+ describe :sunspot_settings do
140
+
141
+ let(:model) { User }
142
+
143
+ describe :text do
144
+
145
+ before(:each) do
146
+ User.searchable do
147
+ associate :text, :company, :name
148
+ end
149
+ end
150
+
151
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::TextType
152
+
153
+ it do
154
+ Company.sunspot_association_configuration.should == {
155
+ :users => { :fields => [:name] }
156
+ }
157
+ end
158
+
159
+ context 'with multiple' do
160
+
161
+ describe 'in one call' do
162
+
163
+ before(:each) do
164
+ User.searchable do
165
+ associate :text, :company, :name, :phone
166
+ end
167
+ end
168
+
169
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::TextType
170
+ it_should_behave_like 'a searchable field', :company_phone, Sunspot::Type::TextType
171
+
172
+ it do
173
+ Company.sunspot_association_configuration.should == {
174
+ :users => { :fields => [:name, :phone] }
175
+ }
176
+ end
177
+
178
+ end
179
+
180
+ describe 'in multiple calls' do
181
+
182
+ before(:each) do
183
+ User.searchable do
184
+ associate :text, :company, :name
185
+ associate :text, :company, :phone
186
+ end
187
+ end
188
+
189
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::TextType
190
+ it_should_behave_like 'a searchable field', :company_phone, Sunspot::Type::TextType
191
+
192
+ it do
193
+ Company.sunspot_association_configuration.should == {
194
+ :users => { :fields => [:name, :phone] }
195
+ }
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+
204
+ describe :string do
205
+
206
+ before(:each) do
207
+ User.searchable do
208
+ associate :string, :company, :name
209
+ end
210
+ end
211
+
212
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::StringType
213
+
214
+ context 'with stored' do
215
+
216
+ before(:each) do
217
+ User.searchable do
218
+ associate :string, :company, :name, :stored => true
219
+ end
220
+ end
221
+
222
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::StringType, true
223
+
224
+ end
225
+
226
+ context 'with multiple' do
227
+
228
+ describe 'in one call' do
229
+
230
+ before(:each) do
231
+ User.searchable do
232
+ associate :string, :company, :name, :phone
233
+ end
234
+ end
235
+
236
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::StringType
237
+ it_should_behave_like 'a searchable field', :company_phone, Sunspot::Type::StringType
238
+
239
+ end
240
+
241
+ describe 'in multiple calls' do
242
+
243
+ before(:each) do
244
+ User.searchable do
245
+ associate :string, :company, :name
246
+ associate :string, :company, :phone
247
+ end
248
+ end
249
+
250
+ it_should_behave_like 'a searchable field', :company_name, Sunspot::Type::StringType
251
+ it_should_behave_like 'a searchable field', :company_phone, Sunspot::Type::StringType
252
+
253
+ end
254
+
255
+ end
256
+
257
+ end
258
+
259
+ end
260
+
261
+ end
262
+
263
+ end
@@ -1,165 +1,4 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SunspotAssociation do
4
-
5
- with_model :User do
6
- table do |t|
7
- t.belongs_to :company
8
- t.string :name
9
- t.timestamps
10
- end
11
-
12
- model do
13
- belongs_to :company
14
- end
15
- end
16
-
17
- with_model :Order do
18
- table do |t|
19
- t.belongs_to :company
20
- t.string :number
21
- t.timestamps
22
- end
23
-
24
- model do
25
- belongs_to :company
26
- end
27
- end
28
-
29
- with_model :Company do
30
- table do |t|
31
- t.string :name
32
- t.string :number
33
- t.timestamps
34
- end
35
-
36
- model do
37
- has_many :orders
38
- has_many :users
39
- end
40
- end
41
-
42
- let(:company) { Company.create({ :name => 'Company name', :number => '1' }) }
43
- let(:order) { Order.create({ :number => '1', :company => company }) }
44
- let(:user) { User.create({ :name => 'John Doe', :company => company }) }
45
-
46
- before(:each) do
47
- Company.sunspot_associate :orders, :fields => :name
48
- Company.sunspot_associate :users, :on_create => true
49
- end
50
-
51
- after(:each) do
52
- Company.reset_sunspot_associations!
53
- end
54
-
55
- describe :sunspot_association_configuration do
56
-
57
- it do
58
- Company.sunspot_association_configuration.should == {
59
- :orders => { :fields => [:name] },
60
- :users => { :fields => [], :on_create => true }
61
- }
62
- end
63
-
64
- context 'with multiple objects' do
65
-
66
- before(:each) do
67
- Company.sunspot_associate :orders, :users, :fields => :name, :on_create => true
68
- end
69
-
70
- it do
71
- Company.sunspot_association_configuration.should == {
72
- :orders => { :fields => [:name], :on_create => true },
73
- :users => { :fields => [:name], :on_create => true },
74
- }
75
- end
76
-
77
- end
78
-
79
- end
80
-
81
- describe :reindex_sunspot_association? do
82
-
83
- subject { company }
84
-
85
- context 'without changes' do
86
-
87
- it { company.reindex_sunspot_association?(:orders).should be_false }
88
- it { company.reindex_sunspot_association?(:users).should be_false }
89
-
90
- end
91
-
92
- context 'with changes' do
93
-
94
- before(:each) { company.name = 'Name change' }
95
-
96
- it { company.reindex_sunspot_association?(:orders).should be_true }
97
- it { company.reindex_sunspot_association?(:users).should be_true }
98
-
99
- end
100
-
101
- context 'with any change' do
102
-
103
- before(:each) { company.number = '5' }
104
-
105
- it { company.reindex_sunspot_association?(:orders).should be_false }
106
- it { company.reindex_sunspot_association?(:users).should be_true }
107
-
108
- end
109
-
110
- end
111
-
112
- describe :callbacks do
113
-
114
- context :after_create do
115
-
116
- let(:company) { Company.new }
117
- after(:each) { company.save }
118
-
119
- it do
120
- company.should_not_receive(:reindex_sunspot_association!).with(:orders)
121
- company.should_receive(:reindex_sunspot_association!).with(:users)
122
- end
123
-
124
- end
125
-
126
- context :after_update do
127
-
128
- context 'with tracked change' do
129
-
130
- after(:each) { company.update_attributes({ :name => 'name change' }) }
131
-
132
- it do
133
- company.should_receive(:reindex_sunspot_association!).with(:orders)
134
- company.should_receive(:reindex_sunspot_association!).with(:users)
135
- end
136
-
137
- end
138
-
139
- context 'with untracked change' do
140
-
141
- after(:each) { company.update_attributes({ :number => '5' }) }
142
-
143
- it do
144
- company.should_not_receive(:reindex_sunspot_association!).with(:orders)
145
- company.should_receive(:reindex_sunspot_association!).with(:users)
146
- end
147
-
148
- end
149
-
150
- end
151
-
152
- context :after_destroy do
153
-
154
- after(:each) { company.destroy }
155
-
156
- it do
157
- company.should_receive(:reindex_sunspot_association!).with(:orders)
158
- company.should_receive(:reindex_sunspot_association!).with(:users)
159
- end
160
-
161
- end
162
-
163
- end
164
-
165
4
  end
@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
10
10
  s.authors = ["Arjen Oosterkamp"]
11
11
  s.email = ["mail@arjen.me"]
12
12
  s.homepage = ""
13
- s.summary = %q{Automatically reindex ActiveRecord associations using Sunspot}
14
- s.description = %q{Automatically reindex ActiveRecord associations using Sunspot}
13
+ s.summary = %q{Automatic association (re)indexing for your searchable Sunspot models.}
14
+ s.description = %q{Automatic association (re)indexing for your searchable Sunspot models.}
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -26,5 +26,5 @@ Gem::Specification.new do |s|
26
26
  s.add_development_dependency "coveralls"
27
27
 
28
28
  s.add_dependency "activerecord", "~> 3.0"
29
- s.add_dependency "sunspot_solr"
29
+ s.add_dependency "sunspot_rails"
30
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunspot_association
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '3.0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: sunspot_solr
111
+ name: sunspot_rails
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -123,7 +123,7 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- description: Automatically reindex ActiveRecord associations using Sunspot
126
+ description: Automatic association (re)indexing for your searchable Sunspot models.
127
127
  email:
128
128
  - mail@arjen.me
129
129
  executables: []
@@ -139,8 +139,12 @@ files:
139
139
  - README.md
140
140
  - Rakefile
141
141
  - lib/sunspot_association.rb
142
+ - lib/sunspot_association/model.rb
143
+ - lib/sunspot_association/searchable.rb
142
144
  - lib/sunspot_association/version.rb
143
145
  - spec/spec_helper.rb
146
+ - spec/sunspot_association/model_spec.rb
147
+ - spec/sunspot_association/searchable_spec.rb
144
148
  - spec/sunspot_association_spec.rb
145
149
  - sunspot_association.gemspec
146
150
  homepage: ''
@@ -166,8 +170,10 @@ rubyforge_project:
166
170
  rubygems_version: 1.8.24
167
171
  signing_key:
168
172
  specification_version: 3
169
- summary: Automatically reindex ActiveRecord associations using Sunspot
173
+ summary: Automatic association (re)indexing for your searchable Sunspot models.
170
174
  test_files:
171
175
  - spec/spec_helper.rb
176
+ - spec/sunspot_association/model_spec.rb
177
+ - spec/sunspot_association/searchable_spec.rb
172
178
  - spec/sunspot_association_spec.rb
173
179
  has_rdoc: