rescue_groups 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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +90 -0
- data/LICENSE.txt +22 -0
- data/README.md +226 -0
- data/Rakefile +30 -0
- data/config/config.rb +26 -0
- data/config/initializer.rb +15 -0
- data/docs/animal_field.md +138 -0
- data/docs/event_field.md +20 -0
- data/docs/organization_field.md +25 -0
- data/fields/animal_field.rb +152 -0
- data/fields/event_field.rb +35 -0
- data/fields/organization_field.rb +40 -0
- data/fields/picture_field.rb +30 -0
- data/lib/api_client.rb +29 -0
- data/lib/queryable.rb +79 -0
- data/lib/relationable.rb +76 -0
- data/lib/remote_client.rb +29 -0
- data/lib/remote_model.rb +47 -0
- data/lib/requests/find.rb +29 -0
- data/lib/requests/invalid_client.rb +1 -0
- data/lib/requests/where.rb +94 -0
- data/lib/response.rb +48 -0
- data/models/animal.rb +57 -0
- data/models/event.rb +41 -0
- data/models/organization.rb +41 -0
- data/models/picture.rb +26 -0
- data/rescue_groups.gemspec +28 -0
- data/rescue_groups.rb +27 -0
- data/search/animal_search.rb +15 -0
- data/search/base_search.rb +72 -0
- data/search/event_search.rb +15 -0
- data/search/filter.rb +49 -0
- data/search/organization_search.rb +15 -0
- data/spec/fixtures/animal/find.json +1 -0
- data/spec/fixtures/animal/where.json +1 -0
- data/spec/fixtures/error.json +20 -0
- data/spec/fixtures/event/find.json +1 -0
- data/spec/fixtures/event/where.json +1 -0
- data/spec/fixtures/organization/find.json +1 -0
- data/spec/fixtures/organization/where.json +1 -0
- data/spec/fixtures/test_constants.rb +12 -0
- data/spec/integration/animal_spec.rb +55 -0
- data/spec/integration/event_spec.rb +33 -0
- data/spec/integration/organization_spec.rb +35 -0
- data/spec/lib/queryable_spec.rb +257 -0
- data/spec/lib/relationable_spec.rb +113 -0
- data/spec/lib/remote_client_spec.rb +27 -0
- data/spec/lib/requests/find_spec.rb +97 -0
- data/spec/lib/requests/where_spec.rb +267 -0
- data/spec/lib/response_spec.rb +99 -0
- data/spec/models/animal_spec.rb +131 -0
- data/spec/models/event_spec.rb +105 -0
- data/spec/models/organization_spec.rb +112 -0
- data/spec/models/picture_spec.rb +87 -0
- data/spec/search/animal_search_spec.rb +8 -0
- data/spec/search/event_search_spec.rb +8 -0
- data/spec/search/filter_spec.rb +39 -0
- data/spec/search/organization_search_spec.rb +8 -0
- data/spec/spec_helper.rb +340 -0
- data/spec/support/model_spec.rb +47 -0
- data/spec/support/searchable_spec.rb +15 -0
- data/support/animal_mock.rb +215 -0
- data/support/base_mock.rb +44 -0
- data/support/event_mock.rb +48 -0
- data/support/organization_mock.rb +53 -0
- data/version.rb +3 -0
- metadata +242 -0
data/docs/event_field.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
## Event Fields
|
2
|
+
* id
|
3
|
+
* org_id
|
4
|
+
* name
|
5
|
+
* event_start
|
6
|
+
* event_end
|
7
|
+
* url
|
8
|
+
* description
|
9
|
+
* location_id
|
10
|
+
* species
|
11
|
+
* location_name
|
12
|
+
* location_url
|
13
|
+
* location_address
|
14
|
+
* location_city
|
15
|
+
* location_state
|
16
|
+
* location_postal_code
|
17
|
+
* location_country
|
18
|
+
* location_phone
|
19
|
+
* location_phone_ext
|
20
|
+
* location_events
|
@@ -0,0 +1,25 @@
|
|
1
|
+
## Organization Fields
|
2
|
+
* id
|
3
|
+
* about
|
4
|
+
* adoption_process
|
5
|
+
* adoption_url
|
6
|
+
* common_application_accept
|
7
|
+
* donation_url
|
8
|
+
* email
|
9
|
+
* facebook_url
|
10
|
+
* fax
|
11
|
+
* location
|
12
|
+
* location_address
|
13
|
+
* location_city
|
14
|
+
* location_country
|
15
|
+
* location_postal
|
16
|
+
* location_state
|
17
|
+
* location_zip_plus_4
|
18
|
+
* meet_pets
|
19
|
+
* name
|
20
|
+
* phone
|
21
|
+
* serve_areas
|
22
|
+
* services
|
23
|
+
* sponsorship_url
|
24
|
+
* type
|
25
|
+
* website_url
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module RescueGroups
|
2
|
+
class AnimalField
|
3
|
+
FIELDS = {
|
4
|
+
id: :animalID,
|
5
|
+
organization_id: :animalOrgID,
|
6
|
+
activity_level: :animalActivityLevel,
|
7
|
+
adoption_fee: :animalAdoptionFee,
|
8
|
+
altered: :animalAltered,
|
9
|
+
available_date: :animalAvailableDate,
|
10
|
+
birthdate: :animalBirthdate,
|
11
|
+
birthdate_exact: :animalBirthdateExact,
|
12
|
+
breed: :animalBreed,
|
13
|
+
coat_length: :animalCoatLength,
|
14
|
+
color: :animalColor,
|
15
|
+
color_id: :animalColorID,
|
16
|
+
color_details: :animalColorDetails,
|
17
|
+
courtesy: :animalCourtesy,
|
18
|
+
declawed: :animalDeclawed,
|
19
|
+
description: :animalDescription,
|
20
|
+
description_plain: :animalDescriptionPlain,
|
21
|
+
distinguishing_marks: :animalDistinguishingMarks,
|
22
|
+
ear_type: :animalEarType,
|
23
|
+
energy_level: :animalEnergyLevel,
|
24
|
+
excercise_needs: :animalExerciseNeeds,
|
25
|
+
eye_color: :animalEyeColor,
|
26
|
+
fence: :animalFence,
|
27
|
+
found: :animalFound,
|
28
|
+
found_date: :animalFoundDate,
|
29
|
+
found_postal_code: :animalFoundPostalcode,
|
30
|
+
general_age: :animalGeneralAge,
|
31
|
+
general_size_potential: :animalGeneralSizePotential,
|
32
|
+
grooming_needs: :animalGroomingNeeds,
|
33
|
+
house_trained: :animalHousetrained,
|
34
|
+
indoor_outdoor: :animalIndoorOutdoor,
|
35
|
+
kill_date: :animalKillDate,
|
36
|
+
kill_reason: :animalKillReason,
|
37
|
+
location: :animalLocation,
|
38
|
+
# location_distance: :animalLocationDistance,
|
39
|
+
location_city_state: :animalLocationCitystate,
|
40
|
+
microchipped: :animalMicrochipped,
|
41
|
+
mixed_breed: :animalMixedBreed,
|
42
|
+
name: :animalName,
|
43
|
+
special_needs: :animalSpecialneeds,
|
44
|
+
special_needs_description: :animalSpecialneedsDescription,
|
45
|
+
needs_foster: :animalNeedsFoster,
|
46
|
+
new_people: :animalNewPeople,
|
47
|
+
not_house_trained_reason: :animalNotHousetrainedReason,
|
48
|
+
obedience_training: :animalObedienceTraining,
|
49
|
+
ok_with_adults: :animalOKWithAdults,
|
50
|
+
ok_with_cats: :animalOKWithCats,
|
51
|
+
ok_with_dogs: :animalOKWithDogs,
|
52
|
+
ok_with_kids: :animalOKWithKids,
|
53
|
+
owner_experience: :animalOwnerExperience,
|
54
|
+
pattern: :animalPattern,
|
55
|
+
pattern_id: :animalPatternID,
|
56
|
+
adoption_pending: :animalAdoptionPending,
|
57
|
+
primary_breed: :animalPrimaryBreed,
|
58
|
+
primary_breed_id: :animalPrimaryBreedID,
|
59
|
+
rescue_id: :animalRescueID,
|
60
|
+
search_string: :animalSearchString,
|
61
|
+
secondary_breed: :animalSecondaryBreed,
|
62
|
+
secondary_breed_id: :animalSecondaryBreedID,
|
63
|
+
sex: :animalSex,
|
64
|
+
shedding: :animalShedding,
|
65
|
+
size_current: :animalSizeCurrent,
|
66
|
+
size_potential: :animalSizePotential,
|
67
|
+
size_uom: :animalSizeUOM,
|
68
|
+
species: :animalSpecies,
|
69
|
+
species_id: :animalSpeciesID,
|
70
|
+
sponsorable: :animalSponsorable,
|
71
|
+
sponsors: :animalSponsors,
|
72
|
+
sponsorhip_details: :animalSponsorshipDetails,
|
73
|
+
sponsorship_minimum: :animalSponsorshipMinimum,
|
74
|
+
status: :animalStatus,
|
75
|
+
status_id: :animalStatusID,
|
76
|
+
summary: :animalSummary,
|
77
|
+
tail_type: :animalTailType,
|
78
|
+
thumbnail_url: :animalThumbnailUrl,
|
79
|
+
up_to_date: :animalUptodate,
|
80
|
+
updated_date: :animalUpdatedDate,
|
81
|
+
url: :animalUrl,
|
82
|
+
vocal: :animalVocal,
|
83
|
+
yard_required: :animalYardRequired,
|
84
|
+
affectionate: :animalAffectionate,
|
85
|
+
apartment: :animalApartment,
|
86
|
+
crate_trained: :animalCratetrained,
|
87
|
+
drools: :animalDrools,
|
88
|
+
eager_to_please: :animalEagerToPlease,
|
89
|
+
escapes: :animalEscapes,
|
90
|
+
even_tempered: :animalEventempered,
|
91
|
+
fetches: :animalFetches,
|
92
|
+
gentle: :animalGentle,
|
93
|
+
good_in_car: :animalGoodInCar,
|
94
|
+
goofy: :animalGoofy,
|
95
|
+
has_allergies: :animalHasAllergies,
|
96
|
+
hearing_impaired: :animalHearingImpaired,
|
97
|
+
hypoallergenic: :animalHypoallergenic,
|
98
|
+
independent: :animalIndependent,
|
99
|
+
intelligent: :animalIntelligent,
|
100
|
+
lap: :animalLap,
|
101
|
+
leash_trained: :animalLeashtrained,
|
102
|
+
needs_companion_animal: :animalNeedsCompanionAnimal,
|
103
|
+
no_cold: :animalNoCold,
|
104
|
+
no_female_dogs: :animalNoFemaleDogs,
|
105
|
+
no_heat: :animalNoHeat,
|
106
|
+
no_large_dogs: :animalNoLargeDogs,
|
107
|
+
no_male_dogs: :animalNoMaleDogs,
|
108
|
+
no_small_dogs: :animalNoSmallDogs,
|
109
|
+
obedient: :animalObedient,
|
110
|
+
ok_for_seniors: :animalOKForSeniors,
|
111
|
+
ok_with_farm_animals: :animalOKWithFarmAnimals,
|
112
|
+
older_kids_only: :animalOlderKidsOnly,
|
113
|
+
ongoing_medical: :animalOngoingMedical,
|
114
|
+
playful: :animalPlayful,
|
115
|
+
plays_toys: :animalPlaysToys,
|
116
|
+
predatory: :animalPredatory,
|
117
|
+
protective: :animalProtective,
|
118
|
+
sight_impaired: :animalSightImpaired,
|
119
|
+
skittish: :animalSkittish,
|
120
|
+
special_diet: :animalSpecialDiet,
|
121
|
+
swims: :animalSwims,
|
122
|
+
timid: :animalTimid,
|
123
|
+
foster_email: :fosterEmail,
|
124
|
+
foster_first_name: :fosterFirstname,
|
125
|
+
foster_last_name: :fosterLastname,
|
126
|
+
foster_name: :fosterName,
|
127
|
+
foster_phone_cell: :fosterPhoneCell,
|
128
|
+
foster_phone_home: :fosterPhoneHome,
|
129
|
+
foster_salutation: :fosterSalutation,
|
130
|
+
location_addresss: :locationAddress,
|
131
|
+
location_city: :locationCity,
|
132
|
+
location_country: :locationCountry,
|
133
|
+
location_url: :locationUrl,
|
134
|
+
location_name: :locationName,
|
135
|
+
location_phone: :locationPhone,
|
136
|
+
location_state: :locationState,
|
137
|
+
location_postal_code: :locationPostalcode,
|
138
|
+
pictures: :animalPictures,
|
139
|
+
videos: :animalVideos,
|
140
|
+
video_urls: :animalVideoUrls,
|
141
|
+
}.freeze
|
142
|
+
|
143
|
+
# method: all
|
144
|
+
# purpose: Return the values of FIELDS for easy use in
|
145
|
+
# requesting fields from the remote API
|
146
|
+
# param: none
|
147
|
+
# return: <Array[Symbol]> - All defined field names
|
148
|
+
def self.all
|
149
|
+
FIELDS.values
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RescueGroups
|
2
|
+
class EventField
|
3
|
+
FIELDS = {
|
4
|
+
id: :eventID,
|
5
|
+
org_id: :eventOrgID,
|
6
|
+
name: :eventName,
|
7
|
+
event_start: :eventStart,
|
8
|
+
event_end: :eventEnd,
|
9
|
+
url: :eventUrl,
|
10
|
+
description: :eventDescription,
|
11
|
+
location_id: :eventLocationID,
|
12
|
+
# location_distance: :eventLocationDistance, # seems to have been deprecated
|
13
|
+
species: :eventSpecies,
|
14
|
+
location_name: :locationName,
|
15
|
+
location_url: :locationUrl,
|
16
|
+
location_address: :locationAddress,
|
17
|
+
location_city: :locationCity,
|
18
|
+
location_state: :locationState,
|
19
|
+
location_postal_code: :locationPostalcode,
|
20
|
+
location_country: :locationCountry,
|
21
|
+
location_phone: :locationPhone,
|
22
|
+
location_phone_ext: :locationPhoneExt,
|
23
|
+
location_events: :locationEvents,
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
# method: all
|
27
|
+
# purpose: Return the values of FIELDS for easy use in
|
28
|
+
# requesting fields from the remote API
|
29
|
+
# param: none
|
30
|
+
# return: <Array[Symbol]> - All defined field names
|
31
|
+
def self.all
|
32
|
+
FIELDS.values
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RescueGroups
|
2
|
+
class OrganizationField
|
3
|
+
FIELDS = {
|
4
|
+
about: :orgAbout,
|
5
|
+
adoption_process: :orgAdoptionProcess,
|
6
|
+
adoption_url: :orgAdoptionUrl,
|
7
|
+
common_application_accept: :orgCommonapplicationAccept,
|
8
|
+
donation_url: :orgDonationUrl,
|
9
|
+
email: :orgEmail,
|
10
|
+
facebook_url: :orgFacebookUrl,
|
11
|
+
fax: :orgFax,
|
12
|
+
id: :orgID,
|
13
|
+
location: :orgLocation,
|
14
|
+
location_address: :orgAddress,
|
15
|
+
location_city: :orgCity,
|
16
|
+
location_country: :orgCountry,
|
17
|
+
# location_distance: :orgLocationDistance, # Seems to have been removed
|
18
|
+
location_postal: :orgPostalcode,
|
19
|
+
location_state: :orgState,
|
20
|
+
location_zip_plus_4: :orgPlus4,
|
21
|
+
meet_pets: :orgMeetPets,
|
22
|
+
name: :orgName,
|
23
|
+
phone: :orgPhone,
|
24
|
+
serve_areas: :orgServeAreas,
|
25
|
+
services: :orgServices,
|
26
|
+
sponsorship_url: :orgSponsorshipUrl,
|
27
|
+
type: :orgType,
|
28
|
+
website_url: :orgWebsiteUrl,
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
# method: all
|
32
|
+
# purpose: Return the values of FIELDS for easy use in
|
33
|
+
# requesting fields from the remote API
|
34
|
+
# param: none
|
35
|
+
# return: <Array[Symbol]> - All defined field names
|
36
|
+
def self.all
|
37
|
+
FIELDS.values
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RescueGroups
|
2
|
+
class PictureField
|
3
|
+
FIELDS = {
|
4
|
+
mediaID: :id,
|
5
|
+
mediaOrder: :order,
|
6
|
+
lastUpdated: :updated_at,
|
7
|
+
fileSize: :file_size,
|
8
|
+
resolutionX: :resolution_x,
|
9
|
+
resolutionY: :resolution_y,
|
10
|
+
fileNameFullsize: :file_name_full_size,
|
11
|
+
fileNameThumbnail: :file_name_thumbnail,
|
12
|
+
urlSecureFullsize: :url_full,
|
13
|
+
urlSecureThumbnail: :url_thumbnail,
|
14
|
+
urlInsecureFullsize: :insecure_url_full,
|
15
|
+
urlInsecureThumbnail: :insecure_url_thumb,
|
16
|
+
original: :original,
|
17
|
+
large: :large,
|
18
|
+
small: :small
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
# method: all
|
22
|
+
# purpose: Return the values of FIELDS for easy use in
|
23
|
+
# requesting fields from the remote API
|
24
|
+
# param: none
|
25
|
+
# return: <Array[Symbol]> - All defined field names
|
26
|
+
def self.all
|
27
|
+
FIELDS.values
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/api_client.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative './remote_client'
|
2
|
+
|
3
|
+
module RescueGroups
|
4
|
+
module ApiClient
|
5
|
+
# This method is called when the ApiClient Module is included
|
6
|
+
# in a class.
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
# method: api_client
|
10
|
+
# purpose: Return or instantiate a new RemoteClient class to
|
11
|
+
# handle all details of talking to the third party
|
12
|
+
# RescueGroups API
|
13
|
+
# param: none
|
14
|
+
# return: RemoteClient
|
15
|
+
def self.api_client
|
16
|
+
@api_client ||= RemoteClient.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# method: api_client
|
20
|
+
# purpose: delegate to class method to retrieve remote client
|
21
|
+
# param: none
|
22
|
+
# return: result of self.api_client
|
23
|
+
def api_client
|
24
|
+
self.class.api_client
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/queryable.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative './requests/find'
|
2
|
+
require_relative './requests/where'
|
3
|
+
|
4
|
+
module RescueGroups
|
5
|
+
class NotFound < StandardError; end
|
6
|
+
class InvalidRequest < StandardError; end
|
7
|
+
|
8
|
+
module Queryable
|
9
|
+
# This method is called when the Queryable Module is included
|
10
|
+
# in a class.
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# method: find
|
17
|
+
# purpose: find one or many objects by primary key (id)
|
18
|
+
# param: ids Array<Integer> primary key(s) of object(s) that will
|
19
|
+
# be requested
|
20
|
+
# return: One found object if one id was given, otherwise an array of found objects
|
21
|
+
# If the response was not successful, an exception is thrown
|
22
|
+
def find(ids)
|
23
|
+
find_request = Requests::Find.new(ids, self, api_client)
|
24
|
+
|
25
|
+
response = find_request.request
|
26
|
+
|
27
|
+
unless response.success? && !response['data'].nil? && !response['data'].empty?
|
28
|
+
fail(NotFound, "Unable to find #{ self.name } with id: #{ ids }")
|
29
|
+
end
|
30
|
+
|
31
|
+
objects = response['data'].map { |data| new(data) }
|
32
|
+
|
33
|
+
[*ids].flatten.length == 1 ? objects.first : objects
|
34
|
+
end
|
35
|
+
|
36
|
+
# method: where
|
37
|
+
# purpose: find one or many objects by any supported filters
|
38
|
+
# param: conditions - <Hash> - mutliple keyed hash containing
|
39
|
+
# the conditions to search against.
|
40
|
+
# example: { breed: 'daschund' }
|
41
|
+
# return: <Array> -An array of found objects
|
42
|
+
# If the response was not successful, an exception is thrown
|
43
|
+
def where(conditions)
|
44
|
+
return find(conditions[:id]) if conditions.keys == [:id]
|
45
|
+
|
46
|
+
where_request = Requests::Where.new(conditions, self, api_client, search_engine_class)
|
47
|
+
|
48
|
+
response = where_request.request
|
49
|
+
|
50
|
+
fail(InvalidRequest, "Problem with request #{ response.error }") unless response.success?
|
51
|
+
|
52
|
+
response_with_additional = additional_request_data(where_request)
|
53
|
+
|
54
|
+
response_with_additional['data'].map do |_data_id, data|
|
55
|
+
new(data)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def additional_request_data(request)
|
62
|
+
unless RescueGroups.config.load_all_results && request.can_request_more?
|
63
|
+
return request.results
|
64
|
+
end
|
65
|
+
|
66
|
+
(request.results['found_rows'] / request.search_engine.limit).times.each do |i|
|
67
|
+
request.update_conditions!(limit: request.search_engine.limit * (i + 1))
|
68
|
+
|
69
|
+
additional_results_response = request.request
|
70
|
+
if !additional_results_response.success?
|
71
|
+
fail(InvalidRequest, "Problem with request #{ additional_results_response.error }")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
request.results
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/relationable.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module RescueGroups
|
2
|
+
module Relationable
|
3
|
+
# This method is called when the Relationable Module is included
|
4
|
+
# in a class.
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
# method: belongs_to
|
11
|
+
# purpose: define methods that denote a relationship
|
12
|
+
# between the class including this module
|
13
|
+
# and another.
|
14
|
+
# When included, it defines methods: relationship_id
|
15
|
+
# relationship_id=
|
16
|
+
# relationship
|
17
|
+
# relationship=
|
18
|
+
# example:
|
19
|
+
# class Foo
|
20
|
+
# include Relationable
|
21
|
+
#
|
22
|
+
# belongs_to :bar
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# param: relationship - <Symbol> - name of the class that a relationship
|
26
|
+
# is intended for
|
27
|
+
# return: nil
|
28
|
+
def belongs_to(relationship)
|
29
|
+
define_method relationship do
|
30
|
+
model = instance_variable_get(:"@#{ relationship }")
|
31
|
+
return model unless model.nil?
|
32
|
+
|
33
|
+
relationship_id = self.send(:"#{ relationship }_id")
|
34
|
+
|
35
|
+
unless relationship_id.nil?
|
36
|
+
klass = RescueGroups.constantize(relationship)
|
37
|
+
|
38
|
+
self.send(:"#{ relationship }=", klass.find(relationship_id))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_writer relationship
|
43
|
+
attr_accessor :"#{ relationship }_id"
|
44
|
+
end
|
45
|
+
# method: has_many
|
46
|
+
# purpose: define methods that denote a relationship
|
47
|
+
# between the class including this module
|
48
|
+
# and another.
|
49
|
+
# When included, it defines methods: relationship
|
50
|
+
# relationship=
|
51
|
+
# example:
|
52
|
+
# class Foo
|
53
|
+
# include Relationable
|
54
|
+
#
|
55
|
+
# has_many :bars
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# param: relationship - <Symbol> - name of the class that a relationship
|
59
|
+
# is intended for
|
60
|
+
# return: nil
|
61
|
+
def has_many(relationship)
|
62
|
+
define_method relationship do
|
63
|
+
temp = instance_variable_get(:"@#{ relationship }")
|
64
|
+
|
65
|
+
return temp unless temp.nil? || temp.empty?
|
66
|
+
|
67
|
+
klass = RescueGroups.constantize(relationship)
|
68
|
+
foreign_key = "#{ self.class.to_s.split('::').last.downcase }_id"
|
69
|
+
klass.where(foreign_key.to_sym => @id)
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_writer relationship
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|