Works like a map function from keyvals to instances.


        Args:

            keyvals(list):  The list of values of the attribute.

            key (str, optional): The attribute to search by. By default, it is
                'id'.


        Returns:

            list: A list of model instances, in the same order as the list of
                keyvals.


        Examples:


            >>> User.get_all([2,5,7, 8000, 11])
            user2@i.com, user5@i.com, user7@i.com, None, user11@i.com

            >>> User.get_all(['user35@i.com', 'user5@i.com'], key='email')
            user35@i.com, user5@i.com

def get_all(cls, keyvals, key='id', user_id=None):
        """Works like a map function from keyvals to instances.


        Args:

            keyvals(list):  The list of values of the attribute.

            key (str, optional): The attribute to search by. By default, it is
                'id'.


        Returns:

            list: A list of model instances, in the same order as the list of
                keyvals.


        Examples:


            >>> User.get_all([2,5,7, 8000, 11])
            user2@i.com, user5@i.com, user7@i.com, None, user11@i.com

            >>> User.get_all(['user35@i.com', 'user5@i.com'], key='email')
            user35@i.com, user5@i.com

        """
        if len(keyvals) == 0:
            return []
        original_keyvals = keyvals
        keyvals_set = list(set(keyvals))
        resultset = cls.query.filter(getattr(cls, key).in_(keyvals_set))
        # This is ridiculous. user_id check cannot be here. A hangover
        # from the time this lib was inside our app codebase
        # if user_id and hasattr(cls, 'user_id'):
        #     resultset = resultset.filter(cls.user_id == user_id)
        # We need the results in the same order as the input keyvals
        # So order by field in SQL
        key_result_mapping = {getattr(result, key): result for result in resultset.all()}
        return [key_result_mapping.get(kv) for kv in original_keyvals]