Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
gemfile: [rails_5_2.gemfile, rails_6_0.gemfile, rails_6_1.gemfile, rails_7_0.gemfile, rails_7_1.gemfile, rails_7_2.gemfile, rails_8_0.gemfile, rails_main.gemfile]
gemfile: [rails_5_2.gemfile, rails_6_0.gemfile, rails_6_1.gemfile, rails_7_0.gemfile, rails_7_1.gemfile, rails_7_2.gemfile, rails_8_0.gemfile, rails_8_1.gemfile, rails_main.gemfile]
ruby_version: ['2.3', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4']
exclude:
- gemfile: rails_main.gemfile
Expand All @@ -29,6 +29,22 @@ jobs:
ruby_version: '3.0'
- gemfile: rails_main.gemfile
ruby_version: '3.1'
- gemfile: rails_main.gemfile
ruby_version: '3.2'
- gemfile: rails_8_1.gemfile
ruby_version: '2.3'
- gemfile: rails_8_1.gemfile
ruby_version: '2.4'
- gemfile: rails_8_1.gemfile
ruby_version: '2.5'
- gemfile: rails_8_1.gemfile
ruby_version: '2.6'
- gemfile: rails_8_1.gemfile
ruby_version: '2.7'
- gemfile: rails_8_1.gemfile
ruby_version: '3.0'
- gemfile: rails_8_1.gemfile
ruby_version: '3.1'
- gemfile: rails_8_0.gemfile
ruby_version: '2.3'
- gemfile: rails_8_0.gemfile
Expand Down Expand Up @@ -117,22 +133,9 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby_version }}
- name: Before build
run: |
sudo apt-get install libsqlite3-dev
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
env:
CC_TEST_REPORTER_ID: aff2c7b9e07e54d5fc9e5588d2e2a8bab4f69950d35000edc2b6250bbaba477d
- name: Run test
run: |
bundle update
bundle install --gemfile spec/gemfiles/${{ matrix.gemfile }} --jobs 4 --retry 3
bundle exec rake code_analysis
bundle exec rspec
- name: Report to CodeClimate
run: |
./cc-test-reporter after-build --exit-code 0
env:
CC_TEST_REPORTER_ID: aff2c7b9e07e54d5fc9e5588d2e2a8bab4f69950d35000edc2b6250bbaba477d
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ YAAF (Yet Another Active Form) is a gem that let you create form objects in an e
We were going to name this gem `ActiveForm` to follow Rails naming conventions but given there are a lot of form object gems named like that we preferred to go with `YAAF`.

![CI](https://github.com/rootstrap/yaaf/workflows/CI/badge.svg)
[![Maintainability](https://api.codeclimate.com/v1/badges/c3dea064e1003b700260/maintainability)](https://codeclimate.com/github/rootstrap/yaaf/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/c3dea064e1003b700260/test_coverage)](https://codeclimate.com/github/rootstrap/yaaf/test_coverage)

## Table of Contents

Expand All @@ -23,6 +21,7 @@ We were going to name this gem `ActiveForm` to follow Rails naming conventions b
- [#save!](#save!)
- [Validations](#validations)
- [Callbacks](#callbacks)
- [Normalizes](#normalizes)
- [Sample app](#sample-app)
- [Links](#links)
- [Development](#development)
Expand Down Expand Up @@ -249,6 +248,19 @@ Available callbacks are (listed in execution order):
- `after_save`
- `after_commit/after_rollback`

### Normalizes (Rails 8.1+)

`YAAF` form objects support `normalizes` the same way as `ActiveModel` models. For example:

```ruby
class RegistrationForm < YAAF::Form
normalizes :email, with: ->(email) { email.strip.downcase }
normalizes :name, with: ->(name) { name.strip.titleize }

# ...
end
```

## Sample app

You can find a sample app making use of the gem [here](https://yaaf-examples.herokuapp.com). Its code is also open source, and you can find it [here](https://github.com/rootstrap/yaaf-examples).
Expand Down
1 change: 0 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

task :code_analysis do
sh 'bundle exec rubocop lib spec'
sh 'bundle exec reek lib'
end
6 changes: 6 additions & 0 deletions lib/yaaf/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ class Form
include ::ActiveModel::Model
include ::ActiveModel::Validations::Callbacks
include ::ActiveRecord::Transactions

if defined?(::ActiveModel::Attributes::Normalization)
include ::ActiveModel::Attributes
include ::ActiveModel::Attributes::Normalization
end

define_model_callbacks :save

delegate :transaction, to: ::ActiveRecord::Base
Expand Down
5 changes: 5 additions & 0 deletions spec/gemfiles/rails_8_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source 'https://rubygems.org'

gemspec path: '../..'

gem 'rails', '~> 8.1.0'
1 change: 1 addition & 0 deletions spec/support/forms.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
require_relative 'forms/with_callback_exception_raising'
require_relative 'forms/custom_transaction_form'
require_relative 'forms/user_destroy_form'
require_relative 'forms/with_normalize_form'
19 changes: 19 additions & 0 deletions spec/support/forms/with_normalize_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class WithNormalizeForm < YAAF::Form
if defined?(ActiveModel::Attributes::Normalization)
attribute :email, :string
attribute :name, :string

normalizes :email, with: ->(email) { email.strip.downcase }
normalizes :name, with: ->(name) { name.strip.titleize }

def initialize(args)
super(args)

@models = [user]
end

def user
@user ||= User.new(email: email, name: name)
end
end
end
50 changes: 50 additions & 0 deletions spec/yaaf/normalization_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

RSpec.describe 'Form with normalization' do
if defined?(ActiveModel::Attributes::Normalization)
let(:form) { WithNormalizeForm.new(args) }
let(:args) { { email: ' TEST@Example.com ', name: ' john doe ' } }

describe 'attribute normalization' do
it 'normalizes email on assignment' do
expect(form.email).to eq('test@example.com')
end

it 'normalizes name on assignment' do
expect(form.name).to eq('John Doe')
end
end

describe '#save' do
subject { form.save }

it 'saves with normalized values' do
expect(subject).to be true
expect(User.last.email).to eq('test@example.com')
expect(User.last.name).to eq('John Doe')
end
end

describe '#valid?' do
it 'validates with normalized values' do
expect(form.valid?).to be true
end
end

context 'when updating attributes' do
it 'normalizes new values' do
form.email = ' test@example.com '
expect(form.email).to eq('test@example.com')
end
end

context 'with nil values' do
let(:args) { { email: nil, name: nil } }

it 'does not normalize nil by default' do
expect(form.email).to be_nil
expect(form.name).to be_nil
end
end
end
end
1 change: 0 additions & 1 deletion yaaf.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ Gem::Specification.new do |spec|

spec.add_development_dependency 'database_cleaner-active_record', '~> 2.1.0'
spec.add_development_dependency 'rake', '~> 13.0.1'
spec.add_development_dependency 'reek', '~> 5.6.0'
spec.add_development_dependency 'rspec', '~> 3.9.0'
spec.add_development_dependency 'rubocop', '~> 0.80.0'
spec.add_development_dependency 'simplecov', '~> 0.17.1'
Expand Down