Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
38
Help us understand the problem. What is going on with this article?
@Esfahan

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

概要

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

参考

38
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Esfahan
WEB系出身。現在はビッグデータの基盤構築、ETLなどがメイン。 / YouTubeで料理チャンネルやってます → https://www.youtube.com/channel/UCDnYBh2TtUAfQ0Z-tl0jTyw / ゲームもやってます -> https://www.youtube.com/channel/UCeqPhExV09EF5o8lZLO15Eg

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
38
Help us understand the problem. What is going on with this article?