Module: CouchbaseOrm::Views::ClassMethods
- Defined in:
- lib/couchbase-orm/views.rb
Constant Summary collapse
- ViewDefaults =
{include_docs: true}.freeze
Instance Method Summary collapse
-
#ensure_design_document! ⇒ Boolean
Ensures that the Couchbase design document is up-to-date with the defined views.
-
#index_view(attr, validate: true, find_method: nil, view_method: nil) ⇒ void
Sets up a Couchbase view and a corresponding finder method for the given attribute.
-
#view(name, map: nil, emit_key: nil, reduce: nil, **options) ⇒ void
Defines a Couchbase view with dynamic method creation.
Instance Method Details
#ensure_design_document! ⇒ Boolean
Ensures that the Couchbase design document is up-to-date with the defined views.
This method checks the current state of the design document in the Couchbase bucket and updates it if there are any discrepancies with the views defined in the current class.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/couchbase-orm/views.rb', line 180 def ensure_design_document! return false unless @views && !@views.empty? existing = {} update_required = false # Grab the existing view details begin ddoc = bucket.view_indexes.get_design_document(@design_document, :production) rescue Couchbase::Error::DesignDocumentNotFound end existing = ddoc.views if ddoc views_actual = {} # Fill in the design documents @views.each do |name, document| views_actual[name.to_s] = Couchbase::Management::View.new( document[:map]&.gsub('{{design_document}}', @design_document), document[:reduce]&.gsub('{{design_document}}', @design_document) ) end # Check there are no changes we need to apply views_actual.each do |name, desired| check = existing[name] if check cmap = (check.map || '').gsub(/\s+/, '') creduce = (check.reduce || '').gsub(/\s+/, '') dmap = (desired.map || '').gsub(/\s+/, '') dreduce = (desired.reduce || '').gsub(/\s+/, '') unless cmap == dmap && creduce == dreduce update_required = true break end else update_required = true break end end # Updated the design document if update_required document = Couchbase::Management::DesignDocument.new document.views = views_actual document.name = @design_document bucket.view_indexes.upsert_design_document(document, :production) true else false end end |
#index_view(attr, validate: true, find_method: nil, view_method: nil) ⇒ void
This method returns an undefined value.
Sets up a Couchbase view and a corresponding finder method for the given attribute.
Couchbase views allow you to create custom queries on your data using map and reduce functions. They are defined in design documents and can be queried to retrieve documents or aggregated data. For more details, see the [Couchbase Views Basics](docs.couchbase.com/server/current/learn/views/views-basics.html).
147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/couchbase-orm/views.rb', line 147 def index_view(attr, validate: true, find_method: nil, view_method: nil) view_method ||= "by_#{attr}" find_method ||= "find_#{view_method}" validates(attr, presence: true) if validate view view_method, emit_key: attr instance_eval " def self.#{find_method}(#{attr}) #{view_method}(key: #{attr}) end ", __FILE__, __LINE__ - 4 end |
#view(name, map: nil, emit_key: nil, reduce: nil, **options) ⇒ void
This method returns an undefined value.
Defines a Couchbase view with dynamic method creation.
Couchbase views allow you to create custom queries on your data using map and reduce functions. They are defined in design documents and can be queried to retrieve documents or aggregated data. For more details, see the [Couchbase Views Basics](docs.couchbase.com/server/current/learn/views/views-basics.html).
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/couchbase-orm/views.rb', line 57 def view(name, map: nil, emit_key: nil, reduce: nil, **) raise ArgumentError.new("#{self} already respond_to? #{name}") if self.respond_to?(name) if emit_key.is_a?(Array) emit_key.each do |key| raise "unknown emit_key attribute for view :#{name}, emit_key: :#{key}" if key && !attribute_names.include?(key.to_s) end elsif emit_key && !attribute_names.include?(emit_key.to_s) raise "unknown emit_key attribute for view :#{name}, emit_key: :#{emit_key}" end = ViewDefaults.merge() method_opts = {} method_opts[:map] = map if map method_opts[:reduce] = reduce if reduce unless method_opts.key? :map if emit_key.instance_of?(Array) method_opts[:map] = <<~EMAP function(doc) { if (doc.type === "{{design_document}}") { emit([#{emit_key.map{ |key| 'doc.' + key.to_s }.join(',')}], null); } } EMAP else emit_key ||= :created_at method_opts[:map] = <<~EMAP function(doc) { if (doc.type === "{{design_document}}") { emit(doc.#{emit_key}, null); } } EMAP end end @views ||= {} name = name.to_sym @views[name] = method_opts singleton_class.__send__(:define_method, name) do |**opts, &result_modifier| opts = .merge(opts).reverse_merge(scan_consistency: :request_plus) CouchbaseOrm.logger.debug("View [#{@design_document}, #{name.inspect}] options: #{opts.inspect}") if result_modifier include_docs(bucket.view_query(@design_document, name.to_s, Couchbase::Options::View.new(**opts.except(:include_docs)))).map(&result_modifier) elsif opts[:include_docs] include_docs(bucket.view_query(@design_document, name.to_s, Couchbase::Options::View.new(**opts.except(:include_docs)))) else bucket.view_query(@design_document, name.to_s, Couchbase::Options::View.new(**opts.except(:include_docs))) end end end |