engine-rea 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/VERSION +1 -1
  2. data/app/models/rea/category.rb +4 -0
  3. data/app/models/rea/category_member.rb +1 -0
  4. data/app/models/rea/category_type.rb +1 -1
  5. data/app/models/rea/group.rb +17 -6
  6. data/app/models/rea/group_type.rb +7 -0
  7. data/app/models/rea/identifier.rb +12 -3
  8. data/config/locales/en.yml +4 -0
  9. data/config/locales/zh-CN.yml +42 -0
  10. data/db/migrate/20120601074531_create_rea_category_types.rb +1 -1
  11. data/db/migrate/20120601074540_create_rea_categories.rb +1 -1
  12. data/db/migrate/20120605030658_create_rea_groups.rb +14 -3
  13. data/db/migrate/20120605082028_create_rea_identifiers.rb +2 -2
  14. data/db/migrate/20120717080004_create_rea_group_types.rb +7 -0
  15. data/engine-rea.gemspec +31 -14
  16. data/lib/generators/rea/install/install_generator.rb +8 -0
  17. data/lib/rails_patch.rb +26 -0
  18. data/lib/rea.rb +25 -1
  19. data/lib/rea/application.rb +86 -0
  20. data/lib/rea/aspect_type.rb +28 -6
  21. data/lib/rea/aspect_type/base.rb +3 -2
  22. data/lib/rea/aspect_type/classification.rb +142 -0
  23. data/lib/rea/aspect_type/description.rb +3 -2
  24. data/lib/rea/aspect_type/due_date.rb +34 -0
  25. data/lib/rea/aspect_type/identification.rb +38 -0
  26. data/lib/rea/engine.rb +1 -3
  27. data/lib/rea/meta_type.rb +1 -1
  28. data/lib/rea/meta_type/agent.rb +1 -1
  29. data/lib/rea/meta_type/commitment.rb +5 -6
  30. data/lib/rea/meta_type/contract.rb +17 -4
  31. data/lib/rea/meta_type/conversion.rb +6 -0
  32. data/lib/rea/meta_type/entity.rb +61 -20
  33. data/lib/rea/meta_type/event.rb +17 -24
  34. data/lib/rea/meta_type/exchange.rb +6 -0
  35. data/lib/rea/meta_type/group.rb +25 -0
  36. data/lib/rea/meta_type/process.rb +28 -0
  37. data/lib/rea/meta_type/resource.rb +5 -1
  38. data/lib/rea/model.rb +65 -0
  39. data/lib/rea/settings.rb +58 -0
  40. data/spec/dummy/db/schema.rb +1 -56
  41. data/spec/generators/rea/install/install_generator_spec.rb +2 -0
  42. data/spec/models/rea/category_member_spec.rb +5 -1
  43. data/spec/models/rea/category_spec.rb +19 -1
  44. data/spec/models/rea/category_type_spec.rb +24 -1
  45. data/spec/models/rea/group_spec.rb +34 -1
  46. data/spec/models/rea/group_type_spec.rb +8 -0
  47. data/spec/rea/application_spec.rb +8 -0
  48. data/spec/rea/aspect_type/classification_spec.rb +107 -0
  49. data/spec/rea/aspect_type/due_date_spec.rb +75 -0
  50. data/spec/rea/aspect_type/identification_spec.rb +64 -0
  51. data/spec/rea/aspect_type_spec.rb +44 -0
  52. data/spec/rea/engine_spec.rb +0 -3
  53. data/spec/rea/meta_type/agent_spec.rb +28 -0
  54. data/spec/rea/meta_type/commitment_spec.rb +45 -0
  55. data/spec/rea/meta_type/contract_spec.rb +42 -0
  56. data/spec/rea/meta_type/entity_spec.rb +58 -0
  57. data/spec/rea/meta_type/event_spec.rb +21 -0
  58. data/spec/rea/meta_type/group_spec.rb +55 -0
  59. data/spec/rea/meta_type/process_spec.rb +5 -0
  60. data/spec/rea/meta_type/resource_spec.rb +65 -0
  61. data/spec/rea/meta_type_spec.rb +1 -1
  62. data/spec/rea/model_spec.rb +79 -0
  63. metadata +32 -15
  64. data/app/models/rea/group_entity.rb +0 -7
  65. data/db/migrate/20120605030708_create_rea_group_entities.rb +0 -9
  66. data/lib/rea/aspect_type/classification_aspect.rb +0 -75
  67. data/lib/rea/aspect_type/due_date_type.rb +0 -5
  68. data/lib/rea/aspect_type/identifier_setup.rb +0 -7
  69. data/lib/rea/dsl.rb +0 -24
  70. data/lib/rea/dsl/behavioral.rb +0 -50
  71. data/lib/rea/dsl/structural.rb +0 -53
  72. data/spec/models/rea/group_entity_spec.rb +0 -5
  73. data/spec/rea/dsl/behavioral_spec.rb +0 -149
  74. data/spec/rea/dsl/structural_spec.rb +0 -299
  75. data/spec/rea/dsl_spec.rb +0 -11
@@ -1,11 +1,33 @@
1
1
  module Rea
2
2
  module AspectType
3
+
3
4
  autoload :Base, 'rea/aspect_type/base'
4
- autoload :IdentifierSetup, 'rea/aspect_type/identifier_setup'
5
- autoload :Description, 'rea/aspect_type/description'
6
- autoload :DueDateType, 'rea/aspect_type/due_date_type'
7
- autoload :Classification, 'rea/aspect_type/classification_aspect'
8
- autoload :ClassificationAspect, 'rea/aspect_type/classification_aspect'
9
- autoload :MemberType, 'rea/aspect_type/classification_aspect'
5
+
6
+ TYPES = %W{identification classification due_date description}
7
+
8
+ TYPES.each do |type|
9
+ require "rea/aspect_type/#{type}"
10
+ end
11
+
12
+
13
+ module ClassMethods
14
+ TYPES.each do |pattern|
15
+ define_method pattern do |*names, &block|
16
+ $options = names.extract_options!
17
+ $options.merge! :base=>self
18
+ self.send :include, "Rea::AspectType::#{pattern.camelize}".constantize
19
+ self.send :cattr_accessor, "#{pattern}_aspect".to_sym
20
+ if names.size == 0
21
+ names << "%s_%s_aspect" % [self.name.underscore, pattern]
22
+ end
23
+ names.each do |name|
24
+ $aspect = "Rea::AspectType::#{pattern.camelize}::Aspect".constantize.new($options)
25
+ $aspect.instance_eval &block if block
26
+ self.send "#{pattern}_aspect=", $aspect
27
+ Rea.context.symbol_table[name] = $aspect
28
+ end
29
+ end
30
+ end
31
+ end
10
32
  end
11
33
  end
@@ -1,8 +1,9 @@
1
1
  module Rea
2
2
  module AspectType
3
3
  class Base
4
- def initialize options={}
5
- options.keys.each { |key| self.instance_variable_set("@#{key}", options[key]) }
4
+ attr_reader :base
5
+ def initialize options = {}
6
+ @base = options.delete(:base)
6
7
  end
7
8
  end
8
9
  end
@@ -0,0 +1,142 @@
1
+ module Rea
2
+ module AspectType
3
+ module Classification
4
+ def self.included base
5
+ base.scope :by_category, lambda { |*categories|
6
+ $options = categories.extract_options!
7
+ $aspect = base.classification_aspect
8
+ $condition = {}
9
+ categories.each do |category|
10
+ $category_type_name = category.category_type.name
11
+ $condition["#{$aspect.member_type_for($category_type_name)}_id"] = category.id
12
+ end
13
+ $condition.merge! $options
14
+ base.where($condition)
15
+ }
16
+
17
+ base.send :has_many, :category_members, :class_name=>::Rea::CategoryMember.name, :as=>:entity
18
+ base.send :has_many, :categories, :class_name=>::Rea::Category.name,
19
+ :through=>:category_members, :source=>:category
20
+
21
+ base.class_eval do
22
+
23
+ def self.categories_for member_type
24
+ self.classification_aspect.categories_for member_type
25
+ end
26
+
27
+ def is? category
28
+ $field_name = self.class.classification_aspect.member_type_for(category.category_type.name)
29
+ self.send($field_name) == category
30
+ end
31
+ def is_in? category
32
+ $field_name = self.class.classification_aspect.member_type_for(category.category_type.name)
33
+ $current = category.class.find(self.send($field_name))
34
+ while($current) do
35
+ return true if $current == category
36
+ $current = $current.parent_category
37
+ end
38
+ return false
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ module CategoryType
45
+
46
+ def self.included base
47
+ base.extend ClassMethods
48
+ end
49
+
50
+ module ClassMethods
51
+ def category_type *category_types, &block
52
+ $options = category_types.extract_options!
53
+ category_types.each do |type|
54
+ $category_type = self.find_or_create_by_name type, $options
55
+ $category_type.instance_eval &block if block
56
+ end
57
+ end
58
+ end
59
+
60
+ def category *category_names, &block
61
+ $options = category_names.extract_options!
62
+ category_names.flatten.each do |name|
63
+ category = self.categories.find_or_create_by_name name, $options
64
+ category.instance_eval &block if block_given?
65
+ end
66
+ end
67
+ end
68
+
69
+ module Category
70
+ def category *category_names, &block
71
+ $options = category_names.extract_options!
72
+ $options = {:category_type_id=>self.category_type_id, :category_id=>self.id}.merge($options)
73
+ category_names.flatten.each do |name|
74
+ $category = self.child_categories.find_or_create_by_name name, $options
75
+ $categroy.instance_eval &block if block_given?
76
+ end
77
+ end
78
+ end
79
+
80
+ class Aspect < Base
81
+
82
+ def members
83
+ @members ||= {}
84
+ end
85
+
86
+ def member *names, &block
87
+ $options = names.extract_options!
88
+ names.each do |name|
89
+ base.attr_accessible "#{name}_id"
90
+ base.belongs_to name, :class_name=>::Rea::Category.name
91
+ members[name] = MemberType.new($options)
92
+ members[name].instance_eval &block if block
93
+ #pp members[name]
94
+ if members[name].multiple_select
95
+ define_multiple_member name, members[name]
96
+ end
97
+ end
98
+ end
99
+
100
+ def member_type_for category_type
101
+ $types = {}
102
+ members.each_pair { |k,v| $types[v.category_type_name] = k }
103
+ $types[category_type.to_sym]
104
+ end
105
+
106
+ def categories_for member_type
107
+ $member_type = members[member_type]
108
+ raise "not found member_type #{member_type}" unless $member_type
109
+ $member_type.category_options
110
+ end
111
+
112
+ private
113
+ def define_multiple_member name, member
114
+ base.send :attr_accessible, "#{name.to_s.singularize}_ids"
115
+ base.send :has_many, name, :through=>:category_members, :source=>:category,
116
+ :class_name=>::Rea::Category.name, :include=> :category_type,
117
+ :conditions=>"rea_category_type.name = #{member.category_type_name}"
118
+ end
119
+
120
+ end
121
+ class MemberType < Base
122
+
123
+ attr_reader :category_type_name, :multiple_select
124
+
125
+ def initialize options={}
126
+ super
127
+ @multiple_select = options[:multiple_select] || false
128
+ end
129
+
130
+ def category name, options={}
131
+ @category_type_name = name
132
+ end
133
+
134
+ def category_options
135
+ Rea::CategoryType.find_by_name(category_type_name).categories
136
+ end
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -1,7 +1,8 @@
1
1
  module Rea
2
2
  module AspectType
3
- class Description < Base
4
- attr_accessor :name, :media
3
+ module Description
4
+ class Aspect < Base
5
+ end
5
6
  end
6
7
  end
7
8
  end
@@ -0,0 +1,34 @@
1
+ module Rea
2
+ module AspectType
3
+ module DueDate
4
+
5
+ class Aspect < Base
6
+ def member *names
7
+ $options = names.extract_options!
8
+
9
+ base.send :scope, :expired_on, lambda { |*names|
10
+ $options = names.extract_options!
11
+ $clause = (names.collect {|name| " #{name} < :now " }).join(" AND ")
12
+ base.where($clause, :now=>DateTime.now )
13
+ }
14
+ base.send :scope, :active_on, lambda { |*names|
15
+ $options = names.extract_options!
16
+ $clause = (names.collect {|name| " #{name} > :now " }).join(" AND ")
17
+ base.where($clause, :now=>DateTime.now )
18
+ }
19
+
20
+ names.each do |name|
21
+ base.send :attr_accessible, name
22
+ base.send :define_method, "#{name}_state" do
23
+ (Time.now > self.send(name)) ? :expired : :active
24
+ end
25
+
26
+ base.send :define_method, "#{name}_expired?" do
27
+ self.send("#{name}_state") == :expired
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ module Rea
2
+ module AspectType
3
+ module Identification
4
+
5
+ def self.included base
6
+ base.before_create do |object|
7
+ base.identification_aspect.identifiers.values.each do |val|
8
+ identifier = Rea::Identifier.find_by_name val.type
9
+ return unless identifier
10
+ object.send "#{val.name}=", identifier.generate
11
+ end
12
+ end
13
+ end
14
+
15
+ class Setup
16
+ attr_accessor :name, :type
17
+ def initialize options={}
18
+ options.keys.each do |key| instance_variable_set("@#{key}", options[key]) end
19
+ end
20
+ end
21
+
22
+ class Aspect < Base
23
+ def identifiers
24
+ @identifiers ||= {}
25
+ end
26
+
27
+ def identifier *names
28
+ $options = names.extract_options!
29
+ names.each do |name|
30
+ $default_id_type = "#{base.name.underscore}.#{name}"
31
+ $options = {:name=>name,:type=>$default_id_type}.merge($options)
32
+ identifiers[name] = Setup.new($options)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -3,9 +3,7 @@ module Rea
3
3
  isolate_namespace Rea
4
4
 
5
5
  initializer :rea_rails_initializer do |app|
6
- ActiveRecord::Base.class_eval do
7
- include Rea::Dsl
8
- end
6
+ app.config.i18n.load_path += Dir[::Rea::Engine.root.join('config','locales','*.{rb,yml}').to_s]
9
7
  end
10
8
  end
11
9
  end
@@ -1,7 +1,7 @@
1
1
  module Rea
2
2
  module MetaType
3
3
 
4
- %w{entity resource event agent commitment contract group type schedule}.each do |name|
4
+ %w{entity resource event agent commitment contract group type schedule process exchange conversion}.each do |name|
5
5
  autoload name.camelize.to_sym, "rea/meta_type/#{name}"
6
6
  end
7
7
  end
@@ -3,7 +3,7 @@ module Rea
3
3
  module Agent
4
4
  def self.included base
5
5
  base.fields = [:name]
6
- Entity.included base
6
+ base.send :include, Entity
7
7
  end
8
8
  end
9
9
  end
@@ -6,20 +6,19 @@ module Rea
6
6
  Entity.included base
7
7
  base.extend ::Rea::MetaType::Event::ClassMethods
8
8
  base.extend ClassMethods
9
+ base.cattr_accessor :event_handler
9
10
  base.after_save :after_save_commitment
10
11
  end
11
12
 
12
13
  def after_save_commitment
13
- if fulfilled_changed?
14
- self.class.event_creator.create_event(self)
14
+ if self.respond_to?(:fulfilled_changed?) && fulfilled_changed?
15
+ self.instance_exec &self.class.event_handler if self.class.event_handler
15
16
  end
16
17
  end
17
18
 
18
19
  module ClassMethods
19
-
20
- def event_creator klass, options={}
21
- cattr_reader :event_creator
22
- self.class_variable_set "@@event_creator", klass
20
+ def event_creator &block
21
+ self.event_handler = block
23
22
  end
24
23
  end
25
24
  end
@@ -3,14 +3,27 @@ module Rea
3
3
  module Contract
4
4
  def self.included base
5
5
  base.fields = nil
6
- Entity.included base
6
+ base.send :include, Entity
7
7
  base.extend ClassMethods
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def clause klass, options={}
12
- has_many klass.name.tableize.to_sym, {:class_name=>klass.name, :foreign_key=>:contract_id}.merge(options)
13
- klass.belongs_to :contract, :class_name => self.name
11
+
12
+ def clauses
13
+ @@clauses ||= []
14
+ end
15
+
16
+ def clause klass_or_symbol, options={}
17
+ $klass = guess_entity_class klass_or_symbol
18
+ has_many $klass.name.tableize.to_sym, {:class_name=>$klass.name, :foreign_key=>:contract_id}.merge(options)
19
+ self.clauses << $klass
20
+ $klass.belongs_to :contract, :class_name => self.name
21
+ end
22
+
23
+ def party name, klass_or_sym, options={}
24
+ $klass = guess_entity_class(klass_or_sym)
25
+ attr_accessible :"#{name}_id"
26
+ belongs_to name, {:class_name=>$klass.name}.merge(options)
14
27
  end
15
28
  end
16
29
  end
@@ -0,0 +1,6 @@
1
+ module Rea
2
+ module MetaType
3
+ class Conversion < Process
4
+ end
5
+ end
6
+ end
@@ -5,38 +5,64 @@ module Rea
5
5
  base.class_eval do
6
6
  unless self.ancestors.include? ActiveRecord::Base
7
7
  include ::Rea::Plugins::ActiveModel
8
- attr_accessor *self.fields if base.fields
8
+ else
9
+ attr_accessible *self.fields if self.fields
10
+ end
11
+ if base.fields
12
+ validates_presence_of *self.fields
9
13
  end
10
- validates_presence_of *self.fields if base.fields
11
14
  end
12
15
  base.extend ClassMethods
16
+ base.extend ::Rea::AspectType::ClassMethods
13
17
  end
14
18
 
15
19
  module ClassMethods
16
20
 
17
- def item name, options={}, &block
18
- if self.ancestors.include?(ActiveRecord::Base)
19
- @context = self.find_or_create_by_name name, options
20
- else
21
- cattr_reader name
22
- @context = self.new({:name=>name.to_s, :value=>1}.merge(options))
23
- self.class_variable_set "@@#{name}", @context
21
+ def setup options=nil
22
+ options = {:entity_type=>:active_record}.merge(options)
23
+ class_option_set :entity_type, options
24
+
25
+ case
26
+ when self.entity_type == :simple
27
+ attr_accessor :id
28
+ self.class_eval do
29
+ def self.find id
30
+ self.items[id]
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def groups; @@groups ||= [] ; end
37
+
38
+ def grouping *names
39
+ $options = names.extract_options!
40
+ names.each do |name|
41
+ attr_accessible "#{name}_id"
42
+ belongs_to name, $options
24
43
  end
25
- block.call if block_given?
26
44
  end
27
45
 
28
- def grouping options={}, &block
29
- has_many :group_entities, :as=>:entity
30
- has_many :groups, :through=>:group_entities
31
- #group_class.entity_classes << self
32
- block.call if block_given?
46
+ def groups_for name
47
+ klass = Rea.context.symbol_table[name]
48
+ klass.all
33
49
  end
34
50
 
35
- def group_item *group_names, &block
36
- options = group_names.extract_options!
37
- group_names.flatten.each do |name|
38
- @context = Rea::Group.groups(self).find_or_create_by_name(name, :entity_types=>self.name)
39
- block.call if block_given?
51
+ def items
52
+ @@items ||= {}
53
+ end
54
+
55
+ def item name, options={}, &block
56
+ if self.entity_type == :simple
57
+ cattr_reader name
58
+ $item = self.new
59
+ options.keys.each do |key|
60
+ $item.instance_variable_set("@#{key}", options[key])
61
+ end if options
62
+ self.class_variable_set "@@#{name}", $item
63
+ items[$item.id] = $item
64
+ else
65
+ raise "not support #{self.entity_type} yet!"
40
66
  end
41
67
  end
42
68
 
@@ -44,6 +70,21 @@ module Rea
44
70
  def specification name, options={}
45
71
  belongs_to name, options
46
72
  end
73
+
74
+ protected
75
+ def guess_entity_class klass_or_symbol
76
+ $klass = klass_or_symbol.is_a?(Symbol) ? Rea.context.symbol_table[klass_or_symbol] : klass_or_symbol
77
+ raise "entity not found #{klass_or_symbol}" unless $klass
78
+ $klass
79
+ end
80
+
81
+ def class_option_set *names
82
+ $options = names.extract_options!
83
+ names.each do |name|
84
+ self.cattr_reader name
85
+ self.class_variable_set "@@#{name}", $options[name]
86
+ end
87
+ end
47
88
  end
48
89
  end
49
90
  end