no_picture

ActiveModelを利用してフォームを作成した時の型変換

対応するレコードがないフォームを使う場合、ActiveModelを使用することで、シンプルなビューを構築しつつ、処理はモデルにかけます。 しかし、ActiveModelのノウハウってあんまり落ちていません。 それなりに ActiveRecord に対する理解も必要で、難しいですね。 ハマったことなど共有していきたいと思います。 フォームからのデータは文字列ですが、ActiveRecord にはコラム自体には型があるため、型変換を自動的に行ってくれます。 これを無意識に使用していると ActiveModelではまります。 具体的には以下のテーブルがあったとします。 class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.integer :age t.boolean :is_person t.timestamps end end end 利用例を見てみましょう。 user = User.new(age: '20') user.age # => 20 user.age.class # => Fixnum user = User.new(is_person: "1") user.is_person # => true user.is_person.class # => TrueClass 文字列から作成しているけども、自動的に数値や、真偽値へと変換されています。 ActiveModel を使用する場合は以下のように実装しておくとよさそうです。 class User2 attr_reader :age, :is_person include ActiveRecord::ConnectionAdapters def initialize(attributes = {}) attributes.each do |key, value| send("#{key}=",value) end end def age=(age) @age = age.to_i end def is_person=(is_person) @is_person = Column.value_to_boolean(is_person) end end 代入する時に値を修正するのが インスタンス変数に直接アクセスした場合にも型が保証できて良いです。 「別に文字列でもいいよ。」なんてこともあると思いますが、 数値だとおもってうっかり使うと '20' * 3 -> '202020' となって欲しい 40とは大きく違います。 チェックボックスを利用すると "1" などなど、値として降ってきます。 特に 真偽値への変換ですが、とりあえずわからなかったので、自前でごまかしていたのですが、調べました。 ActiveRecord::ConnectionAdapters::Column にさままな型変換のメソッドが実装されています。 https://github.com/rails/rails/blob/v3.2.13/activerecord/lib/active_record/connection_adapters/column.rb その中の value_to_boolean を使用しました。 def value_to_boolean(value) if value.is_a?(String) && value.blank?