diff --git a/app/controllers/nonprofits/custom_field_masters_controller.rb b/app/controllers/nonprofits/custom_field_masters_controller.rb index 2f419382..505c8c17 100644 --- a/app/controllers/nonprofits/custom_field_masters_controller.rb +++ b/app/controllers/nonprofits/custom_field_masters_controller.rb @@ -5,7 +5,7 @@ module Nonprofits class CustomFieldMastersController < ApplicationController include Controllers::Nonprofit::Current - include Controllers::Nonprofit::Authorization + include Controllers::Nonprofit::Authorization before_action :authenticate_nonprofit_user! def index @@ -16,20 +16,24 @@ module Nonprofits end def create - json_saved CreateCustomFieldMaster.create(current_nonprofit, params[:custom_field_master]) + json_saved CreateCustomFieldMaster.create(current_nonprofit, custom_field_master_params[:custom_field_master]) end def destroy - custom_field_master = current_nonprofit.custom_field_masters.find(params[:id]) - custom_field_master.update_attribute(:deleted, true) - custom_field_master.custom_field_joins.destroy_all + current_custom_field_definition.discard! + current_custom_field_definition.custom_field_joins.destroy_all render json: {}, status: :ok end private def custom_field_master_params - params.require(:custom_field_master).permit(:nonprofit, :nonprofit_id, :name, :deleted, :created_at) + params.require(:custom_field_master).permit( :name) + end + + + def current_custom_field_definition + current_nonprofit.custom_field_masters.find(params[:id]) end end end diff --git a/app/models/custom_field_master.rb b/app/models/custom_field_master.rb index ca4d96b9..da3563a8 100644 --- a/app/models/custom_field_master.rb +++ b/app/models/custom_field_master.rb @@ -3,11 +3,8 @@ # License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later # Full license explanation at https://github.com/houdiniproject/houdini/blob/master/LICENSE class CustomFieldMaster < ApplicationRecord - # :nonprofit, - # :nonprofit_id, - # :name, - # :deleted, - # :created_at + include Model::Eventable + include Model::Jbuilder validates :name, presence: true validate :no_dupes, on: :create @@ -15,11 +12,48 @@ class CustomFieldMaster < ApplicationRecord belongs_to :nonprofit has_many :custom_field_joins, dependent: :destroy - scope :not_deleted, -> { where(deleted: [nil, false]) } + scope :not_deleted, -> { where(deleted: false) } + add_builder_expansion :nonprofit + + after_create_commit :publish_created + + # TODO replace with Discard gem + define_model_callbacks :discard + + after_discard :publish_delete + + # TODO replace with discard gem + def discard! + run_callbacks(:discard) do + self.deleted = true + save! + end + end + def no_dupes return self if nonprofit.nil? errors.add(:base, 'Duplicate custom field') if nonprofit.custom_field_masters.not_deleted.where(name: name).any? end + + + def to_builder(*expand) + init_builder(*expand) do |json| + json.(self, :id, :name, :deleted) + json.object 'custom_field_definition' + end + end + + +private + def publish_created + Houdini.event_publisher.announce(:custom_field_definition_created, to_event('custom_field_definition.created', :nonprofit).attributes!) + end + + def publish_delete + Houdini.event_publisher.announce(:custom_field_definition_deleted, to_event('custom_field_definition.deleted', :nonprofit).attributes!) + end + + end diff --git a/db/migrate/20210204172319_set_default_deleted_to_false_on_custom_field_definition.rb b/db/migrate/20210204172319_set_default_deleted_to_false_on_custom_field_definition.rb new file mode 100644 index 00000000..5e39117c --- /dev/null +++ b/db/migrate/20210204172319_set_default_deleted_to_false_on_custom_field_definition.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later +# Full license explanation at https://github.com/houdiniproject/houdini/blob/master/LICENSE +class SetDefaultDeletedToFalseOnCustomFieldDefinition < ActiveRecord::Migration[6.1] + def change + change_column_default :custom_field_masters, :deleted, from: nil, to: false + change_column_null :custom_field_masters, :deleted, false + end +end diff --git a/db/structure.sql b/db/structure.sql index cca40872..32275806 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -692,7 +692,7 @@ CREATE TABLE public.custom_field_masters ( id integer NOT NULL, name character varying(255), nonprofit_id integer, - deleted boolean, + deleted boolean DEFAULT false NOT NULL, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL ); @@ -4286,6 +4286,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20210122203303'), ('20210127193411'), ('20210128215402'), -('20210204174909'); +('20210204013426'), +('20210204172319'); diff --git a/docs/event_definitions/Nonprofit/CustomFieldDefinition.ts b/docs/event_definitions/Nonprofit/CustomFieldDefinition.ts new file mode 100644 index 00000000..184cf171 --- /dev/null +++ b/docs/event_definitions/Nonprofit/CustomFieldDefinition.ts @@ -0,0 +1,16 @@ +// License: LGPL-3.0-or-later + +import type { HoudiniEvent, HoudiniObject, IdType } from "../common"; +import type Nonprofit from '.'; + +export interface CustomFieldDefinition extends HoudiniObject { + deleted: boolean; + name: string; + nonprofit: IdType | Nonprofit; + object: 'custom_field_definition'; +} + + +export type CustomFieldDefinitionCreated = HoudiniEvent<'custom_field_definition.created', TagDefinition>; + +export type CustomFieldDefinitionDeleted = HoudiniEvent<'custom_field_definition.deleted', TagDefinition>; \ No newline at end of file diff --git a/spec/models/custom_field_master_spec.rb b/spec/models/custom_field_master_spec.rb new file mode 100644 index 00000000..c9559a5c --- /dev/null +++ b/spec/models/custom_field_master_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# License: AGPL-3.0-or-later WITH WTO-AP-3.0-or-later +# Full license explanation at https://github.com/houdiniproject/houdini/blob/master/LICENSE +require 'rails_helper' + +RSpec.describe CustomFieldMaster, type: :model do + include_context :shared_donation_charge_context + let(:name) { "CustomFieldDefinition1"} + + let(:custom_field_definition) { nonprofit.custom_field_masters.create(name: name) } + let(:np_builder_expanded) { { + 'id' => nonprofit.id, + 'name' => nonprofit.name, + 'object' => 'nonprofit' + }} + + it 'creates' do + expect(custom_field_definition.errors).to be_empty + end + + it 'announces create' do + expect(Houdini.event_publisher).to receive(:announce).with(:custom_field_definition_created, { + 'id' => match_houid('objevt'), + 'object' => 'object_event', + 'type' => 'custom_field_definition.created', + 'data' => { + 'object' => { + 'id'=> kind_of(Numeric), + 'deleted' => false, + 'name' => name, + 'nonprofit'=> np_builder_expanded, + 'object' => 'custom_field_definition' + } + } + }) + + custom_field_definition + end + + it 'announces deleted' do + expect(Houdini.event_publisher).to receive(:announce).with(:custom_field_definition_created, anything).ordered + expect(Houdini.event_publisher).to receive(:announce).with(:custom_field_definition_deleted, { + 'id' => match_houid('objevt'), + 'object' => 'object_event', + 'type' => 'custom_field_definition.deleted', + 'data' => { + 'object' => { + 'id'=> kind_of(Numeric), + 'deleted' => true, + 'name' => name, + 'nonprofit'=> np_builder_expanded, + 'object' => 'custom_field_definition' + } + } + }).ordered + + custom_field_definition.discard! + + end +end