question_chain 0.0.1

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 (94) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +18 -0
  3. data/Licence.txt +20 -0
  4. data/README.rdoc +34 -0
  5. data/Rakefile +2 -0
  6. data/config/initializers/mustache.rb +2 -0
  7. data/lib/question_chain/answerable.rb +142 -0
  8. data/lib/question_chain/answers.rb +290 -0
  9. data/lib/question_chain/models/answers/question_view.rb +21 -0
  10. data/lib/question_chain/models/answers/ui_object_view.rb +67 -0
  11. data/lib/question_chain/models/answers/ui_objects_check_box_view.rb +17 -0
  12. data/lib/question_chain/models/answers/ui_objects_drop_down_view.rb +16 -0
  13. data/lib/question_chain/models/answers/ui_objects_hidden_field_view.rb +8 -0
  14. data/lib/question_chain/models/answers/ui_objects_object_reference_drop_down_view.rb +18 -0
  15. data/lib/question_chain/models/answers/ui_objects_object_search_view.rb +22 -0
  16. data/lib/question_chain/models/answers/ui_objects_relatable_category_drop_down_view.rb +18 -0
  17. data/lib/question_chain/models/answers/ui_objects_text_field_view.rb +8 -0
  18. data/lib/question_chain/models/chain_template.rb +43 -0
  19. data/lib/question_chain/models/question.rb +37 -0
  20. data/lib/question_chain/models/relatable_category_filter.rb +15 -0
  21. data/lib/question_chain/models/rule.rb +27 -0
  22. data/lib/question_chain/models/rules/attribute_change.rb +28 -0
  23. data/lib/question_chain/models/rules/choice_genenerator.rb +5 -0
  24. data/lib/question_chain/models/rules/populate_drop_down.rb +30 -0
  25. data/lib/question_chain/models/rules/search.rb +19 -0
  26. data/lib/question_chain/models/rules/value_change.rb +22 -0
  27. data/lib/question_chain/models/ui_group.rb +71 -0
  28. data/lib/question_chain/models/ui_object.rb +92 -0
  29. data/lib/question_chain/models/ui_object_answer.rb +17 -0
  30. data/lib/question_chain/models/ui_objects/check_box.rb +8 -0
  31. data/lib/question_chain/models/ui_objects/drop_down.rb +17 -0
  32. data/lib/question_chain/models/ui_objects/hidden_field.rb +5 -0
  33. data/lib/question_chain/models/ui_objects/object_reference_drop_down.rb +67 -0
  34. data/lib/question_chain/models/ui_objects/object_search.rb +44 -0
  35. data/lib/question_chain/models/ui_objects/radio_button.rb +5 -0
  36. data/lib/question_chain/models/ui_objects/radio_button_group.rb +5 -0
  37. data/lib/question_chain/models/ui_objects/relatable_category_drop_down.rb +70 -0
  38. data/lib/question_chain/models/ui_objects/text_field.rb +11 -0
  39. data/lib/question_chain/mongo_serialization.rb +62 -0
  40. data/lib/question_chain/mustache_handler.rb +16 -0
  41. data/lib/question_chain/mustache_rails.rb +50 -0
  42. data/lib/question_chain/state_machine.rb +29 -0
  43. data/lib/question_chain/stored_template.rb +30 -0
  44. data/lib/question_chain/version.rb +3 -0
  45. data/lib/question_chain/views/answers/_edit.html.haml +62 -0
  46. data/lib/question_chain/views/answers/_new.html.haml +62 -0
  47. data/lib/question_chain/views/answers/_question.html.mustache +11 -0
  48. data/lib/question_chain/views/answers/_ui_objects_check_box.html.mustache +19 -0
  49. data/lib/question_chain/views/answers/_ui_objects_drop_down.html.mustache +26 -0
  50. data/lib/question_chain/views/answers/_ui_objects_hidden_field.html.mustache +3 -0
  51. data/lib/question_chain/views/answers/_ui_objects_object_reference_drop_down.html.mustache +27 -0
  52. data/lib/question_chain/views/answers/_ui_objects_object_search.html.mustache +20 -0
  53. data/lib/question_chain/views/answers/_ui_objects_relatable_category_drop_down.html.mustache +26 -0
  54. data/lib/question_chain/views/answers/_ui_objects_text_field.html.mustache +19 -0
  55. data/lib/question_chain/views/layouts/application.html.haml +10 -0
  56. data/lib/question_chain.rb +35 -0
  57. data/question_chain.gemspec +31 -0
  58. data/test_app/.gitignore +4 -0
  59. data/test_app/Gemfile +29 -0
  60. data/test_app/Rakefile +16 -0
  61. data/test_app/app/controllers/answers_controller.rb +13 -0
  62. data/test_app/app/controllers/application_controller.rb +4 -0
  63. data/test_app/app/models/container.rb +10 -0
  64. data/test_app/app/models/flight.rb +20 -0
  65. data/test_app/app/views/answers/edit.html.haml +1 -0
  66. data/test_app/app/views/answers/new.html.haml +1 -0
  67. data/test_app/config/application.rb +18 -0
  68. data/test_app/config/boot.rb +13 -0
  69. data/test_app/config/database.yml +15 -0
  70. data/test_app/config/environment.rb +5 -0
  71. data/test_app/config/initializers/app.rb +5 -0
  72. data/test_app/config/initializers/cookie_verification_secret.rb +7 -0
  73. data/test_app/config/initializers/mongodb.rb +2 -0
  74. data/test_app/config/initializers/session_store.rb +3 -0
  75. data/test_app/config/routes.rb +30 -0
  76. data/test_app/config.ru +2 -0
  77. data/test_app/environments/development.rb +19 -0
  78. data/test_app/environments/test.rb +30 -0
  79. data/test_app/lib/tasks/rspec.rake +69 -0
  80. data/test_app/lib/tasks/yard.rake +4 -0
  81. data/test_app/public/.gitkeep +0 -0
  82. data/test_app/script/rails +10 -0
  83. data/test_app/spec/acceptance/new_spec +30 -0
  84. data/test_app/spec/factories.rb +81 -0
  85. data/test_app/spec/models/chain_template_spec.rb +53 -0
  86. data/test_app/spec/models/flight_spec.rb +101 -0
  87. data/test_app/spec/models/question_spec.rb +13 -0
  88. data/test_app/spec/models/rules/value_change_spec.rb +31 -0
  89. data/test_app/spec/models/ui_group_spec.rb +55 -0
  90. data/test_app/spec/models/ui_object_spec.rb +33 -0
  91. data/test_app/spec/models/ui_objects/drop_down_spec.rb +28 -0
  92. data/test_app/spec/models/ui_objects/relatable_category_drop_down_spec.rb +13 -0
  93. data/test_app/spec/spec_helper.rb +25 -0
  94. metadata +325 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # Will automatically pull in this gem and all its
6
+ # dependencies specified in the gemspec
7
+ gem "question_chain", :path => File.expand_path("..", __FILE__)
8
+ gem "yard"
9
+
10
+ # These are development dependencies
11
+ group :test do
12
+ gem "rake"
13
+ gem "rspec", "2.5.0"
14
+ gem 'vcr', '~> 1.5', :require => false
15
+ gem 'webmock', '~> 1.6', :require => false
16
+ gem "autotest"
17
+ end
18
+
data/Licence.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2010 Richard Hooker - richard.hookere@carboncalculated.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = QuestionChain
2
+
3
+ == What Am I?
4
+
5
+ This is not to be used currently! Work in Progress; Extracting not quite complete and SPECS
6
+
7
+ There will be guides on how to use this http://guides.carboncalculated.com
8
+
9
+ This is a Rails3 Gem to be used in conjunction with the soon to be released QuestionChainJS library
10
+ to be used with the CarbonCalculated API http://carboncalculated.com
11
+
12
+ This Gem allows you to create a forms for Carbon Calculations in like 2 sometimes 3 minutes depending on typing speed
13
+
14
+ At the minute this has dependencies on MongoMapper currently thinking about moving to more ORM agnostic approach
15
+
16
+ == Getting started
17
+
18
+ == UiObjects
19
+
20
+ === Drop Downs
21
+
22
+ === Object Reference Drop Downs
23
+
24
+ === Rules
25
+
26
+ === Attribute Change
27
+
28
+ === Search
29
+
30
+ === Markup
31
+
32
+ === CSS
33
+
34
+ === Bundling
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,2 @@
1
+ # == make sure we defined answers modules
2
+ ActionView::Template.register_template_handler(:mustache, MustacheHandler)
@@ -0,0 +1,142 @@
1
+ module QuestionChain
2
+ module Answerable
3
+ extend ActiveSupport::Concern
4
+ include MongoMapper::Serialize
5
+
6
+ included do
7
+ key :question_id, ObjectId
8
+ key :result, Hash
9
+ key :answer_params, Hash
10
+ key :answer_json, String
11
+ key :user_id, ObjectId
12
+ key :reference, String
13
+ key :stored_identifier, String
14
+ key :stored_variable_input, String
15
+ key :created_by, String
16
+ key :_extra_keywords, Array
17
+ timestamps!
18
+
19
+ cattr_accessor :_extra_keyword_methods
20
+ before_save :add_stored_identifier
21
+ before_save :add_extra_keywords
22
+ before_save :cache_attributes
23
+
24
+ # == Search
25
+ plugin Hunt
26
+ searches :reference, :created_by, :stored_variable_input, :stored_identifier, :_extra_keywords
27
+ ensure_index :'searches.default'
28
+
29
+ # == Indexes
30
+ ensure_index :reference
31
+ ensure_index :stored_identifier
32
+ ensure_index :stored_variable_input
33
+
34
+ # == Validations
35
+ validates_presence_of :question_id
36
+ validates_presence_of :answer_params
37
+ validates_presence_of :result
38
+ validates_true_for :answer, :logic => Proc.new {!answer_params.empty?}, :message => nil
39
+ validates_true_for :result, :logic => Proc.new {!result.empty?}, :message => nil
40
+
41
+ # == Associations
42
+ belongs_to :user
43
+
44
+ # == attr Protected
45
+ attr_protected :user_id
46
+
47
+ end
48
+
49
+ module ClassMethods
50
+ require "csv" #ruby19
51
+ def self.to_csv(options = {})
52
+ @csv_string ||= FasterCSV.generate do |csv|
53
+ # header row
54
+ csv << self.attributes_for_api
55
+
56
+ # data rows
57
+ self.all(options).each do |resource|
58
+ attributes = self.attributes_for_api.map do |key|
59
+ resource.send(key)
60
+ end
61
+ csv << attributes
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ module InstanceMethods
68
+ def add_extra_keywords
69
+ unless (self.class._extra_keyword_methods || []).empty?
70
+ self.class._extra_keyword_methods.each do |method|
71
+ self._extra_keywords << self.send(method)
72
+ end
73
+ end
74
+ end
75
+
76
+ def object_reference_characteristics(object_reference = self.object_reference)
77
+ object_reference["characteristics"]
78
+ end
79
+
80
+ def object_references
81
+ result["object_references"]
82
+ end
83
+
84
+ def object_reference(object_reference_id = self.object_reference_id)
85
+ result["object_references"] && result["object_references"][object_reference_id]
86
+ end
87
+
88
+ def object_reference_id(object_reference_name = self.object_reference_name)
89
+ answer_params[object_reference_name]
90
+ end
91
+
92
+ def object_reference_name
93
+ # should be set in the answerable if want to use
94
+ end
95
+
96
+ def variable_input
97
+ # should be set in the answerable if you want to use this
98
+ end
99
+
100
+ # you should set this to be what stored identifier you
101
+ # wish to have if you use more then 1 object in
102
+ # your calculation
103
+ def _identifier
104
+ idents = []
105
+ object_references.each_pair do |key, value|
106
+ idents << value["identifier"]
107
+ end
108
+ idents.join(" ")
109
+ end
110
+
111
+ def identifier
112
+ _identifier == read_attribute(:stored_identifier) ? read_attribute(:stored_identifier) : _identifier
113
+ end
114
+
115
+ def co2
116
+ (result["calculations"]["co2"]["value"] || 0).to_f
117
+ end
118
+
119
+ def ch4
120
+ (result["calculations"]["ch4"]["value"] || 0).to_f
121
+ end
122
+
123
+ def n2o
124
+ (result["calculations"]["n2o"]["value"]|| 0).to_f
125
+ end
126
+
127
+ def co2e
128
+ (result["calculations"]["co2e"]["value"] || 0).to_f
129
+ end
130
+
131
+ private
132
+ def add_stored_identifier
133
+ self.stored_identifier = self.identifier
134
+ end
135
+
136
+ def cache_attributes
137
+ write_attribute(:created_by, user.full_name)
138
+ write_attribute(:stored_variable_input, variable_input)
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,290 @@
1
+ module QuestionChain
2
+ module Answers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_filter :get_context
7
+ before_filter :load_contexts, :except => [:fire_object_search, :fire_populate_drop_down]
8
+ respond_to :json, :only => [:fire_object_search, :fire_populate_drop_down]
9
+ helper_method :question_chain_update_answer_path, :question_chain_answer_path, :collection_path
10
+ end
11
+
12
+ module InstanceMethods
13
+ def new
14
+ @answer = build_resource
15
+ enforce_permission
16
+ @question = question_from_context
17
+ new!
18
+ end
19
+
20
+ def edit
21
+ @answer = resource
22
+ enforce_permission
23
+ @question = Question.find!(resource.question_id).to_hash
24
+ @answer_params = @answer.answer_params # used for mustache templates
25
+ set_answer_values_on_question!(@question, @answer_params)
26
+ edit!
27
+ end
28
+
29
+ def update
30
+ @answer = resource
31
+ enforce_permission
32
+ @answer.user_id = current_user.id
33
+ @answer.answer_params = params[:answer]
34
+ @answer_params = params[:answer] # used for mustache templates
35
+ @question = Question.find!(resource.question_id).to_hash
36
+ @answer.result = get_answer(@question, @answer_params)
37
+ set_answer_values_on_question!(@question, @answer_params)
38
+ build_answer_errors!
39
+ update! do |success, failure|
40
+ success.html do
41
+ flash[:notice] = update_success_flash_message
42
+ @contexts << @answer
43
+ redirect_to update_success_path
44
+ end
45
+ end
46
+ end
47
+
48
+ def create
49
+ @answer = build_resource
50
+ enforce_permission
51
+ @answer.user_id = current_user.id
52
+ @answer.answer_params = params[:answer]
53
+ @answer_params = params[:answer] # used for mustache templates
54
+ @question = question_from_context
55
+ @answer.question_id = @question.id
56
+ @answer.result = get_answer(@question, @answer_params)
57
+ set_answer_values_on_question!(@question, @answer_params)
58
+ build_answer_errors!
59
+ create! do |success, failure|
60
+ success.html do
61
+ flash[:notice] = create_success_flash_message
62
+ @contexts << @answer
63
+ redirect_to create_success_path
64
+ end
65
+ end
66
+ end
67
+
68
+ # == Rule firing for drop down
69
+ def fire_populate_drop_down
70
+ if ui_object = UiObject.find(params[:ui_object_id])
71
+ if rule = ui_object.rules.find(params[:rule_id])
72
+ return render :json => {"options" => rule.get_options(params[:object_ids])}.to_json
73
+ end
74
+ end
75
+ render :json => {:error => "Could not find rule"}.to_json
76
+ end
77
+
78
+ # == Rule firing for search
79
+ def fire_object_search
80
+ if ui_object = UiObject.find(params[:ui_object_id])
81
+ if rule = ui_object.rules.find(params[:rule_id])
82
+ return render :json => {"options" => rule.get_options(params[:q], params[:relatable_category_values])}.to_json
83
+ end
84
+ end
85
+ render :json => {:error => "Could not find rule"}.to_json
86
+ end
87
+
88
+ # seems strange but its true allows
89
+ # for pagination link to work inside list view
90
+ # when editing
91
+ def show
92
+ end_of_association_chain
93
+ redirect_to edit_from_context_path
94
+ end
95
+
96
+ # seems strange but its true
97
+ # allows for pagination link to work
98
+ # when creating a new answer
99
+ def index
100
+ end_of_association_chain
101
+ redirect_to new_from_context_path
102
+ end
103
+
104
+ def enforce_permission
105
+ # override to force permission on the answer object
106
+ end
107
+
108
+ protected
109
+ def create_success_flash_message
110
+ "Your co2 was #{@answer.result["calculations"]["co2"]["value"]} #{@answer.result["calculations"]["co2"]["units"]}"
111
+ end
112
+
113
+ def update_success_flash_message
114
+ "Your co2 was updated to #{@answer.result["calculations"]["co2"]["value"]} #{@answer.result["calculations"]["co2"]["units"]}"
115
+ end
116
+
117
+ def question_chain_answer_path
118
+ contexts = @contexts.dup
119
+ contexts << :answers
120
+ self.send(path_method_from_contexts(contexts), {:context => @context, :question_id => @question.id})
121
+ end
122
+
123
+ def question_chain_update_answer_path
124
+ contexts = @contexts.dup
125
+ contexts << :answer
126
+ self.send(path_method_from_contexts(contexts), {:context => @context, :question_id => @question.id, :id => resource.id})
127
+ end
128
+
129
+ # allows the ui to know what values have been set
130
+ # and therefore sets the ui_objects values
131
+ #
132
+ # @param [Hash] question hash representation of the question
133
+ # @param [Hash] answer_params
134
+ def set_answer_values_on_question!(question_hash, answer)
135
+ answer.each_pair do |key, value|
136
+ question_hash.ui_groups.map{|group| group.ui_objects}.flatten.each do |ui_object|
137
+ if ui_object.name == key.to_s
138
+ ui_object.value = value
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ # @param [Question] calculator_id
145
+ # @param [Hash] answer_params
146
+ # @return [Hash] the result from the co2 computation
147
+ #  which many container errors
148
+ def get_answer(question, answer_params)
149
+ if computation_id = answer_params[:computation_id].blank? ? question.computation_id : answer_params[:computation_id]
150
+ QuestionChain.calculated_session.answer_for_computation(computation_id, answer_params)
151
+ elsif calculator_id = question.calculator_id
152
+ QuestionChain.calculated_session.answer_for_calculator(calculator_id, answer_params)
153
+ end
154
+ end
155
+
156
+ # we false the generation of any normal errors
157
+ # on the answer and merge in the carboncalculated
158
+ # errors as well
159
+ #
160
+ # base errors are in the form of an array
161
+ # errors that have fields are in the form of a hash
162
+ def build_answer_errors!
163
+ if @answer.result[:errors]
164
+ @answer.valid?
165
+ if @answer.result[:errors].is_a?(Hash)
166
+ @answer.errors.merge!(@answer.result[:errors])
167
+ else
168
+ @answer.errors.merge!({:base => @answer.result[:errors]})
169
+ end
170
+ @answer.errors.each_pair{|key, value| value.respond_to?(:flatten!) ? value.flatten! : value}
171
+ @answer.instance_exec(@answer) do |answer|
172
+ def answer.valid?
173
+ false
174
+ end
175
+ # we dont want this to update any attributes if its invalid!
176
+ # this results in a very strange BUG! if not applied
177
+ def answer.update_attributes(attributes)
178
+ false
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ def find_question_ids
185
+ if template = get_chain_template_for_resource(parent_type.to_s)
186
+ template["context"][params[:context]]
187
+ else
188
+ # render not found or something
189
+ end
190
+ end
191
+
192
+ def question_from_context
193
+ if question_id = params[:question_id]
194
+ Question.find!(question_id).to_hash
195
+ else
196
+ ids = find_question_ids
197
+ Question.find!(ids.first).to_hash
198
+ end
199
+ end
200
+
201
+ def resource_collection_name
202
+ @context
203
+ end
204
+
205
+ # handle single resource case scenerio via singularize
206
+ def resource
207
+ if resource_collection_name.singularize == resource_collection_name
208
+ get_resource_ivar || set_resource_ivar(end_of_association_chain)
209
+ else
210
+ get_resource_ivar || set_resource_ivar(end_of_association_chain.find(params[:id]))
211
+ end
212
+ end
213
+
214
+ def collection
215
+ get_collection_ivar || set_collection_ivar(end_of_association_chain.paginate(:page => params[:page], :per_page => 25, :order => :created_at.desc))
216
+ end
217
+
218
+ def get_context
219
+ @context = params[:context]
220
+ end
221
+
222
+ # Loads the contexts and any parent resources
223
+ # to allow easy generation of urls back to
224
+ # the context enclosing resources
225
+ def load_contexts(enclosed_parent = nil)
226
+ end_of_association_chain
227
+ @contexts = [] if @contexts.nil?
228
+ enclosed_parent = enclosed_parent.nil? ? self.parent : enclosed_parent
229
+ unless @contexts.include?(enclosed_parent)
230
+ @contexts << enclosed_parent
231
+ if chain_template = get_chain_template_for_resource(parent.class.name.downcase)
232
+ if parent_resource = chain_template.parent_resource
233
+ resource = parent.send(parent_resource)
234
+ instance_variable_set("@#{parent_resource}", resource)
235
+ load_contexts(resource)
236
+ end
237
+ end
238
+ end
239
+ @contexts.reverse!
240
+ end
241
+
242
+ def new_from_context_path
243
+ new_polymorphic_path(@contexts)
244
+ end
245
+
246
+ def edit_from_context_path
247
+ new_polymorphic_path(@contexts)
248
+ end
249
+
250
+ # if a method matching the context and action that will be called
251
+ # otherwise the polymorphic path is used
252
+ def create_success_path
253
+ if self.respond_to?(path_method_from_contexts(@contexts, "create_success_"))
254
+ self.send(path_method_from_contexts(@contexts, "create_success_"))
255
+ else
256
+ polymorphic_path(@contexts)
257
+ end
258
+ end
259
+
260
+ # builds a url method from the contexts and a given action
261
+ # @param [String] action
262
+ #
263
+ # @return [String] url method call
264
+ def path_method_from_contexts(contexts, action = "")
265
+ url_method = contexts.inject("#{action}") do |string, parent|
266
+ segment = (parent.is_a?(Symbol)) ? parent.to_s : ActiveModel::Naming.singular(parent)
267
+ string << segment
268
+ string << "_"
269
+ end
270
+ url_method << "path"
271
+ url_method
272
+ end
273
+
274
+ # if a method has been decleared of a specific update that is called
275
+ # otherwise the default polymophic path is used
276
+ def update_success_path
277
+ if self.respond_to?(path_method_from_contexts(@contexts, "update_success_"))
278
+ self.send(path_method_from_contexts(@contexts, "update_success_"))
279
+ else
280
+ polymorphic_path(@contexts)
281
+ end
282
+ end
283
+
284
+ def get_chain_template_for_resource(for_resource)
285
+ ChainTemplate.first(:model_state => "active", :for_resource => for_resource, :account_id => @account.try(:id)) ||
286
+ ChainTemplate.first(:model_state => "active", :for_resource => for_resource)
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,21 @@
1
+ module Answers
2
+ class QuestionView < MustacheRails
3
+
4
+ def name
5
+ question.name
6
+ end
7
+
8
+ def label
9
+ question.label
10
+ end
11
+
12
+ def description
13
+ question.description
14
+ end
15
+
16
+ private
17
+ def question
18
+ @question ||= context[:_question]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,67 @@
1
+ module Answers
2
+ class UiObjectView < MustacheRails
3
+
4
+ def dom_id
5
+ "ui_object_#{ui_object.id}"
6
+ end
7
+
8
+ def input_id
9
+ "ui_input_#{ui_object.id}"
10
+ end
11
+
12
+ def extra_info
13
+ ui_object.try(:extra_info)
14
+ end
15
+
16
+ def css_classes
17
+ ui_object.css_classes.join(" ")
18
+ end
19
+
20
+ def has_extra_info
21
+ !extra_info.blank?
22
+ end
23
+
24
+ def label
25
+ ui_object.label
26
+ end
27
+
28
+ def value
29
+ answer_params[ui_object_name] if answer_params
30
+ end
31
+
32
+ def ui_object_name
33
+ ui_object.name
34
+ end
35
+
36
+ def name
37
+ "answer[#{ui_object.name}]"
38
+ end
39
+
40
+ def default_value
41
+ ui_object.default_value
42
+ end
43
+
44
+ def default_styles
45
+ default_styles = ""
46
+ ui_object.ui_attributes.each_pair do |key, value|
47
+ if key.to_s == "visible" && value == "false"
48
+ default_styles << "display:none;visibility:hidden;"
49
+ end
50
+ end
51
+ default_styles
52
+ end
53
+
54
+ def disabled
55
+ ui_object.ui_attributes["disable"] == "true"
56
+ end
57
+
58
+ protected
59
+ def ui_object
60
+ @ui_object ||= context[:_ui_object]
61
+ end
62
+
63
+ def answer_params
64
+ @answer_params ||= context[:_answer_params]
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,17 @@
1
+ module Answers
2
+ class UiObjectsCheckBoxView < Answers::UiObjectView
3
+
4
+ def value
5
+ super || default_value
6
+ end
7
+
8
+ def checked
9
+ if value
10
+ !value.nil?
11
+ else
12
+ ui_object.ui_attributes[:checked]
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Answers
2
+ class UiObjectsDropDownView < Answers::UiObjectView
3
+
4
+ def prompt
5
+ ui_object.prompt
6
+ end
7
+
8
+ def options
9
+ if answer_params
10
+ ui_object.options.map{|option| option.merge!(:selected => option["value"].to_s == value.to_s)}
11
+ else
12
+ ui_object.options
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ module Answers
2
+ class UiObjectsHiddenFieldView < Answers::UiObjectView
3
+
4
+ def value
5
+ super || default_value
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ module Answers
2
+ class UiObjectsObjectReferenceDropDownView < Answers::UiObjectView
3
+
4
+ def prompt
5
+ ui_object.prompt
6
+ end
7
+
8
+ # @return [Array<Hash<value => value, name => name>>]
9
+ def options
10
+ if answer_params
11
+ ui_object.options.map{|option| option.merge!(:selected => option["value"].to_s == value.to_s)}
12
+ else
13
+ ui_object.options
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Answers
2
+ class UiObjectsObjectSearchView < Answers::UiObjectView
3
+
4
+ def search_name
5
+ "answer[search_#{name}]"
6
+ end
7
+
8
+ def search_id
9
+ "search_#{dom_id()}"
10
+ end
11
+
12
+ def search_value
13
+ if answer_params
14
+ answer_params["search_answer"][ui_object_name]
15
+ end
16
+ end
17
+
18
+ def value
19
+ super || default_value
20
+ end
21
+ end
22
+ end