sunspot_association 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: