module Sack::Database::Model::Data

Data Module: Provides a simple data access layer through models.

Constants

VALIDATED_ACTIONS

Actions requiring Validation

Public Instance Methods

method_missing(name, *args) click to toggle source

Method Missing: Catches and routes model actions through database.

Calls superclass method
# File lib/sack/database/model/data.rb, line 33
def method_missing name, *args

        # Check action allowed
        super name, *args unless ACTIONS.include? name

        # Acquire Database
        db = args.slice! 0

        # Check Validation Required
        if VALIDATED_ACTIONS.include? name

                # Acquire Entity
                data = args.last

                # Pre-load for updates
                data = data.clone.merge find(db, args.slice(0)) if name == :update

                # Validate
                errors = []
                raise Validation::ValidationException.new "Invalid Entity [#{data}] for Model #{@model}", errors unless is_valid? db, data, errors
        end

        # Check Delete
        if name == :delete

                # Get ID
                id = args.first

                # Run through Relations
                relationships.each do |_rname, relationship|

                        # Acquire Target Model
                        tmodel = @model_root.const_get relationship[:target].to_s.camelcase

                        # Switch on delete action
                        case relationship[:options][:on_delete]
                                when :detach
                                        tmodel.update_by db, relationship[:fk], id, relationship[:fk] => nil
                                when :delete
                                        tmodel.delete_by db, relationship[:fk], id
                                else
                                        # NoOp
                        end
                end
        end

        # Check Delete By
        if name == :delete_by

                # Fetch Set
                set = fetch_by db, *args

                # Run through Relations
                relationships.each do |_rname, relationship|

                        # Acquire Target Model
                        tmodel = @model_root.const_get relationship[:target].to_s.camelcase

                        # Switch on delete action
                        case relationship[:options][:on_delete]
                                when :detach
                                        set.each { |e| tmodel.update_by db, relationship[:fk], e[:id], relationship[:fk] => nil }
                                when :delete
                                        set.each { |e| tmodel.delete_by db, relationship[:fk], e[:id] }
                                else
                                        # NoOp
                        end
                end
        end

        # Forward to Database
        result = db.send name, table_name, *args

        # Inject Model Proxy into Entity/ies
        (result.is_a?(Array) ? result : [result]).each { |e| e.instance_variable_set('@model_mod', self); e.define_singleton_method(:method_missing) { |n, *a| @model_mod.send n, *a, self } } unless result.frozen?

        result
end