Module: RTM::AR::TraverseAssociations
- Included in:
- Sugar::Topic::PredefinedAssociations
- Defined in:
- lib/rtm/activerecord/traverse_associations.rb,
lib/rtm/activerecord.rb
Instance Method Summary collapse
-
#define_association(prop, options = {}) ⇒ Object
defines methods to traverse a specific assocation for all topics.
Instance Method Details
#define_association(prop, options = {}) ⇒ Object
defines methods to traverse a specific assocation for all topics
7 8 9 10 11 12 13 14 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rtm/activerecord/traverse_associations.rb', line 7 def define_association(prop, ={}) r = [:rule] module_eval(" def direct_\#{prop}_roles\n # prefetch typing topics\n rtype = @ips_\#{prop}_rtype ||= self.topic_map.get(\"\#{r[:role_type]}\")\n atype = @ips_\#{prop}_atype ||= self.topic_map.get(\"\#{r[:association_type]}\")\n otype = @ips_\#{prop}_otype ||= self.topic_map.get(\"\#{r[:other_role_type]}\")\n # return nothing if any of the typing topics does not exist\n return [] unless rtype && atype && otype\n # we do that only here and not earlier because some might me nil\n rtype = rtype.id\n atype = atype.id\n otype = otype.id\n self.__getobj__.roles.map{|r|\n r.ttype_id != nil &&\n r.ttype_id == rtype &&\n r.parent.roles.size == \#{r[:association_arity]} &&\n r.parent != nil &&\n r.parent.ttype_id == atype &&\n (r2 = r.parent.roles.select{|r2| r2.ttype_id != nil &&\n r2.ttype_id == otype}.first) &&\n r2}.select{|r2| r2}.map{|r2| AssociationRole.wrap(r2)}\n end\n def direct_\#{prop}\n direct_\#{prop}_roles.map{|r2| r2.player}.uniq\n end\n EOS\n \n if r[:transitive]\n module_eval(<<-EOS, \"(__AR_DELEGATOR_DEFINE_ASSOCIATION2__)\", 1)\n def \#{prop}\n d = todo = self.direct_\#{prop}\n while todo.size > 0\n todo = todo.map{|dt| dt.direct_\#{prop}}.flatten.uniq - d\n d += todo\n end\n d\n #d2 = self.direct_\#{prop}.map {|dt| dt.\#{prop}}.flatten\n #(d+d2).uniq\n end\n EOS\n else\n if r[:infer] && r[:infer_other] # this part is not testet at all!\n module_eval(<<-EOS, \"(__AR_DELEGATOR_DEFINE_ASSOCIATION3a__)\", 1)\n def \#{prop}\n dps = (self + self.\#{r[:infer]}).flatten.uniq\n dcps = dps.map{|d2| d2.direct_\#{prop}}\n (dcps + dcps.map{|d2| d2.\#{r[:infer_other]}}).flatten.uniq\n end\n EOS\n elsif r[:infer]\n module_eval(<<-EOS, \"(__AR_DELEGATOR_DEFINE_ASSOCIATION3__)\", 1)\n def \#{prop}\n (self.direct_\#{prop} + self.\#{r[:infer]}.map{|d2| d2.direct_\#{prop}}).flatten.uniq\n end\n EOS\n elsif r[:infer_other]\n module_eval(<<-EOS, \"(__AR_DELEGATOR_DEFINE_ASSOCIATION4__)\", 1)\n def \#{prop}\n d = self.direct_\#{prop}\n (d + d.map{|d2| d2.\#{r[:infer_other]}}).flatten.uniq\n end\n EOS\n end\n end\n if r[:add]\n module_eval(<<-EOS, \"(__AR_DELEGATOR_DEFINE_ASSOCIATION_ADD_REMOVE__)\", 1)\n def add_\#{r[:add]}(t)\n a = self.topic_map.create_association(\"\#{r[:association_type]}\")\n a.create_role self, \"\#{r[:role_type]}\"\n a.create_role t, \"\#{r[:other_role_type]}\"\n a\n # TODO add_x in define_association needs to trigger reload of the topics somewhere\n end\n def remove_\#{r[:add]}(t)\n direct_\#{prop}_roles.select{|r| r.player == t}.each{|r| r.parent.remove}\n # TODO remove_x in define_association needs to trigger reload of the topics somewhere\n end\n EOS\n end\nend\n", "(__AR_DELEGATOR_DEFINE_ASSOCIATION__)", 1) |