From 885ab9a01554bf3d23e4b4cb09d1f10e2b72dcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guitaut?= Date: Tue, 27 Jun 2023 02:51:58 +0200 Subject: [PATCH] DEV: Introduce an `array` type for Chat contracts (#22278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This small patch registers a new `ActiveModel` type: `array`. It will split a string on `,` to create a new array. If the value is already an array, nothing will happen and for all other types, it will wrap the value in an array. Here’s an example on an existing contract: ```ruby attribute :target_usernames before_validation do self.target_usernames = ( if target_usernames.is_a?(String) target_usernames.split(",") else target_usernames end ) end # can be rewritten as: attribute :target_usernames, :array ``` --- plugins/chat/lib/chat/types/array.rb | 20 +++++++++++ plugins/chat/plugin.rb | 2 ++ .../chat/spec/lib/chat/types/array_spec.rb | 35 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 plugins/chat/lib/chat/types/array.rb create mode 100644 plugins/chat/spec/lib/chat/types/array_spec.rb diff --git a/plugins/chat/lib/chat/types/array.rb b/plugins/chat/lib/chat/types/array.rb new file mode 100644 index 00000000000..2c4672ff1b5 --- /dev/null +++ b/plugins/chat/lib/chat/types/array.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Chat + module Types + class Array < ActiveModel::Type::Value + def serializable?(_) + false + end + + def cast_value(value) + case value + when String + value.split(",") + else + ::Array.wrap(value) + end + end + end + end +end diff --git a/plugins/chat/plugin.rb b/plugins/chat/plugin.rb index 9f797d04800..2f0e17d373e 100644 --- a/plugins/chat/plugin.rb +++ b/plugins/chat/plugin.rb @@ -496,6 +496,8 @@ after_initialize do ) register_bookmarkable(Chat::MessageBookmarkable) + + ActiveModel::Type.register(:array, Chat::Types::Array) end if Rails.env == "test" diff --git a/plugins/chat/spec/lib/chat/types/array_spec.rb b/plugins/chat/spec/lib/chat/types/array_spec.rb new file mode 100644 index 00000000000..c6e843d4a18 --- /dev/null +++ b/plugins/chat/spec/lib/chat/types/array_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe Chat::Types::Array do + subject(:type) { described_class.new } + + describe "#cast" do + subject(:casted_value) { type.cast(value) } + + context "when 'value' is a string" do + let(:value) { "first,second,third" } + + it "splits it" do + expect(casted_value).to eq(%w[first second third]) + end + end + + context "when 'value' is an array" do + let(:value) { %w[existing array] } + + it "returns it" do + expect(casted_value).to eq(value) + end + end + + context "when 'value' is something else" do + let(:value) { Time.current } + + it "wraps it in a new array" do + expect(casted_value).to eq([value]) + end + end + end +end