Administrate: Separate list of attributes for edit and new forms

Created on 30 Jan 2016  路  15Comments  路  Source: thoughtbot/administrate

It would be great if there is the ability to define list of attributes for new and edit forms separately.

feature fields views-and-styles

All 15 comments

I'm currently running into some issues with this as well. Has anyone discovered how to have separate attributes display for each of these forms?

@abousamra and @mbburch - at the moment, the best way to do this is to generate and customize separate view templates for the new and edit pages.

More specifically, this looks like:

rails generate administrate:views:new MyModelName
rails generate administrate:views:edit MyModelName

These generators will copy the templates that Administrate uses into your project. After that, you'll be free to customize those templates to contain any fields you'd like.

For the future, what kind of API would you like to see that would let you more easily customize new vs edit forms?

Thanks. It seems like there could also be an option to separate those two forms in the dashboard.

Agree with @mbburch. Generating views make more sense in case of adding any views customizations. In our case here I just want to specify which attributes can be edited and which can be viewed and that will be simpler via dashboard.

While not directly related, this would have some overlap with https://github.com/thoughtbot/administrate/issues/460. It seems like we might need to change the syntax for specifying dashboard attributes.

Yeah, your proposal there is exactly what I mean. I think you can close this one in behave of the other.

Great, thanks! I'll leave this open, because we'll probably make that change in two steps. One PR for the new attribute syntax, and one for separating new and edit.

Closing because:

  1. This has been quiet for a long time.
  2. I have closed the related issue https://github.com/thoughtbot/administrate/issues/460

If someone is willing to work on this, I'll be happy to provide guidance and review.

@pablobm I'm willing to throw a PR together to address this if you feel it would be a welcomed addition.

Initially I'm thinking to create a [new, create]/[edit, update]_attributes, similar to the show_page/collection_attributes ones here: https://github.com/thoughtbot/administrate/blob/a4dcaf339989c14498a921d9a1dc40ac84576d1a/lib/administrate/base_dashboard.rb#L63-L65

The new attributes would look for their corresponding NEW/EDIT_FORM_ATTRIBUTES constant, or fallback to FORM_ATTRIBUTES if not set.

I could then check the resource is persisted, and use the corresponding attributes here: https://github.com/thoughtbot/administrate/blob/master/lib/administrate/page/form.rb#L13-L17

Open to other suggestions as well!

@omarvelous - That sounds like a good idea to me. Go for it!

@pablobm while we are on the subject of refactoring these dashboard attribute collections, one thing I've been wondering is, how do we do encapsulation or DRYing up code?

In ActiveRecord it's possible to have separate statements for the different attributes:

validates :title, presence: true
validates :slug, presence: true

Mobility translations are defined similarly:

translates :title
translates :slug
translates :content, type: :text

This allows to extract validates :slug, presence: true and translates :slug to a separate Sluggable concern.

But in Administrate everything is defined in collections:

  ATTRIBUTE_TYPES = {
    title: Field::String,
    slug: Field::String,
  }
  COLLECTION_ATTRIBUTES = %i[
  title
  ]
  SHOW_PAGE_ATTRIBUTES = %i[
  title
  slug
  ]

It would be great to be able to rewrite the above with something like:

attribute :title, Field::String
attribute :slug, Field::String, only: %i(show)

Currently my dashboards have a lot of repetitions between them. Besides being arguably closer to Rails semantics, the above would allow splitting out different aspects in different classes/concerns. The only syntax would also remove the repetitions (title appearing 1x instead of 3x).

In my opinion, the issue with macros such as the proposed attribute is that they enter the territory of DSLs, which Administrate tries to avoid by principle.

Having said that, I think it's still possible to implement separately, as a mixin. Something like this:

module AdministrateDashboardDsl
  extend ActiveSupport::Concern

  class_methods do
    def attribute(attr_name, field_type, opts = {})
      ATTRIBUTE_TYPES[attr_name.to_sym] = field_type.with_options(opts)
    end
  end
end

Which then can be extended to support options like :only that you propose.

Thoughts?

@pablobm I agree with the principle, actually before Administrate I tried RailsAdmin whose DSL I found problematic. But I still think the scenario I described is valid. I would prefer to avoid adding "hacks" on top of administrate though. Maybe Administrate could have just a bit of DSL in the dashboards, similar to what ActiveRecord does in controllers. The majority of the code would still be plain ruby classes and methods. Also one could argue that the ATTRIBUTE_TYPES, COLLECTION_ATTRIBUTES etc definitions are already arbitrary and DSL-like? Just some thoughts...

I understand that the constants we use in dashboards may look a bit like a DSL. In my view they are not because they are very explicit lists: they don't add anything to a hidden property somewhere; instead they are the exact place from where they are read by other code. With a DSL you'd have methods that add them to something else hidden from view.

Regarding adding a DSL like the one you propose, I understand it can be useful, and it can save some effort in situations like the one you propose. However, I fear that they add to Administrate's maintenance burden, while hiding from view details of how Administrate works (useful for potential contributors).

I'm not really 100% against it, but I think it's something that first should be experimented with, and I feel it's definitely not a priority before v1.0 (which I have to admit is not clear when it will come; it's just that there are other priorities). A third-party gem implemented like I propose would be a great way to go about it.

By the way, I think third-party gems should be given a bit more publicity than they get currently. Perhaps as a section on the main README. This way, we'd get people actually trying them out, contributing to experiments, and generally shaping out the future of Administrate.

Also, you mention that my solution might be a "hack". I understand where you are coming from, but I have to disagree. What I propose is what a DSL would end up being in the end anyway. If anything, these experiments help us understand which sort of API hooks Administrate should be providing in order to encourage building on top of it.

Understood, let's leave the question aside for now. If it becomes really needed for me it will force me to try the approach you describe, which in turn would provide some feedback.

Was this page helpful?
0 / 5 - 0 ratings