From b18b889898d2ce27c7d16e1e51d535659590baf9 Mon Sep 17 00:00:00 2001 From: Thomas Cannon Date: Wed, 7 May 2025 07:52:43 -0400 Subject: [PATCH 1/4] Rubocop ignores line length in test files --- .rubocop.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 762eebb..dd3538c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,3 +6,7 @@ Style/StringLiterals: Style/StringLiteralsInInterpolation: EnforcedStyle: double_quotes + +Layout/LineLength: + Exclude: + - test/**/* \ No newline at end of file From a80d4ebd877de52e0283ae4fc21399a72d5dc961 Mon Sep 17 00:00:00 2001 From: Thomas Cannon Date: Wed, 7 May 2025 07:53:53 -0400 Subject: [PATCH 2/4] `copy_attribute_definitions` uses `type_for_attribute` * Using `type_for_attribute` seems to handle mapping certain `ActiveRecord` columns to `ActiveModel` types, notably `TEXT` => `string` in the example application * Unfortunately, we still need to use the `columns_hash` to pull the default value from the column's definition --- lib/trenchcoat.rb | 2 +- test/test_trenchcoat.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/trenchcoat.rb b/lib/trenchcoat.rb index 370bbe5..77db1c0 100644 --- a/lib/trenchcoat.rb +++ b/lib/trenchcoat.rb @@ -22,7 +22,7 @@ def copy_attribute_definitions(model_class:, attributes:) attributes.each do |attribute_name| column = columns.fetch(attribute_name) - attribute column.name, column.type, default: column.default + attribute column.name, model_class.type_for_attribute(attribute_name), default: column.default end end diff --git a/test/test_trenchcoat.rb b/test/test_trenchcoat.rb index 0fb5e7e..430ab63 100644 --- a/test/test_trenchcoat.rb +++ b/test/test_trenchcoat.rb @@ -18,10 +18,9 @@ class CustomForm attr_accessor :post - copy_attribute_definitions(model_class: Post, attributes: %i[title published_at]) + copy_attribute_definitions(model_class: Post, attributes: %i[title body published_at]) quack_like(model_instance_attr: :post) - attribute :body, :string # has to be manually defined because there is not a Text type for ActiveModel by default attribute :is_published, :boolean, default: false alias is_published? is_published From 129386d453735b41625d71bb7e6ed21356a628c7 Mon Sep 17 00:00:00 2001 From: Thomas Cannon Date: Wed, 7 May 2025 07:56:27 -0400 Subject: [PATCH 3/4] `fallback_to_model_values` checks against `original_attributes_hash` * When an attribute has a default value, the check for if the attribute is falsey will be false, since it's using the default value * Instead, we want to actually check against the `original_attributes_hash` (the user-provided hash of attributes, such as the one used by `initialize`) to see if it had a value for that key * If so, we assume that the value has already been processed and does not need the fallback applied * Updated the tests to verify this behavior by setting a default for the `body` column and checking that * An empty model instance is initialized with the default * The model's fallback value is loaded if there was no value provided when initializing --- lib/trenchcoat.rb | 6 +++--- test/test_helper.rb | 2 +- test/test_trenchcoat.rb | 11 +++++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/trenchcoat.rb b/lib/trenchcoat.rb index 77db1c0..670f8ed 100644 --- a/lib/trenchcoat.rb +++ b/lib/trenchcoat.rb @@ -8,9 +8,9 @@ module Trenchcoat module Model extend ActiveSupport::Concern - def fallback_to_model_values(model:, attributes:) - attributes.each do |attribute| - next if send(attribute) + def fallback_to_model_values(model:, attributes_to_check:, original_attributes_hash:) + attributes_to_check.each do |attribute| + next if original_attributes_hash.with_indifferent_access.key?(attribute) send(:"#{attribute}=", model.public_send(attribute)) end diff --git a/test/test_helper.rb b/test/test_helper.rb index 9b76d89..3c21cb7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,7 +10,7 @@ ActiveRecord::Schema.define do create_table :posts do |t| t.string :title, null: false - t.text :body, null: false + t.text :body, null: false, default: "It was a dark and stormy night" t.datetime :published_at end end diff --git a/test/test_trenchcoat.rb b/test/test_trenchcoat.rb index 430ab63..29fda4f 100644 --- a/test/test_trenchcoat.rb +++ b/test/test_trenchcoat.rb @@ -32,8 +32,11 @@ def initialize(attributes = {}) published_at self.post = Post.new if post.blank? - - fallback_to_model_values(model: post, attributes: %i[title body published_at]) + fallback_to_model_values( + model: post, + attributes_to_check: %i[title body published_at], + original_attributes_hash: attributes + ) return if attributes.key?(:is_published) @@ -69,7 +72,7 @@ def normalize_published_at assert_equal true, form.post.new_record? assert_nil form.title - assert_nil form.body + assert_equal "It was a dark and stormy night", form.body assert_nil form.published_at assert_equal false, form.is_published end @@ -85,7 +88,7 @@ def normalize_published_at assert_equal true, form.is_published end - test "fallback_to_model_values: params given, falls back to model instance if falsey parameter" do + test "fallback_to_model_values: params given, falls back to model instance if original_attributes_hash did not include parameter" do time = Time.utc(2021, 2, 2) post = Post.create!(title: "A Post", body: "Post Content") form = CustomForm.new(post: post, title: "Hello", published_at: time, is_published: "1") From 6c736a36484f15987fc05f63f8c0b3e84d31f4a9 Mon Sep 17 00:00:00 2001 From: Thomas Cannon Date: Wed, 7 May 2025 08:00:26 -0400 Subject: [PATCH 4/4] Bump to version 0.2.0 --- Gemfile.lock | 2 +- lib/trenchcoat/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a8a2b42..d5c55ce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - trenchcoat (0.1.0) + trenchcoat (0.2.0) activemodel (>= 7.0) activerecord (>= 7.0) activesupport (>= 7.0) diff --git a/lib/trenchcoat/version.rb b/lib/trenchcoat/version.rb index 3c2f561..4a1b154 100644 --- a/lib/trenchcoat/version.rb +++ b/lib/trenchcoat/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Trenchcoat - VERSION = "0.1.0" + VERSION = "0.2.0" end