Module: CouchbaseOrm::Views::ClassMethods

Defined in:
lib/couchbase-orm/views.rb

Constant Summary collapse

ViewDefaults =
{include_docs: true}

Instance Method Summary collapse

Instance Method Details

#ensure_design_document!Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/couchbase-orm/views.rb', line 97

def ensure_design_document!
    return false unless @views && !@views.empty?
    existing = {}
    update_required = false

    # Grab the existing view details
    ddoc = bucket.design_docs[@design_document]
    existing = ddoc.view_config if ddoc

    views_actual = {}
    # Fill in the design documents
    @views.each do |name, document|
        doc = document.dup
        views_actual[name] = doc
        doc[:map] = doc[:map].gsub('{{design_document}}', @design_document) if doc[:map]
        doc[:reduce] = doc[:reduce].gsub('{{design_document}}', @design_document) if doc[:reduce]
    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
        bucket.save_design_doc({
            views: views_actual
        }, @design_document)

        puts "Couchbase views updated for #{self.name}, design doc: #{@design_document}"
        true
    else
        false
    end
end

#index_view(attr, validate: true, find_method: nil, view_method: nil) ⇒ Object

add a view and lookup method to the model for finding all records using a value in the supplied attr.



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/couchbase-orm/views.rb', line 83

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
    "
end

#view(name, map: nil, emit_key: nil, reduce: nil, **options) ⇒ Object

Defines a view for the model

Examples:

Define some views for a model

class Post < CouchbaseOrm::Base
  view :all
  view :by_rating, emit_key: :rating
end

Post.by_rating.stream do |response|
  # ...
end

Parameters:

  • names (Symbol, String, Array)

    names of the views

  • options (Hash)

    options passed to the Couchbase::View



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/couchbase-orm/views.rb', line 25

def view(name, map: nil, emit_key: nil, reduce: nil, **options)
    raise "unknown emit_key attribute for view :#{name}, emit_key: :#{emit_key}" if emit_key && @attributes[emit_key].nil?

    options = ViewDefaults.merge(options)

    method_opts = {}
    method_opts[:map]    = map    if map
    method_opts[:reduce] = reduce if reduce

    unless method_opts.has_key? :map
        emit_key = emit_key || :created_at

        if emit_key != :created_at && self.attributes[emit_key][:type].to_s == 'Array'
            method_opts[:map] = <<-EMAP
function(doc) {
    var i;
    if (doc.type === "{{design_document}}") {
        for (i = 0; i < doc.#{emit_key}.length; i += 1) {
emit(doc.#{emit_key}[i], null);
        }
    }
}
EMAP
        else
            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 = options.merge(opts)

        if result_modifier
            opts[:include_docs] = true
            bucket.view(@design_document, name, **opts, &result_modifier)
        elsif opts[:include_docs]
            bucket.view(@design_document, name, **opts) { |row|
                self.new(row)
            }
        else
            bucket.view(@design_document, name, **opts)
        end
    end
end