I want to display the select box in enum and save the index number to DB.

Asked 2 years ago, Updated 2 years ago, 310 views

  • macOS 10.15.6
  • Ruby 2.5.7
  • Rails 5.2.3

[Rails] enum tutorial
[Rails] What is enum?Tried creating a select box using enum -Qiita
[Rails] Implementation of select boxes using enum and saving to DB - Qiita
[Rails] What kind of child is Enum?Can you use it?-Qiita
Modify the option tag generated by f.select -Qiita

#Select box shape you want to achieve
<select>
  <option value="1">type1</option>
  <option value="2">type2</option>
  <option value="3">type3</option>
</select>
#What DB save do you want to achieve?
{
    :name=>"name",
    —Integer type of the index number of the value value registered with expense=>1#enum
}

Cannot save DB with '1' is not a valid expense error (the first number is the index number corresponding to the value defined in enum)

#schema.rb
  create_table "destinations", force: :cascade do | t |
    t.string "name"
    t. integer "expense", default:0
  end
#controller
  def create
    @destination=current_user.destinations.build(destination_params)
    [email protected]
      flash[:success] = "Destination added!"
      redirect_to destination_path(@destination)
    else
      render 'destinations/new'
    end
  end

  private

  def destination_params
    param.require(:destination).permit(:name,:expense)
  end
#model
class Destination <ApplicationRecord

  enum expense: {
    "---": 0,
    type1:1,
    type2—2,
    type 3:3,
  }
end
#view
<%=form_with model:@destination|f|%>
  <%=f.label:expense%>
  <%=f.select:expense, options_for_select(Destination.expenses), {}%>
  <%=f.submit%>
<%end%>
#Output HTML
<select name="destination [expense]">
  <option value="0">---</option>
  <option value="1">type1</option>
  <option value="2">type2</option>
  <option value="3">type3</option>
</select>

'1' is not a valid expression, so I checked with binding.pry and expected the error to be caused by sending a value in String type to the column to be stored in Integer type

Check the type of #expense
[1] pry>destination_params [:expense]
"3"
[2] pry>destination_params[:expense].class
String <Object

Attempted to force the conversion of values stored in strong_parameters to Integer type with reference to the following

[Rails] Implementation of select boxes using enum and saving to DB - Qiita

#controller
# in strong_parameters:converting expense to Integer type
# Before Modification
  def destination_params
    param.require(:destination).permit(:name,:expense)
  end

# after modification
  def destination_params
    param.require(:destination).permit(:name).merge(expense:params[:destination][:expense].to_i)
  end
#—Verify that the expression is Integer type
[1] pry>destination_params [:expense]
Unpermitted parameter: :expense
3
[2] pry>destination_params[:expense].class
Unpermitted parameter: :expense
Integer <Numeric
  • I want to save the value (1,2,3) of the select box, but the value saved will be the value of the select box selection (type1, type2, type3)
  • In
  • schema.rb:Expense type should be Integer type, but it can be saved in DB
#—Check the value stored in the expense
[1] pry>destination=destination.first
{
   :name=>"name",
:expense=>"type1",# I want to save the value (1,2,3) of the select box here
}
[2] pry>destination.expense
"type1"
[3] cry>destination.expense.class
String <Object
# sent to controller @destination:check the value of expense
[1] pry>@destination.expense
"type1"
[2] pry>@destination.expense.class
String <Object
  • When will it be converted and saved to the (name definition: corresponding number) defined in enum?
  • Why can I save anything other than the type specified in schema.rb in DB?

I wrote it for a long time, so I'll wrap it up.

  • I want to display the select box with the values defined in enum
  • I want to store the index number of the value defined in enum as Integer type for the value stored in the select box selection

I would like to realize these two points.Thank you for your cooperation.

ruby-on-rails ruby database

2022-09-30 21:54

1 Answers

Rails enum is implemented to be transparent with strings (or symbols) in code notation

If you hit SQL directly or look at the record information stored using the GUI client in DB, it actually stores numbers, not strings.Above Rails, the value of 1 stored in DB is only displayed as type1

If you want Rails to see the actual saved value, you can check it by calling attribute_before_type_cast available when you define enum

>destination.expense_before_type_cast
=>1

Documentation: https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html

The following code has the same meaning and is substituted with the enum value type1.Save to save the number 1 to DB

>destination.expense=1
>destination.expense="type1"
>destination.expense=:type1

If you want to save the index of the select box, you can choose not to enum it.If you want the index value as it is, consider attribute_before_type_cast


2022-09-30 21:54

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.