port5432
port5432

Reputation: 6381

simple_form default collection if blank

In my simple form, I would like to refer to a collection, and have the following behaviour:

So far my code is this (also using simple_enum)

    <%= f.input :back_language, 
                collection: enum_option_pairs(Flashcard, :back_language), 
                label: false, 
                selected: current_user.fluent_language %>

How do I set a default value that doesn't overwrite the saved values ?

Upvotes: 0

Views: 685

Answers (2)

Petr Gazarov
Petr Gazarov

Reputation: 3821


EDIT:

Turns out Reform has an easy way to implement this. :)

When calling property in the form object, just pass in the default option.

property :back_language, default: model.fluent_language

Voila!


ORIGINAL ANSWER:

When using simple_form with reform, behind the hood the form object defines getters and setters when you call property. These methods get delegated to the model, but you can override them if you need to populate the form differently or manipulate form data before saving.

In your case, you would want to override the getter method for back_language.

In your template you will just have:

<%= f.input :back_language, 
            collection: enum_option_pairs(Flashcard, :back_language), 
            label: false %>

The form object will have:

model :user
property :back_language

def back_language
  # takes care of both new and edit actions
  super || model.fluent_language
end

ALTERNATIVELY

If you don't want to deal with form object, you could do this:

<%= f.input :back_language, 
            collection: enum_option_pairs(Flashcard, :back_language), 
            label: false, 
            selected: (@form.back_language || current_user.fluent_language) %>

But I don't advise to keep logic in your template.

Upvotes: 2

Alex
Alex

Reputation: 2518

You could try to just set the value of current_user.fluent_language if it's not present yet without saving it:

<% current_user.fluent_language ||= "you_default_value" %>
<%= f.input :back_language, 
            collection: enum_option_pairs(Flashcard, :back_language), 
            label: false, 
            selected: current_user.fluent_language %>

Edit: I'm not sure what your implementations of fluent_language and back_language like, but according to a comment a probably better solution would be somehting like this:

<% current_user.back_language ||= "you_default_value" %>
<%= f.input :back_language, 
            collection: enum_option_pairs(Flashcard, :back_language), 
            label: false %>

Upvotes: 2

Related Questions