2

It seems like a deceptively simple ask: is it possible to associate a human-friendly string with a machine-friendly state name in an event machine on Rails? I'm using AASM at the moment, but none of the event machine gems I've looked at seem to offer this.

I have weirdly-capitalized states, like "Sent to PE Review", which "flatten" to :sent_to_pe_review as a state symbol. I can't easily get back to a properly-cased label for display on the object in a view, or in a dropdown select on a form. It seems to me that there should be an option like label: "Sent to PE Review" on the definition of the state in the model, but I can't find any such reference.

I've resorted to creating a separate "status" field, and putting the appropriate string in it, depending on state, in a before_save callback. That fixes the view, but not the dropdown list in the form for jumping states. As I contemplate rigging up some sort of collection with state symbols and label strings, the whole thing is feeling very non-Rails-like, and I'm thinking I'm missing something simple. What's the "Rails way" to do this?

David Krider
  • 886
  • 12
  • 27
  • There is no built in way to get the proper case from a symbol...`some_symbol.to_s.humanize` is probably the best you can do. You could create a helper that identifies certain characters that need to be uppercased (through regular expressions) or create a yml file (or hash) that maps states with their human readable counterpart and use that in the view. – Mark Merritt Nov 14 '19 at 22:29

1 Answers1

1

I wound up creating a hash in the class to do the translation:

STATUS_HASH = [
  { state: "screening_in_process", label: "Screening In Process" },
  { state: "screenings_complete", label: "Screenings Complete" },
  ...
  { state: "work_complete", label: "Work Complete" },
  { state: "work_canceled", label: "Work Canceled" }
]

In the edit _form, I can use (with simple_form, and HAML):

= f.input :aasm_state, collection: Project::STATUS_HASH.map { |s| [s[:label], s[:state]] }

Turns out that this solves both problems. In the show view, I can use:

= Project::STATUS_HASH.find{ |s| s[:state] == @project.aasm_state }[:label]

And I've removed the need for storing a separate field on the record for this, and the callback to update it.

Maybe I should try to add support for a label into the AASM gem, but I guess it would, effectively, use the same sort of mechanism in the background.

David Krider
  • 886
  • 12
  • 27