tina4ruby 3.10.85 → 3.10.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e5521375e695d48e70b9f86d6a5c7abb62f9e887ee02ab975308bd51a99ee91
4
- data.tar.gz: fd6c0fb85f91def5fbae4996752c70c36f184cfbec1f61cbc4d3949a8109a4fc
3
+ metadata.gz: c48ff6ca420828c13d58b56461236b1cc88f183d8c26ef07d659a5fdbae0387b
4
+ data.tar.gz: c97876faf8d439dbb7c843708dceaac560c68261d5ba3e10c370b5986e8f0458
5
5
  SHA512:
6
- metadata.gz: 3d4a4d7db8e8fa3b87df07f19ab708ef9a3aebc00d40a5280adf7637869ef9ea40a4b1afce22aa3fd83bfdc6de073fb3eaa34c4842bdc5e6dedf2947758c6cd9
7
- data.tar.gz: fdb5d4fd739f8926f8ec6cbed5d12691219d8938217bc7f3234fa8e1d166487ed8f12095c45e5dd128a3782412b1ef0685d85901e7972db05a0565e48baea4d6
6
+ metadata.gz: 81043f5493f03b8abe8fed8291bba748df5c770cd711a8825837cff14ee9ab855d30736fcf4d2b5f0d5dea9148b6e2b29fbc4fb44c6bbbeb1918741be0d219bc
7
+ data.tar.gz: b918fb9ee51de4a14412ec5b5f0503da65ff7669244c6ff1653c77ab2af02898e4cafc73e7f3b2c95ab07f927f61415cc9318882292d38e2582e55b8eb140d93
@@ -79,6 +79,67 @@ module Tina4
79
79
  register_field(name, :json, nullable: nullable, default: default)
80
80
  end
81
81
 
82
+ # Declare a foreign key integer column and auto-wire relationships.
83
+ #
84
+ # Automatically:
85
+ # - Registers an integer field for the column
86
+ # - Calls belongs_to on this class (strip _id suffix for association name)
87
+ # - Calls has_many on the referenced class (if already loaded)
88
+ #
89
+ # @param name [Symbol] Column name (e.g. :user_id)
90
+ # @param references [Class, String] Referenced model class or its name
91
+ # @param related_name [Symbol, String, nil] Override the has-many name on the referenced model
92
+ #
93
+ # Example:
94
+ # class Post < Tina4::ORM
95
+ # integer_field :id, primary_key: true
96
+ # foreign_key_field :user_id, references: User
97
+ # end
98
+ # # post.user → belongs_to auto-wired
99
+ # # user.posts → has_many auto-wired
100
+ def foreign_key_field(name, references:, related_name: nil, **options)
101
+ register_field(name, :integer, **options)
102
+
103
+ # Derive association name: strip _id suffix
104
+ belongs_name = name.to_s.end_with?("_id") ? name.to_s[0..-4].to_sym : name.to_sym
105
+
106
+ # Wire belongs_to on this class
107
+ belongs_to(belongs_name, class_name: references.to_s.split("::").last, foreign_key: name.to_s) if respond_to?(:belongs_to, true)
108
+
109
+ # Wire has_many on referenced class (if already a loaded Class)
110
+ if references.is_a?(Class) && references.respond_to?(:has_many, true)
111
+ hm_name = (related_name || "#{self.name.split("::").last.downcase}s").to_sym
112
+ references.has_many(hm_name, class_name: self.name.split("::").last, foreign_key: name.to_s)
113
+ end
114
+
115
+ # Register for deferred wiring (resolves when referenced class is later loaded)
116
+ @@_fk_registry ||= {}
117
+ ref_name = references.is_a?(Class) ? references.name.split("::").last : references.to_s.split("::").last
118
+ @@_fk_registry[ref_name] ||= []
119
+ hm_key = (related_name || "#{self.name.split("::").last.downcase}s").to_s
120
+ @@_fk_registry[ref_name] << {
121
+ declaring_class: self,
122
+ has_many_name: hm_key.to_sym,
123
+ foreign_key: name.to_s
124
+ }
125
+ end
126
+
127
+ # Apply any deferred FK-registry has_many wiring for this class.
128
+ # Called automatically when a class that is referenced by a ForeignKeyField is defined.
129
+ def apply_fk_registry!
130
+ class_simple_name = self.name.split("::").last
131
+ return unless defined?(@@_fk_registry) && @@_fk_registry.key?(class_simple_name)
132
+
133
+ @@_fk_registry[class_simple_name].each do |entry|
134
+ next if entry[:applied]
135
+
136
+ has_many(entry[:has_many_name],
137
+ class_name: entry[:declaring_class].name.split("::").last,
138
+ foreign_key: entry[:foreign_key]) if respond_to?(:has_many, true)
139
+ entry[:applied] = true
140
+ end
141
+ end
142
+
82
143
  private
83
144
 
84
145
  def register_field(name, type, **options)
data/lib/tina4/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tina4
4
- VERSION = "3.10.85"
4
+ VERSION = "3.10.86"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tina4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.85
4
+ version: 3.10.86
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tina4 Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-08 00:00:00.000000000 Z
11
+ date: 2026-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack