class ActiveFacts::Metamodel::ObjectType
Public Instance Methods
add_surrogate(type_name = 'Auto Counter', suffix = 'ID')
click to toggle source
# File lib/activefacts/generators/transform/surrogate.rb, line 15 def add_surrogate type_name = 'Auto Counter', suffix = 'ID' # Find or assert the surrogate value type auto_counter = vocabulary.valid_value_type_name(type_name) || constellation.ValueType(:vocabulary => vocabulary, :name => type_name, :concept => [:new, :implication_rule => 'Surrogate key transform']) # Create a subtype to identify this entity type: vt_name = self.name + ' '+suffix my_id = @vocabulary.valid_value_type_name(vt_name) || constellation.ValueType(:vocabulary => vocabulary, :name => vt_name, :concept => :new, :supertype => auto_counter) # Create a fact type identifying_fact_type = constellation.FactType(:concept => :new) my_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 0, :object_type => self) @injected_surrogate_role = my_role id_role = constellation.Role(:concept => :new, :fact_type => identifying_fact_type, :ordinal => 1, :object_type => my_id) # Create a reading (which needs a RoleSequence) reading = constellation.Reading( :fact_type => identifying_fact_type, :ordinal => 0, :role_sequence => [:new], :text => "{0} has {1}" ) constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 0, :role => my_role) constellation.RoleRef(:role_sequence => reading.role_sequence, :ordinal => 1, :role => id_role) # Create two uniqueness constraints for the one-to-one. Each needs a RoleSequence (two RoleRefs) one_id = constellation.PresenceConstraint( :concept => :new, :vocabulary => vocabulary, :name => self.name+'HasOne'+suffix, :role_sequence => [:new], :is_mandatory => true, :min_frequency => 1, :max_frequency => 1, :is_preferred_identifier => false ) @constellation.RoleRef(:role_sequence => one_id.role_sequence, :ordinal => 0, :role => my_role) one_me = constellation.PresenceConstraint( :concept => :new, :vocabulary => vocabulary, :name => self.name+suffix+'IsOfOne'+self.name, :role_sequence => [:new], :is_mandatory => false, :min_frequency => 0, :max_frequency => 1, :is_preferred_identifier => true ) @constellation.RoleRef(:role_sequence => one_me.role_sequence, :ordinal => 0, :role => id_role) end
as_json_metadata()
click to toggle source
# File lib/activefacts/generators/metadata/json.rb, line 55 def as_json_metadata # Using proc avoids polluting the object's namespace with these little methods verbalise_role = proc do |role, plural| fc = Array.new(role.fact_type.all_role.size, plural ? 'some' : 'one') reading = role.fact_type.reading_preferably_starting_with_role(role) fc.reverse! unless reading.role_sequence.all_role_ref.to_a[0].role == role fc[reading.role_sequence.all_role_ref_in_order.to_a.index{|rr| rr.role == role}] = 'this' reading.expand(fc, false) end titlize_words = proc do |phrase| phrase && phrase.split(/\s+/).map{|w| w.sub(/^[a-z]/) {|i| i.upcase}}*' ' end role_name = proc do |role| if role.role_name role.role_name else ref = role.preferred_reference [ titlize_words.call(ref.leading_adjective), role.object_type.name, titlize_words.call(ref.trailing_adjective)].compact*' ' end end return nil if name == '_ImplicitBooleanValueType' object_type = {} object_type["is_main"] = is_table object_type["id"] = concept.guid.to_s functions = object_type["functions"] = [] if is_a?(ActiveFacts::Metamodel::EntityType) # Don't emit a binary objectified fact type that plays no roles (except in implicit fact types: if fact_type and fact_type.all_role.size == 2 and all_role.size == 2 return nil end # Export the supertypes (supertypes_transitive-[self]).sort_by{|t| t.name}.each do |supertype| functions << { "title" => "as #{supertype.name}", "type" => "#{supertype.name}" } end # Export the subtypes (subtypes_transitive-[self]).sort_by{|t| t.name}.each do |subtype| functions << { "title" => "as #{subtype.name}", "type" => "#{subtype.name}" } end # If an objectified fact type, export the fact type's roles if fact_type fact_type.preferred_reading.role_sequence.all_role_ref_in_order.map(&:role).each do |role| functions << { "title" => "involving #{role_name.call(role)}", "type" => "#{role.object_type.name}", "where" => verbalise_role.call(role, true) # REVISIT: Need plural setting here! } end end end # Now export the ordinary roles. Get a sorted list first: roles = all_role.reject do |role| # supertype and subtype roles get handled separately role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) || role.fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType) end.sort_by do |role| # Where this object type plays two roles in the same fact type, # we order them by the position of that role in the preferred reading: [role.fact_type.default_reading, role.fact_type.preferred_reading.role_sequence.all_role_ref_in_order.map(&:role).index(role)] end # For binary fact types, collect the count of the times the unadorned counterpart role name occurs, so we can adorn it plural_counterpart_counts = roles.inject(Hash.new{0}) do |h, role| next h unless role.fact_type.all_role.size == 2 uc = role.all_role_ref.detect do |rr| rs = rr.role_sequence next false if rs.all_role_ref.size != 1 # Looking for a UC over just this one role rs.all_presence_constraint.detect do |pc| next false unless pc.max_frequency == 1 # It's a uniqueness constraint true end end next h if uc # Not a plural role counterpart_role = (role.fact_type.all_role.to_a - [role])[0] h[role_name.call(counterpart_role)] += 1 h end roles.each do |role| type_name = nil counterpart_name = nil if role.fact_type.entity_type and # Role is in an objectified fact type # For binary objectified fact types, we traverse directly to the other role, not just to the objectification !(role.fact_type.entity_type.all_role.size == 2 and role.fact_type.all_role.size == 2) type_name = role.fact_type.entity_type.name counterpart_name = type_name # If self plays more than one role in OFT, need to construct a role name plural = true elsif role.fact_type.all_role.size == 1 # Handle unary roles type_name = 'boolean' counterpart_name = role.fact_type.default_reading plural = false else # Handle binary roles counterpart_role = (role.fact_type.all_role.to_a - [role])[0] type_name = counterpart_role.object_type.name counterpart_name = role_name.call(counterpart_role) # Figure out whether the counterpart is plural (say "all ..." if so) uc = role.all_role_ref.detect do |rr| rs = rr.role_sequence next false if rs.all_role_ref.size != 1 # Looking for a UC over just this one role rs.all_presence_constraint.detect do |pc| next false unless pc.max_frequency == 1 # It's a uniqueness constraint true end end plural = !uc if plural_counterpart_counts[counterpart_name] > 1 counterpart_name += " as " + role_name.call(role) end end node = { "title" => "#{plural ? 'all ' : ''}#{counterpart_name}", "type" => "#{type_name}", "where" => verbalise_role.call(role, plural), "role_id" => role.concept.guid.to_s } node["is_list"] = true if plural functions << node end functions.size > 0 ? object_type : nil end
rails_class_name()
click to toggle source
# File lib/activefacts/generators/traits/rails.rb, line 127 def rails_class_name ActiveSupport::Inflector.camelize(name.gsub(/\s+/, '_')) end
rails_name()
click to toggle source
# File lib/activefacts/generators/traits/rails.rb, line 119 def rails_name RMap::rails_plural_name(name) end
rails_singular_name()
click to toggle source
# File lib/activefacts/generators/traits/rails.rb, line 123 def rails_singular_name RMap::rails_singular_name(name) end