module PgGraph::Data class Association attr_reader :this_table attr_reader :this_field attr_reader :that_table attr_reader :that_field # Dimension of the association attr_reader :dimension def initialize(dimension, this_table, that_table, this_field, that_field) Dimension.validate(dimension, min: 1) constrain this_table, Table constrain that_table, Table constrain this_field, String, Symbol constrain that_field, String, Symbol @dimension = dimension @this_table, @this_field = this_table, this_field @that_table, @that_field = that_table, that_field end # Query the association and return a query object (Record, Query, or # QueryWithDuplicates) def query(field) raise NotThis end # Get object(s). Either a single record or a list of (possible duplicate) # records def get(record) dimension == 1 ? get_record(record) : get_records(record) end def get_record(this_record) if that_field == :id that_table[this_record[this_field].value] else that_table.records.find { |that_record| that_record[that_field].value == this_record[this_field].value } end end def get_records(this_record) that_table.records.find_all { |that_record| that_record[that_field].value == this_record[this_field].value } end end class KindAssociation < Association end class LinkAssociation < Association # From this table to the link table. TableAssociation object attr_reader :this_association # From the link table to 'that' table. RecordAssociation object attr_reader :that_association # The link table in the N:M relation def link_table() this_association.that_table end # The field in the link table that links to this record def this_link_field() this_association.that_field end # The field in the link table that links to that record def that_link_field() that_association.this_field end def initialize( dimension, this_table, that_table, link_table, this_field, this_link_field, that_link_field, that_field) super(dimension, this_table, that_table, this_field, that_field) @this_association = Association.new(2, this_table, link_table, this_field, this_link_field) @that_association = Association.new(1, link_table, that_table, that_link_field, that_field) end # Note that records are not unique for MmTableAssociation but for # NmTableAssociation objects def get_records(record) @this_association.get(record).map { |link_record| @that_association.get(link_record) } end end end