Наиболее подходящий вариант нельзя посоветовать не зная ваших объемов данных и того как вы планируете это использовать.
Если время поиска не критично, типов данных мало, нужно простое и переносимое решение, то я бы посоветовал вариант 1 с сериализацией различных типов в строку.
Вариант с постгревыми json/jsonb добавляет гибкости/производительности, но в json простые типы это число, строка и булев. Даты и прочих типов там нету. Для jsonb поддерживаются индексы. Это решение означает жесткую привязку к PG.
Есть еще вариант похожий на 1, но с заданием разнотипных колонок и хранением в каждом свойстве его типа. Запросы будут выглядет как-то так
SELECT * FROM profile_field_values
WHERE
(property_field="дата рождения"
and value_type="date" and value_date > ?)
and
(property_field="размер ноги"
and value_type="integer" and value_integer < ?)
По скорости вы выиграете, но получите сложности с реализацией и интеграцией всего этого в рельсы.
Еще есть вариация на тему решения N3 - внешний сервис для поиска: Sphinx, Solr, etc...