Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/simple-and-powerful/act-form
The simple way to create form objects or command/service objects with ActiveModel
https://github.com/simple-and-powerful/act-form
activemodel command-object form-model form-object rails ruby service-object validation
Last synced: about 22 hours ago
JSON representation
The simple way to create form objects or command/service objects with ActiveModel
- Host: GitHub
- URL: https://github.com/simple-and-powerful/act-form
- Owner: simple-and-powerful
- License: mit
- Created: 2016-12-13T08:30:09.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-06-25T11:01:22.000Z (3 months ago)
- Last Synced: 2024-09-26T05:58:01.306Z (7 days ago)
- Topics: activemodel, command-object, form-model, form-object, rails, ruby, service-object, validation
- Language: Ruby
- Homepage: https://github.com/simple-and-powerful/act-form
- Size: 56.6 KB
- Stars: 31
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# ActForm
ActForm is the gem that provide a simple way to create `form object` or `command object` or `service object`, it only depends on `activemodel >= 5` and provides few api.
## About v0.5.0
With the power of `dry-schema`, ActForm now can support all the features of `dry-schema`, like:
```ruby
class UserForm < ActForm::Base
params do
required(:name).filled.desc('Name')
optional(:age).value(:integer).desc('Age')
optional(:address).desc('Address')
optional(:nickname).default('nick').desc('Nick')
# below will support in the future
# attribute :desc, default: ->{ 'desc' }
end
end
```Add we can integrate with `grape` easyly.
```ruby
module WorkWithGrapeSpec
class API < Grape::API
format :jsoncontract UserForm.contract
get '/foo' do
'hello world'
endcontract UserForm.contract do
required(:desc).filled
end
get '/bar' do
'hello world'
end
end
end
```## Usage
#### API - `attribute`
```ruby
class UserForm < ActForm::Base
attribute :name, required: true
attribute :age, type: :integer
attribute :address
attribute :nickname, default: 'nick'
attribute :desc, default: ->{ 'desc' }
endform = UserForm.new(name: 'su', age: '18', address: 'somewhere')
form.name # => 'su'
form.age # => 18
form.address # => 'somewhere'
form.nickname # => 'nick'
form.desc # => 'desc'
# override default
form.nickname = 'hello'
form.nickname # => 'hello'# required
form = UserForm.new(age: '18', address: 'somewhere')
form.valid? # => false
form.errors.full_messages # => ["Name require a value"]
```#### Difference between `required` and `validates_presence_of`
`required` will run before the validation, and it will cancel other validations if return false.### form object
#### API - `valid?`
Compliant with the active model api
```ruby
class PhoneForm < ActForm::Base
attribute :phone
validates_format_of :phone, with: /\A\d{11}\z/i
endform = PhoneForm.new
form.valid? # => false
form.errors.full_messages # => ["Phone is invalid"]PhoneForm.new(phone: '12345678901').valid? # => true
```#### API - `sync`
sync only copy attributes to target, will not trigger validate
```ruby
target = Class.new do
attr_accessor :phone
end.newform = PhoneForm.new(phone: '12345678901')
form.sync(target)
target.phone # => '12345678901'
```#### API - `save`
sync to the target and call the save method when passed the validation
```ruby
target = Class.new do
attr_accessor :phone
attr_reader :saved
def save
@saved = true
end
end.newform = PhoneForm.new(phone: '12345678901')
form.save(target) # same as form.sync(target) and target.save
target.phone # => '12345678901'
target.saved # => true
form.persisted? # => true
```#### API - `init_by`
`init_by` will copy attributes form target to the form, and set default target.
```ruby
target = Class.new do
attr_accessor :phone
attr_reader :saved
def save
@saved = true
end
end.newtarget.phone = '12345678901'
form = PhoneForm.new
form.init_by(target)
form.phone # => '12345678901'
form.save # => true
target.saved # => true
```#### API - `combine`
form can combine to other forms
```ruby
class PhoneForm < ActForm::Base
attribute :phone
validates_format_of :phone, with: /\A\d{11}\z/i
endclass EmailForm < ActForm::Base
attribute :email
validate :check_email
def check_email
errors.add(:email, :blank) if email.blank?
end
endclass UserForm < ActForm::Base
combine PhoneForm, EmailForm
endclass AdminForm < ActForm::Base
combine PhoneForm
enduser_form = UserForm.new
user_form.valid?
user_form.errors.full_messages # => ["Phone is invalid", "Email can't be blank"]
UserForm.new(phone: '12345678901', email: '1').valid? # => true
admin_form = AdminForm.new
admin_form.valid?
admin_form.errors.full_messages # => ["Phone is invalid"]
AdminForm.new(phone: '12345678901').valid? # => true
```### command/service object
Command object almost like form object. Command object can't init by `new`, and it has some new features.
#### API - `perform`, `run`, `success?`, `failure?`, `setup`
command object must respond to `perform` method.
```ruby
class CreateUserCommand < ActForm::Command
combine UserForm# Do some pre-inialize actions.
setup do
@name = 'foo'
end
def perform
attributes[:name] = @name
User.create(attributes)
end
endCreateUserCommand.new
# => NoMethodError: private method `new' called for CreateUserCommand:Classcommand = CreateUserCommand.run(phone: '12345678901')
if command.success?
@user = command.result
# do something...
else
command.errors.full_messages # => ["Email can't be blank"]
# do something...
end
```
## InstallationAdd this line to your application's Gemfile:
```ruby
gem 'act_form'
```And then execute:
$ bundle
Or install it yourself as:
$ gem install act_form
## Development
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
### Unit Tests
$ bundle exec rake test
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/simple-and-powerful/act_form. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).