很遗憾,Administrate 不支持此功能。然而,使用一点 Ruby 技巧是可能的。这是非官方的,确切的实现可能会随着新版本的管理而改变。它应该适用于 Administrate 0.15,可能还有其他版本。
关键是Administrate代码中的这个模板: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| %>
第二个列出每条记录的数据列<td>,看起来像这样:
<% collection_presenter.attributes_for(resource).each do |attribute| %>
该链接指向 Administrate 用于呈现集合的模板。这可以是索引页,也可以是 HasMany 字段中的记录列表。在上面的每一行中,它遍历为仪表板定义的集合属性,由collection_presenter.attribute_types 和collection_presenter.attributes_for(...) 返回,具体取决于具体情况。
为了达到您想要的效果,您需要在渲染索引页面或渲染 HasMany 列表时使这些列表不同。目前,HasMany 字段没有选项来规定此列表在他们的情况下必须有所不同。
幸运的是,我们可以在这里一起破解一些东西。
首先,从CourseDashboard::COLLECTION_ATTRIBUTES 中删除:complete。您不希望它在索引页中列出,因此它不应该出现在那里。 不要将其从 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
我们将在UserDashboard 中将此字段用于您的courses 属性:
require "administrate/base_dashboard"
class UserDashboard < Administrate::BaseDashboard
ATTRIBUTE_TYPES = {
# ...
courses: CustomHasManyField
# ...
}
这最初是行不通的,因为该字段是新的。它需要的第一件事是复制现有HasMany 字段的行为。我们可以通过类继承来做到这一点:
class CustomHasManyField < Administrate::Field::HasMany
end
这不会完全模仿HasMany 字段,因为它使用的是生成器提供的基本模板。让我们告诉它改用has_many 模板:
class CustomHasManyField < Administrate::Field::HasMany
def to_partial_path
"/fields/has_many/#{page}"
end
end
好的,现在它应该与HasMany 字段相同。到目前为止,这一直是使用公共接口和“官方”管理的东西。我不得不承认to_partial_path 没有很好的文档记录,但我认为它足够稳定。
所以现在我们必须告诉它将complete 添加到字段列表中......这就是黑客发挥作用的地方。
如果你阅读了Administrate的源码,你会发现上面的collection_presenter是由上层模板提供的。反过来,这被定义为field.associated_collection(order),其中field 是字段对象,在我们的例子中是CustomHasManyField 的一个实例。
所以如果我们可以破解CustomHasManyField#associated_collection 以返回一个集合,其中attribute_types 和attributes_for 包含:complete... 我们应该没问题?
查看集合的代码,我们可以看到两个列表依次基于另一个方法的结果attribute_names,这就是应该呈现哪些属性的真相来源:https://github.com/thoughtbot/administrate/blob/c16b8d1ee3a5ef1d622f9470738e89d73dbb8f1b/lib/administrate/page/collection.rb 如果我们修改这个attribute_names 方法,其余的都应该效仿。
猴子补丁来救援:
class CustomHasManyField < Administrate::Field::HasMany
def associated_collection(*)
collection = super
def collection.attribute_names
[:complete] + super
end
collection
end
def to_partial_path
"/fields/has_many/#{page}"
end
end
看起来它可以在我的电脑上运行。对你有用吗?
至于以更正式的方式来做这件事……你想为这个项目创建一个 PR 吗?