Как мне написать ассоциацию Rails 5.2 для отношений, хранящихся в jsonb?
В некоторых местах я использую PostgreSQL jsonb для гибкого хранения отношений с другими моделями.Например, мы используем комбинацию STI и jsonb для создания гибкого журнала событий.
class Event < ApplicationRecord
include HasJsonbAccessors
end
class Event::AddedUserToGroup < Event
jsonb_belongs_to :user
jsonb_belongs_to :group
end
class Event::UserPurchase < Event
jsonb_belongs_to :user
jsonb_belongs_to :order
end
С jsonb_accessor
мы собрали вместе методы доступа и проверки.
module HasJsonbAccessors
extend ActiveSupport::Concern
class_methods do
def jsonb_belongs_to(association, optional: false)
association_id_field = "#{association}_id".to_sym
association_class = association.to_s.classify.constantize
jsonb_accessor :data,
association_id_field => :integer
validates association, presence: true unless optional
define_method(association) do
association_class.where(id: self.send(association_id_field)).first
end
define_method("#{association}=".to_sym) do |object|
self.send("#{association_id_field}=".to_sym, object.id)
end
end
end
end
Другой пример, гибкий набор правил фильтрации, которые потенциально могут использовать список любых моделей.Я взломал основы отношений has_many
.
class FilterRules < ApplicationRecord
jsonb_accessor :rules,
group_ids: [:integer, array: true],
other_rule: :string,
...
def groups
return [] if !group_ids
return Group.find(group_ids)
end
def groups=(groups)
self.group_ids = groups.try(:map, &:id)
end
end
Но без настоящей ассоциации многие инструменты не будут работать с этими моделями.Например, ActiveAdmin и Formtastic хотят настоящую ассоциацию has_many.И мы не получаем реляционную целостность или каскады.
Я смотрел на activerecord-jsonb-Ассоциации , но он копается в кишках Rails и нарушается изменениями 5.1 -> 5.2за пределами моей способности ремонтировать.
Есть ли какие-либо указатели для начала написания правильной пользовательской ассоциации Rails?