在一个区域显示管理属性,但在另一区域不显示管理属性

Bra*_*est 3 ruby-on-rails administrate

我正在创建一个学习管理系统。我有用户注册了课程。我想在用户显示页面上显示用户何时完成课程。像这样:

在此输入图像描述

complete如果我在app/dashboards/course_dashboard.rbunder添加属性COLLECTION_ATTRIBUTES,它也会显示在课程索引页面中,这是我不想要的:

在此输入图像描述

如何将此complete属性添加到“用户显示”页面上的用户课程信息(如第一张图片所示),但不将其添加到“课程索引”页面(如第二张图片所示)?

pab*_*obm 6

不幸的是,Administrate 不支持开箱即用。不过,通过一些 Ruby 技巧就可以实现这一点。这是非官方的,确切的实施可能会随着新版本的管理而改变。它应该与Administrate 0.15以及可能的其他版本一起使用。

关键是管理代码中的这个模板:https://github.com/thoughtbot/administrate/blob/c16b8d1ee3a5ef1d622f9470738e89d73dbb8f1b/app/views/administrate/application/_collection.html.erb

这里有两行很重要。第一个列出了表标题<th>,就是这个:

<% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
Run Code Online (Sandbox Code Playgroud)

第二个列出了每条记录的数据列<td>,如下所示:

<% collection_presenter.attributes_for(resource).each do |attribute| %>
Run Code Online (Sandbox Code Playgroud)

该链接指向管理用来呈现集合的模板。这可以是索引页,也可以是 HasMany 字段中的记录列表。在上面的每一行中,它都会迭代为仪表板定义的集合属性(由collection_presenter.attribute_types和返回collection_presenter.attributes_for(...),具体取决于具体情况)。

为了达到您想要的效果,您需要在渲染索引页或渲染 HasMany 列表时使这些列表不同。目前,HasMany 字段没有选项来指示此列表的情况必须有所不同。

幸运的是,我们可以在这里一起破解一些东西。

首先,:complete从 中删除CourseDashboard::COLLECTION_ATTRIBUTES。您不希望它在索引页中列出,因此它不应该出现在那里。不要将其从 中删除CourseDashboard::ATTRIBUTE_TYPES,因为我们仍然需要定义它,以便我们可以在其他地方使用它。

二是开辟新领域。我将称之为CustomHasMany,但它可以是任何东西:

$ ./bin/rails g administrate:field custom_has_many
      create  app/fields/custom_has_many_field.rb
      create  app/views/fields/custom_has_many_field/_show.html.erb
      create  app/views/fields/custom_has_many_field/_index.html.erb
      create  app/views/fields/custom_has_many_field/_form.html.erb
Run Code Online (Sandbox Code Playgroud)

我们将courses在以下位置使用此字段作为您的属性UserDashboard

<% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
Run Code Online (Sandbox Code Playgroud)

这最初是行不通的,因为这个领域是新的。它需要的第一件事是复制现有HasMany字段的行为。我们可以通过类继承来做到这一点:

<% collection_presenter.attributes_for(resource).each do |attribute| %>
Run Code Online (Sandbox Code Playgroud)

这不会完全模仿该HasMany字段,因为它使用生成器提供的基本模板。让我们告诉它使用has_many模板:

$ ./bin/rails g administrate:field custom_has_many
      create  app/fields/custom_has_many_field.rb
      create  app/views/fields/custom_has_many_field/_show.html.erb
      create  app/views/fields/custom_has_many_field/_index.html.erb
      create  app/views/fields/custom_has_many_field/_form.html.erb
Run Code Online (Sandbox Code Playgroud)

好的,现在它应该与字段相同HasMany。到目前为止,这一直在使用公共接口和“官方”管理内容。我不得不承认这to_partial_path没有很好的记录,但我认为它足够稳定。

所以现在我们必须告诉它添加complete到字段列表中......这就是黑客发挥作用的地方。

如果你阅读了Administrate的源码,你会发现collection_presenter上面的内容是由上层模板提供的。反过来,它被定义为field.associated_collection(order),其中field是字段对象,在我们的例子中是 的实例CustomHasManyField

因此,如果我们可以破解CustomHasManyField#associated_collection返回一个集合,其中attribute_typesattributes_for包含:complete...我们应该没问题吗?

查看集合的代码,我们可以看到两个列表依次基于另一个方法的结果attribute_names,这是应呈现哪些属性的真相来源: https: //github.com/thoughtbot/administrate/ blob/c16b8d1ee3a5ef1d622f9470738e89d73dbb8f1b/lib/administrate/page/collection.rb如果我们修改这个attribute_names方法,其余的应该效仿。

猴子补丁来救援:

require "administrate/base_dashboard"

class UserDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    # ...
    courses: CustomHasManyField
    # ...
  }

Run Code Online (Sandbox Code Playgroud)

看起来它在我的电脑上有效。对你起作用吗?

至于以更正式的方式执行此操作...您想为该项目创建 PR 吗?