From 25544c9d007c92b96928a7277cb87088f531ded0 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Tue, 25 Aug 2026 11:40:00 +0200 Subject: [PATCH] feat(orm): add belongs_to and has_many associations --- lib/prism/orm/associable.rb | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/prism/orm/associable.rb diff --git a/lib/prism/orm/associable.rb b/lib/prism/orm/associable.rb new file mode 100644 index 0000000..0e3045d --- /dev/null +++ b/lib/prism/orm/associable.rb @@ -0,0 +1,44 @@ +module Prism + module Orm + module Associable + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + def associations + @associations ||= {} + end + + def belongs_to(name, class_name: nil, foreign_key: nil) + target = class_name || Inflector.camelize(name.to_s) + key = (foreign_key || "#{name}_id").to_s + associations[name.to_sym] = { type: :belongs_to, class_name: target, foreign_key: key } + + define_method(name) do + value = self[key] + next nil if value.nil? + @association_cache ||= {} + @association_cache[name] ||= Object.const_get(target).find(value) + end + + define_method("#{name}=") do |record| + self[key] = record&.id + @association_cache ||= {} + @association_cache[name] = record + end + end + + def has_many(name, class_name: nil, foreign_key: nil) + target = class_name || Inflector.classify(name.to_s) + key = (foreign_key || "#{Inflector.underscore(self.name)}_id").to_s + associations[name.to_sym] = { type: :has_many, class_name: target, foreign_key: key } + + define_method(name) do + Object.const_get(target).where(key => id) + end + end + end + end + end +end