Merge a dict with the model

        This is needed because schematics doesn't auto cast
        values when assigned. This method allows us to ensure
        incoming data & existing data on a model are always
        coerced properly.

        We create a temporary model instance with just the new
        data so all the features of schematics deserialization
        are still available.

        :param data:
            dict of potentially new different data to merge

        :param clean:
            set the dirty bit back to clean. This is useful
            when the merge is coming from the store where
            the data could have been mutated & the new merged
            in data is now the single source of truth.

        :param validate:
            run the schematics validate method

        :return:
            nothing.. it has mutation side effects

def merge(self, data, clean=False, validate=False):
        """ Merge a dict with the model

        This is needed because schematics doesn't auto cast
        values when assigned. This method allows us to ensure
        incoming data & existing data on a model are always
        coerced properly.

        We create a temporary model instance with just the new
        data so all the features of schematics deserialization
        are still available.

        :param data:
            dict of potentially new different data to merge

        :param clean:
            set the dirty bit back to clean. This is useful
            when the merge is coming from the store where
            the data could have been mutated & the new merged
            in data is now the single source of truth.

        :param validate:
            run the schematics validate method

        :return:
            nothing.. it has mutation side effects
        """

        try:
            model = self.__class__(data)
        except ConversionError as errors:
            abort(self.to_exceptions(errors.messages))

        for key, val in model.to_native().items():
            if key in data:
                setattr(self, key, val)

        if validate:
            try:
                self.validate()
            except ModelValidationError as errors:
                abort(self.to_exceptions(errors.messages))

        if clean:
            self._original = self.to_native()