cql_qdm_patientapi 1.0.0

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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +46 -0
  3. data/.travis.yml +15 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +127 -0
  6. data/LICENSE +201 -0
  7. data/README.md +2 -0
  8. data/README.rdoc +2 -0
  9. data/Rakefile +32 -0
  10. data/app/assets/javascripts/cql_qdm_patientapi/.keep +0 -0
  11. data/app/assets/javascripts/cql_qdm_patientapi.js.coffee +3 -0
  12. data/app/assets/javascripts/cqlpatient.js.coffee +232 -0
  13. data/app/assets/javascripts/datatypes/adverseevent.js.coffee +70 -0
  14. data/app/assets/javascripts/datatypes/allergyintolerance.js.coffee +63 -0
  15. data/app/assets/javascripts/datatypes/assessment.js.coffee +159 -0
  16. data/app/assets/javascripts/datatypes/careexperience.js.coffee +47 -0
  17. data/app/assets/javascripts/datatypes/caregoal.js.coffee +60 -0
  18. data/app/assets/javascripts/datatypes/characteristic_birthdate.js.coffee +28 -0
  19. data/app/assets/javascripts/datatypes/communication.js.coffee +116 -0
  20. data/app/assets/javascripts/datatypes/datatype.js.coffee +44 -0
  21. data/app/assets/javascripts/datatypes/device.js.coffee +163 -0
  22. data/app/assets/javascripts/datatypes/diagnosis.js.coffee +67 -0
  23. data/app/assets/javascripts/datatypes/diagnosticstudy.js.coffee +215 -0
  24. data/app/assets/javascripts/datatypes/encounter.js.coffee +213 -0
  25. data/app/assets/javascripts/datatypes/familyhistory.js.coffee +37 -0
  26. data/app/assets/javascripts/datatypes/immunization.js.coffee +152 -0
  27. data/app/assets/javascripts/datatypes/intervention.js.coffee +164 -0
  28. data/app/assets/javascripts/datatypes/laboratorytest.js.coffee +243 -0
  29. data/app/assets/javascripts/datatypes/medication.js.coffee +486 -0
  30. data/app/assets/javascripts/datatypes/patient_characteristic.js.coffee +23 -0
  31. data/app/assets/javascripts/datatypes/patient_characteristic_expired.js.coffee +38 -0
  32. data/app/assets/javascripts/datatypes/patient_characteristic_payer.js.coffee +33 -0
  33. data/app/assets/javascripts/datatypes/patient_characteristic_sex.js.coffee +23 -0
  34. data/app/assets/javascripts/datatypes/physicalexam.js.coffee +223 -0
  35. data/app/assets/javascripts/datatypes/procedure.js.coffee +296 -0
  36. data/app/assets/javascripts/datatypes/substance.js.coffee +294 -0
  37. data/app/assets/javascripts/datatypes/symptom.js.coffee +49 -0
  38. data/app/assets/javascripts/types/component.js.coffee +71 -0
  39. data/app/assets/javascripts/types/facility.js.coffee +41 -0
  40. data/app/assets/javascripts/types/id.js.coffee +23 -0
  41. data/app/assets/javascripts/utils/helpers.js.coffee +101 -0
  42. data/bin/rails +12 -0
  43. data/coffeelint.json +135 -0
  44. data/cql_qdm_patientapi.gemspec +25 -0
  45. data/lib/cql_qdm_patientapi/engine.rb +6 -0
  46. data/lib/cql_qdm_patientapi/version.rb +3 -0
  47. data/lib/cql_qdm_patientapi.rb +4 -0
  48. data/vendor/assets/javascripts/cql4browsers.js +53992 -0
  49. metadata +133 -0
@@ -0,0 +1,294 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+
8
+ ###
9
+ Data elements that meet criteria using this datatype should document that the
10
+ substance indicated by the QDM category and its corresponding value set was
11
+ actually given to the patient.
12
+ ###
13
+ class CQL_QDM.SubstanceAdministered extends CQL_QDM.QDMDatatype
14
+ ###
15
+ @param {Object} entry - the HDS data criteria object to convert
16
+ ###
17
+ constructor: (@entry) ->
18
+ super @entry
19
+ @_authorDatetime = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
20
+ @_dosage = @entry.dose
21
+ @_frequency = @entry.frequency
22
+ @_negationRationale = @entry.negationReason
23
+ @_relevantPeriodLow = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
24
+ if @entry.end_time
25
+ @_relevantPeriodHigh = CQL_QDM.Helpers.convertDateTime(@entry.end_time)
26
+ else
27
+ # No end time; high is set to infinity
28
+ @_relevantPeriodHigh = CQL_QDM.Helpers.infinityDateTime()
29
+ @_route = @entry.route
30
+ @_supply = @entry.supply
31
+
32
+ ###
33
+ Author date time is only present when this data type has been negated.
34
+ @returns {Date}
35
+ ###
36
+ authorDatetime: ->
37
+ @_authorDatetime
38
+
39
+ ###
40
+ @returns {Quantity}
41
+ ###
42
+ dosage: ->
43
+ if @_dosage?
44
+ new cql.Quantity({unit: @_dosage['unit'], value: @_dosage['value']})
45
+ else
46
+ null
47
+
48
+ ###
49
+ @returns {Code}
50
+ ###
51
+ frequency: ->
52
+ # TODO: Frequency currently not in HDS model. Can probably add by calculating based off of dose & regimen
53
+ throw new Error('Bonnie does not currently support SubstanceAdministered.frequency')
54
+ if @_frequency?
55
+ new cql.Code(@_frequency.code, @_frequency.code_system)
56
+ else
57
+ null
58
+
59
+ ###
60
+ @returns {Code}
61
+ ###
62
+ negationRationale: ->
63
+ if @_negationRationale?
64
+ new cql.Code(@_negationRationale.code, @_negationRationale.code_system)
65
+ else
66
+ null
67
+
68
+ ###
69
+ @returns {Interval<Date>}
70
+ ###
71
+ relevantPeriod: ->
72
+ low = @_relevantPeriodLow
73
+ high = @_relevantPeriodHigh
74
+ if low?
75
+ new cql.Interval(low, high)
76
+ else
77
+ null
78
+
79
+ ###
80
+ @returns {Code}
81
+ ###
82
+ route: ->
83
+ if @_route?
84
+ new cql.Code(@_route.code, @_route.code_system)
85
+ else
86
+ null
87
+
88
+ ###
89
+ @returns {Quantity}
90
+ ###
91
+ supply: ->
92
+ if @_supply?
93
+ new cql.Quantity({unit: @_supply['unit'], value: @_supply['value']})
94
+ else
95
+ null
96
+
97
+
98
+ ###
99
+ Data elements that meet criteria using this datatype should document a request
100
+ for the substance indicated by the QDM category and its corresponding value set.
101
+ ###
102
+ class CQL_QDM.SubstanceOrder extends CQL_QDM.QDMDatatype
103
+ ###
104
+ @param {Object} entry - the HDS data criteria object to convert
105
+ ###
106
+ constructor: (@entry) ->
107
+ super @entry
108
+ @_authorDatetime = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
109
+ @_dosage = @entry.dose
110
+ @_frequency = @entry.frequency
111
+ @_method = @entry.method
112
+ @_negationRationale = @entry.negationReason
113
+ @_reason = @entry.reason
114
+ @_refills = @entry.refills
115
+ @_route = @entry.route
116
+ @_supply = @entry.supply
117
+
118
+ ###
119
+ @returns {Date}
120
+ ###
121
+ authorDatetime: ->
122
+ @_authorDatetime
123
+
124
+ ###
125
+ @returns {Quantity}
126
+ ###
127
+ dosage: ->
128
+ if @_dosage?
129
+ new cql.Quantity({unit: @_dosage['unit'], value: @_dosage['value']})
130
+ else
131
+ null
132
+
133
+ ###
134
+ @returns {Code}
135
+ ###
136
+ frequency: ->
137
+ # TODO: Frequency currently not in HDS model. Can probably add by calculating based off of dose & regimen
138
+ throw new Error('Bonnie does not currently support SubstanceOrder.frequency')
139
+ if @_frequency?
140
+ new cql.Code(@_frequency.code, @_frequency.code_system)
141
+ else
142
+ null
143
+
144
+ ###
145
+ @returns {Code}
146
+ ###
147
+ method: ->
148
+ if @_method?
149
+ new cql.Code(@_method.code, @_method.code_system)
150
+ else
151
+ null
152
+
153
+ ###
154
+ @returns {Code}
155
+ ###
156
+ negationRationale: ->
157
+ if @_negationRationale?
158
+ new cql.Code(@_negationRationale.code, @_negationRationale.code_system)
159
+ else
160
+ null
161
+
162
+ ###
163
+ @returns {Code}
164
+ ###
165
+ reason: ->
166
+ if @_reason?
167
+ new cql.Code(@_reason.code, @_reason.code_system)
168
+ else
169
+ null
170
+
171
+ ###
172
+ @returns {Integer}
173
+ ###
174
+ refills: ->
175
+ # TODO: Refills should represent 'The number of refills allowed by the prescription.'
176
+ throw new Error('Bonnie does not currently support SubstanceOrder.refills')
177
+
178
+ ###
179
+ @returns {Code}
180
+ ###
181
+ route: ->
182
+ if @_route?
183
+ new cql.Code(@_route.code, @_route.code_system)
184
+ else
185
+ null
186
+
187
+ ###
188
+ @returns {Quantity}
189
+ ###
190
+ supply: ->
191
+ if @_supply?
192
+ new cql.Quantity({unit: @_supply['unit'], value: @_supply['value']})
193
+ else
194
+ null
195
+
196
+
197
+ ###
198
+ Data elements that meet criteria using this datatype should document a
199
+ recommendation for the substance indicated by the QDM category and its
200
+ corresponding value set.
201
+ ###
202
+ class CQL_QDM.SubstanceRecommended extends CQL_QDM.QDMDatatype
203
+ ###
204
+ @param {Object} entry - the HDS data criteria object to convert
205
+ ###
206
+ constructor: (@entry) ->
207
+ super @entry
208
+ @_authorDatetime = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
209
+ @_dosage = @entry.dose
210
+ @_frequency = @entry.frequency
211
+ @_method = @entry.method
212
+ @_negationRationale = @entry.negationReason
213
+ @_reason = @entry.reason
214
+ @_refills = @entry.refills
215
+ @_route = @entry.route
216
+ @_supply = @entry.supply
217
+
218
+ ###
219
+ @returns {Date}
220
+ ###
221
+ authorDatetime: ->
222
+ @_authorDatetime
223
+
224
+ ###
225
+ @returns {Quantity}
226
+ ###
227
+ dosage: ->
228
+ if @_dosage?
229
+ new cql.Quantity({unit: @_dosage['unit'], value: @_dosage['value']})
230
+ else
231
+ null
232
+
233
+ ###
234
+ @returns {Code}
235
+ ###
236
+ frequency: ->
237
+ # TODO: Frequency currently not in HDS model. Can probably add by calculating based off of dose & regimen
238
+ throw new Error('Bonnie does not currently support SubstanceRecommended.frequency')
239
+ if @_frequency?
240
+ new cql.Code(@_frequency.code, @_frequency.code_system)
241
+ else
242
+ null
243
+
244
+ ###
245
+ @returns {Code}
246
+ ###
247
+ method: ->
248
+ if @_method?
249
+ new cql.Code(@_method.code, @_method.code_system)
250
+ else
251
+ null
252
+
253
+ ###
254
+ @returns {Code}
255
+ ###
256
+ negationRationale: ->
257
+ if @_negationRationale?
258
+ new cql.Code(@_negationRationale.code, @_negationRationale.code_system)
259
+ else
260
+ null
261
+
262
+ ###
263
+ @returns {Code}
264
+ ###
265
+ reason: ->
266
+ if @_reason?
267
+ new cql.Code(@_reason.code, @_reason.code_system)
268
+ else
269
+ null
270
+
271
+ ###
272
+ @returns {Integer}
273
+ ###
274
+ refills: ->
275
+ # TODO: Refills should represent 'The number of refills allowed by the prescription.'
276
+ throw new Error('Bonnie does not currently support SubstanceRecommended.refills')
277
+
278
+ ###
279
+ @returns {Code}
280
+ ###
281
+ route: ->
282
+ if @_route?
283
+ new cql.Code(@_route.code, @_route.code_system)
284
+ else
285
+ null
286
+
287
+ ###
288
+ @returns {Quantity}
289
+ ###
290
+ supply: ->
291
+ if @_supply?
292
+ new cql.Quantity({unit: @_supply['unit'], value: @_supply['value']})
293
+ else
294
+ null
@@ -0,0 +1,49 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+
8
+ ###
9
+ Data elements that meet criteria using this datatype should document the
10
+ symptom and its corresponding value set. The onset datetime corresponds to the
11
+ implicit start datetime of the datatype and the abatement datetime corresponds
12
+ to the implicit stop datetime of the datatype. If the abatement datetime is
13
+ null, then the symptom is considered to still be active. When this datatype is
14
+ used with timing relationships, the criterion is looking for whether the
15
+ symptom was active for the time frame indicated by the timing relationships.
16
+ ###
17
+ class CQL_QDM.Symptom extends CQL_QDM.QDMDatatype
18
+ ###
19
+ @param {Object} entry - the HDS data criteria object to convert
20
+ ###
21
+ constructor: (@entry) ->
22
+ super @entry
23
+ @_prevalencePeriodLow = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
24
+ if @entry.end_time
25
+ @_prevalencePeriodHigh = CQL_QDM.Helpers.convertDateTime(@entry.end_time)
26
+ else
27
+ # No end time; high is set to infinity
28
+ @_prevalencePeriodHigh = CQL_QDM.Helpers.infinityDateTime()
29
+ @_severity = @entry.severity
30
+
31
+ ###
32
+ @returns {Interval<Date>}
33
+ ###
34
+ prevalencePeriod: ->
35
+ low = @_prevalencePeriodLow
36
+ high = @_prevalencePeriodHigh
37
+ if low?
38
+ new cql.Interval(low, high)
39
+ else
40
+ null
41
+
42
+ ###
43
+ @returns {Code}
44
+ ###
45
+ severity: ->
46
+ if @_severity?
47
+ new cql.Code(@_severity.code, @_severity.code_system)
48
+ else
49
+ null
@@ -0,0 +1,71 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+ ###
8
+ Represents a CQL 'component' for use in the CQL execution engine.
9
+ ###
10
+ class CQL_QDM.Component
11
+   constructor: (component) ->
12
+ @_result = CQL_QDM.Helpers.formatResult(component.result)
13
+ @_code = new cql.Code(component.code.code, component.code.code_system)
14
+
15
+   exec: (ctx) ->
16
+     @
17
+   
18
+   toString: () ->
19
+     "#{@_result.toString()} '#{@_code.toString()}'"
20
+
21
+ ###
22
+ @returns {Code}
23
+ ###
24
+ code: ->
25
+ if @_code?
26
+ @_code
27
+ else
28
+ null
29
+
30
+ ###
31
+ The model_info_file also lists Integer, Decimal, DateTime, Time, and Ratio.
32
+ Decimal and Integer are covered under Quantity with a nil unit.
33
+ Ratio is not yet supported with CQL although it appears in the QDM model.
34
+ Time and Datetime are covered by Date
35
+ @returns {Code|Quantity}
36
+ ###
37
+ result: ->
38
+ if @_result?
39
+ @_result
40
+ else
41
+ null
42
+
43
+ ###
44
+ Represents a CQL 'component' for Laboratory Test Performed, which has a reference range.
45
+ ###
46
+ class CQL_QDM.ResultComponent extends CQL_QDM.Component
47
+ constructor: (component) ->
48
+ super(component)
49
+ referenceRangeLow = component.referenceRangeLow if component.referenceRangeLow.scalar # {"scalar": scalar, "unit": unit}}
50
+ referenceRangeHigh = component.referenceRangeHigh if component.referenceRangeHigh.scalar
51
+ referenceRangeLow_value = referenceRangeLow.scalar if referenceRangeLow
52
+ referenceRangeHigh_value = referenceRangeHigh.scalar if referenceRangeHigh
53
+
54
+ # If only one of low/high is defined, make interval with undefined endpoint
55
+ @_referenceRange = new cql.Interval(referenceRangeLow_value, referenceRangeHigh_value) if referenceRangeLow_value || referenceRangeHigh_value
56
+ # TODO: might need to deal with units in the future
57
+
58
+   exec: (ctx) ->
59
+     @
60
+
61
+ toString: () ->
62
+ "'#{@_referenceRange.toString()}'"
63
+
64
+ ###
65
+ @returns {Interval<Quantity>}
66
+ ###
67
+ referenceRange: ->
68
+ if @_referenceRange?
69
+ @_referenceRange
70
+ else
71
+ null
@@ -0,0 +1,41 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+ ###
8
+ Represents a CQL 'facility' for use in the CQL execution engine.
9
+ ###
10
+ class CQL_QDM.FacilityLocation
11
+   constructor: (facility) ->
12
+ @_code = new cql.Code(facility.code.code, facility.code.code_system, undefined, facility.display)
13
+
14
+ locationPeriodLow = CQL_QDM.Helpers.convertDateTime(facility.locationPeriodLow) if facility.locationPeriodLow
15
+ locationPeriodHigh = CQL_QDM.Helpers.convertDateTime(facility.locationPeriodHigh) if facility.locationPeriodHigh
16
+ # If only one of Low/High is defined, make an interval with an undefined start or end
17
+ @_locationPeriod = new cql.Interval(locationPeriodLow, locationPeriodHigh) if locationPeriodLow || locationPeriodHigh
18
+
19
+   exec: (ctx) ->
20
+     @
21
+   
22
+   toString: () ->
23
+     "#{@_locationPeriod} '#{@_code.toString()}'"
24
+
25
+ ###
26
+ @returns {Code}
27
+ ###
28
+ code: ->
29
+ if @_code?
30
+ @_code
31
+ else
32
+ null
33
+
34
+ ###
35
+ @returns {Interval<Date>}
36
+ ###
37
+ locationPeriod: ->
38
+ if @_locationPeriod?
39
+ @_locationPeriod
40
+ else
41
+ null
@@ -0,0 +1,23 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+ ###
8
+ Represents the QDM.Id used in the execution engine.
9
+ ###
10
+ class CQL_QDM.Id
11
+ constructor: (@value, @namingSystem) ->
12
+
13
+ ###
14
+ @returns {String}
15
+ ###
16
+ namingSystem: ->
17
+ @namingSystem
18
+
19
+ ###
20
+ @returns {String}
21
+ ###
22
+ value: ->
23
+ @namingSystem
@@ -0,0 +1,101 @@
1
+ ###
2
+ @namespace scoping into the CQL_QDM namespace (all classes and
3
+ their methods will be accessable through the CQL_QDM namespace)
4
+ ###
5
+ @CQL_QDM ||= {}
6
+
7
+
8
+ ###
9
+ Various helper methods.
10
+ ###
11
+ class CQL_QDM.Helpers
12
+
13
+ ###
14
+ Used to convert a Bonnie date + time into a compatible cql DateTime.
15
+
16
+ @param {String} input - the date time to convert
17
+ @returns cql.DateTime
18
+ ###
19
+ @convertDateTime: (input) ->
20
+ if input?
21
+ if moment.utc(input, 'MM/DD/YYYY hh:mm A', true).isValid() || moment.utc(input, 'MM/DD/YYYY h:mm A', true).isValid()
22
+ cql.DateTime.fromDate(moment.utc(input, 'MM/DD/YYYY hh:mm A').toDate(), 0)
23
+ else
24
+ cql.DateTime.fromDate(moment.utc(input, 'X').toDate(), 0)
25
+ else
26
+ null
27
+
28
+ ###
29
+ Returns an 'end of range' cql.DateTime.
30
+ See Section 3.4.1 "System-Defined Types" in the CQL specification.
31
+
32
+ @returns cql.DateTime
33
+ ###
34
+ @infinityDateTime: ->
35
+ cql.DateTime.parse('9999-12-31T23:59:59.999+0000')
36
+
37
+ ###
38
+ For DateTime values makes sure value meets the CQL standard.
39
+ For scalar values:
40
+ - First checks that the value component is numeric
41
+ - Second for the unit component attempts to clean up freetext
42
+ to match a standard version.
43
+
44
+ @param {Result} input - the result object to be parsed into a Quantity
45
+ @returns cql.Quantity
46
+ ###
47
+ @formatResult: (input) ->
48
+ if input?
49
+ if input?.units == 'UnixTime'
50
+ CQL_QDM.Helpers.convertDateTime(input.scalar)
51
+ else if input.codes?
52
+ code_system = Object.keys(input.codes)?[0]
53
+ code = input.codes[code_system]?[0]
54
+ new cql.Code(code, code_system)
55
+ else if input.code?
56
+ code_system = input.code.code_system
57
+ code = input.code.code
58
+ new cql.Code(code, code_system)
59
+ # Check that the scalar portion is a number and the units are a non-zero length string.
60
+ else if (input.scalar?.match(/^[-+]?[0-9]*\.?[0-9]+$/) != null)
61
+ if input.units.length > 0
62
+ new cql.Quantity({unit: input.units , value: parseFloat(input.scalar)})
63
+ else
64
+ parseFloat(input.scalar)
65
+ else
66
+ null
67
+
68
+ ###
69
+ @returns {Array}
70
+ ###
71
+ @relatedTo: (relatedToInput) ->
72
+ relatedToArray = []
73
+ if relatedToInput?
74
+ for relatedTo in relatedToInput
75
+ if relatedTo?
76
+ relatedToArray.push new CQL_QDM.Id(relatedTo.referenced_id)
77
+ relatedToArray
78
+
79
+ ###
80
+ @returns {Array}
81
+ ###
82
+ @components: (componentsInput) ->
83
+ components = []
84
+ if componentsInput?
85
+ for value in componentsInput.values
86
+ if value?
87
+ components.push new CQL_QDM.Component(value)
88
+ components
89
+
90
+ ###
91
+ @returns {Array}
92
+ ###
93
+ @diagnoses: (diagnosesInput, principalDiagnosisInput) ->
94
+ diagnoses = []
95
+ if diagnosesInput?
96
+ for diagnosis in diagnosesInput.values
97
+ if diagnosis?
98
+ diagnoses.push new cql.Code(diagnosis.code, diagnosis.code_system)
99
+ if principalDiagnosisInput?
100
+ diagnoses.push new cql.Code(principalDiagnosisInput.code, principalDiagnosisInput.code_system)
101
+ diagnoses
data/bin/rails ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/cql_qdm_patientapi/engine', __FILE__)
6
+
7
+ # Set up gems listed in the Gemfile.
8
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
+
11
+ require 'rails/all'
12
+ require 'rails/engine/commands'