The following unit test code fails.
item_spec.rb
it 'Only half-width numbers can be saved' do
@item.price = '1000'
@item.valid?
expect(@item.errors.full_messages).to include('Price Half-width characters.')
end
When assigning the character string "1000" to the integer type item "price", Implicit type conversion was done and the price was assigned the number "0".
↓ Check how implicit type conversion is performed on the console ↓
irb(main):002:0> @item.price = '1000'
=> "1000"
irb(main):003:0> @item.price
=> 0
After substituting the character string "1000", the price value will be the numerical value "0".
This is due to a feature called "ActiveRecord Attributes API" added in Rails 5. Implicit type conversion is an image in which the following setter is moving behind the scenes. The point is to_i.
#Setter
def price=(price)
@price = price.to_i
end
Solved by writing the following in the Item model
item.rb
class Item < ApplicationRecord
attr_accessor :price
[Explanation] attr_accessor is a method that can realize setter / getter processing for items. The following description and "attr_accessor: price" have the same meaning.
#Setter
def price=(price)
@price = price
end
#Getter
def price
@price
end
That is, by calling a pure setter (not to_i) with this You will be able to assign a string that is not to_i to price.
irb(main):002:0> @item.price = '1000'
=> "1000"
irb(main):003:0> @item.price
=> "1000"
For the mechanism of "Active Record Attributes API", I referred to the following article. https://www.wantedly.com/companies/wantedly/post_articles/31132
Recommended Posts