From ae0d93972e6b9556ce01cfc35f4757a6015968c4 Mon Sep 17 00:00:00 2001 From: Maxim Colls Date: Tue, 1 May 2018 13:17:37 +0100 Subject: [PATCH 01/12] Added dashbaord events --- app/models/event.rb | 20 ++++++++++++++++++++ app/services/persister/post_persister.rb | 14 +++++++++++++- db/migrate/20180501093846_create_events.rb | 13 +++++++++++++ db/schema.rb | 11 ++++++++++- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 app/models/event.rb create mode 100644 db/migrate/20180501093846_create_events.rb diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 000000000..5c82aacef --- /dev/null +++ b/app/models/event.rb @@ -0,0 +1,20 @@ +class Event < ActiveRecord::Base + ACTIONS = ['create', 'update'].freeze + + belongs_to :post + belongs_to :member + belongs_to :transfer + + validates :action, inclusion: { :in => ACTIONS }, presence: true + validate :resource_presence + + private + + # Validates that only one resourece id is set + # + def resource_presence + return if post_id.present? ^ member_id.present? ^ transfer_id.present? + + errors.add(:base, 'Specify only one resource id: `post_id`, `member_id` or `transfer_id`') + end +end diff --git a/app/services/persister/post_persister.rb b/app/services/persister/post_persister.rb index eb4e94fe3..2feb13eda 100644 --- a/app/services/persister/post_persister.rb +++ b/app/services/persister/post_persister.rb @@ -7,11 +7,23 @@ def initialize(post) end def save - post.save + ::ActiveRecord::Base.transaction do + post.save! + create_save_event! + post + end + rescue ActiveRecord::RecordInvalid => _exception + false end def update_attributes(params) post.update_attributes(params) end + + private + + def create_save_event! + ::Event.create! action: :create, post: post + end end end diff --git a/db/migrate/20180501093846_create_events.rb b/db/migrate/20180501093846_create_events.rb new file mode 100644 index 000000000..7464bbad1 --- /dev/null +++ b/db/migrate/20180501093846_create_events.rb @@ -0,0 +1,13 @@ +class CreateEvents < ActiveRecord::Migration + def change + create_table :events do |t| + t.string :action, :null => false + + t.integer :post_id + t.integer :member_id + t.integer :transfer_id + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e4e2e2e1d..6537b2213 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180221161343) do +ActiveRecord::Schema.define(version: 20180501093846) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -76,6 +76,15 @@ add_index "documents", ["documentable_id", "documentable_type"], name: "index_documents_on_documentable_id_and_documentable_type", using: :btree add_index "documents", ["label"], name: "index_documents_on_label", using: :btree + create_table "events", force: :cascade do |t| + t.string "action", null: false + t.integer "post_id" + t.integer "member_id" + t.integer "transfer_id" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "members", force: :cascade do |t| t.integer "user_id" t.integer "organization_id" From d7b3f606743dccd88a2e9383c87e2023e77f8b4c Mon Sep 17 00:00:00 2001 From: Maxim Colls Date: Mon, 7 May 2018 19:31:19 +0100 Subject: [PATCH 02/12] Fixed typo and hashrocket --- app/models/event.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/event.rb b/app/models/event.rb index 5c82aacef..146179b8a 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -5,12 +5,12 @@ class Event < ActiveRecord::Base belongs_to :member belongs_to :transfer - validates :action, inclusion: { :in => ACTIONS }, presence: true + validates :action, inclusion: { in: ACTIONS }, presence: true validate :resource_presence private - # Validates that only one resourece id is set + # Validates that only one resource id is set # def resource_presence return if post_id.present? ^ member_id.present? ^ transfer_id.present? From 17a20bcf777388b4bd2c5bab24020e677c3011fa Mon Sep 17 00:00:00 2001 From: Maxim Colls Date: Mon, 7 May 2018 19:31:28 +0100 Subject: [PATCH 03/12] Added Event model specs --- spec/models/event_spec.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 spec/models/event_spec.rb diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb new file mode 100644 index 000000000..11b6d2ba5 --- /dev/null +++ b/spec/models/event_spec.rb @@ -0,0 +1,25 @@ +require "spec_helper" + +describe Event do + let(:post) { Fabricate(:post) } + let(:member) { Fabricate(:member) } + let(:event) { Event.new action: 'create' } + + describe '#resource_presence validation' do + context 'has no resources' do + it { expect(event).to_not be_valid } + end + + context 'has one resource' do + before { event.post = post } + + it { expect(event).to be_valid } + end + + context 'has two resources' do + before { event.post = post; event.member = member } + + it { expect(event).to_not be_valid } + end + end +end From 780d73347475632f8a10a753f681570021b1d815 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 10 May 2018 22:17:09 +0200 Subject: [PATCH 04/12] Update and configure shoulda-matchers --- Gemfile | 2 +- Gemfile.lock | 10 +++------- spec/spec_helper.rb | 8 ++++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index dde7f6d1f..f52a82458 100644 --- a/Gemfile +++ b/Gemfile @@ -54,7 +54,7 @@ end group :test do gem "database_cleaner", '1.6.2' - gem 'shoulda', ">= 3.5" + gem 'shoulda-matchers', '~> 3.1.2' gem 'fabrication' gem 'faker' gem 'capybara', '~> 2.7' diff --git a/Gemfile.lock b/Gemfile.lock index 6a7480ce9..57b021967 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -329,12 +329,8 @@ GEM selenium-webdriver (3.11.0) childprocess (~> 0.5) rubyzip (~> 1.2) - shoulda (3.5.0) - shoulda-context (~> 1.0, >= 1.0.1) - shoulda-matchers (>= 1.4.1, < 3.0) - shoulda-context (1.2.1) - shoulda-matchers (2.8.0) - activesupport (>= 3.0.0) + shoulda-matchers (3.1.2) + activesupport (>= 4.0.0) simple_form (3.1.0) actionpack (~> 4.0) activemodel (~> 4.0) @@ -427,7 +423,7 @@ DEPENDENCIES rubocop (~> 0.52.1) sass-rails (~> 5.0.7) select2-rails - shoulda (>= 3.5) + shoulda-matchers (~> 3.1.2) simple_form (>= 3.0.0) skylight uglifier (= 2.7.2) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 43434d797..8e737cd26 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,6 +10,7 @@ require 'fabrication' require 'selenium/webdriver' require 'faker' +require 'shoulda/matchers' I18n.reload! Capybara.register_driver :chrome do |app| @@ -149,3 +150,10 @@ def set_browser_locale(locale) end RSpec.configure(&:infer_spec_type_from_file_location!) + +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end From b08f271a7f9638ca0760ccc04efa52d08022b6fc Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 10 May 2018 22:30:48 +0200 Subject: [PATCH 05/12] Modify events table migration with plain SQL --- db/migrate/20180501093846_create_events.rb | 43 ++++++++++++++++++---- db/schema.rb | 13 +++---- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/db/migrate/20180501093846_create_events.rb b/db/migrate/20180501093846_create_events.rb index 7464bbad1..6372ac2a6 100644 --- a/db/migrate/20180501093846_create_events.rb +++ b/db/migrate/20180501093846_create_events.rb @@ -1,13 +1,40 @@ +# This migration does not use Rails ActiveRecord ORM DSL since +# it doesn't provide data integrity (foreign key) for polymorphic models. +# +# The technique applied is called Exclusive Belongs To (AKA Exclusive Arc) +# +# Please read the following article for more details: +# https://hashrocket.com/blog/posts/modeling-polymorphic-associations-in-a-relational-database +# class CreateEvents < ActiveRecord::Migration - def change - create_table :events do |t| - t.string :action, :null => false + def up + execute <<-SQL + CREATE TYPE action_enum AS ENUM ('create', 'update'); - t.integer :post_id - t.integer :member_id - t.integer :transfer_id + CREATE TABLE events ( + id serial PRIMARY KEY, + action action_enum NOT NULL, + post_id integer REFERENCES posts, + member_id integer REFERENCES members, + transfer_id integer REFERENCES transfers, + created_at timestamp without time zone, + updated_at timestamp without time zone, + CHECK( + ( + (post_id IS NOT NULL)::integer + + (member_id IS NOT NULL)::integer + + (transfer_id IS NOT NULL)::integer + ) = 1 + ) + ); - t.timestamps - end + CREATE UNIQUE INDEX ON events (post_id) WHERE post_id IS NOT NULL; + CREATE UNIQUE INDEX ON events (member_id) WHERE member_id IS NOT NULL; + CREATE UNIQUE INDEX ON events (transfer_id) WHERE transfer_id IS NOT NULL; + SQL + end + + def down + drop_table :events end end diff --git a/db/schema.rb b/db/schema.rb index 6537b2213..a8bf50749 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -76,14 +76,8 @@ add_index "documents", ["documentable_id", "documentable_type"], name: "index_documents_on_documentable_id_and_documentable_type", using: :btree add_index "documents", ["label"], name: "index_documents_on_label", using: :btree - create_table "events", force: :cascade do |t| - t.string "action", null: false - t.integer "post_id" - t.integer "member_id" - t.integer "transfer_id" - t.datetime "created_at" - t.datetime "updated_at" - end +# Could not dump table "events" because of following StandardError +# Unknown type 'action_enum' for column 'action' create_table "members", force: :cascade do |t| t.integer "user_id" @@ -207,4 +201,7 @@ add_index "users", ["email"], name: "index_users_on_email", using: :btree add_foreign_key "accounts", "organizations" + add_foreign_key "events", "members", name: "events_member_id_fkey" + add_foreign_key "events", "posts", name: "events_post_id_fkey" + add_foreign_key "events", "transfers", name: "events_transfer_id_fkey" end From 0da31cbcb7573b3ee24e6d09607e2f908f736c97 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 10 May 2018 22:35:10 +0200 Subject: [PATCH 06/12] Add more specs to Event model --- spec/models/event_spec.rb | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 11b6d2ba5..1c37b2e9b 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -1,25 +1,46 @@ require "spec_helper" describe Event do - let(:post) { Fabricate(:post) } - let(:member) { Fabricate(:member) } - let(:event) { Event.new action: 'create' } + describe 'Validations' do + it { is_expected.to validate_presence_of(:action) } + it { is_expected.to validate_inclusion_of(:action).in_array(::Event::ACTIONS) } - describe '#resource_presence validation' do - context 'has no resources' do - it { expect(event).to_not be_valid } - end + describe '#resource_presence validation' do + let(:post) { Fabricate(:post) } + let(:member) { Fabricate(:member) } + let(:event) { Event.new action: 'create' } - context 'has one resource' do - before { event.post = post } + context 'has no resources' do + it { expect(event).to_not be_valid } + end - it { expect(event).to be_valid } - end + context 'has one resource' do + before { event.post = post } - context 'has two resources' do - before { event.post = post; event.member = member } + it { expect(event).to be_valid } + end - it { expect(event).to_not be_valid } + context 'has two resources' do + before { event.post = post; event.member = member } + + it { expect(event).to_not be_valid } + end end end + + describe 'Relations' do + it { is_expected.to belong_to(:post) } + it { is_expected.to belong_to(:member) } + it { is_expected.to belong_to(:transfer) } + + it { is_expected.to have_db_column(:post_id) } + it { is_expected.to have_db_column(:member_id) } + it { is_expected.to have_db_column(:transfer_id) } + end + + describe 'Indexes' do + it { is_expected.to have_db_index(:post_id) } + it { is_expected.to have_db_index(:member_id) } + it { is_expected.to have_db_index(:transfer_id) } + end end From 43a0f4f7bbfdc4b6ba23b6bbfdcef0b324ca2d16 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Wed, 16 May 2018 10:18:29 +0200 Subject: [PATCH 07/12] Use Rails enum, backed by an integer column with CHECK constraint --- app/models/event.rb | 4 ++-- db/migrate/20180501093846_create_events.rb | 5 ++--- db/schema.rb | 14 ++++++++++++-- spec/models/event_spec.rb | 9 ++++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/models/event.rb b/app/models/event.rb index 146179b8a..2058045b7 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,11 +1,11 @@ class Event < ActiveRecord::Base - ACTIONS = ['create', 'update'].freeze + enum action: { created: 0, updated: 1 } belongs_to :post belongs_to :member belongs_to :transfer - validates :action, inclusion: { in: ACTIONS }, presence: true + validates :action, presence: true validate :resource_presence private diff --git a/db/migrate/20180501093846_create_events.rb b/db/migrate/20180501093846_create_events.rb index 6372ac2a6..514d42af3 100644 --- a/db/migrate/20180501093846_create_events.rb +++ b/db/migrate/20180501093846_create_events.rb @@ -9,16 +9,15 @@ class CreateEvents < ActiveRecord::Migration def up execute <<-SQL - CREATE TYPE action_enum AS ENUM ('create', 'update'); - CREATE TABLE events ( id serial PRIMARY KEY, - action action_enum NOT NULL, + action integer NOT NULL, post_id integer REFERENCES posts, member_id integer REFERENCES members, transfer_id integer REFERENCES transfers, created_at timestamp without time zone, updated_at timestamp without time zone, + CHECK(action IN (0, 1)), CHECK( ( (post_id IS NOT NULL)::integer + diff --git a/db/schema.rb b/db/schema.rb index a8bf50749..7ec6f09ea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -76,8 +76,18 @@ add_index "documents", ["documentable_id", "documentable_type"], name: "index_documents_on_documentable_id_and_documentable_type", using: :btree add_index "documents", ["label"], name: "index_documents_on_label", using: :btree -# Could not dump table "events" because of following StandardError -# Unknown type 'action_enum' for column 'action' + create_table "events", force: :cascade do |t| + t.integer "action", null: false + t.integer "post_id" + t.integer "member_id" + t.integer "transfer_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "events", ["member_id"], name: "events_member_id_idx", unique: true, where: "(member_id IS NOT NULL)", using: :btree + add_index "events", ["post_id"], name: "events_post_id_idx", unique: true, where: "(post_id IS NOT NULL)", using: :btree + add_index "events", ["transfer_id"], name: "events_transfer_id_idx", unique: true, where: "(transfer_id IS NOT NULL)", using: :btree create_table "members", force: :cascade do |t| t.integer "user_id" diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 1c37b2e9b..2961fc2ee 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -1,14 +1,17 @@ -require "spec_helper" +require 'spec_helper' describe Event do describe 'Validations' do it { is_expected.to validate_presence_of(:action) } - it { is_expected.to validate_inclusion_of(:action).in_array(::Event::ACTIONS) } + it do + is_expected.to define_enum_for(:action) + .with([:created, :updated]) + end describe '#resource_presence validation' do let(:post) { Fabricate(:post) } let(:member) { Fabricate(:member) } - let(:event) { Event.new action: 'create' } + let(:event) { Event.new action: 'created' } context 'has no resources' do it { expect(event).to_not be_valid } From 898ee75670da062328d91b9ac54699bf14ffdc8a Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Wed, 16 May 2018 10:46:14 +0200 Subject: [PATCH 08/12] Fix and improve specs --- app/services/persister/post_persister.rb | 2 +- .../services/persister/post_persister_spec.rb | 33 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/app/services/persister/post_persister.rb b/app/services/persister/post_persister.rb index 2feb13eda..ff9a1de87 100644 --- a/app/services/persister/post_persister.rb +++ b/app/services/persister/post_persister.rb @@ -23,7 +23,7 @@ def update_attributes(params) private def create_save_event! - ::Event.create! action: :create, post: post + ::Event.create! action: :created, post: post end end end diff --git a/spec/services/persister/post_persister_spec.rb b/spec/services/persister/post_persister_spec.rb index 9592b1fd2..6ae8139b6 100644 --- a/spec/services/persister/post_persister_spec.rb +++ b/spec/services/persister/post_persister_spec.rb @@ -4,25 +4,40 @@ let(:organization) { Fabricate(:organization) } let(:user) { Fabricate(:user) } let(:category) { Fabricate(:category) } - let(:post) { Fabricate(:post, organization: organization) } + let(:post) do + Fabricate.build( + :offer, + organization: organization, + user: user, + category: category, + title: 'Title' + ) + end + let(:persister) { ::Persister::PostPersister.new(post) } describe '#save' do - it 'saves the post' do - post = Offer.new(organization: organization, user: user, category: category, title: 'Title') - persister = ::Persister::PostPersister.new(post) - - persister.save + before { persister.save } + it 'saves the post' do expect(post).to be_persisted end + + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(post_id: post.id).first.action).to eq('created') + end end describe '#update_attributes' do - it 'updates the attributes' do - persister = ::Persister::PostPersister.new(post) - persister.update_attributes(title: 'New title') + before { persister.update_attributes(title: 'New title') } + it 'updates the resource attributes' do expect(post.title).to eq('New title') end + + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(post_id: post.id).first.action).to eq('updated') + end end end From 0eb2536ae31b8cee4aee981acda6b1a3dfb1db4c Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 17 May 2018 08:39:16 +0200 Subject: [PATCH 09/12] Use ActiveRecord DSL as much as possible --- db/migrate/20180501093846_create_events.rb | 36 ++++++++++++---------- db/schema.rb | 6 ++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/db/migrate/20180501093846_create_events.rb b/db/migrate/20180501093846_create_events.rb index 514d42af3..af3fffbee 100644 --- a/db/migrate/20180501093846_create_events.rb +++ b/db/migrate/20180501093846_create_events.rb @@ -8,28 +8,32 @@ # class CreateEvents < ActiveRecord::Migration def up + create_table :events do |t| + t.integer :action, null:false + t.integer :post_id + t.integer :member_id + t.integer :transfer_id + t.timestamps + end + + add_foreign_key :events, :posts, name: 'events_post_id_fkey' + add_foreign_key :events, :members, name: 'events_member_id_fkey' + add_foreign_key :events, :transfers, name: 'events_transfer_id_fkey' + + add_index :events, :post_id, unique: true, where: 'post_id IS NOT NULL' + add_index :events, :member_id, unique: true, where: 'member_id IS NOT NULL' + add_index :events, :transfer_id, unique: true, where: 'transfer_id IS NOT NULL' + execute <<-SQL - CREATE TABLE events ( - id serial PRIMARY KEY, - action integer NOT NULL, - post_id integer REFERENCES posts, - member_id integer REFERENCES members, - transfer_id integer REFERENCES transfers, - created_at timestamp without time zone, - updated_at timestamp without time zone, - CHECK(action IN (0, 1)), - CHECK( + ALTER TABLE events + ADD CHECK(action IN (0, 1)), + ADD CHECK( ( (post_id IS NOT NULL)::integer + (member_id IS NOT NULL)::integer + (transfer_id IS NOT NULL)::integer ) = 1 - ) - ); - - CREATE UNIQUE INDEX ON events (post_id) WHERE post_id IS NOT NULL; - CREATE UNIQUE INDEX ON events (member_id) WHERE member_id IS NOT NULL; - CREATE UNIQUE INDEX ON events (transfer_id) WHERE transfer_id IS NOT NULL; + ); SQL end diff --git a/db/schema.rb b/db/schema.rb index 7ec6f09ea..f3751e936 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -85,9 +85,9 @@ t.datetime "updated_at" end - add_index "events", ["member_id"], name: "events_member_id_idx", unique: true, where: "(member_id IS NOT NULL)", using: :btree - add_index "events", ["post_id"], name: "events_post_id_idx", unique: true, where: "(post_id IS NOT NULL)", using: :btree - add_index "events", ["transfer_id"], name: "events_transfer_id_idx", unique: true, where: "(transfer_id IS NOT NULL)", using: :btree + add_index "events", ["member_id"], name: "index_events_on_member_id", unique: true, where: "(member_id IS NOT NULL)", using: :btree + add_index "events", ["post_id"], name: "index_events_on_post_id", unique: true, where: "(post_id IS NOT NULL)", using: :btree + add_index "events", ["transfer_id"], name: "index_events_on_transfer_id", unique: true, where: "(transfer_id IS NOT NULL)", using: :btree create_table "members", force: :cascade do |t| t.integer "user_id" From 833bf307b6117cb7f1707225a8406d0cffb9c406 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 17 May 2018 08:53:33 +0200 Subject: [PATCH 10/12] Create :updated event on Post update --- app/services/persister/post_persister.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/services/persister/post_persister.rb b/app/services/persister/post_persister.rb index ff9a1de87..0c0bb8004 100644 --- a/app/services/persister/post_persister.rb +++ b/app/services/persister/post_persister.rb @@ -17,7 +17,13 @@ def save end def update_attributes(params) - post.update_attributes(params) + ::ActiveRecord::Base.transaction do + post.update_attributes!(params) + create_update_event! + post + end + rescue ActiveRecord::RecordInvalid => _exception + false end private @@ -25,5 +31,9 @@ def update_attributes(params) def create_save_event! ::Event.create! action: :created, post: post end + + def create_update_event! + ::Event.create! action: :updated, post: post + end end end From dabf7e4e3ea8370fd4b5c779d5e9e70cf7867a30 Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 17 May 2018 09:18:26 +0200 Subject: [PATCH 11/12] Create :created and :updated event for Member --- app/services/persister/member_persister.rb | 28 ++++++++++++++++++- .../persister/member_persister_spec.rb | 25 ++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/app/services/persister/member_persister.rb b/app/services/persister/member_persister.rb index 4bed82cf1..51594ffd6 100644 --- a/app/services/persister/member_persister.rb +++ b/app/services/persister/member_persister.rb @@ -7,7 +7,33 @@ def initialize(member) end def save - member.save + ::ActiveRecord::Base.transaction do + member.save! + create_save_event! + member + end + rescue ActiveRecord::RecordInvalid => _exception + false + end + + def update_attributes(params) + ::ActiveRecord::Base.transaction do + member.update_attributes!(params) + create_update_event! + member + end + rescue ActiveRecord::RecordInvalid => _exception + false + end + + private + + def create_save_event! + ::Event.create! action: :created, member: member + end + + def create_update_event! + ::Event.create! action: :updated, member: member end end end diff --git a/spec/services/persister/member_persister_spec.rb b/spec/services/persister/member_persister_spec.rb index 9ca7f61b6..7377ee375 100644 --- a/spec/services/persister/member_persister_spec.rb +++ b/spec/services/persister/member_persister_spec.rb @@ -3,15 +3,32 @@ describe Persister::MemberPersister do let(:organization) { Fabricate(:organization) } let(:user) { Fabricate(:user) } + let(:member) { Fabricate.build(:member, user: user, organization: organization) } + let(:persister) { ::Persister::MemberPersister.new(member) } describe '#save' do + before { persister.save } + it 'saves the member' do - member = Member.new(user: user, organization: organization) + expect(member).to be_persisted + end - persister = ::Persister::MemberPersister.new(member) - persister.save + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(member_id: member.id).first.action).to eq('created') + end + end - expect(member).to be_persisted + describe '#update_attributes' do + before { persister.update_attributes(member_uid: 666) } + + it 'updates the resource attributes' do + expect(member.member_uid).to eq(666) + end + + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(member_id: member.id).first.action).to eq('updated') end end end From b4955815b3e450c17fe1141e16a5481ad03fdc5a Mon Sep 17 00:00:00 2001 From: Enrico Stano Date: Thu, 17 May 2018 09:33:20 +0200 Subject: [PATCH 12/12] Create :created and :updated event for Transfer --- app/services/persister/transfer_persister.rb | 28 +++++++++++++++- spec/fabricators/transfer_fabricator.rb | 5 +++ .../persister/transfer_persister_spec.rb | 32 ++++++++++++++++--- 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 spec/fabricators/transfer_fabricator.rb diff --git a/app/services/persister/transfer_persister.rb b/app/services/persister/transfer_persister.rb index 5e72e46d7..a5fd86f12 100644 --- a/app/services/persister/transfer_persister.rb +++ b/app/services/persister/transfer_persister.rb @@ -7,7 +7,33 @@ def initialize(transfer) end def save - transfer.save + ::ActiveRecord::Base.transaction do + transfer.save! + create_save_event! + transfer + end + rescue ActiveRecord::RecordInvalid => _exception + false + end + + def update_attributes(params) + ::ActiveRecord::Base.transaction do + transfer.update_attributes!(params) + create_update_event! + transfer + end + rescue ActiveRecord::RecordInvalid => _exception + false + end + + private + + def create_save_event! + ::Event.create! action: :created, transfer: transfer + end + + def create_update_event! + ::Event.create! action: :updated, transfer: transfer end end end diff --git a/spec/fabricators/transfer_fabricator.rb b/spec/fabricators/transfer_fabricator.rb new file mode 100644 index 000000000..02b6c193a --- /dev/null +++ b/spec/fabricators/transfer_fabricator.rb @@ -0,0 +1,5 @@ +Fabricator(:transfer) do + source { Fabricate(:account) } + destination { Fabricate(:account) } + amount 10 +end diff --git a/spec/services/persister/transfer_persister_spec.rb b/spec/services/persister/transfer_persister_spec.rb index a7d77dab8..89acc338b 100644 --- a/spec/services/persister/transfer_persister_spec.rb +++ b/spec/services/persister/transfer_persister_spec.rb @@ -5,15 +5,39 @@ let(:destination_account) { Fabricate(:account) } let(:organization) { Fabricate(:organization) } let(:post) { Fabricate(:post, organization: organization) } + let(:transfer) do + Fabricate.build( + :transfer, + post: post, + source: source_account, + destination: destination_account + ) + end + let(:persister) { ::Persister::TransferPersister.new(transfer) } describe '#save' do + before { persister.save } + it 'saves the transfer' do - transfer = Transfer.new(post: post, source: source_account, destination: destination_account) + expect(transfer).to be_persisted + end + + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(transfer_id: transfer.id).first.action).to eq('created') + end + end - persister = ::Persister::TransferPersister.new(transfer) - persister.save + describe '#update_attributes' do + before { persister.update_attributes(amount: 666) } - expect(transfer).to be_persisted + it 'updates the resource attributes' do + expect(transfer.amount).to eq(666) + end + + # TODO: write better expectation + it 'creates an event' do + expect(Event.where(transfer_id: transfer.id).first.action).to eq('updated') end end end