I'm creating a Learning Management System. I've got Users enrolled in Courses. I'd like to show when a User has completed a course on the Users Show page. Like this:
If I add the complete Attribute in app/dashboards/course_dashboard.rb under COLLECTION_ATTRIBUTES, it shows in the Course Index page also, which I don't want:
How can I add this complete attribute to the user's course information on the User Show page (as in the first image) but not add it to the Course Index page (as in the second image)?


Unfortunately, Administrate doesn't support this out of the box. However it's possible with a little bit of Ruby trickery. This is unofficial and the exact implementation may change with new versions of Administrate. It should work with Administrate 0.15, and probably other versions.
The key is this template in Administrate's code: https://github.com/thoughtbot/administrate/blob/c16b8d1ee3a5ef1d622f9470738e89d73dbb8f1b/app/views/administrate/application/_collection.html.erb
There are two lines that are important here. The first one lists the table headers
<th>, and it is this one:The second one lists the data columns
<td>for each record, and it looks like this:The link is to the template that Administrate uses to render collections. This can be an index page, or a list of records in a HasMany field. In each of the lines above, it iterates through the collection attributes defined for the dashboard, as returned by
collection_presenter.attribute_typesandcollection_presenter.attributes_for(...), depending on the case.In order to achieve your desired effect, you need those lists to be different when rendering an index page or when rendering the HasMany list. Currently there isn't an option for HasMany fields to dictate that this list has to be any different in their case.
Fortunately we can hack something together here.
First, remove
:completefromCourseDashboard::COLLECTION_ATTRIBUTES. You don't want it listed in the index page, so it shouldn't appear there. Do not remove it fromCourseDashboard::ATTRIBUTE_TYPES, as we still need to define it so that we can use it elsewhere.Second, create a new field. I'm going to call it
CustomHasMany, but it could be anything:We'll use this field for your
coursesattribute inUserDashboard:This is not going to work initially, as the field is new. The first thing it needs is to copy the behaviour of the existing
HasManyfield. We can do this with class inheritance:This won't quite mimic the
HasManyfield because it's using the basic templates provided by the generator. Let's tell it to use thehas_manytemplates instead:OK, so now it should be the same as a
HasManyfield. So far this has been using public interfaces and "official" Administrate stuff. I have to admit thatto_partial_pathis not well documented, but I think it's stable enough.So now we have to tell it to add
completeto the list of fields... This is where the hack comes in play.If you read the source code of Administrate, you'll find that
collection_presenterabove is provided by the upper-level template. In turn this is defined asfield.associated_collection(order), wherefieldis the field object, which in our case is an instance ofCustomHasManyField.So if we can hack
CustomHasManyField#associated_collectionto return a collection whoseattribute_typesandattributes_forinclude:complete... we should be ok?Looking at the code for collections, we can see that both lists are in turn based on the result of another method
attribute_names, which is the source of truth as to which attributes should be rendered: https://github.com/thoughtbot/administrate/blob/c16b8d1ee3a5ef1d622f9470738e89d73dbb8f1b/lib/administrate/page/collection.rb If we modify thisattribute_namesmethod, the rest should follow suit.Monkeypatching to the rescue:
That looks like it works in my computer. Does it work for you?
As for doing this in a more official manner... Do you feel like creating a PR for the project?