From cd458b24e00783962598678089d01e8e48abd5e7 Mon Sep 17 00:00:00 2001 From: Joshua Young Date: Sat, 24 Sep 2022 21:04:11 +1000 Subject: [PATCH] Add support for alias_attribute --- .../model_plugins/active_record_attribute.rb | 55 ++++++++++++------- .../active_record_serialized_attribute.rb | 35 +++++++----- lib/sorbet-rails/model_plugins/base.rb | 41 ++++++++++++++ spec/generators/rails-template.rb | 5 ++ spec/generators/sorbet_test_cases.rb | 12 +++- spec/support/v5.2/app/models/spell_book.rb | 3 + spec/support/v5.2/app/models/wizard.rb | 2 + spec/support/v5.2/sorbet_test_cases.rb | 12 +++- spec/support/v6.0/app/models/spell_book.rb | 3 + spec/support/v6.0/app/models/wizard.rb | 2 + spec/support/v6.0/sorbet_test_cases.rb | 12 +++- spec/support/v6.1/app/models/spell_book.rb | 3 + spec/support/v6.1/app/models/wizard.rb | 2 + spec/support/v6.1/sorbet_test_cases.rb | 12 +++- spec/support/v7.0/app/models/spell_book.rb | 3 + spec/support/v7.0/app/models/wizard.rb | 2 + spec/support/v7.0/sorbet_test_cases.rb | 12 +++- spec/test_data/v5.2/expected_spell_book.rbi | 24 ++++++++ spec/test_data/v5.2/expected_squib.rbi | 9 +++ spec/test_data/v5.2/expected_wizard.rbi | 9 +++ .../v5.2/expected_wizard_wo_spellbook.rbi | 9 +++ spec/test_data/v6.0/expected_spell_book.rbi | 24 ++++++++ spec/test_data/v6.0/expected_squib.rbi | 9 +++ spec/test_data/v6.0/expected_wizard.rbi | 9 +++ .../v6.0/expected_wizard_wo_spellbook.rbi | 9 +++ spec/test_data/v6.1/expected_spell_book.rbi | 24 ++++++++ spec/test_data/v6.1/expected_squib.rbi | 9 +++ spec/test_data/v6.1/expected_wizard.rbi | 9 +++ .../v6.1/expected_wizard_wo_spellbook.rbi | 9 +++ spec/test_data/v7.0/expected_spell_book.rbi | 24 ++++++++ spec/test_data/v7.0/expected_squib.rbi | 9 +++ spec/test_data/v7.0/expected_wizard.rbi | 9 +++ .../v7.0/expected_wizard_wo_spellbook.rbi | 9 +++ 33 files changed, 380 insertions(+), 40 deletions(-) diff --git a/lib/sorbet-rails/model_plugins/active_record_attribute.rb b/lib/sorbet-rails/model_plugins/active_record_attribute.rb index 6d45cc5f..87e2bfcd 100644 --- a/lib/sorbet-rails/model_plugins/active_record_attribute.rb +++ b/lib/sorbet-rails/model_plugins/active_record_attribute.rb @@ -12,28 +12,39 @@ def generate(root) model_class_rbi = root.create_class(self.model_class_name) model_class_rbi.create_include(attribute_module_name) + model_defined_enums = @model_class.defined_enums + model_defined_aliases = @model_class.send(:attribute_aliases) + column_names = columns_hash.keys + aliases_hash = model_class_columns_to_aliases(column_names, model_defined_aliases) + attributes_and_aliases_hash = model_class_attributes_and_aliases(columns_hash, aliases_hash) + + attributes_and_aliases_hash.each do |attribute_name, column_def| + column_name = aliases_hash.find { |_column_name, aliases| aliases.include?(attribute_name) }&.first + column_name ||= attribute_name - columns_hash.sort.each do |column_name, column_def| if model_defined_enums.has_key?(column_name) generate_enum_methods( - root, - model_class_rbi, - attribute_module_rbi, - model_defined_enums, - column_name, - column_def, + root: root, + model_class_rbi: model_class_rbi, + attribute_module_rbi: attribute_module_rbi, + model_defined_enums: model_defined_enums, + attribute_name: attribute_name, + column_name: column_name.presence || attribute_name, + column_def: column_def, ) elsif serialization_coder_for_column(column_name) next # handled by the ActiveRecordSerializedAttribute plugin else column_type = type_for_column_def(column_def) + attribute_module_rbi.create_method( - column_name.to_s, + attribute_name.to_s, return_type: column_type.to_s, ) + attribute_module_rbi.create_method( - "#{column_name}=", + "#{attribute_name}=", parameters: [ Parameter.new("value", type: value_type_for_attr_writer(column_type)) ], @@ -42,29 +53,33 @@ def generate(root) end attribute_module_rbi.create_method( - "#{column_name}?", + "#{attribute_name}?", return_type: "T::Boolean", ) end end + private + sig { params( root: Parlour::RbiGenerator::Namespace, model_class_rbi: Parlour::RbiGenerator::Namespace, attribute_module_rbi: Parlour::RbiGenerator::Namespace, model_defined_enums: T::Hash[String, T::Hash[String, T.untyped]], + attribute_name: String, column_name: String, column_def: T.untyped, ).void } def generate_enum_methods( - root, - model_class_rbi, - attribute_module_rbi, - model_defined_enums, - column_name, - column_def + root:, + model_class_rbi:, + attribute_module_rbi:, + model_defined_enums:, + attribute_name:, + column_name:, + column_def: ) should_skip_setter_getter = false nilable_column = nilable_column?(column_def) @@ -91,11 +106,11 @@ def generate_enum_methods( # add directly to model_class_rbi because they are included # by sorbet's hidden.rbi model_class_rbi.create_method( - "typed_#{column_name}", + "typed_#{attribute_name}", return_type: assignable_type, ) model_class_rbi.create_method( - "typed_#{column_name}=", + "typed_#{attribute_name}=", parameters: [ Parameter.new("value", type: assignable_type) ], @@ -112,11 +127,11 @@ def generate_enum_methods( return_type = "T.nilable(#{return_type})" if nilable_column attribute_module_rbi.create_method( - column_name.to_s, + attribute_name.to_s, return_type: return_type, ) attribute_module_rbi.create_method( - "#{column_name}=", + "#{attribute_name}=", parameters: [ Parameter.new("value", type: assignable_type) ], diff --git a/lib/sorbet-rails/model_plugins/active_record_serialized_attribute.rb b/lib/sorbet-rails/model_plugins/active_record_serialized_attribute.rb index 9b7c7577..e13507c1 100644 --- a/lib/sorbet-rails/model_plugins/active_record_serialized_attribute.rb +++ b/lib/sorbet-rails/model_plugins/active_record_serialized_attribute.rb @@ -13,6 +13,9 @@ def generate(root) model_class_rbi = root.create_class(self.model_class_name) model_class_rbi.create_include(serialize_module_name) + model_defined_aliases = T.unsafe(@model_class).attribute_aliases + aliases_hash = model_class_columns_to_aliases(model_defined_aliases) + columns_hash.sort.each do |column_name, column_def| serialization_coder = serialization_coder_for_column(column_name) next unless serialization_coder @@ -20,23 +23,25 @@ def generate(root) nilable = nilable_column?(column_def) attr_type = attr_types_for_coder(serialization_coder) - serialize_module_rbi.create_method( - column_name.to_s, - return_type: ColumnType.new(base_type: attr_type, nilable: nilable).to_s, - ) + [column_name].union(aliases_hash[column_name] || []).each do |attribute_name| + serialize_module_rbi.create_method( + attribute_name.to_s, + return_type: ColumnType.new(base_type: attr_type, nilable: nilable).to_s, + ) - serialize_module_rbi.create_method( - "#{column_name}=", - parameters: [ - Parameter.new('value', type: ColumnType.new(base_type: attr_type, nilable: nilable).to_s) - ], - return_type: nil, - ) + serialize_module_rbi.create_method( + "#{attribute_name}=", + parameters: [ + Parameter.new('value', type: ColumnType.new(base_type: attr_type, nilable: nilable).to_s) + ], + return_type: nil, + ) - serialize_module_rbi.create_method( - "#{column_name}?", - return_type: 'T::Boolean', - ) + serialize_module_rbi.create_method( + "#{attribute_name}?", + return_type: 'T::Boolean', + ) + end end end diff --git a/lib/sorbet-rails/model_plugins/base.rb b/lib/sorbet-rails/model_plugins/base.rb index 8800c363..3e4bbb0b 100644 --- a/lib/sorbet-rails/model_plugins/base.rb +++ b/lib/sorbet-rails/model_plugins/base.rb @@ -30,6 +30,8 @@ def initialize(model_class, available_classes) @available_classes = T.let(available_classes, T::Set[String]) end + private + sig { params(column_name: String).returns(T.nilable(Class)) } def serialization_coder_for_column(column_name) column_type = @model_class.type_for_attribute(column_name) @@ -44,5 +46,44 @@ def serialization_coder_for_column(column_name) Object end end + + sig { + params(column_names: T::Array[String], aliases: T::Hash[String, String]) + .returns(T::Hash[String, T::Array[String]]) + } + def model_class_columns_to_aliases(column_names, aliases) + column_names.each_with_object({}) do |column_name, columns_to_aliases| + columns_to_aliases[column_name] = aliases.select! do |_alias_name, attribute_name| + attribute_name == column_name + end.keys + + columns_to_aliases[column_name].each do |direct_alias_name| + columns_to_aliases[column_name].concat(aliases, direct_alias_name) + end + end + end + + sig { params(hash: T::Hash[String, String], initial_value: String).returns(T::Array[String]) } + def recursive_keys_for_value(hash, initial_value) + initial_keys = hash.select { |_key, value| value == initial_value }.keys + initial_keys.flat_map { |key| [key].concat(recursive_keys_for_value(hash, key)) } + end + + sig { + params( + columns_hash: T::Hash[String, T.untyped], + aliases_hash: T::Hash[String, T::Array[String]], + ).returns(T::Hash[String, T.untyped]) + } + def model_class_attributes_and_aliases(columns_hash, aliases_hash) + columns_hash + .sort + .each_with_object({}) do |(column_name, column_def), hash| + attributes = [column_name].union(aliases_hash[column_name] || []) + attributes.each do |attribute_name| + hash[attribute_name] = column_def + end + end + end end end diff --git a/spec/generators/rails-template.rb b/spec/generators/rails-template.rb index a8e79395..fff98c44 100644 --- a/spec/generators/rails-template.rb +++ b/spec/generators/rails-template.rb @@ -92,6 +92,9 @@ class SpellBook < ApplicationRecord dark_art: 999, } + alias_attribute :title, :name + alias_attribute :book_category, :book_type + scope :recent, -> { where('created_at > ?', 1.month.ago) } end RUBY @@ -179,6 +182,8 @@ class Professor; end serialize :pets, Array serialize :patronus_characteristics, JSON + alias_attribute :ordinary_wizarding_level_results, :owl_results + has_one :wand has_many :spell_books # habtm which is optional at the db level diff --git a/spec/generators/sorbet_test_cases.rb b/spec/generators/sorbet_test_cases.rb index 27df2767..b8f04ace 100644 --- a/spec/generators/sorbet_test_cases.rb +++ b/spec/generators/sorbet_test_cases.rb @@ -8,6 +8,17 @@ # -- model columns T.assert_type!(wizard.name, T.nilable(String)) +spell_book = wizard.spell_books.first! +T.assert_type!(spell_book, SpellBook) + +# -- alias attributes +T.assert_type!(spell_book.title, String) # standard alias attribute +T.assert_type!(spell_book.book_category, String) # enum alias attribute +T.assert_type!( + wizard.ordinary_wizarding_level_results, # serialized alias attribute + T.nilable(T::Hash[T.untyped, T.untyped]) +) + # -- time/date columns T.assert_type!(wizard.created_at, ActiveSupport::TimeWithZone) T.assert_type!(wand.broken_at, T.nilable(Time)) @@ -157,7 +168,6 @@ T.assert_type!(Wizard.all.empty?, T::Boolean) # Finder methods -- CollectionProxy -spell_book = wizard.spell_books.first! spell_books = wizard.spell_books T.assert_type!(spell_books.exists?(name: 'Fantastic Beasts'), T::Boolean) T.assert_type!(spell_books.find(spell_book.id), SpellBook) diff --git a/spec/support/v5.2/app/models/spell_book.rb b/spec/support/v5.2/app/models/spell_book.rb index ab2fb0e0..0462a0c7 100644 --- a/spec/support/v5.2/app/models/spell_book.rb +++ b/spec/support/v5.2/app/models/spell_book.rb @@ -14,5 +14,8 @@ class SpellBook < ApplicationRecord dark_art: 999, } + alias_attribute :title, :name + alias_attribute :book_category, :book_type + scope :recent, -> { where('created_at > ?', 1.month.ago) } end diff --git a/spec/support/v5.2/app/models/wizard.rb b/spec/support/v5.2/app/models/wizard.rb index 703a76aa..3b90ffa1 100644 --- a/spec/support/v5.2/app/models/wizard.rb +++ b/spec/support/v5.2/app/models/wizard.rb @@ -52,6 +52,8 @@ class Professor; end serialize :pets, Array serialize :patronus_characteristics, JSON + alias_attribute :ordinary_wizarding_level_results, :owl_results + has_one :wand has_many :spell_books # habtm which is optional at the db level diff --git a/spec/support/v5.2/sorbet_test_cases.rb b/spec/support/v5.2/sorbet_test_cases.rb index b46e810f..711044e8 100644 --- a/spec/support/v5.2/sorbet_test_cases.rb +++ b/spec/support/v5.2/sorbet_test_cases.rb @@ -8,6 +8,17 @@ # -- model columns T.assert_type!(wizard.name, T.nilable(String)) +spell_book = wizard.spell_books.first! +T.assert_type!(spell_book, SpellBook) + +# -- alias attributes +T.assert_type!(spell_book.title, String) # standard alias attribute +T.assert_type!(spell_book.book_category, String) # enum alias attribute +T.assert_type!( + wizard.ordinary_wizarding_level_results, # serialized alias attribute + T.nilable(T::Hash[T.untyped, T.untyped]) +) + # -- time/date columns T.assert_type!(wizard.created_at, ActiveSupport::TimeWithZone) T.assert_type!(wand.broken_at, T.nilable(Time)) @@ -161,7 +172,6 @@ T.assert_type!(Wizard.all.empty?, T::Boolean) # Finder methods -- CollectionProxy -spell_book = wizard.spell_books.first! spell_books = wizard.spell_books T.assert_type!(spell_books.exists?(name: 'Fantastic Beasts'), T::Boolean) T.assert_type!(spell_books.find(spell_book.id), SpellBook) diff --git a/spec/support/v6.0/app/models/spell_book.rb b/spec/support/v6.0/app/models/spell_book.rb index efe838aa..b0c6c951 100644 --- a/spec/support/v6.0/app/models/spell_book.rb +++ b/spec/support/v6.0/app/models/spell_book.rb @@ -14,5 +14,8 @@ class SpellBook < ApplicationRecord dark_art: 999, } + alias_attribute :title, :name + alias_attribute :book_category, :book_type + scope :recent, -> { where('created_at > ?', 1.month.ago) } end diff --git a/spec/support/v6.0/app/models/wizard.rb b/spec/support/v6.0/app/models/wizard.rb index 33b5f8c5..c1fff751 100644 --- a/spec/support/v6.0/app/models/wizard.rb +++ b/spec/support/v6.0/app/models/wizard.rb @@ -52,6 +52,8 @@ class Professor; end serialize :pets, Array serialize :patronus_characteristics, JSON + alias_attribute :ordinary_wizarding_level_results, :owl_results + has_one :wand has_many :spell_books # habtm which is optional at the db level diff --git a/spec/support/v6.0/sorbet_test_cases.rb b/spec/support/v6.0/sorbet_test_cases.rb index b46e810f..711044e8 100644 --- a/spec/support/v6.0/sorbet_test_cases.rb +++ b/spec/support/v6.0/sorbet_test_cases.rb @@ -8,6 +8,17 @@ # -- model columns T.assert_type!(wizard.name, T.nilable(String)) +spell_book = wizard.spell_books.first! +T.assert_type!(spell_book, SpellBook) + +# -- alias attributes +T.assert_type!(spell_book.title, String) # standard alias attribute +T.assert_type!(spell_book.book_category, String) # enum alias attribute +T.assert_type!( + wizard.ordinary_wizarding_level_results, # serialized alias attribute + T.nilable(T::Hash[T.untyped, T.untyped]) +) + # -- time/date columns T.assert_type!(wizard.created_at, ActiveSupport::TimeWithZone) T.assert_type!(wand.broken_at, T.nilable(Time)) @@ -161,7 +172,6 @@ T.assert_type!(Wizard.all.empty?, T::Boolean) # Finder methods -- CollectionProxy -spell_book = wizard.spell_books.first! spell_books = wizard.spell_books T.assert_type!(spell_books.exists?(name: 'Fantastic Beasts'), T::Boolean) T.assert_type!(spell_books.find(spell_book.id), SpellBook) diff --git a/spec/support/v6.1/app/models/spell_book.rb b/spec/support/v6.1/app/models/spell_book.rb index efe838aa..b0c6c951 100644 --- a/spec/support/v6.1/app/models/spell_book.rb +++ b/spec/support/v6.1/app/models/spell_book.rb @@ -14,5 +14,8 @@ class SpellBook < ApplicationRecord dark_art: 999, } + alias_attribute :title, :name + alias_attribute :book_category, :book_type + scope :recent, -> { where('created_at > ?', 1.month.ago) } end diff --git a/spec/support/v6.1/app/models/wizard.rb b/spec/support/v6.1/app/models/wizard.rb index 33b5f8c5..c1fff751 100644 --- a/spec/support/v6.1/app/models/wizard.rb +++ b/spec/support/v6.1/app/models/wizard.rb @@ -52,6 +52,8 @@ class Professor; end serialize :pets, Array serialize :patronus_characteristics, JSON + alias_attribute :ordinary_wizarding_level_results, :owl_results + has_one :wand has_many :spell_books # habtm which is optional at the db level diff --git a/spec/support/v6.1/sorbet_test_cases.rb b/spec/support/v6.1/sorbet_test_cases.rb index 63f90832..6600601f 100644 --- a/spec/support/v6.1/sorbet_test_cases.rb +++ b/spec/support/v6.1/sorbet_test_cases.rb @@ -8,6 +8,17 @@ # -- model columns T.assert_type!(wizard.name, T.nilable(String)) +spell_book = wizard.spell_books.first! +T.assert_type!(spell_book, SpellBook) + +# -- alias attributes +T.assert_type!(spell_book.title, String) # standard alias attribute +T.assert_type!(spell_book.book_category, String) # enum alias attribute +T.assert_type!( + wizard.ordinary_wizarding_level_results, # serialized alias attribute + T.nilable(T::Hash[T.untyped, T.untyped]) +) + # -- time/date columns T.assert_type!(wizard.created_at, ActiveSupport::TimeWithZone) T.assert_type!(wand.broken_at, T.nilable(Time)) @@ -163,7 +174,6 @@ T.assert_type!(Wizard.all.empty?, T::Boolean) # Finder methods -- CollectionProxy -spell_book = wizard.spell_books.first! spell_books = wizard.spell_books T.assert_type!(spell_books.exists?(name: 'Fantastic Beasts'), T::Boolean) T.assert_type!(spell_books.find(spell_book.id), SpellBook) diff --git a/spec/support/v7.0/app/models/spell_book.rb b/spec/support/v7.0/app/models/spell_book.rb index ab2fb0e0..0462a0c7 100644 --- a/spec/support/v7.0/app/models/spell_book.rb +++ b/spec/support/v7.0/app/models/spell_book.rb @@ -14,5 +14,8 @@ class SpellBook < ApplicationRecord dark_art: 999, } + alias_attribute :title, :name + alias_attribute :book_category, :book_type + scope :recent, -> { where('created_at > ?', 1.month.ago) } end diff --git a/spec/support/v7.0/app/models/wizard.rb b/spec/support/v7.0/app/models/wizard.rb index c4ff4e6d..58a89002 100644 --- a/spec/support/v7.0/app/models/wizard.rb +++ b/spec/support/v7.0/app/models/wizard.rb @@ -52,6 +52,8 @@ class Professor; end serialize :pets, Array serialize :patronus_characteristics, JSON + alias_attribute :ordinary_wizarding_level_results, :owl_results + has_one :wand has_many :spell_books # habtm which is optional at the db level diff --git a/spec/support/v7.0/sorbet_test_cases.rb b/spec/support/v7.0/sorbet_test_cases.rb index 0d9ffb72..c6ac18c5 100644 --- a/spec/support/v7.0/sorbet_test_cases.rb +++ b/spec/support/v7.0/sorbet_test_cases.rb @@ -8,6 +8,17 @@ # -- model columns T.assert_type!(wizard.name, T.nilable(String)) +spell_book = wizard.spell_books.first! +T.assert_type!(spell_book, SpellBook) + +# -- alias attributes +T.assert_type!(spell_book.title, String) # standard alias attribute +T.assert_type!(spell_book.book_category, String) # enum alias attribute +T.assert_type!( + wizard.ordinary_wizarding_level_results, # serialized alias attribute + T.nilable(T::Hash[T.untyped, T.untyped]) +) + # -- time/date columns T.assert_type!(wizard.created_at, ActiveSupport::TimeWithZone) T.assert_type!(wand.broken_at, T.nilable(Time)) @@ -162,7 +173,6 @@ T.assert_type!(Wizard.all.empty?, T::Boolean) # Finder methods -- CollectionProxy -spell_book = wizard.spell_books.first! spell_books = wizard.spell_books T.assert_type!(spell_books.exists?(name: 'Fantastic Beasts'), T::Boolean) T.assert_type!(spell_books.find(spell_book.id), SpellBook) diff --git a/spec/test_data/v5.2/expected_spell_book.rbi b/spec/test_data/v5.2/expected_spell_book.rbi index 34baa213..cc608d85 100644 --- a/spec/test_data/v5.2/expected_spell_book.rbi +++ b/spec/test_data/v5.2/expected_spell_book.rbi @@ -37,6 +37,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def book_type?; end + sig { returns(String) } + def book_category; end + + sig { params(value: T.any(Integer, String, Symbol)).void } + def book_category=(value); end + + sig { returns(T::Boolean) } + def book_category?; end + sig { returns(Integer) } def id; end @@ -55,6 +64,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def name?; end + sig { returns(String) } + def title; end + + sig { params(value: T.any(String, Symbol)).void } + def title=(value); end + + sig { returns(T::Boolean) } + def title?; end + sig { returns(Integer) } def wizard_id; end @@ -140,6 +158,12 @@ class SpellBook < ApplicationRecord sig { params(value: SpellBook::BookType).void } def typed_book_type=(value); end + sig { returns(SpellBook::BookType) } + def typed_book_category; end + + sig { params(value: SpellBook::BookType).void } + def typed_book_category=(value); end + class BookType < T::Enum enums do Unclassified = new(%q{unclassified}) diff --git a/spec/test_data/v5.2/expected_squib.rbi b/spec/test_data/v5.2/expected_squib.rbi index 5bf3b92d..ebcbbc7c 100644 --- a/spec/test_data/v5.2/expected_squib.rbi +++ b/spec/test_data/v5.2/expected_squib.rbi @@ -130,6 +130,15 @@ module Squib::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v5.2/expected_wizard.rbi b/spec/test_data/v5.2/expected_wizard.rbi index 90202f24..02ef8c28 100644 --- a/spec/test_data/v5.2/expected_wizard.rbi +++ b/spec/test_data/v5.2/expected_wizard.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi b/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi index 3b2f4868..e9e33591 100644 --- a/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi +++ b/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.0/expected_spell_book.rbi b/spec/test_data/v6.0/expected_spell_book.rbi index 121a89dc..65568b0c 100644 --- a/spec/test_data/v6.0/expected_spell_book.rbi +++ b/spec/test_data/v6.0/expected_spell_book.rbi @@ -37,6 +37,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def book_type?; end + sig { returns(String) } + def book_category; end + + sig { params(value: T.any(Integer, String, Symbol)).void } + def book_category=(value); end + + sig { returns(T::Boolean) } + def book_category?; end + sig { returns(Integer) } def id; end @@ -55,6 +64,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def name?; end + sig { returns(String) } + def title; end + + sig { params(value: T.any(String, Symbol)).void } + def title=(value); end + + sig { returns(T::Boolean) } + def title?; end + sig { returns(Integer) } def wizard_id; end @@ -149,6 +167,12 @@ class SpellBook < ApplicationRecord sig { params(value: SpellBook::BookType).void } def typed_book_type=(value); end + sig { returns(SpellBook::BookType) } + def typed_book_category; end + + sig { params(value: SpellBook::BookType).void } + def typed_book_category=(value); end + class BookType < T::Enum enums do Unclassified = new(%q{unclassified}) diff --git a/spec/test_data/v6.0/expected_squib.rbi b/spec/test_data/v6.0/expected_squib.rbi index 79c00a7e..92e61517 100644 --- a/spec/test_data/v6.0/expected_squib.rbi +++ b/spec/test_data/v6.0/expected_squib.rbi @@ -130,6 +130,15 @@ module Squib::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.0/expected_wizard.rbi b/spec/test_data/v6.0/expected_wizard.rbi index bc1fbc52..ddb49024 100644 --- a/spec/test_data/v6.0/expected_wizard.rbi +++ b/spec/test_data/v6.0/expected_wizard.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi b/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi index 814ca593..b46c2453 100644 --- a/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi +++ b/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.1/expected_spell_book.rbi b/spec/test_data/v6.1/expected_spell_book.rbi index d00eb8bb..d8f7ff5b 100644 --- a/spec/test_data/v6.1/expected_spell_book.rbi +++ b/spec/test_data/v6.1/expected_spell_book.rbi @@ -37,6 +37,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def book_type?; end + sig { returns(String) } + def book_category; end + + sig { params(value: T.any(Integer, String, Symbol)).void } + def book_category=(value); end + + sig { returns(T::Boolean) } + def book_category?; end + sig { returns(Integer) } def id; end @@ -55,6 +64,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def name?; end + sig { returns(String) } + def title; end + + sig { params(value: T.any(String, Symbol)).void } + def title=(value); end + + sig { returns(T::Boolean) } + def title?; end + sig { returns(Integer) } def wizard_id; end @@ -149,6 +167,12 @@ class SpellBook < ApplicationRecord sig { params(value: SpellBook::BookType).void } def typed_book_type=(value); end + sig { returns(SpellBook::BookType) } + def typed_book_category; end + + sig { params(value: SpellBook::BookType).void } + def typed_book_category=(value); end + class BookType < T::Enum enums do Unclassified = new(%q{unclassified}) diff --git a/spec/test_data/v6.1/expected_squib.rbi b/spec/test_data/v6.1/expected_squib.rbi index fbac8d3f..5404ad69 100644 --- a/spec/test_data/v6.1/expected_squib.rbi +++ b/spec/test_data/v6.1/expected_squib.rbi @@ -130,6 +130,15 @@ module Squib::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.1/expected_wizard.rbi b/spec/test_data/v6.1/expected_wizard.rbi index 3884877c..e098aa2c 100644 --- a/spec/test_data/v6.1/expected_wizard.rbi +++ b/spec/test_data/v6.1/expected_wizard.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v6.1/expected_wizard_wo_spellbook.rbi b/spec/test_data/v6.1/expected_wizard_wo_spellbook.rbi index db2b31c5..e806b011 100644 --- a/spec/test_data/v6.1/expected_wizard_wo_spellbook.rbi +++ b/spec/test_data/v6.1/expected_wizard_wo_spellbook.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v7.0/expected_spell_book.rbi b/spec/test_data/v7.0/expected_spell_book.rbi index 5148e68c..c8c39396 100644 --- a/spec/test_data/v7.0/expected_spell_book.rbi +++ b/spec/test_data/v7.0/expected_spell_book.rbi @@ -37,6 +37,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def book_type?; end + sig { returns(String) } + def book_category; end + + sig { params(value: T.any(Integer, String, Symbol)).void } + def book_category=(value); end + + sig { returns(T::Boolean) } + def book_category?; end + sig { returns(Integer) } def id; end @@ -55,6 +64,15 @@ module SpellBook::GeneratedAttributeMethods sig { returns(T::Boolean) } def name?; end + sig { returns(String) } + def title; end + + sig { params(value: T.any(String, Symbol)).void } + def title=(value); end + + sig { returns(T::Boolean) } + def title?; end + sig { returns(Integer) } def wizard_id; end @@ -149,6 +167,12 @@ class SpellBook < ApplicationRecord sig { params(value: SpellBook::BookType).void } def typed_book_type=(value); end + sig { returns(SpellBook::BookType) } + def typed_book_category; end + + sig { params(value: SpellBook::BookType).void } + def typed_book_category=(value); end + class BookType < T::Enum enums do Unclassified = new(%q{unclassified}) diff --git a/spec/test_data/v7.0/expected_squib.rbi b/spec/test_data/v7.0/expected_squib.rbi index e4baa46b..d1129216 100644 --- a/spec/test_data/v7.0/expected_squib.rbi +++ b/spec/test_data/v7.0/expected_squib.rbi @@ -130,6 +130,15 @@ module Squib::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v7.0/expected_wizard.rbi b/spec/test_data/v7.0/expected_wizard.rbi index 189f89bc..19762fd9 100644 --- a/spec/test_data/v7.0/expected_wizard.rbi +++ b/spec/test_data/v7.0/expected_wizard.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end diff --git a/spec/test_data/v7.0/expected_wizard_wo_spellbook.rbi b/spec/test_data/v7.0/expected_wizard_wo_spellbook.rbi index ae2fac1f..b3baceaf 100644 --- a/spec/test_data/v7.0/expected_wizard_wo_spellbook.rbi +++ b/spec/test_data/v7.0/expected_wizard_wo_spellbook.rbi @@ -130,6 +130,15 @@ module Wizard::GeneratedSerializedAttributeMethods sig { returns(T::Boolean) } def owl_results?; end + sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) } + def ordinary_wizarding_level_results; end + + sig { params(value: T.nilable(T::Hash[T.untyped, T.untyped])).void } + def ordinary_wizarding_level_results=(value); end + + sig { returns(T::Boolean) } + def ordinary_wizarding_level_results?; end + sig { returns(T.nilable(ActiveRecord::Coders::JSON)) } def patronus_characteristics; end