Last active
October 16, 2023 16:25
-
-
Save naofumi/cb885a8ec2731489652f3af0bf89c2c4 to your computer and use it in GitHub Desktop.
Delegation-based implementation of Rails FormObjects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AdminUsers::RegistrationForm | |
include ActiveModel::Model | |
attr_accessor :object | |
validates :first_name, :last_name, :email, presence: true | |
delegate :first_name, :first_name=, | |
:last_name, :last_name=, | |
:email, :email=, | |
:password, :password=, | |
:persisted?, to: :object | |
def initialize(params, object = AdminUser.new) | |
@object = object | |
assign_attributes(params) | |
end | |
def save | |
valid? && object.save | |
end | |
end | |
# Tests | |
require 'rails_helper' | |
RSpec.describe 'RegistrationForm', type: :model do | |
context 'if admin_user is not persisted' do | |
let(:params) { { first_name: 'firsty', last_name: 'lasty', email: '[email protected]', password: 'foo2#passwo' } } | |
it 'saves if valid' do | |
@form = AdminUsers::RegistrationForm.new(params) | |
expect { @form.save }.to change(AdminUser, :count).by(1) | |
end | |
it 'fails to save if invalid' do | |
form = AdminUsers::RegistrationForm.new(params.except(:first_name)) | |
expect { form.save }.not_to change(AdminUser, :count) | |
expect(form.errors.full_messages).to include 'First nameを入力してください' | |
end | |
end | |
context 'if admin_user is persisted' do | |
let(:admin_user) { create(:admin_user, first_name: 'old_name') } | |
let(:params) { { first_name: 'updated_name' } } | |
it 'saves if valid' do | |
expect do | |
form = AdminUsers::RegistrationForm.new(params, admin_user) | |
form.save | |
end.to change { admin_user.reload.first_name }.from('old_name').to('updated_name') | |
end | |
it 'fails to save if invalid' do | |
form = nil | |
expect do | |
form = AdminUsers::RegistrationForm.new(params.merge(first_name: ''), admin_user) | |
form.save | |
end.not_to change { admin_user.reload.first_name }.from('old_name') | |
expect(form.errors.full_messages).to include 'First Nameを入力してください' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment