Module: RailsFields::ClassMethods
- Defined in:
- lib/rails_fields/class_methods.rb
Instance Attribute Summary collapse
-
#name ⇒ type
Declares a field with enforcement.
Instance Method Summary collapse
-
#declared_fields ⇒ Object
TODO: Check all models at rails init app? like migrations?.
- #declared_fields=(value) ⇒ Object
- #enforce_declared_fields ⇒ Object
-
#field(name, type, null: true, index: false) ⇒ type
Declares a field with enforcement.
- #gql_type ⇒ Object
- #write_migration(index: nil) ⇒ Object
Instance Attribute Details
#name ⇒ type
Declares a field with enforcement.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rails_fields/class_methods.rb', line 30 def field(name, type, null: true, index: false) # Check if type is a valid GraphQL type # GraphQL::Types.const_get(type) if type.is_a?(Symbol) || type.is_a?(String) unless Utils.valid_type?(type) raise Errors::RailsFieldsUnknownTypeError.new(" Declared field '#{name}' in class '#{self.name}' of unknown type '#{type}'. Allowed types are: #{Utils.allowed_types.join(', ')}. ") end declared_fields << OpenStruct.new(name: name.to_s, type:, null:, index:) end |
Instance Method Details
#declared_fields ⇒ Object
TODO: Check all models at rails init app? like migrations?
5 6 7 |
# File 'lib/rails_fields/class_methods.rb', line 5 def declared_fields @declared_fields ||= [] end |
#declared_fields=(value) ⇒ Object
9 10 11 |
# File 'lib/rails_fields/class_methods.rb', line 9 def declared_fields=(value) @declared_fields = value end |
#enforce_declared_fields ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rails_fields/class_methods.rb', line 87 def enforce_declared_fields database_columns = column_names.map(&:to_sym) declared_fields_names = declared_fields.map(&:name).map(&:to_sym) || [] changes = RailsFields::Utils.detect_changes(self) migration = RailsFields::Utils.generate_migration(self, changes) instance_methods = self.instance_methods(false).select do |method| instance_method(method).source_location.first.start_with?(Rails.root.to_s) end extra_methods = instance_methods - declared_fields_names.map(&:to_sym) has_changes = !changes.nil? unless extra_methods.empty? # TODO: Custom error subclass raise "You have extra methods declared in #{name}: #{extra_methods.join(', ')}. Please remove them or declare them as fields." end if has_changes = <<~STRING ---------------- Declared Fields: #{declared_fields_names.join(', ')} Database columns: #{database_columns.join(', ')} Changes: #{changes.to_yaml.lines[1..-1].join} Migration: #{migration} ---------------- STRING raise Errors::RailsFieldsMismatchError.new() end end |
#field(name, type, null: true, index: false) ⇒ type
Declares a field with enforcement.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rails_fields/class_methods.rb', line 30 def field(name, type, null: true, index: false) # Check if type is a valid GraphQL type # GraphQL::Types.const_get(type) if type.is_a?(Symbol) || type.is_a?(String) unless Utils.valid_type?(type) raise Errors::RailsFieldsUnknownTypeError.new(" Declared field '#{name}' in class '#{self.name}' of unknown type '#{type}'. Allowed types are: #{Utils.allowed_types.join(', ')}. ") end declared_fields << OpenStruct.new(name: name.to_s, type:, null:, index:) end |
#gql_type ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/rails_fields/class_methods.rb', line 42 def gql_type return RailsFields.processed_classes[self] if RailsFields.processed_classes[self].present? fields = declared_fields owner_self = self type = Class.new(::Types::BaseObject) do # graphql_name "#{owner_self.name}Type" graphql_name "#{owner_self.name}" description "A type representing a #{owner_self.name}" fields.each do |f| next if f.type.nil? # TODO: ! remove references fields # Assuming a proper mapping from your custom types to GraphQL types # TODO: use a better method or block field_gql_type = f.name == :id ? GraphQL::Types::ID : Utils::RAILS_TO_GQL_TYPE_MAP[f.type] field f.name, field_gql_type end end # Cache the processed class here to prevent infinite recursion RailsFields.processed_classes[self] = type type.instance_eval do owner_self.reflections.each do |association_name, reflection| if reflection.macro == :has_many reflection_klass = if reflection.[:through] through_reflection_klass = reflection.through_reflection.klass source_reflection_name = reflection.source_reflection_name.to_s source_reflection = through_reflection_klass.reflections[source_reflection_name] source_reflection ? source_reflection.klass : through_reflection_klass else reflection.klass end field association_name, [reflection_klass.gql_type], null: true elsif reflection.macro == :belongs_to field association_name, reflection.klass.gql_type, null: true end end type end end |
#write_migration(index: nil) ⇒ Object
13 14 15 16 |
# File 'lib/rails_fields/class_methods.rb', line 13 def write_migration(index: nil) changes = RailsFields::Utils.detect_changes(self) RailsFields::Utils.generate_migration(self, changes, index:, write: true) end |