question_chain 0.0.1 → 0.0.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.
- data/README.rdoc +110 -8
- data/lib/question_chain/answerable.rb +16 -23
- data/lib/question_chain/models/chain_template.rb +5 -1
- data/lib/question_chain/models/ui_object.rb +6 -4
- data/lib/question_chain/state_machine.rb +1 -1
- data/lib/question_chain/version.rb +1 -1
- data/question_chain.gemspec +3 -3
- data/test_app/Gemfile +4 -4
- data/test_app/environments/test.rb +1 -1
- data/test_app/spec/factories.rb +6 -0
- data/test_app/spec/models/flight_spec.rb +10 -10
- data/test_app/spec/models/ui_group_spec.rb +1 -1
- data/test_app/spec/spec_helper.rb +13 -0
- metadata +9 -11
- data/test_app/spec/acceptance/new_spec +0 -30
data/README.rdoc
CHANGED
@@ -2,19 +2,123 @@
|
|
2
2
|
|
3
3
|
== What Am I?
|
4
4
|
|
5
|
-
|
5
|
+
There will be guides on how to use this http://guides.carboncalculated.com;
|
6
6
|
|
7
|
-
|
7
|
+
This Rails3 Engine allows you to create a forms for Carbon Calculations in like 2 sometimes 3 minutes depending on typing speed.
|
8
8
|
|
9
|
-
|
10
|
-
to be used with the CarbonCalculated API http://carboncalculated.com
|
9
|
+
== Dependencies
|
11
10
|
|
12
|
-
|
11
|
+
MongoMapper 0.9.0
|
13
12
|
|
14
|
-
|
13
|
+
Mongoid 2.0.0 (mongoid branch)
|
14
|
+
|
15
|
+
Note you will have to go through a few hoops to get this working currently however once you have UI for carbon calculations
|
16
|
+
can be generated very very quickly!
|
17
|
+
|
18
|
+
If you really want to dive in then please look at this example application using question chain;
|
19
|
+
|
20
|
+
https://github.com/carboncalculated/example-question-chain-application
|
15
21
|
|
16
22
|
== Getting started
|
17
23
|
|
24
|
+
Firstly You will need to be using creating a Rails3 Application;
|
25
|
+
|
26
|
+
add question_chain to your Gemfile
|
27
|
+
|
28
|
+
gem "question_chain"
|
29
|
+
|
30
|
+
you will also need the QuestionChainJS https://github.com/carboncalculated/QuestionChainJS
|
31
|
+
|
32
|
+
This is currently Mootools dependent;
|
33
|
+
|
34
|
+
== Setup
|
35
|
+
|
36
|
+
You will need to create a method (calculated_session) on your Rails Application Module; as question_chain
|
37
|
+
will look for a calculated session here when it talks to the carbon calculated API
|
38
|
+
|
39
|
+
module YourApplication
|
40
|
+
def self.calculated_session
|
41
|
+
@session ||= Calculated::Session.create(:api_key => ENV[:api_key])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
=== Background Information
|
46
|
+
|
47
|
+
With quesition_chain you are given a Rails3 Engine; this engine provides you with the following;
|
48
|
+
|
49
|
+
* Controller Module: (QuestionChain::Answers) For creating editing models that emit carbon (ie Journey; Material; Waste; Car)
|
50
|
+
|
51
|
+
* Model Module: (QuestionChain::Answerable) Helper Methods for any model that emits carbon.
|
52
|
+
|
53
|
+
* ChainTemplate: Defines context of where in your application your emitting models are located and what if any parent resources
|
54
|
+
it has; example
|
55
|
+
|
56
|
+
* Question: You build a "Question" its this quesition id (4babb5fef78b124341000002) that is then rendered for calculations in the UI
|
57
|
+
|
58
|
+
Please look at the example application that uses this Gem; before you go any further
|
59
|
+
|
60
|
+
=== Questions
|
61
|
+
|
62
|
+
This is where you can build up your UI for the question you wish to ask to calculated emissions;
|
63
|
+
|
64
|
+
* "What was your origin airport and destination airport?"
|
65
|
+
* "How many miles did you travel in your car?"
|
66
|
+
* "What material and how many tones of it do you use?"
|
67
|
+
|
68
|
+
Each question will relate to the CarbonCalcualated API! therefore a question will need either a
|
69
|
+
computation_id or a calculator_id
|
70
|
+
|
71
|
+
At the minute there is no UI for creating these question however there are example rake tasks that can be
|
72
|
+
seen in the example application
|
73
|
+
|
74
|
+
=== ChainTemplate
|
75
|
+
|
76
|
+
This where you can define "calculation contexts"; what does that mean? this is where you can say what resource
|
77
|
+
emits and its association with another resource; Example below is basically saying for user class it has
|
78
|
+
many flights these flights are to seen as a QuestionChain Question; Its the flight that emits Carbon!
|
79
|
+
|
80
|
+
ChainTemplate.create!(
|
81
|
+
:for_resource => "user",
|
82
|
+
:context => {
|
83
|
+
"flights" => ["4babb5fef78b124341000002"]
|
84
|
+
})
|
85
|
+
|
86
|
+
=== Controllers
|
87
|
+
|
88
|
+
=== Routing
|
89
|
+
|
90
|
+
There is currently not a helper for the routing however this is an example structure to get an application working
|
91
|
+
where the context is a calculation model
|
92
|
+
|
93
|
+
# == Have yet to create a Routing helper from question Chain
|
94
|
+
# Hence manua here and this is about is obvious well its just not
|
95
|
+
match '/answers/fire_object_search' => 'answers#fire_object_search'
|
96
|
+
match '/answers/fire_populate_drop_down' => 'answers#fire_populate_drop_down'
|
97
|
+
|
98
|
+
chain_template_routes = lambda do
|
99
|
+
scope "/:context(/:question_id)" do
|
100
|
+
resources :answers, :only => [:new, :create, :index] do
|
101
|
+
collection do
|
102
|
+
post :fire_populate_drop_down
|
103
|
+
post :fire_object_search
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
scope "/:context" do
|
109
|
+
resources :answers, :only => [:edit, :update, :show] do
|
110
|
+
collection do
|
111
|
+
post :fire_populate_drop_down
|
112
|
+
post :fire_object_search
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
resource :users do
|
119
|
+
chain_template_routes.call
|
120
|
+
end
|
121
|
+
|
18
122
|
== UiObjects
|
19
123
|
|
20
124
|
=== Drop Downs
|
@@ -30,5 +134,3 @@ At the minute this has dependencies on MongoMapper currently thinking about movi
|
|
30
134
|
=== Markup
|
31
135
|
|
32
136
|
=== CSS
|
33
|
-
|
34
|
-
=== Bundling
|
@@ -2,6 +2,7 @@ module QuestionChain
|
|
2
2
|
module Answerable
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
include MongoMapper::Serialize
|
5
|
+
|
5
6
|
|
6
7
|
included do
|
7
8
|
key :question_id, ObjectId
|
@@ -22,7 +23,7 @@ module QuestionChain
|
|
22
23
|
before_save :cache_attributes
|
23
24
|
|
24
25
|
# == Search
|
25
|
-
|
26
|
+
include Hunt
|
26
27
|
searches :reference, :created_by, :stored_variable_input, :stored_identifier, :_extra_keywords
|
27
28
|
ensure_index :'searches.default'
|
28
29
|
|
@@ -35,8 +36,9 @@ module QuestionChain
|
|
35
36
|
validates_presence_of :question_id
|
36
37
|
validates_presence_of :answer_params
|
37
38
|
validates_presence_of :result
|
38
|
-
|
39
|
-
|
39
|
+
validates_presence_of :user
|
40
|
+
validate :valid_answer_params
|
41
|
+
validate :valid_result
|
40
42
|
|
41
43
|
# == Associations
|
42
44
|
belongs_to :user
|
@@ -45,25 +47,7 @@ module QuestionChain
|
|
45
47
|
attr_protected :user_id
|
46
48
|
|
47
49
|
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
|
-
|
50
|
+
|
67
51
|
module InstanceMethods
|
68
52
|
def add_extra_keywords
|
69
53
|
unless (self.class._extra_keyword_methods || []).empty?
|
@@ -134,9 +118,18 @@ module QuestionChain
|
|
134
118
|
end
|
135
119
|
|
136
120
|
def cache_attributes
|
137
|
-
write_attribute(:created_by, user.full_name)
|
121
|
+
write_attribute(:created_by, user.full_name) if user && user.respond_to?(:full_name)
|
138
122
|
write_attribute(:stored_variable_input, variable_input)
|
139
123
|
end
|
124
|
+
|
125
|
+
def valid_answer_params
|
126
|
+
errors.add(:answer_params, "") if answer_params.empty?
|
127
|
+
end
|
128
|
+
|
129
|
+
def valid_result
|
130
|
+
errors.add(:result, "") if result.empty?
|
131
|
+
end
|
140
132
|
end
|
133
|
+
|
141
134
|
end
|
142
135
|
end
|
@@ -29,7 +29,7 @@ class ChainTemplate
|
|
29
29
|
# == Validations
|
30
30
|
validates_presence_of :for_resource
|
31
31
|
validates_presence_of :context
|
32
|
-
|
32
|
+
validate :valid_context
|
33
33
|
|
34
34
|
def self.attributes_for_api
|
35
35
|
%w(id name for_resource account_id parent_resource)
|
@@ -40,4 +40,8 @@ class ChainTemplate
|
|
40
40
|
self.active_at = Time.now
|
41
41
|
self.save!
|
42
42
|
end
|
43
|
+
|
44
|
+
def valid_context
|
45
|
+
errors.add(:context, "") if context.empty?
|
46
|
+
end
|
43
47
|
end
|
@@ -33,9 +33,7 @@ class UiObject
|
|
33
33
|
validates_presence_of :ui_group_id
|
34
34
|
validates_presence_of :label
|
35
35
|
validates_presence_of :ui_attributes
|
36
|
-
|
37
|
-
!ui_attributes.empty?
|
38
|
-
}
|
36
|
+
validate :valid_ui_attributes
|
39
37
|
validates_associated :rules
|
40
38
|
|
41
39
|
# == Associations
|
@@ -44,7 +42,7 @@ class UiObject
|
|
44
42
|
|
45
43
|
# == Hooks
|
46
44
|
before_save :add_rule_observers!
|
47
|
-
|
45
|
+
before_validation :set_default_attributes, :on => :create
|
48
46
|
|
49
47
|
def self.attributes_for_api
|
50
48
|
%w(id name _type label description default_value ui_attributes ui_group_id rules extra_info css_classes)
|
@@ -88,5 +86,9 @@ class UiObject
|
|
88
86
|
self.add_observer(rule, :fire!)
|
89
87
|
end
|
90
88
|
end
|
89
|
+
|
90
|
+
def valid_ui_attributes
|
91
|
+
errors.add(:ui_attributes, "") if ui_attributes.empty?
|
92
|
+
end
|
91
93
|
|
92
94
|
end
|
data/question_chain.gemspec
CHANGED
@@ -9,13 +9,13 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Richard Hooker"]
|
10
10
|
s.email = ["richard.hooker@carboncalculated.com"]
|
11
11
|
s.homepage = ""
|
12
|
-
s.summary = %q{Rails3 Gem to Generate Carbon Calculated
|
13
|
-
s.description = %q{Rails3 Gem to Generate Carbon Calculated
|
12
|
+
s.summary = %q{Rails3 Gem to Generate Carbon Calculated Applications}
|
13
|
+
s.description = %q{Rails3 Gem to Generate Carbon Calculated Applications}
|
14
14
|
|
15
15
|
s.rubyforge_project = "question_chain"
|
16
16
|
|
17
17
|
s.add_dependency 'mustache', '>= 0.98.0'
|
18
|
-
s.add_dependency 'mongo_mapper', '
|
18
|
+
s.add_dependency 'mongo_mapper', '~> 0.9.0'
|
19
19
|
s.add_dependency 'mustache', '>= 0.98.0'
|
20
20
|
s.add_dependency 'hashie', ">= 0.2.1"
|
21
21
|
s.add_dependency 'crack', ">= 0.1.8"
|
data/test_app/Gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
## Bundle the gems you use:
|
4
|
-
gem "rails", "3.0.
|
4
|
+
gem "rails", "3.0.7"
|
5
5
|
|
6
|
-
gem "bson_ext", "1.
|
6
|
+
gem "bson_ext", "1.3.0"
|
7
7
|
gem "inherited_resources"
|
8
|
-
gem "mongo_mapper", "0.
|
9
|
-
gem "hunt"
|
8
|
+
gem "mongo_mapper", "~> 0.9.0"
|
9
|
+
gem "hunt", :git => "git://github.com/hookercookerman/hunt.git"
|
10
10
|
gem "transitions"
|
11
11
|
gem "question_chain", :path =>File.expand_path("../../", __FILE__), :require => "question_chain"
|
12
12
|
gem "yard"
|
data/test_app/spec/factories.rb
CHANGED
@@ -15,11 +15,17 @@ Factory.sequence :related_attribute do |n|
|
|
15
15
|
"related_attribute_#{n}"
|
16
16
|
end
|
17
17
|
|
18
|
+
Factory.define :user do |f|
|
19
|
+
f.first_name {"Egg"}
|
20
|
+
f.last_name {"Beans"}
|
21
|
+
end
|
22
|
+
|
18
23
|
Factory.define :flight do |f|
|
19
24
|
f.question_id {BSON::ObjectId.new}
|
20
25
|
f.result{ {"co2"=> "45.5", "object_references" => {"123" => {"identifier" => "beans"}}}}
|
21
26
|
f.answer_params {{"flight" => "123"}}
|
22
27
|
f.reference {Factory.next(:name)}
|
28
|
+
f.association :user
|
23
29
|
end
|
24
30
|
|
25
31
|
Factory.define :chain_template do |f|
|
@@ -8,14 +8,14 @@ describe "Flight (Test Model)" do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should have answerable keys" do
|
11
|
-
@flight.keys.should include(
|
12
|
-
@flight.keys.should include(
|
13
|
-
@flight.keys.should include(
|
14
|
-
@flight.keys.should include(
|
15
|
-
@flight.keys.should include(
|
16
|
-
@flight.keys.should include(
|
17
|
-
@flight.keys.should include(
|
18
|
-
@flight.keys.should include(
|
11
|
+
@flight.keys.should include("question_id")
|
12
|
+
@flight.keys.should include("result")
|
13
|
+
@flight.keys.should include("answer_params")
|
14
|
+
@flight.keys.should include("answer_json")
|
15
|
+
@flight.keys.should include("user_id")
|
16
|
+
@flight.keys.should include("reference")
|
17
|
+
@flight.keys.should include("stored_identifier")
|
18
|
+
@flight.keys.should include("_extra_keywords")
|
19
19
|
end
|
20
20
|
|
21
21
|
it "Should have access to _extra_keyword class method" do
|
@@ -63,8 +63,8 @@ describe "Flight (Test Model)" do
|
|
63
63
|
flights.first.should == @flight
|
64
64
|
end
|
65
65
|
|
66
|
-
it "should not be found on a silly search like
|
67
|
-
flights = Flight.search "
|
66
|
+
it "should not be found on a silly search like crumpets" do
|
67
|
+
flights = Flight.search "crumpets"
|
68
68
|
flights.should be_empty
|
69
69
|
end
|
70
70
|
end
|
@@ -32,7 +32,7 @@ describe "UiGroup" do
|
|
32
32
|
@ui_group = Factory.build(:ui_group)
|
33
33
|
@text_field = @ui_group.text_fields.create!(Factory.attributes_for(:text_field))
|
34
34
|
@relatable_category_drop_down = @ui_group.relatable_category_drop_downs.create!(Factory.attributes_for(:relatable_category_drop_down))
|
35
|
-
@object_referenece_drop_down = @ui_group.
|
35
|
+
@object_referenece_drop_down = @ui_group.create_object_reference_drop_down(Factory.attributes_for(:object_reference_drop_down))
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should have 3 ui_objects" do
|
@@ -4,6 +4,19 @@ require 'rspec/rails'
|
|
4
4
|
|
5
5
|
# Requires supporting files with custom matchers and macros, etc,
|
6
6
|
# in ./support/ and its subdirectories.
|
7
|
+
class User
|
8
|
+
include MongoMapper::Document
|
9
|
+
|
10
|
+
# == Keys
|
11
|
+
key :first_name, String
|
12
|
+
key :last_name, String
|
13
|
+
|
14
|
+
def full_name
|
15
|
+
"#{first_name} #{last_name}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
7
20
|
require File.expand_path("../factories", __FILE__)
|
8
21
|
|
9
22
|
require "database_cleaner"
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Richard Hooker
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-04-19 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -38,13 +38,13 @@ dependencies:
|
|
38
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
segments:
|
44
44
|
- 0
|
45
|
-
-
|
46
|
-
-
|
47
|
-
version: 0.
|
45
|
+
- 9
|
46
|
+
- 0
|
47
|
+
version: 0.9.0
|
48
48
|
type: :runtime
|
49
49
|
version_requirements: *id002
|
50
50
|
- !ruby/object:Gem::Dependency
|
@@ -152,7 +152,7 @@ dependencies:
|
|
152
152
|
version: 0.3.0
|
153
153
|
type: :runtime
|
154
154
|
version_requirements: *id009
|
155
|
-
description: Rails3 Gem to Generate Carbon Calculated
|
155
|
+
description: Rails3 Gem to Generate Carbon Calculated Applications
|
156
156
|
email:
|
157
157
|
- richard.hooker@carboncalculated.com
|
158
158
|
executables: []
|
@@ -244,7 +244,6 @@ files:
|
|
244
244
|
- test_app/lib/tasks/yard.rake
|
245
245
|
- test_app/public/.gitkeep
|
246
246
|
- test_app/script/rails
|
247
|
-
- test_app/spec/acceptance/new_spec
|
248
247
|
- test_app/spec/factories.rb
|
249
248
|
- test_app/spec/models/chain_template_spec.rb
|
250
249
|
- test_app/spec/models/flight_spec.rb
|
@@ -286,7 +285,7 @@ rubyforge_project: question_chain
|
|
286
285
|
rubygems_version: 1.3.7
|
287
286
|
signing_key:
|
288
287
|
specification_version: 3
|
289
|
-
summary: Rails3 Gem to Generate Carbon Calculated
|
288
|
+
summary: Rails3 Gem to Generate Carbon Calculated Applications
|
290
289
|
test_files:
|
291
290
|
- test_app/Gemfile
|
292
291
|
- test_app/Rakefile
|
@@ -312,7 +311,6 @@ test_files:
|
|
312
311
|
- test_app/lib/tasks/yard.rake
|
313
312
|
- test_app/public/.gitkeep
|
314
313
|
- test_app/script/rails
|
315
|
-
- test_app/spec/acceptance/new_spec
|
316
314
|
- test_app/spec/factories.rb
|
317
315
|
- test_app/spec/models/chain_template_spec.rb
|
318
316
|
- test_app/spec/models/flight_spec.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# Todo For Acceptance Specs
|
2
|
-
|
3
|
-
# Feature: New Answer (for a Flight)
|
4
|
-
# In order add a new answer for a resource that can have a co2 computation
|
5
|
-
# As an application user
|
6
|
-
# I want to be able create a new answer
|
7
|
-
#
|
8
|
-
# Scenario: New Answer for a flight resource (Question wants a distance and a flight)
|
9
|
-
# Given a flight context exists with a valid question
|
10
|
-
# When go to the new flight answers page
|
11
|
-
#
|
12
|
-
# Then show me the page
|
13
|
-
# And I should see "Flight Calculator" within "#question"
|
14
|
-
# And I should see "Please enter flight details" within "#question"
|
15
|
-
# And I should see "Distance" within "#ui_objects"
|
16
|
-
# And I should see "Flight" within "#ui_objects"
|
17
|
-
# And I should see "flight1" within ".ui-objects-object_reference-drop-down-template"
|
18
|
-
# And I should see "flight2" within ".ui-objects-object_reference-drop-down-template"
|
19
|
-
#
|
20
|
-
# Feature: Edit Answer (for a Flight)
|
21
|
-
# In order to change the the details of the resource for a carbon calculation so calculations are correct
|
22
|
-
# As an application user
|
23
|
-
# I want to be able create a edit a carbon calculated resource (Flight)
|
24
|
-
#
|
25
|
-
# Scenario: View the edit page for the flight resource
|
26
|
-
# Given a flight context exists with a valid question
|
27
|
-
# And a flight exists with the id: "3458234509854309534", distance: "12", :flight => "23432234234"
|
28
|
-
# When go to the edit flight answer page
|
29
|
-
#
|
30
|
-
|