groovy 0.6.8 → 0.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc2f1ef55cf22504bc95fd3a143108b0d7097816274606cb557851c588c7ba02
4
- data.tar.gz: 8881018c1036dab4257291bde59c8797317ba1568cafcb7d87ac12f8b7cf9499
3
+ metadata.gz: da506ad46a6a3aad6cd965b7fcc43079fd61903c1e1a9f0bee659342430dc9ad
4
+ data.tar.gz: 6eba099bd0552fcc3ce8aaa15a0d9fb46486a96e1c1eee8dcd427f86a7d44256
5
5
  SHA512:
6
- metadata.gz: 63e936c9c4920be9e27d3567acc575cf75900fcd5be9786b55f171f068dec19ab4b618ce22367ae7856c30d602517574a61fbc2fef37e36dfc62a9f9d2b7bbf6
7
- data.tar.gz: ee9f1292bb74220dd40acc1058151d4ca6f390e94b4f1b6e9c13561d6dfb1aa9a5df774d858a66695906478a70a8ba49c9ce368585496223287ad67a8276f563
6
+ metadata.gz: 4c26e85b1dc605632deff25150f39e3794079c75581c0098c4893d01fced0729a6f4cd99fea8cae1d840aa003b219dfc62a62acbc0fa0743514d2d4464bbf98a
7
+ data.tar.gz: 1efedf625a489694dc51442664438d8d3a1984dfa50398734f97ecccf8f8146ff4543c06f9a1a6b9a0b17c4007d4fd1baa636b5d2ade8a98b300142133e89240
data/lib/groovy/model.rb CHANGED
@@ -17,6 +17,31 @@ module Groovy
17
17
  @models ||= {}
18
18
  end
19
19
 
20
+ module Utils
21
+ def self.singularize(str)
22
+ str.to_s.sub(/ies$/, 'y').sub(/s$/, '')
23
+ end
24
+
25
+ # category -> categories
26
+ # product -> products
27
+ def self.pluralize(str)
28
+ return str if str[-1] == 's' # already ends with s, assume already plural
29
+ str.to_s.sub(/y$/, 'ie') + 's'
30
+ end
31
+
32
+ def self.pluralize_and_classify(str)
33
+ classify(pluralize(str))
34
+ end
35
+
36
+ def self.underscore(str)
37
+ str.gsub(/([A-Z])/) { |x| "_#{x.downcase}" }.sub(/^_/, '')
38
+ end
39
+
40
+ def self.classify(str)
41
+ str.to_s.gsub(/([A-Z])/, '_\1').split('_').collect! { |w| w.capitalize }.join
42
+ end
43
+ end
44
+
20
45
  module Model
21
46
 
22
47
  def self.initialize_from_record(obj)
@@ -30,23 +55,21 @@ module Groovy
30
55
  # end
31
56
 
32
57
  def self.model_from_table(table_name)
33
- get_class(table_name.to_s.sub(/ies$/, 'y').sub(/s$/, ''))
58
+ get_class(Utils.singularize(table_name))
34
59
  end
35
60
 
36
61
  def self.included(base)
37
62
  base.extend(ClassMethods)
38
63
  base.include(Forwardable)
39
- base.table_name = base.name.sub(/y$/, 'ie') + 's'
64
+ base.table_name = Utils.pluralize(base.name)
40
65
 
41
66
  # add to global model list
42
67
  # Groovy.models[base.name] = base
43
68
  Groovy.models[base.table_name] = base
44
69
  end
45
70
 
46
- def self.get_class(table_name)
47
- # classify method
48
- classified = table_name.gsub(/([A-Z])/, '_\1').split('_').collect! { |w| w.capitalize }.join
49
- Kernel.const_get(classified)
71
+ def self.get_class(klass_name)
72
+ Kernel.const_get(Utils.classify(klass_name))
50
73
  end
51
74
 
52
75
  module ClassMethods
@@ -63,11 +86,15 @@ module Groovy
63
86
  end
64
87
 
65
88
  def underscore_name
66
- name.gsub(/([A-Z])/) { |x| "_#{x.downcase}" }.sub(/^_/, '')
89
+ Utils.underscore(name)
67
90
  end
68
91
 
69
92
  def attribute_names
70
- @attribute_names ||= schema.attribute_columns
93
+ schema.attribute_columns
94
+ end
95
+
96
+ def reference_names
97
+ schema.singular_references + schema.plural_references
71
98
  end
72
99
 
73
100
  # def singular_refs
@@ -87,11 +114,13 @@ module Groovy
87
114
  self.context_name = options[:context] || Groovy.first_context_name
88
115
  self.table_name = options[:table_name] if options[:table_name]
89
116
 
90
- s = Schema.new(db_context, table_name, {})
117
+ s = Schema.new(db_context, table_name, options)
91
118
  yield s if block
92
119
  s.sync
93
120
 
94
- extend(PatriciaTrieMethods) if table.is_a?(Groonga::PatriciaTrie)
121
+ include(HashTable) if table.is_a?(Groonga::Hash)
122
+ include(PatriciaTrieTable) if table.is_a?(Groonga::PatriciaTrie)
123
+
95
124
  s.column_names.each { |col| add_accessors_for(col, s) }
96
125
  s
97
126
  end
@@ -118,7 +147,7 @@ module Groovy
118
147
  elsif s.plural_references.include?(col)
119
148
  add_vector_accessors(col)
120
149
  else
121
- puts "WARNING: Unknown column type: #{col}"
150
+ raise "Unknown column type: #{col}"
122
151
  end
123
152
  end
124
153
 
@@ -147,13 +176,13 @@ module Groovy
147
176
  end
148
177
  end
149
178
 
150
- def create(attributes, key = nil)
151
- obj = new(attributes, nil, key)
179
+ def create(attributes)
180
+ obj = new(attributes)
152
181
  obj.save ? obj : false
153
182
  end
154
183
 
155
- def create!(attributes, key = nil)
156
- create(attributes, key) or raise Error, "Invalid"
184
+ def create!(attributes)
185
+ create(attributes) or raise Error, "Invalid"
157
186
  end
158
187
 
159
188
  def update_all(attrs)
@@ -174,6 +203,12 @@ module Groovy
174
203
  # Groonga["#{table_name}.#{name}"] # .search, .similar_search, etc
175
204
  # end
176
205
 
206
+ def search_table
207
+ schema.search_table
208
+ end
209
+
210
+ def_instance_delegators :search_table, :prefix_search, :each_with_prefix # just these two for now
211
+
177
212
  def index_search(column, query, options = {}, &block)
178
213
  results = table.select { |rec| rec[column].match(query) }
179
214
  render_results(results, &block)
@@ -230,6 +265,14 @@ module Groovy
230
265
  query.where(*args, &block)
231
266
  end
232
267
 
268
+ def each(&block)
269
+ query.each(&block)
270
+ end
271
+
272
+ def find_or_create_by(attributes)
273
+ find_by(**attributes) || create(**attributes)
274
+ end
275
+
233
276
  [:first, :last, :select, :find_by, :search, :not, :sort_by, :in_batches, :limit, :offset, :paginate].each do |scope_method|
234
277
  define_method scope_method do |**args, &block|
235
278
  query.public_send(scope_method, **args, &block)
@@ -308,21 +351,80 @@ module Groovy
308
351
  end
309
352
  end
310
353
 
311
- module PatriciaTrieMethods
312
- extend Forwardable
313
- def_instance_delegators :table, :scan, :prefix_search, :open_prefix_cursor, :tag_keys
354
+ module PatriciaTrieTable
355
+ def self.included(base)
356
+ base.extend(ClassMethods)
357
+ end
358
+
359
+ module ClassMethods
360
+ extend Forwardable
361
+ def_instance_delegators :table, :scan, :prefix_search, :open_prefix_cursor, \
362
+ :suffix_search, :open_near_cursor, :tag_keys
314
363
 
315
- def each_with_prefix(prefix, options = {}, &block)
316
- table.open_prefix_cursor(prefix, options) do |cursor|
317
- cursor.each { |r| yield r }
364
+ def each_with_prefix(prefix, options = {}, &block)
365
+ table.open_prefix_cursor(prefix, options) do |cursor|
366
+ cursor.each { |r| yield r }
367
+ end
368
+ end
369
+
370
+ def each_near(str, options = {}, &block)
371
+ table.open_near_cursor(str, options) do |cursor|
372
+ cursor.each { |r| yield r }
373
+ end
318
374
  end
319
375
  end
320
376
  end
321
377
 
378
+ module HashTable
379
+ def self.included(base)
380
+ base.extend(ClassMethods)
381
+ end
382
+
383
+ module ClassMethods
384
+ def find(key)
385
+ if record = table[key.to_s] and record.record_id
386
+ new_from_record(record)
387
+ end
388
+ end
389
+
390
+ def new_from_record(record)
391
+ # new(record.attributes, record)
392
+ new(record._key, nil, record)
393
+ end
394
+
395
+ def create(key, attributes)
396
+ obj = new(key, attributes)
397
+ obj.save ? obj : false
398
+ end
399
+
400
+ def create!(key, attributes)
401
+ create(key, attributes) or raise Error, "Invalid"
402
+ end
403
+ end
404
+
405
+ def initialize(key, attrs = nil, record = nil)
406
+ @key = key
407
+ super(attrs, record)
408
+ end
409
+
410
+ def load_record
411
+ self.class.table[key]
412
+ end
413
+
414
+ # def new_record?
415
+ # key.nil?
416
+ # end
417
+
418
+ def key
419
+ @key || (record ? record._key : nil)
420
+ end
421
+
422
+ end
423
+
322
424
  attr_reader :id, :record, :changes
323
425
 
324
- def initialize(attrs = nil, record = nil, key = nil)
325
- @attributes, @vectors, @_key = {}, {}, key # key is used on creation only
426
+ def initialize(attrs = nil, record = nil)
427
+ @attributes, @vectors = {}, {}
326
428
  @foreign_refs_to_update = {}
327
429
 
328
430
  if set_record(record)
@@ -344,9 +446,9 @@ module Groovy
344
446
 
345
447
  # get reference to the actual record in the Groonga table,
346
448
  # not the temporary one we get as part of a search result.
347
- # def load_record
348
- # self.class.table[id]
349
- # end
449
+ def load_record
450
+ self.class.table[id]
451
+ end
350
452
 
351
453
  def attributes
352
454
  load_attributes_from_record # populate missing
@@ -356,7 +458,7 @@ module Groovy
356
458
  alias_method :attrs, :attributes
357
459
 
358
460
  def inspect
359
- "#<#{self.class.name} id:#{id.inspect} attributes:[#{self.class.attribute_names.join(', ')}]>"
461
+ "#<#{self.class.name} id:#{id.inspect} attributes:[#{self.class.attribute_names.join(', ')}] references:[#{self.class.reference_names.join(', ')}]>"
360
462
  end
361
463
 
362
464
  def dump
@@ -365,7 +467,6 @@ module Groovy
365
467
 
366
468
  def new_record?
367
469
  id.nil?
368
- # _key.nil?
369
470
  end
370
471
 
371
472
  def persisted?
@@ -427,6 +528,9 @@ module Groovy
427
528
  update_attributes(obj) or raise "Invalid!"
428
529
  end
429
530
 
531
+ alias_method :update, :update_attributes
532
+ alias_method :update!, :update_attributes!
533
+
430
534
  def save(options = {})
431
535
  return false if respond_to?(:invalid?) and invalid?
432
536
  if new_record?
@@ -455,7 +559,7 @@ module Groovy
455
559
  unless new_record?
456
560
  # raise RecordNotPersisted if id.nil?
457
561
  # ensure_persisted!
458
- rec = self.class.table[id] # _key
562
+ rec = load_record
459
563
  set_record(rec)
460
564
  # load_attributes_from_record
461
565
  end
@@ -494,11 +598,6 @@ module Groovy
494
598
  return val.to_i == 0 ? nil : val
495
599
  end
496
600
 
497
- # def _key
498
- # return unless record
499
- # record.respond_to?(:_key) ? record._key : id
500
- # end
501
-
502
601
  def load_attributes_from_record
503
602
  self.class.attribute_names.each do |col|
504
603
  public_send("#{col}=", get_record_attribute(col)) unless @attributes.key?(col)
@@ -533,7 +632,14 @@ module Groovy
533
632
  if record.nil? # not persisted yet
534
633
  set_attribute(name, obj.id) # obj should be a groovy model or groonga record
535
634
  else
536
- val = obj.respond_to?(:record) ? obj.record : obj
635
+ val = if obj.is_a?(Groovy::Model)
636
+ obj.id
637
+ elsif obj.respond_to?(:record)
638
+ # obj.record.record_id
639
+ obj.record
640
+ else
641
+ obj
642
+ end
537
643
  record[name] = val
538
644
  end
539
645
  end
@@ -545,7 +651,7 @@ module Groovy
545
651
 
546
652
  def create
547
653
  fire_callbacks(:before_create)
548
- set_record(self.class.insert(@attributes, @_key))
654
+ set_record(self.class.insert(@attributes, @key))
549
655
  update_foreign_refs
550
656
  fire_callbacks(:after_create)
551
657
  self
data/lib/groovy/query.rb CHANGED
@@ -80,20 +80,26 @@ module Groovy
80
80
  add_param(AND + "(#{map_operator(handle_timestamps(conditions))})")
81
81
  when Hash # { foo: 'bar' } or { views: 1..100 }
82
82
  conditions.each do |key, val|
83
- if val.is_a?(Range)
83
+ case val
84
+ when Model
85
+ raise "Object not persisted yet!" unless val.persisted?
86
+ str = "#{key}:#{val.id}"
87
+ add_param(AND + str)
88
+
89
+ when Range
84
90
  add_param(AND + [key, val.min].join(':>=')) if val.min # lte
85
91
  add_param(AND + [key, val.max].join(':<=')) if val.max # gte
86
92
 
87
- elsif val.is_a?(Regexp)
93
+ when Regexp
88
94
  str = val.source.gsub('/', '_slash_').gsub('(', '_openp_').gsub(')', '_closep_').gsub(REMOVE_INVALID_CHARS_REGEX, '')
89
95
  param = val.source[0] == '^' ? ':^' : val.source[-1] == '$' ? ':$' : ':~' # starts with or regexp
90
96
  add_param(AND + [key, str.downcase].join(param)) # regex must be downcase
91
97
 
92
- elsif val.is_a?(Array) # { foo: [1,2,3] }
98
+ when Array # { foo: [1,2,3] }
93
99
  str = "#{key}:#{val.join(" OR #{key}:")}"
94
100
  add_param(AND + str)
95
101
 
96
- elsif val.is_a?(Time)
102
+ when Time
97
103
  # The second, specify the timestamp as string in following format:
98
104
  # “(YEAR)/(MONTH)/(DAY) (HOUR):(MINUTE):(SECOND)”
99
105
 
data/lib/groovy/schema.rb CHANGED
@@ -4,6 +4,14 @@ module Groovy
4
4
  class Schema
5
5
 
6
6
  SEARCH_TABLE_NAME = 'Terms'.freeze
7
+
8
+ SEARCH_TABLE_OPTIONS = {
9
+ type: :patricia_trie,
10
+ normalizer: :NormalizerAuto,
11
+ key_type: "ShortText",
12
+ default_tokenizer: "TokenBigram"
13
+ }.freeze
14
+
7
15
  COLUMN_DEFAULTS = {
8
16
  compress: :zstandard
9
17
  }.freeze
@@ -33,6 +41,10 @@ module Groovy
33
41
  @table ||= context[table_name]
34
42
  end
35
43
 
44
+ def table_type
45
+ (@opts[:type] || :array).to_sym
46
+ end
47
+
36
48
  # def [](key)
37
49
  # # @spec[key.to_sym]
38
50
  # table.columns.select { |c| c.column? && c.name.to_s == "#{table_name}.#{key.to_s}" }
@@ -115,11 +127,11 @@ module Groovy
115
127
  end
116
128
 
117
129
  def reference(name, table_name = nil, options = {})
118
- table_name = "#{name}s" if table_name.nil?
130
+ table_name = Utils.pluralize_and_classify(name) if table_name.nil?
119
131
 
120
132
  unless context[table_name]
121
133
  log "Table #{table_name} doesn't exist yet! Creating now..."
122
- create_table!(table_name)
134
+ create_table!(table_name, nil)
123
135
  end
124
136
 
125
137
  refs_by_table[table_name] = name.to_sym
@@ -174,19 +186,17 @@ module Groovy
174
186
  name_col = [table_name, col].join('.')
175
187
  log "Adding index on #{name_col}"
176
188
  Groonga::Schema.change_table(SEARCH_TABLE_NAME, context: context) do |table|
177
- # table.index(name_col, name: name_col, with_position: true, with_section: true)
178
- table.index(name_col, name: name_col.sub('.', '_'))
189
+ if opts[:search] # search column requires with_position: true
190
+ table.index(name_col, name: name_col, with_position: true, with_section: true)
191
+ else
192
+ table.index(name_col, name: name_col.sub('.', '_'))
193
+ end
179
194
  end
180
195
  end
181
196
 
182
197
  def ensure_search_table!
183
198
  return if search_table
184
- opts = (@opts[:search_table] || {}).merge({
185
- type: :patricia_trie,
186
- normalizer: :NormalizerAuto,
187
- key_type: "ShortText",
188
- default_tokenizer: "TokenBigram"
189
- })
199
+ opts = (@opts[:search_table] || {}).merge(SEARCH_TABLE_OPTIONS)
190
200
  log("Creating search table with options: #{opts.inspect}")
191
201
  Groonga::Schema.create_table(SEARCH_TABLE_NAME, opts.merge(context: context))
192
202
  end
@@ -225,9 +235,9 @@ module Groovy
225
235
  end
226
236
  end
227
237
 
228
- def create_table!(name = table_name)
229
- log "Creating table #{name}!"
230
- Groonga::Schema.create_table(name, context: context)
238
+ def create_table!(name = table_name, type = table_type)
239
+ log "Creating table #{name} with type #{type.inspect}!"
240
+ Groonga::Schema.create_table(name, context: context, type: type)
231
241
  end
232
242
 
233
243
  def remove_table!(name = table_name)
@@ -1,3 +1,3 @@
1
1
  module Groovy
2
- VERSION = '0.6.8'.freeze
2
+ VERSION = '0.7.1'.freeze
3
3
  end
@@ -4,14 +4,14 @@ describe Groovy::Model do
4
4
 
5
5
  before :all do
6
6
  Groovy.open('tmp/callbacks', 'callbacks_spec')
7
- load_callbacks_schema!
7
+ load_test_schema!
8
8
  end
9
9
 
10
10
  after :all do
11
11
  Groovy.close('callbacks_spec')
12
12
  end
13
13
 
14
- def load_callbacks_schema!
14
+ def load_test_schema!
15
15
  klass = Class.new
16
16
  Object.const_set("User", klass)
17
17
  User.class_eval do
@@ -35,8 +35,6 @@ describe Groovy::Model do
35
35
  # puts "updated"
36
36
  end
37
37
  end
38
-
39
- User.add_reference :comments, "Comments", type: :vector
40
38
  end
41
39
 
42
40
  it 'fires created callbacks' do
data/spec/model_spec.rb CHANGED
@@ -15,7 +15,6 @@ describe Groovy::Model do
15
15
  end
16
16
 
17
17
  describe '.scope' do
18
-
19
18
  before :all do
20
19
  TestProduct.class_eval do
21
20
  scope :with_name, -> (name) { where(name: name) if name }
@@ -120,6 +119,21 @@ describe Groovy::Model do
120
119
  end
121
120
 
122
121
  describe '#update_attributes' do
122
+
123
+ it 'allows setting references out of searches' do
124
+ cat = TestCategory.create!(name: 'A category')
125
+ cat2 = TestCategory.create!(name: 'Another category')
126
+
127
+ prod = TestProduct.create!(name: 'A product', price: 100)
128
+ prod.update_attributes(test_category: cat)
129
+
130
+ last = TestCategory.last
131
+ expect(last).to eq(cat2)
132
+ puts "last: #{last.inspect}"
133
+ prod.update_attributes(test_category: last)
134
+ expect(prod.reload.test_category).to eq(cat2)
135
+ end
136
+
123
137
  end
124
138
 
125
139
  describe '#save' do
@@ -147,15 +161,12 @@ describe Groovy::Model do
147
161
  end
148
162
 
149
163
  describe 'attributes accessors' do
150
-
151
164
  end
152
165
 
153
166
  describe 'singular refs' do
154
-
155
167
  end
156
168
 
157
169
  describe 'plural refs' do
158
-
159
170
  end
160
171
 
161
172
  end
data/spec/query_spec.rb CHANGED
@@ -16,6 +16,13 @@ describe Groovy::Query do
16
16
  Groovy.close('query_spec')
17
17
  end
18
18
 
19
+ # describe '#first' do
20
+ # it 'returns a valid object' do
21
+ # res = TestProduct.first
22
+ # expect(res.record.table.name).to eq(TestProduct.table.name)
23
+ # end
24
+ # end
25
+
19
26
  describe '#where' do
20
27
  describe 'boolean value' do
21
28
  it 'finds expected records' do
@@ -0,0 +1,74 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Groovy::Model do
4
+
5
+ CONTEXT_NAME = 'schema_spec'
6
+
7
+ before :all do
8
+ Groovy.open('tmp/' + CONTEXT_NAME, CONTEXT_NAME)
9
+ load_test_schema!
10
+ end
11
+
12
+ after :all do
13
+ Groovy.close(CONTEXT_NAME)
14
+ end
15
+
16
+ def load_test_schema!
17
+ klass = Class.new
18
+ Object.const_set("Product", klass)
19
+ Product.class_eval do
20
+ include Groovy::Model
21
+
22
+ schema(type: 'hash', context: CONTEXT_NAME) do |t|
23
+ t.string :name
24
+ t.many :categories
25
+ t.timestamps
26
+ end
27
+ end
28
+
29
+ klass = Class.new
30
+ Object.const_set("Category", klass)
31
+ Category.class_eval do
32
+ include Groovy::Model
33
+
34
+ schema(context: CONTEXT_NAME) do |t|
35
+ t.many :products, "Products"
36
+ t.string :name
37
+ t.timestamps
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'hash table' do
43
+
44
+ it 'creates, updates and finds records as expected' do
45
+ product = Product.new('ipod-mini', name: 'iPod Mini')
46
+ expect(product.new_record?).to eq(true)
47
+
48
+ expect(product.name).to eq('iPod Mini')
49
+ expect(product.save).to eq(true)
50
+ expect(product.persisted?).to eq(true)
51
+ expect(product.key).to eq('ipod-mini')
52
+
53
+ expect(product.update_attributes(name: 'iPod Mini 2nd Generation'))
54
+ expect(product.name).to eq('iPod Mini 2nd Generation')
55
+
56
+ expect(Product.find('ipod-mini')).to eq(product)
57
+ end
58
+
59
+ it 'works with references too' do
60
+ product = Product.new('ipod-mini', name: 'iPod Mini')
61
+ expect(product.save).to eq(true)
62
+
63
+ category = Category.new(name: 'iPods')
64
+ expect(category.save).to eq(true)
65
+
66
+ category.products << product
67
+ product.categories << category
68
+
69
+ expect(product.reload.categories).to eq([category])
70
+ end
71
+
72
+ end
73
+
74
+ end
data/spec/search_spec.rb CHANGED
@@ -6,7 +6,7 @@ describe Groovy::Model, 'searching' do
6
6
  Groovy.open('tmp/search', 'search_spec')
7
7
  load_schema! 'search_spec'
8
8
 
9
- TestProduct.add_column :description, :string, index: true
9
+ TestProduct.add_column :description, :string, index: true #, search: true
10
10
 
11
11
  TestProduct.create!(name: 'First product', description: 'Lorem ipsum dolor sit amet')
12
12
  TestProduct.create!(name: 'Second product', description: 'Lorea el ipsum poh loco')
@@ -51,4 +51,25 @@ describe Groovy::Model, 'searching' do
51
51
  expect(res.first.name).to eq('Second product')
52
52
  end
53
53
  end
54
+
55
+ describe 'prefix search' do
56
+ it 'returns results' do
57
+ res = TestProduct.prefix_search('Lore')
58
+ expect(res.count).to eq(0)
59
+
60
+ res = TestProduct.prefix_search('lore')
61
+ expect(res.count).to eq(2)
62
+ expect(res.first).to be_a(Groonga::Record)
63
+ parts = res.map { |rec| rec['._key'] }
64
+ expect(parts).to eq(['lorem', 'lorea'])
65
+ end
66
+
67
+ # it 'works with each_with_prefix too' do
68
+ # parts = []
69
+ # res = TestProduct.each_with_prefix('lore') do |rec|
70
+ # parts.push(rec['._key'])
71
+ # end
72
+ # expect(parts).to eq(['lorem', 'lorea'])
73
+ # end
74
+ end
54
75
  end
data/spec/spec_helper.rb CHANGED
@@ -16,12 +16,21 @@ RSpec.configure do |config|
16
16
  end
17
17
  end
18
18
 
19
+ class TestCategory
20
+ include Groovy::Model
21
+ end
22
+
19
23
  class TestProduct
20
24
  include Groovy::Model
21
25
  end
22
26
 
23
27
  def load_schema!(context_name)
28
+ TestCategory.load_schema context: context_name do |t|
29
+ t.string :name
30
+ end
31
+
24
32
  TestProduct.load_schema context: context_name do |t|
33
+ t.one :test_category
25
34
  t.boolean :visible
26
35
  t.string :name
27
36
  t.integer :price
data/spec/vector_spec.rb CHANGED
@@ -63,6 +63,13 @@ describe Groovy::Model do
63
63
  expect(user2.reload.comments).to eq([])
64
64
  end
65
65
 
66
+ it 'finds records using relations too' do
67
+ user = User.create(name: 'John')
68
+ comment = Comment.create(author: user, content: 'Hello there!')
69
+
70
+ expect(Comment.find_by(author: user)).to eq(comment)
71
+ end
72
+
66
73
  end
67
74
 
68
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groovy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.8
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-06 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rroonga
@@ -101,13 +101,14 @@ files:
101
101
  - spec/groovy_spec.rb
102
102
  - spec/model_spec.rb
103
103
  - spec/query_spec.rb
104
+ - spec/schema_spec.rb
104
105
  - spec/search_spec.rb
105
106
  - spec/spec_helper.rb
106
107
  - spec/vector_spec.rb
107
108
  homepage: https://github.com/tomas/groovy
108
109
  licenses: []
109
110
  metadata: {}
110
- post_install_message:
111
+ post_install_message:
111
112
  rdoc_options: []
112
113
  require_paths:
113
114
  - lib
@@ -122,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
- rubygems_version: 3.4.10
126
- signing_key:
126
+ rubygems_version: 3.4.6
127
+ signing_key:
127
128
  specification_version: 4
128
129
  summary: A wrapper around Groonga/Rroonga
129
130
  test_files: []