administrate icon indicating copy to clipboard operation
administrate copied to clipboard

Enums - Select tag dont keep saved option selected on edit page

Open DavidGeismarLtd opened this issue 3 years ago • 2 comments

  • What were you trying to do? create a select form an enum field. In my model Program : enum publication_status: { 'publié' => 'published', 'a venir' => 'upcoming', 'brouillon' => 'draft' }, _prefix: :publication_status Keys are the "human" readable values, values are the value to be stored in db

In my administrate dashboard :

      ATTRIBUTE_TYPES = {
        publication_status: Field::Select.with_options(collection: Program.publication_statuses)
    }

This generates the following html :

<select name="program[publication_status]" id="program_publication_status"><option value="published">publié</option>
<option value="upcoming">a venir</option>
<option value="draft">brouillon</option></select>

However when I then update the resource and go back on the edit page the saved value is not the option selected, instead it is always the first one.

Am I not following the right approach for using enums with administrate or is this a bug ?

  • What did you end up with (logs, or, even better, example apps are great!)?
  • What versions are you running?
    • Rails 6.0.3
    • administrate 0.15.0

DavidGeismarLtd avatar Mar 09 '21 19:03 DavidGeismarLtd

Hm, this might be a bug, but I'm not sure. I wonder if it's something that we specifically do not support, for some reason.

I noticed that there's a plugin to support enums: https://github.com/Valiot/administrate-field-enum, however I haven't tried it, so I don't know if it would solve your problem.

Perhaps this should be supported by Administrate? I'm not sure. It might be tricky for some reason. If you want to give it a try and provide a PR, we could have a look at it.

pablobm avatar Mar 25 '21 17:03 pablobm

There's nothing special about an enum from the perspective of a select element. The enum values are simply the options available to choose from.

The thing is enums are usually stored in the database as integers, so @DavidGeismarLtd's enum definition appears to be atypical and either incorrect or possibly using a gem that allows string-based enums. I'd expect to see this instead:

{ 'publié': 0, 'a venir': 1, 'brouillon': 2 }

I didn't try to replicate this, so just taking a guess based on normal enum usage. If a value is actually getting saved (which can't be seen here so is not a certainty), it's probably being saved as 0 1 or 2 in the database. Any saved data associated with this field would not match the values being passed in, hence nothing will ever show up preselected.

AFlowOfCode avatar Mar 26 '21 22:03 AFlowOfCode

I was able to reproduce this today. The issue stems from how ActiveRecord works with enums, which can be a bit too clever depending on your taste.

So far, our Select field has assumed that if you did program.publication_status, you would get the "low-level value" so to speak, in your case it would be something like "published". This would be typical if you handle these values manually.

However if you use enums you get an abstraction layer such that your code never has to see the low-level values. Instead program.publication_status gives you "publié", which is the opposite behaviour.

Fortunately there is a way to detect when a field is actually an enum, so I'm hoping I can use this in order to do the right thing in the enum case. I have put something together that seems to work: https://github.com/thoughtbot/administrate/pull/2348

pablobm avatar Apr 06 '23 19:04 pablobm

A fix for this is ready for review at https://github.com/thoughtbot/administrate/pull/2348

pablobm avatar Apr 13 '23 13:04 pablobm