LoginSignup
48
45

More than 3 years have passed since last update.

RailsでDBと連携しないModelを作成する

Last updated at Posted at 2016-12-10

概要

RailsのModelは、通常DBと結びついていないと使えないが、
データソースをDBではなく外部APIなどに変更し、
validation機能はそのまま使いたい。

ActiveModel::ModelをMixInしてvalidation機能を有効にし、
callbackでvalidateすることで実現する。

環境

  • rails 5.0.0.1
  • ruby 2.3.1

ソースコード例

ActiveModel::ModelをMixIn
これで通常のModelと同様にvalidate機能を利用できる。
自作validationも使えるようになる。

app/model/sample.rb
class Sample
  # MixIn
  include ActiveModel::Model

  attr_accessor :name, :email, :age

  # before_saveを使うための記述
  define_model_callbacks :save
  # callbackで実行するmethodを指定
  before_save :form_validation

  # validations
  validates :name, presence: true, strict: true
  # email: trueは自作validation
  validates :email, email: true, presence: true, strict: true
  validates :age, presence: true, strict: true

  # method例
  def all
    run_callbacks :save do
      'Your profile: #{name}, #{age}'
    end
  end

  # method例
  def find(id)
    run_callbacks :save do
      %Q(sample data: #{id})
    end
  end

  # callback用 validation
  private
  def form_validation
    self.valid?
    #unless self.valid?
    #  self.errors.add(:attribute, self.errors.full_messages, strict: true)
    #end
  end
end

rspec

RSpec.describe Sample, type: :model do
  describe 'Sample validation' do
    context 'with the all parameters' do
      subject { Sample.new(name: 'MyName', age: 17) }
      it "returns no error" do
        expect { subject.valid? }.not_to raise_error
      end
    end
    context 'without any parameter' do
      subject { Sample.new }
      it "returns StrictValidationFailed" do
        expect { subject.valid? }.to raise_error(ActiveModel::StrictValidationFailed)
      end
      it "returns StrictValidationFailed with message" do
        expect { subject.valid? }.to raise_error(ActiveModel::StrictValidationFailed, 'Name translation missing: ja.activemodel.errors.models.sample.attributes.name.blank')
      end
    end
    context 'with name without age' do
      subject { Sample.new(name: 'MyName') }
      it "returns StrictValidationFailed" do
        expect { subject.valid? }.to raise_error(ActiveModel::StrictValidationFailed)
      end
      it "returns StrictValidationFailed with message" do
        expect { subject.valid? }.to raise_error(ActiveModel::StrictValidationFailed, 'Age translation missing: ja.activemodel.errors.models.sample.attributes.age.blank')
      end
    end
  end
  describe 'Methods', type: :query do
    subject { Sample.new(name: 'MyName', age: 17) }
    describe 'all' do
      it 'returns text' do
        expect(subject.all).to eq('Your profile: MyName, 17')
      end
    end
  end
end

参考

48
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
45