如何在 Adminstrate gem 中关联 Ancestry gem 数据

How do I relate Ancestry gem data in Administrate gem

我在我的 Rails 6 应用程序中使用管理 gem。我已经创建了一个类别模型,我正在使用祖先 gem 来组织树结构等。我在尝试将祖先 gem 集成到 Adminstrate 中时遇到了问题。主要是祖先 gem 的 parent_id 为空的问题,因此 2. 试图在管理中显示 child name/relationships。

  1. Adminstrate gem 因为关系在编辑表单时将不接受空值是“祖先”被添加到管理中的仪表板表单。
  2. 我试图克服的另一个问题是显示 child 祖先使用的 ID 的关联名称。因此祖先使用字符串字段帮助使用类别行的 id 定位 parent。我不知道如何操作管理 dashboard/controller 来显示字段名称。

如有任何帮助,我们将不胜感激。我用谷歌搜索了一下,似乎找不到与同一问题相关的任何内容。

是否值得同时使用 Ancestry 和 Adminstrate?或者我应该只创建自己的类别控制器和视图以允许管理员修改类别数据吗?如果可能的话,我更愿意尝试将所有管理内容保留在 Adminstrate 中。

万分感谢

只需在下面添加我的解决方案,以防其他人遇到问题。

允许 Administrate 接受空值,即使由于祖先 gem 在模型中使用关系而可能需要存在。例如

class Category < ApplicationRecord
  has_ancestry
end

您可以在 Adminstrate 的管理控制器中覆盖 'resource params'。

# Override `resource_params` if you want to transform the submitted
# data before it's persisted. For example, the following would turn all
# empty values into nil values. It uses other APIs such as `resource_class`
# and `dashboard`:

 def resource_params
   params.require(resource_class.model_name.param_key).
     permit(dashboard.permitted_attributes).
     transform_values { |value| value == "" ? nil : value }
 end

第 2 部分。

在仪表板类别中,我想将 ID 更改为描述性名称。 Ancestry gem 使用字符串字段显示父类别的 ID。

仪表板 > category_dashboard.rb 文件

  ATTRIBUTE_TYPES = {
    ancestry: Field::Select.with_options(collection: Category.all.map do |cat| [cat.name, cat.id] end),
    #ancestry: Field::Text,
  }.freeze

我已将 attriubte_type 设为 select,其中包含选项值而不是文本字段,并映射了名称和 ID。

这让我可以 select 父类别的 ID 看到他们的名字而不是 ID。但是,我不能 select 一个 Null 值,如果我想让第 1 部分做它的事情并使一个空白字段 = null,我需要将这个 select 区域留空。在管理员用户添加时将该类别设置为父类别。

您可以使用生成命令生成管理中的所有字段。 (一旦有机会,我会把它添加到评论中)。

添加后,我可以编辑 Select 字段表单。这允许我添加 :include_blank => 'Primary Category' 到管理中的 select 字段表单。

   <% if field.selectable_options.first&.is_a?(Array) %>
       <%= f.select(
         field.attribute,
         options_from_collection_for_select(
           field.selectable_options,
           :last,
           :first,
           field.data.presence,
         ),
       :include_blank => 'Primary Category'
       ) %>
  <% else %>
    <%= f.select(
      field.attribute,
      options_from_collection_for_select(
        field.selectable_options,
        :to_s,
        :to_s,
        field.data.presence,
      ),
    :include_blank => 'Primary Category'
    ) %>
  <% end %>