пользовательский фильтр активного администратора для сериализованного атрибута - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть следующие модели:

Class User < ApplicationRecord
  has_one :profile
end

class Profile < ApplicationRecord
  belongs_to :user
end

У меня есть колонка навыков в профиле, в которой хранится множество навыков.Я использую rails active admin и при фильтрации пользователей с навыками, с которыми я столкнулся, проблема

PG :: InvalidTextRepresentation: ОШИБКА: неверно сформированный массив, литерал: "java"

myкод фильтра:

filter :profile_skills, label: 'Skills', as: :string

Я не понимаю, в чем проблема.пожалуйста, помогите мне

1 Ответ

0 голосов
/ 11 февраля 2019

ActiveAdmin использует Ransack гем для фильтрации.Простейший способ фильтрации по массиву с помощью ransack - определить область в модели:

class Profile < ApplicationRecord
  # @!method skills_includes(skill)
  #   @param skill [String]
  #   @return [ActiveRecord::Relation<Profile>]
  scope :where_skills_contains, ->(skill) { where("skills @> ?", "{#{skill}}") }
end

Используя эту область, вы можете фильтровать профили по таким навыкам как Profile. skills_include('java').

По умолчанию ransack не выполняетне разрешать использовать области для фильтрации, поэтому вам необходимо белый список этой области:

class Profile
  def self.ransackable_scopes(*)
    %i(where_skills_contains) 
  end

  private_class_method :ransackable_scopes
end

Теперь возможна возможность перебора области в фильтре:

filter :where_skills_contains, label: :skills, as: :string

Обратите внимание, что вы не можете назвать фильтр (и область действия) skills_contains, потому что он сгенерирует совершенно другой запрос к базе данных.

> Profile.ransack(where_skills_contains: 'java').result.to_sql 
#=> SELECT "profiles".* FROM "profiles" WHERE (skills @> '{java}')
> Profile.ransack(skills_contains: 'java').result.to_sql
#=> SELECT "profiles".* FROM "profiles" WHERE ("profiles"."skills" ILIKE '{%java%}')
...