A reminder of how to get the enum value saved in the DB in Rails with attribute_before_type_cast
https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html
https://railsdoc.com/page/options_for_select
https://310nae.com/rails-selectbox/
https://qiita.com/ozackiee/items/17b91e26fad58e147f2e
https://ja.stackoverflow.com/questions/72551/enum-でセレクトボックスを表示させてインデックス番号をdb-に保存したい
Please note that when using enum, the value looks different on Rails and the value saved in DB.
Rails enum is implemented so that it can be handled transparently as a character string (or symbol) in the code notation.
As you can see by hitting SQL directly or looking at the record information saved using the DB GUI client, the number is actually saved instead of the string.
Reference URL: <https://ja.stackoverflow.com/questions/72551/enum-%e3%81%a7%e3%82%bb%e3%83%ac%e3%82%af%e3%83%88 % e3% 83% 9c% e3% 83% 83% e3% 82% af% e3% 82% b9% e3% 82% 92% e8% a1% a8% e7% a4% ba% e3% 81% 95% e3 % 81% 9b% e3% 81% a6% e3% 82% a4% e3% 83% b3% e3% 83% 87% e3% 83% 83% e3% 82% af% e3% 82% b9% e7% 95 % aa% e5% 8f% b7% e3% 82% 92db-% e3% 81% ab% e4% bf% 9d% e5% ad% 98% e3% 81% 97% e3% 81% 9f% e3% 81% 84>
The actual value defined by enum behaves as a name definition on Rails.
sample.rb
#blood type(blood_type)Enum definition
enum blood_type: {
Type A: 0,
B type: 1,
O type: 2,
AB type: 3,
#Name definition on Rails:Actual value stored in DB
}
Check the operation based on the following assumptions
schema.rb
#Name column in Parson model, blood_Create type column
create_table "persons", force: :cascade do |t|
t.string "name"
t.integer "blood_type"
end
parson.rb
#blood on model_define type with enum
class Person < ApplicationRecord
enum blood_type: {
Type A: 0,
B type: 1,
O type: 2,
AB type: 3,
}
end
Check the operation of attribite_before_type_cast
using rails console
$ rails console
> person = Person.create(name: "Alice", blood_type: 0) #Create person object,DB save
:name => "Alice"
:blood_type => "Type A"
> person.blood_type #Get the value on rails
"Type A"
> person.blood_type #Get the class of values on rails
String < Object
> person.blood_type_before_type_cast #Get the value of DB
0
> person.blood_type_before_type_cast #Get the class of DB values
Integer < Numeric
attributes
: Instance method that can get attribute name => value
for instance
attributes_before_type_cast
: Before version of attributes. Instance method that can get the actual value on the DB in the form of attribute name => value
Use rails console
to see the difference in behavior between attributes
and attributes_before_type_cast
$ rails console
> person = Person.create(name: "Alice", blood_type: 0) #Create person object,DB save
:name => "Alice"
:blood_type => "Type A"
> person.attributes #Show name definitions on rails
"name" => "Alice"
"blood_type" => "Type A"
> person.attributes_type_before_type_cast #Display the actual value of DB
"name" => "Alice"
"blood_type" => 0
In my case I used it to generate a new post form from the value defined in the enum
#HTML you want to output
<select>
<option value="1">type1</option>
<option value="2">type2</option>
<option value="3">type3</option>
</select>
person.rb
# blood_define type with enum
class Person < ApplicationRecord
enum blood_type: {
Type A: 0,
B type: 1,
O type: 2,
AB type: 3,
}
end
persons_controller.rb
#Create person object
def new
@person = Person.new
end
I am using the value obtained by attirbute_before_type_cast
to set the default value (selected: value)
Ruby:new.html.erb
#Form generation from enum value
<%= form_with model: @person local: true do |f| %>
<%= f.select :blood_type, options_for_select(Person.blood_types, @person.expense_before_type_cast), {} %>
<%= f.submit %>
<% end %>
#Each value at the time of form generation
<%= form_with model: @Model name do|f| %>
<%= f.select :Column name, options_for_select(Model name.Column name複数形, @Model name.Column name_before_type_cast), {} %>
<%= f.submit %>
<% end %>
** There is a caveat in the empty brackets ({}) in the select tag **
Be sure to set the empty parentheses {}, in the option part even if you do not set the normal option. Without this empty brace, the HTML options would be ignored, so setting id/class doesn't work! It will be that.
Reference URL: https://310nae.com/rails-selectbox/
# options_for_select syntax
options_for_select(Array or hash of elements,Default value, {option}, {htmloption})
include_blank: true
(empty the first line)selected: default_value
id: id_name
(give id)class: class_name
(grant class)attribute_before_type_cast
or attributes_before_type_cast
to get the actual value saved in the DB when using enumI've never used enums and I was really into it when creating a portfolio, so it was a good study! If you make a mistake, please comment!
Recommended Posts