Class: ActiveFacts::Metamodel::ObjectType
- Inherits:
-
Object
- Object
- ActiveFacts::Metamodel::ObjectType
- Defined in:
- lib/activefacts/generators/traits/rails.rb,
lib/activefacts/generators/helpers/rails.rb,
lib/activefacts/generators/metadata/json.rb,
lib/activefacts/generators/transform/surrogate.rb
Instance Method Summary collapse
- #add_surrogate(type_name = 'Auto Counter', suffix = 'ID') ⇒ Object
- #as_json_metadata ⇒ Object
- #rails_class_name ⇒ Object
- #rails_name ⇒ Object
- #rails_singular_name ⇒ Object
Instance Method Details
#add_surrogate(type_name = 'Auto Counter', suffix = 'ID') ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# 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 = constellation.FactType(:concept => :new) my_role = constellation.Role(:concept => :new, :fact_type => , :ordinal => 0, :object_type => self) @injected_surrogate_role = my_role id_role = constellation.Role(:concept => :new, :fact_type => , :ordinal => 1, :object_type => my_id) # Create a reading (which needs a RoleSequence) reading = constellation.Reading( :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 ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/activefacts/generators/metadata/json.rb', line 55 def # 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.(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 ⇒ Object
127 128 129 |
# File 'lib/activefacts/generators/traits/rails.rb', line 127 def rails_class_name ActiveSupport::Inflector.camelize(name.gsub(/\s+/, '_')) end |
#rails_name ⇒ Object
119 120 121 |
# File 'lib/activefacts/generators/traits/rails.rb', line 119 def rails_name RMap::rails_plural_name(name) end |
#rails_singular_name ⇒ Object
123 124 125 |
# File 'lib/activefacts/generators/traits/rails.rb', line 123 def rails_singular_name RMap::rails_singular_name(name) end |