couch_potato 1.17.0 → 1.19.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a78d19f65a75932bb6f60639fc9ad3dff0151e9c7de7f8cbc31e1b61038f7fa8
4
- data.tar.gz: c5383ffd3db50bd45d727a84b62588dcd70d6ea3d07ac96559e1318c145fb057
3
+ metadata.gz: 46b162f592d8c1c7dada2e150793fbfc5f8c76c1e9bb8a3364f8f2895505335b
4
+ data.tar.gz: eca37db69c74f6f58ec6bb518028a100e9b74ce1bfbe7edce16b899c5caa7406
5
5
  SHA512:
6
- metadata.gz: 38aa7ce10b0f12429789ecc0f25e34b276f98eadedac900f2ea18b7c1845549be28becb624d4da1c89506d814fa403b7f9647f960f3be534ac47b02c839f6866
7
- data.tar.gz: e0b48a96f9a485d0765b066b5e5bca043058b85af246775abdf2bf3afb598bf691b09ae156182b9ecf1ff9dcc0acdee3bb5cc899a8722d0a75bdff9ded965b7b
6
+ metadata.gz: c4f8edddc5e9a667bb09cb1fa9c5ee5bbb6f374088f27d039bfedd21ce59f13be2a963803bb40be0677916ab9d1d3543eb325849dd5f05010089092ceb0ce891
7
+ data.tar.gz: 4952e15f37cce9db1e07032f8588a24d28d990cba4e657b657cd4621cf8786a08af9289daadcc1c65a1f6d7f55ea4aef447f7e7e409c488bb706e6ea39e61c4f
@@ -16,19 +16,19 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: ["3.0", "3.1", "3.2", "jruby"]
19
+ ruby: ["3.2", "3.3", "jruby"]
20
20
  gemfile:
21
- - "active_support_7_0"
22
- - "active_support_7_1"
21
+ - "active_support_7_2"
22
+ - "active_support_8_0"
23
23
  exclude:
24
24
  - ruby: "jruby"
25
- gemfile: "active_support_7_0"
25
+ gemfile: "active_support_8_0"
26
26
  steps:
27
- - uses: actions/checkout@v2
27
+ - uses: actions/checkout@v4
28
28
  - name: Set up CouchDB
29
- uses: cobot/couchdb-action@v4
29
+ uses: cobot/couchdb-action@v5
30
30
  with:
31
- couchdb version: "2.3.1"
31
+ couchdb-version: "2.3.1"
32
32
  - name: Set up Ruby
33
33
  uses: ruby/setup-ruby@v1
34
34
  with:
@@ -36,3 +36,5 @@ jobs:
36
36
  bundler-cache: true
37
37
  - name: Run tests
38
38
  run: bundle exec rake spec_ci
39
+ env:
40
+ DATABASE: http://admin:admin@localhost:5984/couch_potato_test
data/CHANGES.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## Changes
2
2
 
3
+ # 1.19.0 / rspec-matchers 4.2.0
4
+
5
+ - add `single_design_document` config option
6
+ - remove support for lists and lib
7
+
8
+ # 1.18.0
9
+
10
+ - add testing Rails 7.2/8 on CI
11
+ - change gemspec to allow for Rails 8
12
+ - remove support for Rails < 7.2
13
+
3
14
  # 1.17.0
4
15
 
5
16
  - filter out nil ids for loading multiple documents
data/README.md CHANGED
@@ -80,6 +80,12 @@ Another switch allows you to store each CouchDB view in its own design document.
80
80
  CouchPotato::Config.split_design_documents_per_view = true
81
81
  ```
82
82
 
83
+ With the following switch, couch potato only creates a single design document for all views:
84
+
85
+ ```ruby
86
+ CouchPotato::Config.single_design_document = true
87
+ ```
88
+
83
89
  If you are using more than one database from your app, you can create aliases:
84
90
 
85
91
  ```ruby
@@ -95,6 +101,7 @@ Create a `config/couchdb.yml`:
95
101
  default: &default
96
102
  split_design_documents_per_view: true # optional, default is false
97
103
  digest_view_names: true # optional, default is false
104
+ single_design_document: true # optional, default is false
98
105
  default_language: :erlang # optional, default is javascript
99
106
  database_host: "http://127.0.0.1:5984"
100
107
 
@@ -299,7 +306,7 @@ user.valid? # => false
299
306
  user.errors[:name] # => ['can't be blank']
300
307
  ```
301
308
 
302
- #### Finding stuff / views / lists
309
+ #### Finding stuff / views
303
310
 
304
311
  In order to find data in your CouchDB you have to create a [view](http://books.couchdb.org/relax/design-documents/views) first. Couch Potato offers you to create and manage those views for you. All you have to do is declare them in your classes:
305
312
 
@@ -403,14 +410,6 @@ class User
403
410
  end
404
411
  ```
405
412
 
406
- commonJS modules can also be used in custom views:
407
-
408
- ```ruby
409
- class User
410
- view :all, :map => "function(doc) { emit(null, require("views/lib/test").test)}", :lib => {:test => "exports.test = 'test'"}, :include_docs => true, :type => :custom
411
- end
412
- ```
413
-
414
413
  If you don't want the results to be converted into models the raw view is your friend:
415
414
 
416
415
  ```ruby
@@ -450,49 +449,6 @@ You can pass in your own view specifications by passing in `:type => MyViewSpecC
450
449
 
451
450
  If turned on, Couch Potato will append an MD5 digest of the map function to each view name. This makes sure (together with split_design_documents_per_view) that no views/design documents are ever updated. Instead, new ones are created. Since reindexing can take a long time once your database is larger, you want to avoid blocking your app while CouchDB is busy. Instead, you create a new view, warm it up, and only then start using it.
452
451
 
453
- ##### Lists
454
-
455
- CouchPotato also supports [CouchDB lists](http://books.couchdb.org/relax/design-documents/lists). With lists you can process the result of a view query with another JavaScript function. This can be useful for example if you want to filter your results, or add some data to each document.
456
-
457
- Defining a list works similarly to views:
458
-
459
- ```ruby
460
- class User
461
- include CouchPotato::Persistence
462
-
463
- property :first_name
464
- view :with_full_name, key: first_namne, list: :add_last_name
465
- view :all, key: :first_name
466
-
467
- list :add_last_name, <<-JS
468
- function(head, req) {
469
- var row;
470
- send('{"rows": [');
471
- while(row = getRow()) {
472
- row.doc.name = row.doc.first_name + ' doe';
473
- send(JSON.stringify(row));
474
- };
475
- send(']}');
476
- }
477
- JS
478
- end
479
-
480
- CouchPotato.database.save User.new(first_name: 'joe')
481
- CouchPotato.database.view(User.with_full_name).first.name # => 'joe doe'
482
- ```
483
-
484
- You can also pass in the list at query time:
485
-
486
- ```ruby
487
- CouchPotato.database.view(User.all(list: :add_last_name))
488
- ```
489
-
490
- And you can pass parameters to the list:
491
-
492
- ```ruby
493
- CouchPotato.database.view(User.all(list: :add_last_name, list_params: {filter: '*'}))
494
- ```
495
-
496
452
  #### Associations
497
453
 
498
454
  Not supported. Not sure if they ever will be. You can implement those yourself using views and custom methods on your models.
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  desc 'Run all specs for all gemfiles'
28
28
  task :spec do
29
- %w(7_1 7_0).each do |version|
29
+ %w(7_2 8_0).each do |version|
30
30
  Bundler.with_original_env do
31
31
  puts "Running tests with ActiveSupport #{version.sub('_', '.')}"
32
32
  sh "env BUNDLE_GEMFILE=gemfiles/active_support_#{version} bundle install"
data/couch_potato.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.version = CouchPotato::VERSION
14
14
  s.platform = Gem::Platform::RUBY
15
15
 
16
- s.add_dependency 'activemodel', ['>= 5.0', '< 8.0']
16
+ s.add_dependency 'activemodel', ['>= 7.2', '< 8.1']
17
17
  s.add_dependency 'couchrest', '~>2.0.0'
18
18
  s.add_dependency 'json', '~> 2.3'
19
19
 
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'railties', '~>7.0.8'
3
+ gem 'railties', '~>7.2.1'
4
4
  gem 'activemodel'
5
5
  gem 'execjs'
6
6
 
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'railties', '~>7.1.3'
3
+ gem 'railties', '~>8.0.1'
4
4
  gem 'activemodel'
5
5
  gem 'execjs'
6
6
 
@@ -273,8 +273,6 @@ module CouchPotato
273
273
  map: spec.map_function,
274
274
  reduce: spec.reduce_function
275
275
  } },
276
- ({ spec.list_name => spec.list_function } unless spec.list_name.nil?),
277
- spec.lib,
278
276
  spec.language
279
277
  ).query_view!(spec.view_parameters)
280
278
  end
@@ -12,16 +12,20 @@ require File.dirname(__FILE__) + '/persistence/type_caster'
12
12
  require File.dirname(__FILE__) + '/persistence/revisions'
13
13
  require File.dirname(__FILE__) + '/forbidden_attributes_protection'
14
14
  require File.dirname(__FILE__) + '/view/custom_views'
15
- require File.dirname(__FILE__) + '/view/lists'
16
15
  require File.dirname(__FILE__) + '/view/view_query'
17
16
 
18
17
 
19
18
  module CouchPotato
20
19
  module Persistence
20
+ module TrackModels
21
+ def inherited(child)
22
+ super
23
+ CouchPotato.models << child
24
+ end
25
+ end
21
26
 
22
27
  def self.included(base) #:nodoc:
23
- base.send :include, Properties, Callbacks, Json, CouchPotato::View::CustomViews,
24
- CouchPotato::View::Lists
28
+ base.send :include, Properties, Callbacks, Json, CouchPotato::View::CustomViews
25
29
  base.send :include, DirtyAttributes, GhostAttributes, Attachments
26
30
  base.send :include, MagicTimestamps, ActiveModelCompliance,
27
31
  ForbiddenAttributesProtection, Revisions
@@ -31,9 +35,8 @@ module CouchPotato
31
35
  alias_method :id, :_id
32
36
  alias_method :id=, :_id=
33
37
 
34
- def self.inherited(child)
35
- super
36
- CouchPotato.models << child
38
+ class << self
39
+ prepend TrackModels
37
40
  end
38
41
  end
39
42
 
@@ -1,4 +1,4 @@
1
1
  module CouchPotato
2
- VERSION = '1.17.0'.freeze
3
- RSPEC_VERSION = '4.1.0'.freeze
2
+ VERSION = '1.19.0'.freeze
3
+ RSPEC_VERSION = '4.2.0'.freeze
4
4
  end
@@ -3,7 +3,7 @@
3
3
  module CouchPotato
4
4
  module View
5
5
  class BaseViewSpec
6
- attr_reader :reduce_function, :lib, :list_name, :list_function, :design_document, :view_name, :klass, :options, :language
6
+ attr_reader :reduce_function, :design_document, :view_name, :klass, :options, :language
7
7
  attr_accessor :view_parameters
8
8
 
9
9
  private :klass, :options
@@ -11,7 +11,7 @@ module CouchPotato
11
11
  def initialize(klass, view_name, options, view_parameters)
12
12
  normalized_view_parameters = ViewParameters.normalize_view_parameters view_parameters
13
13
 
14
- @list_name = normalized_view_parameters.delete(:list) || options[:list]
14
+
15
15
  @language = options[:language] || Config.default_language
16
16
 
17
17
  assert_valid_view_parameters normalized_view_parameters
@@ -19,16 +19,12 @@ module CouchPotato
19
19
  @options = options
20
20
  @view_name = compute_view_name(view_name,
21
21
  options.key?(:digest_view_name) ? options[:digest_view_name] : Config.digest_view_names)
22
- @design_document = translate_to_design_doc_name(klass.to_s, @view_name, @list_name)
23
- @list_params = normalized_view_parameters.delete :list_params
24
-
25
- @list_function = klass.lists(@list_name) if @list_name
22
+ @design_document = design_doc_name
26
23
  @view_parameters = {}
27
24
  %i[group include_docs descending group_level limit].each do |key|
28
25
  @view_parameters[key] = options[key] if options.include?(key)
29
26
  end
30
27
  @view_parameters.merge!(normalized_view_parameters)
31
- @view_parameters.merge!(@list_params) if @list_params
32
28
  end
33
29
 
34
30
  def process_results(results)
@@ -42,10 +38,16 @@ module CouchPotato
42
38
  private
43
39
 
44
40
  def compute_view_name(view_name, digest)
41
+ name = if CouchPotato::Config.single_design_document
42
+ "#{translate_to_design_doc_name(klass.to_s, view_name)}-#{view_name}"
43
+ else
44
+ view_name
45
+ end
46
+
45
47
  if digest
46
- "#{view_name}-#{Digest::MD5.hexdigest(map_function + reduce_function.to_s)}"
48
+ "#{name}-#{Digest::MD5.hexdigest(map_function + reduce_function.to_s)}"
47
49
  else
48
- view_name
50
+ name
49
51
  end
50
52
  end
51
53
 
@@ -56,10 +58,18 @@ module CouchPotato
56
58
  end
57
59
 
58
60
  def valid_view_parameters
59
- %w[list_params key keys startkey startkey_docid endkey endkey_docid limit stale descending skip group group_level reduce include_docs inclusive_end]
61
+ %w[key keys startkey startkey_docid endkey endkey_docid limit stale descending skip group group_level reduce include_docs inclusive_end]
62
+ end
63
+
64
+ def design_doc_name
65
+ if CouchPotato::Config.single_design_document
66
+ 'couch_potato'
67
+ else
68
+ translate_to_design_doc_name(klass.to_s, view_name)
69
+ end
60
70
  end
61
71
 
62
- def translate_to_design_doc_name(klass_name, view_name, list_name)
72
+ def translate_to_design_doc_name(klass_name, view_name)
63
73
  klass_name = klass_name.dup
64
74
  klass_name.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
65
75
  klass_name.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
@@ -68,7 +78,6 @@ module CouchPotato
68
78
 
69
79
  if CouchPotato::Config.split_design_documents_per_view
70
80
  doc_name += "_view_#{view_name}" if view_name.present?
71
- doc_name += "_list_#{list_name}" if list_name.present?
72
81
  end
73
82
  doc_name
74
83
  end
@@ -13,10 +13,6 @@ module CouchPotato
13
13
  options[:reduce]
14
14
  end
15
15
 
16
- def lib
17
- options[:lib]
18
- end
19
-
20
16
  def view_parameters
21
17
  {:include_docs => options[:include_docs] || false}.merge(super)
22
18
  end
@@ -9,9 +9,21 @@ require 'couch_potato/view/view_parameters'
9
9
  module CouchPotato
10
10
  module View
11
11
  module CustomViews
12
+ module TrackViews
13
+ def inherited(child)
14
+ super
15
+ CouchPotato.views << child
16
+ end
17
+ end
12
18
 
13
19
  def self.included(base) #:nodoc:
14
20
  base.extend ClassMethods
21
+ CouchPotato.views << base
22
+ base.class_eval do
23
+ class << self
24
+ prepend TrackViews
25
+ end
26
+ end
15
27
  end
16
28
 
17
29
  module ClassMethods
@@ -96,7 +96,7 @@ module CouchPotato
96
96
  end
97
97
 
98
98
  delegate :view_name, :view_parameters, :design_document, :map_function,
99
- :reduce_function, :list_name, :lib, :language, to: :view_spec_delegate
99
+ :reduce_function, :language, to: :view_spec_delegate
100
100
 
101
101
  def process_results(results)
102
102
  results = Results.new(results)
@@ -1,6 +1,6 @@
1
1
  module CouchPotato
2
2
  module View
3
- # A view for custom map/reduce functions that returns the raw data fromcouchdb
3
+ # A view for custom map/reduce functions that returns the raw data from couchdb
4
4
  #
5
5
  # example:
6
6
  # view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :reduce => nil
@@ -10,7 +10,7 @@ module CouchPotato
10
10
  # view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :results_filter => lambda{|results| results['rows].map{|row| row['value']}}
11
11
  #
12
12
  # example:
13
- # view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :lib => {:module => "exports.name = 'module';"
13
+ # view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw"
14
14
  class RawViewSpec < BaseViewSpec
15
15
  def map_function
16
16
  options[:map]
@@ -19,10 +19,6 @@ module CouchPotato
19
19
  def reduce_function
20
20
  options[:reduce]
21
21
  end
22
-
23
- def lib
24
- options[:lib]
25
- end
26
22
  end
27
23
  end
28
24
  end
@@ -2,18 +2,13 @@ module CouchPotato
2
2
  module View
3
3
  # Used to query views (and create them if they don't exist). Usually you won't have to use this class directly. Instead it is used internally by the CouchPotato::Database.view method.
4
4
  class ViewQuery
5
- def initialize(couchrest_database, design_document_name, view, list = nil, lib = nil, language = :javascript)
5
+ def initialize(couchrest_database, design_document_name, view, language = :javascript)
6
6
  @database = couchrest_database
7
7
  @design_document_name = design_document_name
8
8
  @view_name = view.keys[0]
9
9
  @map_function = view.values[0][:map]
10
10
  @reduce_function = view.values[0][:reduce]
11
- @lib = lib
12
11
  @language = language
13
- if list
14
- @list_function = list.values[0]
15
- @list_name = list.keys[0]
16
- end
17
12
  end
18
13
 
19
14
  def query_view!(parameters = {})
@@ -42,34 +37,41 @@ module CouchPotato
42
37
  def update_view
43
38
  design_doc = @database.get "_design/#{@design_document_name}" rescue nil
44
39
  original_views = design_doc && design_doc['views'].dup
45
- original_lists = design_doc && design_doc['lists'] && design_doc['lists'].dup
46
- view_updated unless design_doc.nil?
40
+ view_updated
47
41
  design_doc ||= empty_design_document
48
- design_doc['views'][@view_name.to_s] = view_functions
49
- if @lib
50
- design_doc['views']['lib'] = (design_doc['views']['lib'] || {}).merge(@lib)
42
+ if CouchPotato::Config.single_design_document
43
+ design_doc['views'] = all_views
44
+ else
45
+ design_doc['views'][@view_name.to_s] = view_functions
51
46
  end
52
- if @list_function
53
- design_doc['lists'] ||= {}
54
- design_doc['lists'][@list_name.to_s] = @list_function
47
+ if original_views != design_doc['views']
48
+ @database.save_doc(design_doc)
55
49
  end
56
- @database.save_doc(design_doc) if original_views != design_doc['views'] || original_lists != design_doc['lists']
57
50
  end
58
51
 
59
- def view_functions
60
- if @reduce_function
61
- {'map' => @map_function, 'reduce' => @reduce_function}
62
- else
63
- {'map' => @map_function}
64
- end
52
+ def all_views
53
+ CouchPotato.views.flat_map do |klass|
54
+ specs = klass.views.map { |view_name, view| klass.execute_view(view_name, {}) }
55
+ specs.map do |klass_spec|
56
+ { klass_spec.view_name => view_functions(klass_spec.map_function, klass_spec.reduce_function) }
57
+ end
58
+ end.inject(&:merge)
59
+ end
60
+
61
+ def view_functions(map_function = @map_function, reduce_function = @reduce_function)
62
+ {'map' => map_function, 'reduce' => reduce_function}.compact
65
63
  end
66
64
 
67
65
  def empty_design_document
68
- {'views' => {}, 'lists' => {}, "_id" => "_design/#{@design_document_name}", "language" => @language.to_s}
66
+ {'views' => {}, "_id" => "_design/#{@design_document_name}", "language" => @language.to_s}
69
67
  end
70
68
 
71
69
  def view_has_been_updated?
72
- updated_views[[@design_document_name, @view_name]]
70
+ if CouchPotato::Config.single_design_document
71
+ updated_views.any?
72
+ else
73
+ updated_views[[@design_document_name, @view_name]]
74
+ end
73
75
  end
74
76
 
75
77
  def view_updated
@@ -81,11 +83,7 @@ module CouchPotato
81
83
  end
82
84
 
83
85
  def query_view(parameters)
84
- if @list_name
85
- @database.connection.get CouchRest.paramify_url("/#{@database.name}/_design/#{@design_document_name}/_list/#{@list_name}/#{@view_name}", parameters)
86
- else
87
- @database.view view_url, parameters
88
- end
86
+ @database.view view_url, parameters
89
87
  end
90
88
 
91
89
  def view_url
data/lib/couch_potato.rb CHANGED
@@ -9,9 +9,10 @@ JSON.create_id = 'ruby_class'
9
9
  CouchRest.decode_json_objects = true
10
10
 
11
11
  module CouchPotato
12
- Config = Struct.new(:database_host, :database_name, :digest_view_names,
12
+ Config = Struct.new(:database_host, :database_name, :digest_view_names, :single_design_document,
13
13
  :split_design_documents_per_view, :default_language, :additional_databases).new
14
14
  Config.split_design_documents_per_view = false
15
+ Config.single_design_document = false
15
16
  Config.digest_view_names = false
16
17
  Config.default_language = :javascript
17
18
  Config.database_host = 'http://127.0.0.1:5984'
@@ -29,6 +30,7 @@ module CouchPotato
29
30
  Config.database_host = config['database_host'] if config['database_host']
30
31
  Config.additional_databases = config['additional_databases'].stringify_keys if config['additional_databases']
31
32
  Config.split_design_documents_per_view = config['split_design_documents_per_view'] if config['split_design_documents_per_view']
33
+ Config.single_design_document = config['single_design_document'] if config['single_design_document']
32
34
  Config.digest_view_names = config['digest_view_names'] if config['digest_view_names']
33
35
  Config.default_language = config['default_language'] if config['default_language']
34
36
  end
@@ -40,6 +42,12 @@ module CouchPotato
40
42
  @models
41
43
  end
42
44
 
45
+ # returns all the classes that include the CouchPotato::View::CustomViews module
46
+ def self.views
47
+ @views ||= []
48
+ @views
49
+ end
50
+
43
51
  # Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
44
52
  def self.database
45
53
  Thread.current[:__couch_potato_database] ||= Database.new(couchrest_database)
@@ -418,7 +418,7 @@ describe 'properties' do
418
418
 
419
419
  it "should include complex datatypes fully inspected" do
420
420
  comment.title = {'en' => 'Blog post'}
421
- expect(comment.inspect).to include('title: {"en"=>"Blog post"}')
421
+ expect(comment.inspect).to match(/title: {"en"\s*=>\s*"Blog post"}/)
422
422
 
423
423
  comment.title = nil
424
424
  expect(comment.inspect).to include('title: nil')
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'single design document' do
4
+ let(:db) { CouchPotato.database }
5
+ let(:couchrest_db) { db.couchrest_database }
6
+
7
+ class Thing1
8
+ include CouchPotato::Persistence
9
+
10
+ property :title
11
+
12
+ view :all, key: :title
13
+ end
14
+
15
+ class Thing2
16
+ include CouchPotato::Persistence
17
+
18
+ property :name
19
+
20
+ view :all, key: :name
21
+ end
22
+
23
+ class Thing3 < Thing1 # should work with inheritance
24
+ property :tag
25
+
26
+ view :by_tag, key: :tag
27
+ end
28
+
29
+ before(:each) do
30
+ recreate_db
31
+ CouchPotato::Config.single_design_document = true
32
+ CouchPotato.views.select! { |v| [Thing1, Thing2, Thing3].include?(v) } # clear classes from other specs
33
+ end
34
+
35
+ after(:each) do
36
+ CouchPotato::Config.single_design_document = false
37
+ end
38
+
39
+ it 'creates a single design document for all views' do
40
+ thing1 = Thing1.new title: 't1'
41
+ db.save! thing1
42
+ thing2 = Thing2.new name: 'n2'
43
+ db.save! thing2
44
+
45
+ db.view(Thing1.all) # create all views when querying the first one
46
+
47
+ expect(couchrest_db.get('_design/couch_potato')['views'].keys)
48
+ .to(eq(['thing1-all', 'thing2-all', 'thing3-by_tag']))
49
+ end
50
+
51
+ it 'returns the correct models' do
52
+ thing1 = Thing1.new title: 't1'
53
+ db.save! thing1
54
+ thing2 = Thing2.new name: 'n2'
55
+ db.save! thing2
56
+ thing3 = Thing3.new tag: 'tag1'
57
+ db.save! thing3
58
+
59
+ expect(db.view(Thing1.all('t1'))).to eq([thing1])
60
+ expect(db.view(Thing2.all('n2'))).to eq([thing2])
61
+ expect(db.view(Thing3.by_tag('tag1'))).to eq([thing3])
62
+ end
63
+ end
@@ -87,7 +87,7 @@ describe 'attributes' do
87
87
  plant = Plant.new
88
88
  expect do
89
89
  plant.length
90
- end.to raise_error(NoMethodError, /undefined method `length'/)
90
+ end.to raise_error(NoMethodError, /undefined method [`']length'/)
91
91
  end
92
92
  end
93
93