clinical 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.
- data/.document +5 -0
- data/.gitignore +8 -0
- data/LICENSE +20 -0
- data/README.rdoc +7 -0
- data/Rakefile +87 -0
- data/VERSION +1 -0
- data/clinical.gemspec +81 -0
- data/features/finding_clinical_trials.feature +52 -0
- data/features/getting_keywords_and_categories.feature +9 -0
- data/features/step_definitions/clinical_steps.rb +74 -0
- data/features/support/env.rb +6 -0
- data/lib/clinical/address.rb +10 -0
- data/lib/clinical/agency.rb +6 -0
- data/lib/clinical/collaborator.rb +6 -0
- data/lib/clinical/collection.rb +24 -0
- data/lib/clinical/condition.rb +20 -0
- data/lib/clinical/contact.rb +13 -0
- data/lib/clinical/extensions.rb +28 -0
- data/lib/clinical/intervention.rb +13 -0
- data/lib/clinical/lead_sponsor.rb +6 -0
- data/lib/clinical/location.rb +10 -0
- data/lib/clinical/outcome.rb +29 -0
- data/lib/clinical/primary_outcome.rb +6 -0
- data/lib/clinical/secondary_outcome.rb +6 -0
- data/lib/clinical/sponsor.rb +27 -0
- data/lib/clinical/status.rb +42 -0
- data/lib/clinical/trial.rb +181 -0
- data/lib/clinical.rb +29 -0
- data/test/clinical/trial_test.rb +48 -0
- data/test/fixtures/lupus_single.xml +171 -0
- data/test/fixtures/open_set.xml +212 -0
- data/test/test_helper.rb +23 -0
- metadata +127 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Dan Pickett
|
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
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin require "metric_fu" rescue LoadError; end
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "clinical"
|
10
|
+
gem.summary = %Q{a library for accessing data from ClinicalTrials.gov}
|
11
|
+
gem.email = "dpickett@enlightsolutions.com"
|
12
|
+
gem.homepage = "http://github.com/dpickett/clinical"
|
13
|
+
gem.authors = ["Dan Pickett"]
|
14
|
+
gem.add_dependency("jnunemaker-httparty", ">= 0.4.3")
|
15
|
+
gem.add_dependency("jnunemaker-happymapper", ">= 0.2.5")
|
16
|
+
gem.add_dependency("mislav-will_paginate", ">= 2.3.11")
|
17
|
+
gem.add_dependency("nokogiri", ">= 1.3.3")
|
18
|
+
|
19
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
+
end
|
21
|
+
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
Rake::TestTask.new(:test) do |test|
|
28
|
+
test.libs << 'lib' << 'test'
|
29
|
+
test.pattern = 'test/**/*_test.rb'
|
30
|
+
test.verbose = true
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace :rcov do
|
34
|
+
require 'rcov/rcovtask'
|
35
|
+
Rcov::RcovTask.new(:tests) do |test|
|
36
|
+
test.libs << 'test'
|
37
|
+
test.pattern = 'test/**/*_test.rb'
|
38
|
+
test.rcov_opts = %w{--aggregate coverage.data --exclude osx\/objc,gems\/,spec\/}
|
39
|
+
test.verbose = true
|
40
|
+
end
|
41
|
+
|
42
|
+
require 'cucumber/rake/task'
|
43
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
44
|
+
t.rcov = true
|
45
|
+
t.rcov_opts = %w{--aggregate coverage.data --exclude osx\/objc,gems\/,features\/,spec\/ -o "features_rcov"}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
begin
|
49
|
+
desc "Run both specs and features to generate aggregated coverage"
|
50
|
+
task :rcov do |t|
|
51
|
+
rm "coverage.data" if File.exist?("coverage.data")
|
52
|
+
Rake::Task["rcov:cucumber"].invoke
|
53
|
+
Rake::Task["rcov:tests"].invoke
|
54
|
+
end
|
55
|
+
rescue LoadError
|
56
|
+
task :rcov do
|
57
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
62
|
+
require 'cucumber/rake/task'
|
63
|
+
Cucumber::Rake::Task.new(:features)
|
64
|
+
|
65
|
+
rescue LoadError
|
66
|
+
task :features do
|
67
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
task :default => :test
|
72
|
+
|
73
|
+
require 'rake/rdoctask'
|
74
|
+
Rake::RDocTask.new do |rdoc|
|
75
|
+
if File.exist?('VERSION.yml')
|
76
|
+
config = YAML.load(File.read('VERSION.yml'))
|
77
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
78
|
+
else
|
79
|
+
version = ""
|
80
|
+
end
|
81
|
+
|
82
|
+
rdoc.rdoc_dir = 'rdoc'
|
83
|
+
rdoc.title = "clinical #{version}"
|
84
|
+
rdoc.rdoc_files.include('README*')
|
85
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
86
|
+
end
|
87
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.2
|
data/clinical.gemspec
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{clinical}
|
5
|
+
s.version = "0.2.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Dan Pickett"]
|
9
|
+
s.date = %q{2009-07-28}
|
10
|
+
s.email = %q{dpickett@enlightsolutions.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"clinical.gemspec",
|
23
|
+
"features/finding_clinical_trials.feature",
|
24
|
+
"features/getting_keywords_and_categories.feature",
|
25
|
+
"features/step_definitions/clinical_steps.rb",
|
26
|
+
"features/support/env.rb",
|
27
|
+
"lib/clinical.rb",
|
28
|
+
"lib/clinical/address.rb",
|
29
|
+
"lib/clinical/agency.rb",
|
30
|
+
"lib/clinical/collaborator.rb",
|
31
|
+
"lib/clinical/collection.rb",
|
32
|
+
"lib/clinical/condition.rb",
|
33
|
+
"lib/clinical/contact.rb",
|
34
|
+
"lib/clinical/extensions.rb",
|
35
|
+
"lib/clinical/intervention.rb",
|
36
|
+
"lib/clinical/lead_sponsor.rb",
|
37
|
+
"lib/clinical/location.rb",
|
38
|
+
"lib/clinical/outcome.rb",
|
39
|
+
"lib/clinical/primary_outcome.rb",
|
40
|
+
"lib/clinical/secondary_outcome.rb",
|
41
|
+
"lib/clinical/sponsor.rb",
|
42
|
+
"lib/clinical/status.rb",
|
43
|
+
"lib/clinical/trial.rb",
|
44
|
+
"test/clinical/trial_test.rb",
|
45
|
+
"test/fixtures/lupus_single.xml",
|
46
|
+
"test/fixtures/open_set.xml",
|
47
|
+
"test/test_helper.rb"
|
48
|
+
]
|
49
|
+
s.has_rdoc = true
|
50
|
+
s.homepage = %q{http://github.com/dpickett/clinical}
|
51
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.3.2}
|
54
|
+
s.summary = %q{a library for accessing data from ClinicalTrials.gov}
|
55
|
+
s.test_files = [
|
56
|
+
"test/clinical/trial_test.rb",
|
57
|
+
"test/test_helper.rb"
|
58
|
+
]
|
59
|
+
|
60
|
+
if s.respond_to? :specification_version then
|
61
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
62
|
+
s.specification_version = 3
|
63
|
+
|
64
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
65
|
+
s.add_runtime_dependency(%q<jnunemaker-httparty>, [">= 0.4.3"])
|
66
|
+
s.add_runtime_dependency(%q<jnunemaker-happymapper>, [">= 0.2.5"])
|
67
|
+
s.add_runtime_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
|
68
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 1.3.3"])
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<jnunemaker-httparty>, [">= 0.4.3"])
|
71
|
+
s.add_dependency(%q<jnunemaker-happymapper>, [">= 0.2.5"])
|
72
|
+
s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
|
73
|
+
s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
|
74
|
+
end
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<jnunemaker-httparty>, [">= 0.4.3"])
|
77
|
+
s.add_dependency(%q<jnunemaker-happymapper>, [">= 0.2.5"])
|
78
|
+
s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
|
79
|
+
s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Feature: As a potential participant for a clinical study
|
2
|
+
I want to search for clinical trials
|
3
|
+
So that I can find out more information about them
|
4
|
+
|
5
|
+
Scenario: Find open studies
|
6
|
+
Given I am searching for trials where "recruiting" is "true"
|
7
|
+
When I perform the search
|
8
|
+
Then I should get trials that are "open"
|
9
|
+
|
10
|
+
Scenario: Find closed studies
|
11
|
+
Given I am searching for trials where "recruiting" is "false"
|
12
|
+
When I perform the search
|
13
|
+
Then I should get trials that are not "open"
|
14
|
+
|
15
|
+
Scenario: Find a specific condition
|
16
|
+
Given I am searching for trials where "condition" is "hemophelia"
|
17
|
+
When I perform the extended search
|
18
|
+
Then I should get trials where the "conditions" contains "hemophelia"
|
19
|
+
|
20
|
+
Scenario: Find a specific intervention
|
21
|
+
Given I am searching for trials where "intervention" is "drug"
|
22
|
+
When I perform the extended search
|
23
|
+
Then I should get trials where the "interventions" contains "drug"
|
24
|
+
|
25
|
+
Scenario: Find a specific outcome
|
26
|
+
Given I am searching for trials where "outcome" is "toxic"
|
27
|
+
When I perform the extended search
|
28
|
+
Then I should get trials where the "outcomes" contains "toxic"
|
29
|
+
|
30
|
+
Scenario: Find a specific sponsor
|
31
|
+
Given I am searching for trials where "sponsor" is "Eli Lilly"
|
32
|
+
When I perform the extended search
|
33
|
+
Then I should get trials where the "sponsors" contains "Eli Lilly"
|
34
|
+
|
35
|
+
Scenario: Find a specific trial
|
36
|
+
When I attempt to retrieve trial "NCT00001372"
|
37
|
+
Then I should get a trial
|
38
|
+
And the trial should have an "id" of "NCT00001372"
|
39
|
+
|
40
|
+
Scenario: Find a specific trial with extended attributes
|
41
|
+
When I attempt to retrieve trial "NCT00454363"
|
42
|
+
Then I should get a trial
|
43
|
+
And the trial should have a "phase" of "2"
|
44
|
+
And the trial should have "conditions" like "Lung Cancer"
|
45
|
+
And the trial should have a "minimum_age" of "21 Years"
|
46
|
+
And the trial should have "sponsors" like "M.D. Anderson"
|
47
|
+
|
48
|
+
Scenario: Find a non-existant trial
|
49
|
+
When I attempt to retrieve trial "4325785"
|
50
|
+
Then I should not get a trial
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: As a user of the clinical library
|
2
|
+
I want to retrieve keywords, categories, and terms from ClinicalTrials.gov
|
3
|
+
So that I can associate related trials
|
4
|
+
|
5
|
+
Scenario: Get keywords, categories, and terms
|
6
|
+
When I attempt to retrieve keywords for trial "NCT00001372"
|
7
|
+
Then the trial should have "keywords" like "Autoimmunity"
|
8
|
+
And the trial should have "categories" like "Urologic Diseases"
|
9
|
+
And the trial should have "terms" like "Connective Tissue Diseases"
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Given /^I am searching for trials where "([^\"]*)" is "([^\"]*)"$/ do |field, value|
|
2
|
+
@params ||= {}
|
3
|
+
|
4
|
+
if value == "true"
|
5
|
+
value = true
|
6
|
+
elsif value == "false"
|
7
|
+
value = false
|
8
|
+
end
|
9
|
+
|
10
|
+
@params[field.to_sym] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I perform the search$/ do
|
14
|
+
@trials = Clinical::Trial.find(:conditions => @params)
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I perform the extended search$/ do
|
18
|
+
@trials = Clinical::Trial.find(:conditions => @params, :extended => true)
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^I attempt to retrieve trial "([^\"]*)"$/ do |id|
|
22
|
+
@trial = Clinical::Trial.find_by_id(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
When /^I attempt to retrieve keywords for trial "([^\"]*)"$/ do |id|
|
26
|
+
@trial = Clinical::Trial.find_by_id(id)
|
27
|
+
@trial.get_metadata
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^I should get trials that are (not )?"([^\"]*)"$/ do |not_included, field|
|
31
|
+
if not_included
|
32
|
+
result = false
|
33
|
+
else
|
34
|
+
result = true
|
35
|
+
end
|
36
|
+
|
37
|
+
@trials.each do |trial|
|
38
|
+
trial.send(field + "?").should(eql(result))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Then /^I should get trials where the "([^\"]*)" contains "([^\"]*)"$/ do |field, value|
|
43
|
+
@trials.each do |trial|
|
44
|
+
item_values = []
|
45
|
+
result = trial.send(field)
|
46
|
+
if result.is_a?(Array)
|
47
|
+
found = false
|
48
|
+
result.each do |i|
|
49
|
+
found = true if i.to_s =~ /#{value}/i
|
50
|
+
end
|
51
|
+
found.should be_true
|
52
|
+
else
|
53
|
+
result.to_s.should =~ /#{value}/i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Then /^I should get a trial$/ do
|
59
|
+
@trial.should_not be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
Then /^the trial should have an? "([^\"]*)" of "([^\"]*)"$/ do |field, value|
|
63
|
+
@trial.send(field).to_s.should eql(value)
|
64
|
+
end
|
65
|
+
|
66
|
+
Then /^the trial should have "([^\"]*)" like "([^\"]*)"$/ do |field, value|
|
67
|
+
@trial.send(field).to_s.should =~ /#{Regexp.escape(value)}/
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
Then /^I should not get a trial$/ do
|
72
|
+
@trial.should be_nil
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Clinical
|
2
|
+
class Collection < WillPaginate::Collection
|
3
|
+
include HappyMapper
|
4
|
+
attr_accessor :count
|
5
|
+
class << self
|
6
|
+
def create_from_results(page, per_page, body)
|
7
|
+
results = SearchResult.parse(body)
|
8
|
+
col = create(page, per_page, results.count || 0) do |pager|
|
9
|
+
pager.replace(results.trials)
|
10
|
+
end
|
11
|
+
col.count = results.count
|
12
|
+
col
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class SearchResult
|
17
|
+
include HappyMapper
|
18
|
+
tag "search_results"
|
19
|
+
attribute "count", Integer
|
20
|
+
|
21
|
+
has_many :trials, Clinical::Trial
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Clinical
|
2
|
+
class Condition
|
3
|
+
attr_accessor :name
|
4
|
+
include HappyMapper
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
self.name || ""
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def parse(xml, options)
|
12
|
+
xml.find("condition").collect do |n|
|
13
|
+
item = new
|
14
|
+
item.name = n.content.chomp.strip
|
15
|
+
item
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Clinical
|
2
|
+
class Contact
|
3
|
+
include HappyMapper
|
4
|
+
|
5
|
+
element :first_name, String
|
6
|
+
element :middle_name, String
|
7
|
+
element :last_name, String
|
8
|
+
element :degrees, String
|
9
|
+
element :phone, String
|
10
|
+
element :phone_ext, String
|
11
|
+
element :email, String
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#thanks Rails Core!
|
2
|
+
module Clinical
|
3
|
+
module Extensions
|
4
|
+
module Array
|
5
|
+
def extract_options!
|
6
|
+
last.is_a?(::Hash) ? pop : {}
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module String
|
12
|
+
def underscore(camel_cased_word)
|
13
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
14
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
15
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
16
|
+
tr("-", "_").
|
17
|
+
downcase
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
unless String.instance_methods.include?("underscore")
|
24
|
+
String.send(:include, Clinical::Extensions::String)
|
25
|
+
end
|
26
|
+
unless Array.instance_methods.include?("extract_options!")
|
27
|
+
Array.send(:include, Clinical::Extensions::Array)
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Clinical
|
2
|
+
class Intervention
|
3
|
+
include HappyMapper
|
4
|
+
|
5
|
+
element :type, String, :tag => "intervention_type"
|
6
|
+
element :description, String
|
7
|
+
element :name, String, :tag => "intervention_name"
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"#{self.name} (#{self.type}): #{self.description}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Clinical
|
2
|
+
module Outcome
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.class_eval do
|
7
|
+
include InstanceMethods
|
8
|
+
include HappyMapper
|
9
|
+
element :measure, String
|
10
|
+
element :time_frame, String
|
11
|
+
element :safety_issue, String
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
def primary?
|
17
|
+
self.class.tag_name == "primary_outcome"
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
val = "#{measure}"
|
22
|
+
val << ", TIME FRAME: #{time_frame}" if time_frame
|
23
|
+
val << ",SAFETY ISSUE: #{safety_issue}" if safety_issue
|
24
|
+
val
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Clinical
|
2
|
+
module Sponsor
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
attr_accessor :name
|
6
|
+
include HappyMapper
|
7
|
+
end
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
base.send(:include, InstanceMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def to_s
|
14
|
+
name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
module ClassMethods
|
18
|
+
def parse(xml, options = {})
|
19
|
+
xml.find(tag_name).collect do |n|
|
20
|
+
item = new
|
21
|
+
item.name = n.content.chomp.strip
|
22
|
+
item
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Clinical
|
2
|
+
class Status
|
3
|
+
STATUSES = [
|
4
|
+
:not_yet_recruiting,
|
5
|
+
:recruiting,
|
6
|
+
:enrolling_by_invitation,
|
7
|
+
:active,
|
8
|
+
:not_recruiting,
|
9
|
+
:completed,
|
10
|
+
:suspended,
|
11
|
+
:terminated,
|
12
|
+
:withdrawn,
|
13
|
+
:available,
|
14
|
+
:no_longer_available
|
15
|
+
]
|
16
|
+
|
17
|
+
OPEN_STATUSES = [
|
18
|
+
:not_yet_recruiting,
|
19
|
+
:recruiting
|
20
|
+
]
|
21
|
+
|
22
|
+
attr_reader :name
|
23
|
+
|
24
|
+
def initialize(sym)
|
25
|
+
@name = sym
|
26
|
+
end
|
27
|
+
|
28
|
+
def open?
|
29
|
+
OPEN_STATUSES.include?(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
@name.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def parse(s)
|
38
|
+
s.nil? ? nil : Status.new(s.downcase.gsub(" ", "_").to_sym)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|