module CRUDServices
extend ActiveSupport::Concern
included do
def find(klass, args = {})
run_service(
klass,
"Find",
FindRecordService,
args.merge(record_class: klass),
)
end
def find_all(klass, args = {})
args.reverse_merge!(no_filters: true)
run_service(
klass,
"FindAll",
FindAllRecordsService,
args.merge(record_class: klass),
plural_output: true,
)
end
def create(klass, attributes = {}, args = {})
run_service(
klass,
"Create",
CreateRecordService,
args.merge(record_class: klass, attributes:),
)
end
def create!(klass, attributes = {}, args = {})
create(klass, attributes, args.merge(raise_on_error: true))
end
def update(record, attributes = {}, args = {})
run_service(
record.class,
"Update",
UpdateRecordService,
args.merge(record:, attributes:),
)
end
def update!(record, attributes = {}, args = {})
update(record, attributes, args.merge(raise_on_error: true))
end
def destroy(record, args = {})
run_service(
record.class,
"Destroy",
DestroyRecordService,
args.merge(record:),
)
end
def destroy!(record, args = {})
destroy(record, args.merge(raise_on_error: true))
end
def create_or_update!(klass, record, attributes = {}, args = {})
if record
update!(record, attributes, args)
else
create!(klass, attributes, args)
end
end
private
def resource_name(klass, plural: false)
name = klass.name.demodulize.underscore
plural ? name.pluralize : name
end
def run_service(klass, class_postfix, default_class, args, opts = {})
begin
service_class = "#{klass}::#{class_postfix}".constantize
rescue NameError
service_class = default_class
end
service_class
.with(self)
.run(args)
.public_send(resource_name(klass, plural: opts[:plural_output]))
end
end
end