ar_pg_array 0.8.4 → 0.9.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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.4
1
+ 0.9.0
@@ -17,13 +17,23 @@ module ActiveRecord
17
17
  alias_method_chain :attribute_condition, :postgresql_arrays
18
18
  end
19
19
 
20
- def quote_bound_value_with_postgresql_arrays(value)
21
- if ::PGArrays::PgArray === value
22
- connection.quote_array_by_base_type(value, value.base_type)
23
- else
24
- quote_bound_value_without_postgresql_arrays(value)
20
+ if instance_method(:quote_bound_value).arity == 1
21
+ def quote_bound_value_with_postgresql_arrays(value)
22
+ if ::PGArrays::PgArray === value
23
+ connection.quote_array_by_base_type(value, value.base_type)
24
+ else
25
+ quote_bound_value_without_postgresql_arrays(value)
26
+ end
27
+ end
28
+ else
29
+ def quote_bound_value_with_postgresql_arrays(value, c = connection)
30
+ if ::PGArrays::PgArray === value
31
+ c.quote_array_by_base_type(value, value.base_type)
32
+ else
33
+ quote_bound_value_without_postgresql_arrays(value, c)
34
+ end
25
35
  end
26
- end
36
+ end
27
37
  alias_method_chain :quote_bound_value, :postgresql_arrays
28
38
  end
29
39
  end
@@ -55,13 +65,13 @@ module PGArrays
55
65
  end
56
66
 
57
67
  class PgAll
58
- def include?
68
+ def include?(v)
59
69
  Array === v && (self - v).empty?
60
70
  end
61
71
  end
62
72
 
63
73
  class PgIncludes < PgArray
64
- def include?
74
+ def include?(v)
65
75
  Array === v && (v - self).empty?
66
76
  end
67
77
  end
@@ -32,7 +32,7 @@ module Arel
32
32
  end
33
33
 
34
34
  class Attribute
35
- module Predications
35
+ methods = lambda do
36
36
  def ar_any(other)
37
37
  Predicates::ArrayAny.new(self, other)
38
38
  end
@@ -58,13 +58,19 @@ module Arel
58
58
  end
59
59
  end
60
60
  end
61
+ if defined? PREDICATES
62
+ PREDICATES.concat [:ar_any, :ar_all, :ar_included]
63
+ class_exec &methods
64
+ else
65
+ Predications.class_exec &methods
66
+ end
61
67
  end
62
68
  end
63
69
 
64
70
  module PGArrays
65
71
  class PgArray
66
72
  def to_sql( formatter = nil )
67
- formatter.engine.quote_array_for_arel_by_base_type(self, base_type)
73
+ formatter.engine.connection.quote_array_for_arel_by_base_type(self, base_type)
68
74
  end
69
75
 
70
76
  def to_a
@@ -1,69 +1,153 @@
1
1
  module PGArrays
2
2
  module ReferencesBy
3
- class RelationHolder < Struct.new(:relation, :field, :klass)
4
-
5
- def referenced(obj)
6
- ids = obj.read_attribute(field) || []
7
- klass.find( ids.sort ).sort_by{|o| ids.index(o.id)}
8
- end
9
-
10
- def set_referenced(obj, value)
11
- value = value.map{|v|
12
- case v
13
- when ActiveRecord::Base then v.id
14
- when nil then nil
15
- else v.to_i
16
- end
17
- }.compact
18
- obj.write_attribute( field, value )
19
- end
20
-
21
- def validate(obj)
22
- has_ids = klass.find(:all, :select=>'id', :conditions=>{:id=>obj.read_attribute(field)}).map(&:id)
23
- unless has_ids.sort == obj.read_attribute(field).sort
24
- obj.errors.add(relation, :wrong_array_reference)
25
- end
26
- end
27
-
28
- def for_referenced(obj_klass)
29
- condition = lambda do |obj|
30
- { :conditions=>{field.to_sym => case obj when klass then obj.id else obj.to_i end} }
31
- end
32
- obj_klass.send(:named_scope, "#{relation}_include", condition )
33
- end
34
-
35
- end
36
-
37
- module ClassMethods
38
- def references_by_array( relation, options = {} )
39
- unless ActiveSupport::Memoizable === self
40
- extend ActiveSupport::Memoizable
41
- end
3
+ if defined? ::Arel
4
+ HAS_AREL=true
5
+ NAMED_SCOPE='scope'
6
+ else
7
+ NAMED_SCOPE='named_scope'
8
+ if defined? ::FakeArel
9
+ HAS_AREL= true
10
+ else
11
+ HAS_AREL=false
12
+ end
13
+ end
42
14
 
43
- relation = relation.to_s.pluralize
44
- field = "#{relation.singularize}_ids"
45
- klass_name = (options[:class_name] || relation).to_s.singularize.camelize
46
- klass = klass_name.constantize
47
- holder = RelationHolder.new(relation, field, klass )
48
-
49
- define_method(relation) do
50
- holder.referenced(self)
51
- end
52
- memoize relation
53
-
54
- define_method("#{relation}=") do |value|
55
- flush_cache(relation)
56
- holder.set_referenced(self, value)
57
- end
58
-
59
- if options[:validate]
60
- validate {|o| holder.validate(o)}
61
- end
62
-
63
- holder.for_referenced(self)
64
- end
65
-
66
- end
15
+ class RelationHolder < Struct.new(:relation, :field, :klass)
16
+
17
+ def referenced(obj)
18
+ ids = obj[field] || []
19
+ objs = klass.find_all_by_id( ids.sort )
20
+ if ids.size < 20
21
+ objs.sort_by{|o| ids.index(o.id)}
22
+ else
23
+ to_ind = ids.each_with_index.inject({}){|h, (v,i)| h[v]=i; h}
24
+ objs.sort_by{|o| to_ind[o.id]}
25
+ end
26
+ end
27
+
28
+ def set_referenced(obj, value)
29
+ obj[field] = map_to_ids(value)
30
+ end
31
+
32
+ if HAS_AREL
33
+ def validate(obj)
34
+ has_ids = klass.where(:id=>obj.read_attribute(field)).
35
+ select('id').all.map(&:id)
36
+ unless has_ids.sort == obj.read_attribute(field).sort
37
+ obj.errors.add(relation, :wrong_array_reference)
38
+ end
39
+ end
40
+
41
+ def for_referenced(obj_klass)
42
+ myself = self
43
+ obj_klass.class_exec do
44
+ puts "named_scope #{NAMED_SCOPE} #{myself.relation}_include"
45
+ self.send NAMED_SCOPE, "#{myself.relation}_include", lambda{|*objs|
46
+ objs = myself.map_to_ids objs.flatten
47
+ where(myself.field.to_sym => objs.search_all)
48
+ }
49
+
50
+ self.send NAMED_SCOPE, "#{myself.relation}_have_all", lambda{|*objs|
51
+ objs = myself.map_to_ids objs.flatten
52
+ where(myself.field.to_sym => objs.search_all)
53
+ }
54
+
55
+ self.send NAMED_SCOPE, "#{myself.relation}_have_any", lambda{|*objs|
56
+ objs = myself.map_to_ids objs.flatten
57
+ where(myself.field.to_sym => objs.search_any)
58
+ }
59
+
60
+ self.send NAMED_SCOPE, "#{myself.relation}_included_into", lambda{|*objs|
61
+ objs = myself.map_to_ids objs.flatten
62
+ where(myself.field.to_sym => objs.search_subarray)
63
+ }
64
+ end
65
+ end
66
+ else
67
+ def validate(obj)
68
+ has_ids = klass.find(:all,
69
+ :select=>'id',
70
+ :conditions=>{:id=>obj.read_attribute(field)}
71
+ ).map(&:id)
72
+ unless has_ids.sort == obj.read_attribute(field).sort
73
+ obj.errors.add(relation, :wrong_array_reference)
74
+ end
75
+ end
76
+
77
+ def for_referenced(obj_klass)
78
+ myself = self
79
+ obj_klass.class_exec do
80
+ named_scope "#{myself.relation}_include", lambda{|*objs|
81
+ objs = myself.map_to_ids objs.flatten
82
+ { :conditions=>{ myself.field.to_sym => objs.search_all } }
83
+ }
84
+
85
+ named_scope "#{myself.relation}_have_all", lambda{|*objs|
86
+ objs = myself.map_to_ids objs.flatten
87
+ { :conditions=>{ myself.field.to_sym => objs.search_all } }
88
+ }
89
+
90
+ named_scope "#{myself.relation}_have_any", lambda{|*objs|
91
+ objs = myself.map_to_ids objs.flatten
92
+ { :conditions=>{ myself.field.to_sym => objs.search_any } }
93
+ }
94
+
95
+ named_scope "#{myself.relation}_included_into", lambda{|*objs|
96
+ objs = myself.map_to_ids objs.flatten
97
+ { :conditions=>{ myself.field.to_sym => objs.search_subarray } }
98
+ }
99
+ end
100
+ end
101
+ end
102
+
103
+ def val_to_id(val)
104
+ case val
105
+ when ActiveRecord::Base then val.id
106
+ when nil then nil
107
+ else val.to_i
108
+ end
109
+ end
110
+
111
+ def map_to_ids(vals)
112
+ (r = vals.map{|v| val_to_id(v)}).compact!
113
+ r
114
+ end
115
+ end
116
+
117
+ module ClassMethods
118
+ def references_by_array( relation, options = {} )
119
+ unless ActiveSupport::Memoizable === self
120
+ extend ActiveSupport::Memoizable
121
+ end
122
+
123
+ relation = relation.to_s.pluralize
124
+ field = "#{relation.singularize}_ids"
125
+ klass_name = (options[:class_name] || relation).to_s.singularize.camelize
126
+ klass = klass_name.constantize
127
+ holder = RelationHolder.new(relation, field, klass )
128
+
129
+ meths = Module.new do
130
+ define_method(relation) do
131
+ holder.referenced(self)
132
+ end
133
+
134
+ define_method("#{relation}=") do |value|
135
+ flush_cache(relation)
136
+ holder.set_referenced(self, value)
137
+ end
138
+ end
139
+ include meths
140
+
141
+ memoize relation
142
+
143
+ if options[:validate]
144
+ validate {|o| holder.validate(o)}
145
+ end
146
+
147
+ holder.for_referenced(self)
148
+ end
149
+
150
+ end
67
151
  end
68
152
  end
69
153
 
@@ -216,7 +216,7 @@ module ActiveRecord
216
216
  options = args.extract_options! # options = args.extract_options!
217
217
  column_names = args # column_names = args
218
218
  #
219
- column_names.each { |name| column(name, '#{key}_array', options) }# column_names.each { |name| column(name, 'string_array', options) }
219
+ column_names.each { |name| column(name, :'#{key}_array', options) }# column_names.each { |name| column(name, 'string_array', options) }
220
220
  end # end
221
221
  EOV
222
222
  Table.class_eval <<-EOV
@@ -225,7 +225,7 @@ module ActiveRecord
225
225
  column_names = args # column_names = args
226
226
  #
227
227
  column_names.each { |name| # column_names.each { |name|
228
- @base.add_column(@table_name, name, '#{key}_array', options) # @base.add_column(@table_name, name, 'string_array', options) }
228
+ @base.add_column(@table_name, name, :'#{key}_array', options) # @base.add_column(@table_name, name, 'string_array', options) }
229
229
  } # }
230
230
  end # end
231
231
  EOV
@@ -234,7 +234,7 @@ module ActiveRecord
234
234
 
235
235
  def type_to_sql_with_postgresql_arrays(type, limit = nil, precision = nil, scale = nil)
236
236
  if type.to_s =~ /^(.+)_array$/
237
- type_to_sql_without_postgresql_arrays($1, limit, precision, scale)+'[]'
237
+ type_to_sql_without_postgresql_arrays($1.to_sym, limit, precision, scale)+'[]'
238
238
  else
239
239
  type_to_sql_without_postgresql_arrays(type, limit, precision, scale)
240
240
  end
@@ -0,0 +1,2 @@
1
+ class Bulk < ActiveRecord::Base
2
+ end
@@ -0,0 +1,28 @@
1
+ first:
2
+ id: 1
3
+ ints: [ 1 ]
4
+ strings: [ one ]
5
+ times: [<%= Time.now.at_beginning_of_month.to_s(:db)%>, <%= Time.now.at_beginning_of_day.to_s(:db) %>]
6
+ floats: [1.0, 2.3]
7
+ decimals: [1.0, 2.3]
8
+ second:
9
+ id: 2
10
+ ints: [ 2 ]
11
+ strings: [ two ]
12
+ times: [2010-01-01, 2010-02-01]
13
+ floats: [2.0, 2.3]
14
+ decimals: [2.0, 2.3]
15
+ third:
16
+ id: 3
17
+ ints: [ 2, 3 ]
18
+ strings: [ two, three ]
19
+ times: [2010-03-01, 2010-04-01]
20
+ floats: [2.0, 2.5]
21
+ decimals: [2.0, 2.5]
22
+ four:
23
+ id: 4
24
+ ints: [ ]
25
+ strings: [ ]
26
+ times: [ ]
27
+ floats: [ ]
28
+ decimals: [ ]
@@ -0,0 +1,3 @@
1
+ class Item < ActiveRecord::Base
2
+ references_by_array :tags, :validate=>true
3
+ end
@@ -0,0 +1,22 @@
1
+ i1:
2
+ id: 1
3
+ tag_ids: [ 1 ]
4
+ i2:
5
+ id: 2
6
+ tag_ids: [ 3 ]
7
+ i3:
8
+ id: 3
9
+ tag_ids: [ 1, 3 ]
10
+ i4:
11
+ id: 4
12
+ tag_ids: [ 3, 1 ]
13
+ i5:
14
+ id: 5
15
+ tag_ids: [ 1, 2 ]
16
+ i6:
17
+ id: 6
18
+ tag_ids: [ 1, 2, 3 ]
19
+ i7:
20
+ id: 7
21
+ tag_ids: [ ]
22
+
@@ -0,0 +1,21 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table "tags", :force => true do |t|
3
+ t.string :name
4
+ t.timestamps
5
+ end
6
+
7
+ create_table "items", :force => true do |t|
8
+ t.string :value
9
+ t.integer_array :tag_ids, :default => [1, 2]
10
+ t.string_array :tag_names, :default => %w{as so}
11
+ end
12
+
13
+ create_table "bulks", :force => true do |t|
14
+ t.string :value
15
+ t.integer_array :ints, :default => [1, 2]
16
+ t.string_array :strings, :default => %w{as so}
17
+ t.timestamp_array :times, :default => %w{2010-01-01 2010-02-01}
18
+ t.float_array :floats, :default => [1.0, 1.2]
19
+ t.decimal_array :decimals, :default => [1.0, 1.2]
20
+ end
21
+ end
@@ -0,0 +1,2 @@
1
+ class Tag < ActiveRecord::Base
2
+ end
@@ -0,0 +1,15 @@
1
+ one:
2
+ id: 1
3
+ name: one
4
+ created_at: <%= Date.today.to_s(:db) %>
5
+ updated_at: <%= Time.now.to_s(:db) %>
6
+ two:
7
+ id: 2
8
+ name: two
9
+ created_at: <%= Date.today.to_s(:db) %>
10
+ updated_at: <%= Time.now.to_s(:db) %>
11
+ three:
12
+ id: 3
13
+ name: three
14
+ created_at: <%= Date.today.to_s(:db) %>
15
+ updated_at: <%= Time.now.to_s(:db) %>
@@ -0,0 +1,221 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe "PgArray" do
4
+ describe "Array" do
5
+ before :all do
6
+ @ability_class = Class.new do
7
+ include CanCan::Ability
8
+ end
9
+ @acheck = Struct.new(:a)
10
+ end
11
+
12
+ before :each do
13
+ @ability = @ability_class.new
14
+ end
15
+
16
+ it "should change type" do
17
+ [].pg.should be_an_instance_of(PGArrays::PgArray)
18
+ [].search_any.should be_an_instance_of(PGArrays::PgAny)
19
+ [].search_all.should be_an_instance_of(PGArrays::PgAll)
20
+ [].search_subarray.should be_an_instance_of(PGArrays::PgIncludes)
21
+ end
22
+
23
+ it "should provide search_any for cancan" do
24
+ ab.can :boom, @acheck, :a => [1, 2].search_any
25
+ ab.should be_able_to(:boom, the([1]))
26
+ ab.should be_able_to(:boom, the([1, 3]))
27
+ ab.should be_able_to(:boom, the([3, 1]))
28
+ ab.should be_able_to(:boom, the([1, 2]))
29
+ ab.should be_able_to(:boom, the([1, 2, 3]))
30
+ ab.should_not be_able_to(:boom, the([3]))
31
+ ab.should_not be_able_to(:boom, the([]))
32
+ end
33
+
34
+ it "should provide search_all for cancan" do
35
+ ab.can :boom, @acheck, :a => [1, 2].search_all
36
+ ab.should_not be_able_to(:boom, the([1]))
37
+ ab.should_not be_able_to(:boom, the([1, 3]))
38
+ ab.should_not be_able_to(:boom, the([3, 1]))
39
+ ab.should be_able_to(:boom, the([1, 2]))
40
+ ab.should be_able_to(:boom, the([1, 2, 3]))
41
+ ab.should_not be_able_to(:boom, the([3]))
42
+ ab.should_not be_able_to(:boom, the([]))
43
+ end
44
+
45
+ it "should provide search_subarray for cancan" do
46
+ ab.can :boom, @acheck, :a => [1, 2].search_subarray
47
+ ab.should be_able_to(:boom, the([1]))
48
+ ab.should_not be_able_to(:boom, the([1, 3]))
49
+ ab.should_not be_able_to(:boom, the([3, 1]))
50
+ ab.should be_able_to(:boom, the([1, 2]))
51
+ ab.should_not be_able_to(:boom, the([1, 2, 3]))
52
+ ab.should_not be_able_to(:boom, the([3]))
53
+ ab.should be_able_to(:boom, the([]))
54
+ end
55
+
56
+ def the(ar)
57
+ @acheck.new(ar)
58
+ end
59
+
60
+ def ab
61
+ @ability
62
+ end
63
+ end
64
+
65
+ describe "AR" do
66
+ it "should adequatly insert fixtures" do
67
+ bulk = Bulk.find(1)
68
+ bulk.ints.should == [ 1 ]
69
+ bulk.strings.should == %w{one}
70
+ bulk.times.should == [Time.now.at_beginning_of_month, Time.now.at_beginning_of_day]
71
+ bulk.floats.should == [1.0, 2.3]
72
+ bulk.decimals.should == [1.0, 2.3]
73
+ end
74
+
75
+ it "should be created with defaults" do
76
+ bulk = Bulk.new
77
+ bulk.ints.should == [1, 2]
78
+ bulk.strings.should == %w{as so}
79
+ bulk.floats.should == [1.0, 1.2]
80
+ bulk.decimals.should == [1.0, 1.2]
81
+ map_times(bulk.times).should ==
82
+ map_times(parse_times(%w{2010-01-01 2010-02-01}))
83
+ end
84
+
85
+ it "should save changes" do
86
+ bulk = Bulk.find(3)
87
+ for field in %w{ints strings floats decimals times}
88
+ bulk.send(field+'=', bulk.send(field).reverse)
89
+ end
90
+ bulk.save!
91
+ bulk = Bulk.find(:first, :conditions=>'3 = id')
92
+ bulk.ints.should == [3, 2]
93
+ bulk.strings.should == %w{three two}
94
+ bulk.floats.should == [2.5, 2]
95
+ bulk.decimals.should == [2.5, 2]
96
+ map_times(bulk.times).should == map_times(parse_times(%w{2010-04-01 2010-03-01}))
97
+ end
98
+
99
+ it "should allow to use sql" do
100
+ bulks_where(['ints && ?', [1,2].pg]).should == bulks_where(:id=>[1,2,3])
101
+ end
102
+
103
+ it "should allow to use finders" do
104
+ bulks_where(:ints => [2].search_any).should == bulks_where(:id=>[2,3])
105
+ bulks_where(:ints => [2,3].search_any).should == bulks_where(:id=>[2,3])
106
+ bulks_where(:ints => [1,2].search_any).should == bulks_where(:id=>[1,2,3])
107
+
108
+ bulks_where(:ints => [2].search_all).should == bulks_where(:id=>[2,3])
109
+ bulks_where(:ints => [2,3].search_all).should == bulks_where(:id=>[3])
110
+ bulks_where(:ints => [1,2].search_all).should == []
111
+
112
+ bulks_where(:ints => [2].search_subarray).should == bulks_where(:id=>[2,4])
113
+ bulks_where(:ints => [2,3].search_subarray).should == bulks_where(:id=>[2,3,4])
114
+ bulks_where(:ints => [1,2].search_subarray).should == bulks_where(:id=>[1,2,4])
115
+ end
116
+
117
+ def map_times(times)
118
+ times.map{|t| t.strftime("%F %T")}
119
+ end
120
+
121
+ def parse_times(times)
122
+ times.map{|t| DateTime.parse(t)}
123
+ end
124
+
125
+ def bulks_where(cond)
126
+ Bulk.where(cond).order('id').all
127
+ end
128
+ end
129
+
130
+ describe "CanCan" do
131
+ before :all do
132
+ @ability_class = Class.new do
133
+ include CanCan::Ability
134
+ end
135
+ @all_items = Item.all
136
+ end
137
+
138
+ before :each do
139
+ @ability = @ability_class.new
140
+ end
141
+
142
+ it "should provide search_any for cancan" do
143
+ should_match_ids_with_ability [2, 3, 4, 6], :tag_ids => [3].search_any
144
+ should_match_ids_with_ability [1, 3, 4, 5, 6], :tag_ids => [1, 2].search_any
145
+ end
146
+
147
+ it "should provide search_all for cancan" do
148
+ should_match_ids_with_ability [2, 3, 4, 6], :tag_ids => [3].search_all
149
+ should_match_ids_with_ability [5, 6], :tag_ids => [1, 2].search_all
150
+ end
151
+
152
+ it "should provide search_subarray for cancan" do
153
+ should_match_ids_with_ability [2, 7], :tag_ids => [3].search_subarray
154
+ should_match_ids_with_ability [1, 5, 7], :tag_ids => [1, 2].search_subarray
155
+ end
156
+
157
+ def should_match_ids_with_ability(ids, ability)
158
+ act = (ability[:tag_ids].class.name + ids.join('_')).to_sym
159
+ ab.can act, Item, ability
160
+ items = accessible_items(act)
161
+ items.should == items_where(:id=>ids)
162
+ should_be_able_all items, act
163
+ should_not_be_able_except items, act
164
+ end
165
+
166
+ def ab
167
+ @ability
168
+ end
169
+
170
+ def accessible_items(act)
171
+ Item.accessible_by(ab, act).order('id').all
172
+ end
173
+
174
+ def items_where(cond)
175
+ Item.where(cond).order('id').all
176
+ end
177
+
178
+ def should_be_able_all(items, act)
179
+ items.each{|item| ab.should be_able_to(act, item)}
180
+ end
181
+
182
+ def should_not_be_able_except(items, act)
183
+ (@all_items - items).each{|item| ab.should_not be_able_to(act, items)}
184
+ end
185
+ end
186
+
187
+ describe "references_by" do
188
+ it "should fetch tags in saved order" do
189
+ Item.find(3).tags.should == [Tag.find(1), Tag.find(3)]
190
+ Item.find(4).tags.should == [Tag.find(3), Tag.find(1)]
191
+ end
192
+
193
+ it "should save tags references" do
194
+ item = Item.find(3)
195
+ item.tags= [Tag.find(1), '3', 2]
196
+ item.tags.should == [Tag.find(1), Tag.find(3), Tag.find(2)]
197
+ item.save!
198
+ item.reload
199
+ item.tags.should == [Tag.find(1), Tag.find(3), Tag.find(2)]
200
+ item.tags= [1,3]
201
+ item.save!
202
+ item.reload
203
+ item.tags.should == [Tag.find(1), Tag.find(3)]
204
+ end
205
+
206
+ it "should define named scopes for tags" do
207
+ Item.tags_include(3).order('id').all.should == items_where(:id=>[2,3,4,6])
208
+ Item.tags_include(1,3).order('id').all.should == items_where(:id=>[3,4,6])
209
+ Item.tags_have_all(3).order('id').all.should == items_where(:id=>[2,3,4,6])
210
+ Item.tags_have_all(1,3).order('id').all.should == items_where(:id=>[3,4,6])
211
+ Item.tags_have_any(3).order('id').all.should == items_where(:id=>[2,3,4,6])
212
+ Item.tags_have_any(1,3).order('id').all.should == items_where(:id=>[1,2,3,4,5,6])
213
+ Item.tags_included_into(3).order('id').all.should == items_where(:id=>[2,7])
214
+ Item.tags_included_into(1,3).order('id').all.should == items_where(:id=>[1,2,3,4,7])
215
+ end
216
+
217
+ def items_where(cond)
218
+ Item.where(cond).order('id').all
219
+ end
220
+ end
221
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ gem 'rspec'
3
+ gem 'activerecord'
4
+
5
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
+ $:.unshift(File.dirname(__FILE__) + '/fixtures')
7
+
8
+ require 'active_record'
9
+ require 'active_record/fixtures'
10
+ gem 'pg'
11
+ begin
12
+ gem 'arel'
13
+ rescue Gem::LoadError
14
+ require 'fake_arel'
15
+ class ActiveRecord::Base
16
+ named_scope :joins, lambda {|*join| {:joins => join } if join[0]}
17
+ end
18
+ end
19
+ require 'cancan'
20
+ require 'cancan/matchers'
21
+ require 'ar_pg_array'
22
+
23
+
24
+ ActiveRecord::Base.establish_connection(
25
+ :adapter => 'postgresql',
26
+ :database => 'postgres',
27
+ :encoding => 'utf8'
28
+ )
29
+ ActiveRecord::Base.connection.create_database('test_pg_array', :encoding=>'utf8') rescue nil
30
+
31
+ ActiveRecord::Base.establish_connection(
32
+ :adapter => 'postgresql',
33
+ :database => 'test_pg_array',
34
+ :encoding => 'utf8'
35
+ )
36
+ ActiveRecord::Base.logger = Logger.new(STDOUT) #if $0 == 'irb'
37
+
38
+ require 'tag'
39
+ require 'item'
40
+ require 'bulk'
41
+ ActiveRecord::Base.silence do
42
+ ActiveRecord::Migration.verbose = false
43
+
44
+ # load schema
45
+ load File.join('spec/fixtures/schema.rb')
46
+ # load fixtures
47
+ Fixtures.create_fixtures("spec/fixtures", ActiveRecord::Base.connection.tables)
48
+ end
49
+
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_pg_array
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 59
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 8
8
- - 4
9
- version: 0.8.4
8
+ - 9
9
+ - 0
10
+ version: 0.9.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Sokolov Yura aka funny_falcon
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-08-19 00:00:00 +04:00
18
+ date: 2010-09-04 00:00:00 +04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -25,6 +26,7 @@ dependencies:
25
26
  requirements:
26
27
  - - ">="
27
28
  - !ruby/object:Gem::Version
29
+ hash: 3
28
30
  segments:
29
31
  - 0
30
32
  version: "0"
@@ -50,6 +52,16 @@ files:
50
52
  - lib/ar_pg_array/references_by.rb
51
53
  - lib/ar_pg_array/schema.rb
52
54
  - lib/ar_pg_array/schema_arel.rb
55
+ - spec/fixtures/bulk.rb
56
+ - spec/fixtures/bulks.yml
57
+ - spec/fixtures/item.rb
58
+ - spec/fixtures/items.yml
59
+ - spec/fixtures/schema.rb
60
+ - spec/fixtures/tag.rb
61
+ - spec/fixtures/tags.yml
62
+ - spec/pg_array_spec.rb
63
+ - spec/spec.opts
64
+ - spec/spec_helper.rb
53
65
  has_rdoc: true
54
66
  homepage: http://github.com/funny-falcon/activerecord-postgresql-arrays
55
67
  licenses: []
@@ -64,6 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
76
  requirements:
65
77
  - - ">="
66
78
  - !ruby/object:Gem::Version
79
+ hash: 3
67
80
  segments:
68
81
  - 0
69
82
  version: "0"
@@ -72,6 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
85
  requirements:
73
86
  - - ">="
74
87
  - !ruby/object:Gem::Version
88
+ hash: 3
75
89
  segments:
76
90
  - 0
77
91
  version: "0"
@@ -82,5 +96,10 @@ rubygems_version: 1.3.7
82
96
  signing_key:
83
97
  specification_version: 3
84
98
  summary: Use power of PostgreSQL Arrays in ActiveRecord
85
- test_files: []
86
-
99
+ test_files:
100
+ - spec/fixtures/schema.rb
101
+ - spec/fixtures/item.rb
102
+ - spec/fixtures/bulk.rb
103
+ - spec/fixtures/tag.rb
104
+ - spec/pg_array_spec.rb
105
+ - spec/spec_helper.rb