Skip to content

Commit

Permalink
Migrate to Granite::Form (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
andriusch authored Nov 22, 2022
1 parent 48e7dc1 commit 927c94f
Show file tree
Hide file tree
Showing 16 changed files with 53 additions and 54 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source 'https://rubygems.org'
git_source(:toptal) { |repo| "https://github.com/#{repo}.git" }
git_source(:toptal) { |repo| "https://github.com/toptal/#{repo}.git" }

gemspec
10 changes: 5 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ BaseAction.with(performer: performer, custom: true)

### Attributes

The next step is defining action attributes. There are several types of them and they are provided by `active_data` gem:
The next step is defining action attributes. There are several types of them and they are provided by `granite-form` gem:

```ruby
class Action < Granite::Action
Expand All @@ -170,13 +170,13 @@ class Action < Granite::Action
end
```

For detailed information on the available types and usage examples, check out [ActiveData documentation](https://github.com/pyromaniac/active_data#attributes).
For detailed information on the available types and usage examples, check out [Granite::Form documentation](https://github.com/toptal/granite-form#attributes).

The attributes behave pretty much as they do with `ActiveData` objects, except for `represents`:
The attributes behave pretty much as they do with `Granite::Form` objects, except for `represents`:

#### Represents

In `ActiveData` objects, when a model attribute is exposed through `represents` and the AD object changes, the exposed attribute is updated right away, and Granite Actions update the represented attribute using `assign_data`.
In `Granite::Form` objects, when a model attribute is exposed through `represents` and the AD object changes, the exposed attribute is updated right away, and Granite Actions update the represented attribute using `assign_data`.

#### Assign_data

Expand Down Expand Up @@ -213,7 +213,7 @@ class CreateBook < Granite::Action
end
```

For more information on the associations available and usage examples, see [ActiveData documentation](https://github.com/pyromaniac/active_data#associations).
For more information on the associations available and usage examples, see [Granite::Form documentation](https://github.com/toptal/granite-form#associations).

### NestedActions

Expand Down
2 changes: 1 addition & 1 deletion granite.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.5'

s.add_runtime_dependency 'actionpack', '>= 5.1', '< 7.1'
s.add_runtime_dependency 'active_data', '~> 1.2.0'
s.add_runtime_dependency 'granite-form'
s.add_runtime_dependency 'activesupport', '>= 5.1', '< 7.1'
s.add_runtime_dependency 'memoist', '~> 0.16'
s.add_runtime_dependency 'ruby2_keywords', '~> 0.0.5'
Expand Down
2 changes: 1 addition & 1 deletion lib/granite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ def self.context
require 'granite/typecasters'
require 'granite/rails' if defined?(::Rails)

ActiveData.base_concern = Granite::Base
Granite::Form.base_concern = Granite::Base
6 changes: 3 additions & 3 deletions lib/granite/action.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'active_data'
require 'granite/form'
require 'active_record/errors'
require 'active_record/validations'
require 'active_support/callbacks'
Expand Down Expand Up @@ -27,7 +27,7 @@ def initialize(action)
end

# We are using a lot of stacked additional logic for `assign_attributes`
# At least, represented and nested attributes modules in ActiveData
# At least, represented and nested attributes modules in Granite::Form
# are having such a method redefiniions. Both are prepended to the
# Granite action, so we have to prepend our patch as well in order
# to put it above all other, so it will handle the attributes first.
Expand Down Expand Up @@ -55,7 +55,7 @@ def assign_attributes(attributes)
merge_errors(e.record.errors)
end

handle_exception ActiveData::ValidationError do |e|
handle_exception Granite::Form::ValidationError do |e|
merge_errors(e.model.errors)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/granite/action/subject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def assign_subject(args, attributes, reflection)

self.subject = args.first unless args.empty?
fail SubjectNotFoundError, self.class unless subject
rescue ActiveData::AssociationTypeMismatch
rescue Granite::Form::AssociationTypeMismatch
raise SubjectTypeMismatchError.new(self.class, args.first.class.name, reflection.klass)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/granite/action/transaction_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def trigger_after_commit_callbacks(callbacks)

def log_errors(errors)
errors.each do |error|
ActiveData.config.logger.error "Unhandled error in callback: #{error.inspect}\n#{error.backtrace.join("\n")}"
Granite::Form.config.logger.error "Unhandled error in callback: #{error.inspect}\n#{error.backtrace.join("\n")}"
end
end
end
Expand Down
20 changes: 10 additions & 10 deletions lib/granite/base.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
require 'active_data/model'
require 'active_data/model/primary'
require 'active_data/model/lifecycle'
require 'active_data/model/associations'
require 'granite/form/model'
require 'granite/form/model/primary'
require 'granite/form/model/lifecycle'
require 'granite/form/model/associations'

require 'granite/translations'
require 'granite/represents'
require 'granite/assign_data'

module Granite
# Base included in Granite::Action, but also used by ActiveData when building data objects (e.g. when using
# Base included in Granite::Action, but also used by Granite::Form when building data objects (e.g. when using
# embeds_many)
module Base
extend ActiveSupport::Concern

include ActiveSupport::Callbacks
include ActiveData::Model
include ActiveData::Model::Representation
include ActiveData::Model::Dirty
include ActiveData::Model::Associations
include ActiveData::Model::Primary
include Granite::Form::Model
include Granite::Form::Model::Representation
include Granite::Form::Model::Dirty
include Granite::Form::Model::Associations
include Granite::Form::Model::Primary
include ActiveModel::Validations::Callbacks

include Granite::Util
Expand Down
21 changes: 10 additions & 11 deletions lib/granite/represents/attribute.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module Granite
module Represents
class Attribute < ActiveData::Model::Attributes::Attribute
class Attribute < Granite::Form::Model::Attributes::Attribute
types = {}
types[ActiveRecord::Enum::EnumType] = String if defined?(ActiveRecord)
TYPES = types.freeze

delegate :writer, :reader, :reader_before_type_cast, to: :reflection

def initialize(*_args)
Expand All @@ -27,13 +26,13 @@ def typecast(value)
def type
return reflection.options[:type] if reflection.options[:type].present?

active_data_type || type_from_type_for_attribute || super
granite_form_type || type_from_type_for_attribute || super
end

def typecaster
@typecaster ||= begin
type_class = type.instance_of?(Class) ? type : type.class
@typecaster = ActiveData.typecaster(type_class.ancestors.grep(Class))
@typecaster = Granite::Form.typecaster(type_class.ancestors.grep(Class))
end
end

Expand Down Expand Up @@ -67,20 +66,20 @@ def set_default_value_before_type_cast
end
end

def active_data_type
return nil unless reference.is_a?(ActiveData::Model)
def granite_form_type
return nil unless reference.is_a?(Granite::Form::Model)

reference_attribute = reference.attribute(name)

return nil if reference_attribute.nil?

return Granite::Action::Types::Collection.new(reference_attribute.type) if [
ActiveData::Model::Attributes::ReferenceMany,
ActiveData::Model::Attributes::Collection,
ActiveData::Model::Attributes::Dictionary
Granite::Form::Model::Attributes::ReferenceMany,
Granite::Form::Model::Attributes::Collection,
Granite::Form::Model::Attributes::Dictionary
].any? { |klass| reference_attribute.is_a? klass }

reference_attribute.type # TODO: create `type_for_attribute` method inside of ActiveData
reference_attribute.type # TODO: create `type_for_attribute` method inside of Granite::Form
end

def type_from_type_for_attribute
Expand All @@ -103,7 +102,7 @@ def attribute_name
def convert_type_to_value_class(attribute_type)
return attribute_type.value_class if attribute_type.respond_to?(:value_class)

ActiveData::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord::TYPES[attribute_type.type&.to_sym]
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/granite/represents/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Granite
module Represents
class Reflection < ActiveData::Model::Attributes::Reflections::Represents
class Reflection < Granite::Form::Model::Attributes::Reflections::Represents
class << self
def build(target, generated_methods, name, *args, &block)
options = args.last
Expand Down
6 changes: 3 additions & 3 deletions lib/granite/typecasters.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'active_data'
require 'granite/form'

ActiveData.typecaster('Granite::Action::Types::Collection') do |value, attribute|
typecaster = ActiveData.typecaster(attribute.type.subtype)
Granite::Form.typecaster('Granite::Action::Types::Collection') do |value, attribute|
typecaster = Granite::Form.typecaster(attribute.type.subtype)
if value.respond_to? :transform_values
value.transform_values { |v| typecaster.call(v, attribute) }
elsif value.respond_to?(:map)
Expand Down
6 changes: 3 additions & 3 deletions spec/lib/granite/action/performing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def execute_perform!(*)
let(:action) { Action.new(user, login: 'Login', skills_attributes: [{name: ''}]) }

before do
allow(ActiveData.config.logger).to receive(:info)
allow(Granite::Form.config.logger).to receive(:info)
end

specify { expect(action.perform).to be(false) }
Expand Down Expand Up @@ -208,7 +208,7 @@ def execute_perform!(*)
let(:action) { Action.new(user, login: 'Login', skills_attributes: [{name: ''}]) }

before do
allow(ActiveData.config.logger).to receive(:info)
allow(Granite::Form.config.logger).to receive(:info)
end

specify do
Expand Down Expand Up @@ -321,7 +321,7 @@ def execute_perform!(*)
let(:action) { Action.new(user, login: 'Login', skills_attributes: [{name: ''}]) }

before do
allow(ActiveData.config.logger).to receive(:info)
allow(Granite::Form.config.logger).to receive(:info)
end

specify do
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/granite/action/transaction_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
it 'calls for every callback, fails with first callback error and logs others' do
expect(object_listener).to receive(:run_callbacks).with(:commit).ordered
expect(block_listener).to receive(:do_stuff).ordered
expect(ActiveData.config.logger).to receive(:error).with(/Unhandled.*RuntimeError.*callback failed second.*\n.*transaction_manager_spec.*/)
expect(Granite::Form.config.logger).to receive(:error).with(/Unhandled.*RuntimeError.*callback failed second.*\n.*transaction_manager_spec.*/)
expect { subject }.to raise_error 'callback failed first'
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/granite/action_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def execute_perform!(*)
describe 'active data' do
before do
stub_class 'DummyUser' do
include ActiveData::Model
include Granite::Form::Model
attribute :email, String
attribute :full_name, String

Expand Down Expand Up @@ -140,7 +140,7 @@ def execute_perform!(*)
subject { Action.new }

before do
allow(ActiveData.config.logger).to receive(:info)
allow(Granite::Form.config.logger).to receive(:info)
end

specify do
Expand Down
18 changes: 9 additions & 9 deletions spec/lib/granite/represents/attribute_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

before do
stub_class(:dummy_user) do
include ActiveData::Model
include Granite::Form::Model

attribute :sign_in_count, Integer, default: '1'
attribute :created_at, Time
Expand Down Expand Up @@ -171,8 +171,8 @@ def user
end

stub_class(:holder) do
include ActiveData::Model
include ActiveData::Model::Associations
include Granite::Form::Model
include Granite::Form::Model::Associations

references_many :users, class_name: 'User'
end
Expand All @@ -197,8 +197,8 @@ def holder

before do
stub_class(:holder) do
include ActiveData::Model
include ActiveData::Model::Associations
include Granite::Form::Model
include Granite::Form::Model::Associations

collection :users, String
end
Expand All @@ -223,8 +223,8 @@ def holder

before do
stub_class(:holder) do
include ActiveData::Model
include ActiveData::Model::Associations
include Granite::Form::Model
include Granite::Form::Model::Associations

dictionary :numbers, Float
end
Expand All @@ -244,7 +244,7 @@ def holder
end
end

it 'derrives type from attribute of ActiveData::Model' do
it 'derrives type from attribute of Granite::Form::Model' do
expect(subject.type).to eq Integer
end

Expand Down Expand Up @@ -294,7 +294,7 @@ def holder

describe '#typecaster' do
specify do
expect(subject.typecaster).to eq ActiveData.typecaster(Integer)
expect(subject.typecaster).to eq Granite::Form.typecaster(Integer)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/granite_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

describe '#authorize_action!' do
before do
allow(ActiveData.config.logger).to receive(:info)
allow(Granite::Form.config.logger).to receive(:info)
end

context 'without performer' do
Expand Down

0 comments on commit 927c94f

Please sign in to comment.