Использование моделей пространства имен с ассоциациями polymorphi c в Rails Admin - PullRequest
1 голос
/ 18 марта 2020

В RailsAdmin Я пытаюсь управлять своим полиморфом c Region двумя классами, одним пространством имен, а другим - нет.

class Region < ApplicationRecord
  belongs_to :contentable, polymorphic: true
end

class Event::Exhibition < ApplicationRecord
  has_many :regions, as: :contentable
end

class Post < ApplicationRecord
  has_many :regions, as: :contentable
end

Все работает, кроме ajax выборка экземпляров моделей с пространством имен.

Когда я пытаюсь выбрать, например, Event::Exhibition, я вижу это в консоли моего браузера.

Error: Syntax error, unrecognized expression: #event::exhibition-js-options rails_admin.js:1502:8
    error http://localhost:3000/assets/rails_admin/rails_admin.js:1502

Когда я выбираю Post все мои сообщения возвращаются, как и ожидалось.

Это ошибка, или я могу обойти это с другими настройками? Единственный конфиг, который у меня есть для этого, - указать Rails Admin использовать поле.

edit do
  field :contentable
end

Копаться в HTML и JavaScript немного больше (спасибо @ Guillermo ) Я заметил, что сгенерированный выпадающий список выглядит следующим образом.

<option value=""></option>
<option value="Event::ArtFair">Art fair</option>
<option value="Event::Exhibition">Exhibition</option>
<option selected="selected" value="Post">News article</option>

Когда выбрана любая из опций со значением Event::, Sizzle жалуется, вызывая синтаксическую ошибку.

В моем инспекторе кода, если Я избегаю двоеточия, заставляя значения Event\:\:ArtFair и Event\:\:Exhibition работать как положено.

1 Ответ

0 голосов
/ 19 марта 2020

Понятно, это недействительные js идентификаторы. Я думаю, что вы можете изменить значения, если вы определили содержимое выбора, добавив метод экземпляра _enum.

Сначала вам нужно получить список возможных соперников для модели.

Я снимаю с бедра здесь, но это должно быть что-то вроде:

  def self.contentable_models
    ActiveRecord::Base.descendants.select do |model|
      model.reflect_on_all_associations(:has_many).any? do |has_many_association|
        has_many_association.options[:as] == :contentable
      end
    end
  end

  def contentable_enum
    self.class.contentable_models.map |model|
      [
        model.name.humanize,
        model.class.name.gsub(':','\:')
      ]
    end
  end

Я не уверен насчет производительности contentable_models, если у вас много моделей, он будет повторяться на всех из них, чтобы найти contentable, который вы, возможно, захотите запомнить этим значением.

Возможно, вам потребуется определить поле contentable как enum или даже поле contentable_type. Не уверен

...