Rails4 DB連携なしモデルでバリデーション機能を使う

More than 3 years have passed since last update.


Goal


  • RailsでActiveRecord機能モデルを使うときは、必ずバックエンドでDBと紐付いていなければならない

  • 今回は、たとえばCSVファイルのCRUDなどRails4でDB連携しないモデルを作成したい

  • RailsのActiveModelが搭載するvalidation機能・callback機能を使って、モデル呼び出し側が意識することなく自動でオブジェクトをチェックするエコシステムをつくりたい


Milestone


  • rails generate modelを実行するとDBと関連付けられてしまうため、これは使わない


    • ActiveRecordを継承したモデルが作成されてしまう、migrationファイルが作成されてしまう



  • モデルクラスを新規作成し、クラスにActiveModelモジュールをMixInさせることで、必要な機能だけをクラスに取り込むことができる(Rails3とRails4ではやりかたがけっこう違うらしい)

  • include ActiveModel::Modelによってvalidationが使えるようになる

  • (追記) ActiveModel::ModelをincludeしていればCallbacksはincludeしなくてもOKでした


    • // include ActiveModel::Callbacksによってコールバックが使えるようになる




Example


  • フォームを使ってアップロードされてきたcsvファイルをそのままサーバに保存するケース


app/models/csv.rb

class Csv

include ActiveModel::Model
#include ActiveModel::Callbacks

attr_accessor :operator_id, :type, :data_csv
define_model_callbacks :save

before_save {
self.valid?
}

validates :file_path, presence: true
validates :type, presence: true, numericality: true
validates :data_csv, presence: true

def save
run_callbacks :save do
@uploaded_file_str = self.data_csv.read
File.open(self.file_path, 'wb') do | new_file |
new_file.write(@uploaded_file_str)
end
end
end
end



ベーシックなクラスに機能をMixIn

class Csv

include ActiveModel::Model
#include ActiveModel::Callbacks


  • include ActiveModel::Modelによってvalidatesメソッドなどが有効に
    // include ActiveModel::Callbacksによってコールバック機能が有効になる

  • ActiveRecord継承のモデルでない場合、validatesメソッドに'on'を渡しても作動せず、またbefore_saveなどのメソッドがデフォルトで使えないので、コールバックを明示的に指定する

  • モデル呼び出し側で、model.valid?のようにバリデーションを実行したいだけならばコールバック機能を使う必要はない


コールバックを使ってValidation自動実行をつくる

Csvモデルに定義されたsaveメソッドにコールバックを設定する

define_model_callbacks定義をいれることで、デフォルトでは、before_save, around_save, after_saveが有効になる

define_model_callbacks :save

さらに、before_saveなどのイベントを発火させるためにsaveメソッドをrun_callbacksでラップする

def save

run_callbacks :save do
# save時に実行させたい実装
end
end

before_saveなどのタイミングで実行させたいロジックを実装する

ブロックでなくてもメソッドを指定してもいい

before_save {

self.valid?
}


References