module CouchbaseOrm::Views::ClassMethods

Constants

ViewDefaults

Public Instance Methods

ensure_design_document!() click to toggle source
# File lib/couchbase-orm/views.rb, line 113
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) click to toggle source

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

# File lib/couchbase-orm/views.rb, line 99
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) click to toggle source

Defines a view for the model

@param [Symbol, String, Array] names names of the views @param [Hash] options options passed to the {Couchbase::View}

@example 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
# File lib/couchbase-orm/views.rb, line 25
            def view(name, map: nil, emit_key: nil, reduce: nil, **options)
                if emit_key.class == Array
                    emit_key.each do |key|
                        raise "unknown emit_key attribute for view :#{name}, emit_key: :#{key}" if key && @attributes[key].nil?
                    end
                else
                    raise "unknown emit_key attribute for view :#{name}, emit_key: :#{emit_key}" if emit_key && @attributes[emit_key].nil?
                end

                options = ViewDefaults.merge(options)

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

                unless method_opts.has_key? :map
                    if emit_key.class == 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 = 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
                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