engine-rea 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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