flight 0.0.2 → 0.0.4
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/LICENSE +20 -20
- data/README.rdoc +17 -17
- data/features/flight_committees.feature +20 -0
- data/features/flight_emissions.feature +15 -0
- data/features/step_definitions/carbon_steps.rb +57 -0
- data/features/support/env.rb +19 -0
- data/lib/flight.rb +21 -251
- data/lib/flight/carbon_model.rb +270 -0
- data/lib/flight/characterization.rb +31 -0
- data/lib/flight/data.rb +34 -0
- data/lib/flight/summarization.rb +20 -0
- data/lib/test_support/data_models/aircraft.rb +25 -0
- data/lib/test_support/data_models/aircraft_class.rb +6 -0
- data/lib/test_support/data_models/aircraft_manufacturer.rb +5 -0
- data/lib/test_support/data_models/airline.rb +24 -0
- data/lib/test_support/data_models/airport.rb +52 -0
- data/lib/test_support/data_models/flight_configuration.rb +3 -0
- data/lib/test_support/data_models/flight_distance_class.rb +3 -0
- data/lib/test_support/data_models/flight_domesticity.rb +3 -0
- data/lib/test_support/data_models/flight_fuel_type.rb +6 -0
- data/lib/test_support/data_models/flight_propulsion.rb +3 -0
- data/lib/test_support/data_models/flight_seat_class.rb +8 -0
- data/lib/test_support/data_models/flight_segment.rb +30 -0
- data/lib/test_support/data_models/flight_service.rb +3 -0
- data/lib/test_support/db/schema.rb +337 -0
- data/lib/test_support/flight_record.rb +34 -0
- metadata +160 -19
- data/.document +0 -5
- data/.gitignore +0 -21
- data/Rakefile +0 -54
- data/VERSION +0 -1
- data/flight.gemspec +0 -57
- data/test/helper.rb +0 -10
- data/test/test_flight.rb +0 -7
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'weighted_average'
|
2
|
+
|
3
|
+
module BrighterPlanet
|
4
|
+
module Flight
|
5
|
+
module CarbonModel
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, ::Leap::Subject
|
8
|
+
base.decide :emission, :with => :characteristics do
|
9
|
+
committee :emission do
|
10
|
+
quorum 'from fuel and passengers with coefficients',
|
11
|
+
:needs => [:fuel, :passengers, :seat_class_multiplier, :emission_factor,
|
12
|
+
:radiative_forcing_index, :freight_share, :date] do |characteristics, timeframe|
|
13
|
+
if timeframe.include? characteristics[:date]
|
14
|
+
#( kg fuel ) * ( kg CO2 / kg fuel ) = kg CO2
|
15
|
+
(characteristics[:fuel] / characteristics[:passengers] * characteristics[:seat_class_multiplier]) * characteristics[:emission_factor] * characteristics[:radiative_forcing_index] * (1 - characteristics[:freight_share])
|
16
|
+
else
|
17
|
+
0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
quorum 'default' do
|
22
|
+
raise "The emission committee's default quorum should never be called"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
committee :fuel do # returns kg fuel
|
27
|
+
quorum 'from fuel per segment and emplanements and trips', :needs => [:fuel_per_segment, :emplanements_per_trip, :trips] do |characteristics|
|
28
|
+
characteristics[:fuel_per_segment] * characteristics[:emplanements_per_trip].to_f * characteristics[:trips].to_f
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
committee :fuel_per_segment do # returns kg fuel
|
33
|
+
quorum 'from adjusted distance and fuel use formula and emplanements and trips', :needs => [:adjusted_distance_per_segment, :fuel_use_coefficients, :endpoint_fuel] do |characteristics|
|
34
|
+
characteristics[:fuel_use_coefficients][:m3].to_f * characteristics[:adjusted_distance_per_segment].to_f ** 3 +
|
35
|
+
characteristics[:fuel_use_coefficients][:m2].to_f * characteristics[:adjusted_distance_per_segment].to_f ** 2 +
|
36
|
+
characteristics[:fuel_use_coefficients][:m1].to_f * characteristics[:adjusted_distance_per_segment].to_f +
|
37
|
+
characteristics[:endpoint_fuel].to_f
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
committee :adjusted_distance_per_segment do
|
42
|
+
quorum 'from adjusted distance and emplanements', :needs => [:adjusted_distance, :emplanements_per_trip] do |characteristics|
|
43
|
+
characteristics[:adjusted_distance] / characteristics[:emplanements_per_trip]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
committee :endpoint_fuel do
|
48
|
+
quorum 'from aircraft', :needs => :aircraft do |characteristics|
|
49
|
+
characteristics[:aircraft].endpoint_fuel
|
50
|
+
end
|
51
|
+
|
52
|
+
quorum 'from aircraft class', :needs => :aircraft_class do |characteristics|
|
53
|
+
characteristics[:aircraft_class].endpoint_fuel
|
54
|
+
end
|
55
|
+
|
56
|
+
quorum 'default' do
|
57
|
+
Aircraft.fallback.andand.endpoint_fuel
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
committee :fuel_use_coefficients do
|
62
|
+
quorum 'from aircraft', :needs => :aircraft do |characteristics|
|
63
|
+
characteristics[:aircraft].attributes.symbolize_keys.slice(:m1, :m2, :m3)
|
64
|
+
end
|
65
|
+
|
66
|
+
quorum 'from aircraft class', :needs => :aircraft_class do |characteristics|
|
67
|
+
characteristics[:aircraft_class].attributes.symbolize_keys.slice(:m1, :m2, :m3)
|
68
|
+
end
|
69
|
+
|
70
|
+
quorum 'default' do
|
71
|
+
fallback = Aircraft.fallback
|
72
|
+
if fallback
|
73
|
+
fallback.attributes.symbolize_keys.slice(:m1, :m2, :m3)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
committee :passengers do
|
79
|
+
quorum 'from seats and load factor', :needs => [:seats, :load_factor] do |characteristics|
|
80
|
+
(characteristics[:seats] * characteristics[:load_factor]).round
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
committee :seats do
|
85
|
+
# leaving this here to explain how someday we might lookup seat count based on both airline AND aircraft
|
86
|
+
#SE quorum 'from_airline_and_aircraft', :needs => [:airline, :aircraft] do |characteristics, timeframe|
|
87
|
+
#SE if aircraft = AirlineAircraft.memoized_find_by_airline_id_and_aircraft_id(characteristics[:airline].id, characteristics[:aircraft].id)
|
88
|
+
#SE aircraft.seats
|
89
|
+
#SE end
|
90
|
+
#SE end
|
91
|
+
|
92
|
+
quorum 'from aircraft', :needs => :aircraft do |characteristics|
|
93
|
+
characteristics[:aircraft].seats
|
94
|
+
end
|
95
|
+
|
96
|
+
quorum 'from seats estimate', :needs => :seats_estimate do |characteristics|
|
97
|
+
characteristics[:seats_estimate]
|
98
|
+
end
|
99
|
+
|
100
|
+
quorum 'from cohort', :needs => :cohort do |characteristics|
|
101
|
+
seats = characteristics[:cohort].weighted_average :seats, :weighted_by => :passengers
|
102
|
+
if seats.nil? or seats.zero?
|
103
|
+
nil
|
104
|
+
else
|
105
|
+
seats
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
quorum 'from aircraft class', :needs => :aircraft_class do |characteristics|
|
110
|
+
characteristics[:aircraft_class].seats
|
111
|
+
end
|
112
|
+
|
113
|
+
quorum 'default' do
|
114
|
+
FlightSegment.fallback.andand.seats
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
committee :load_factor do
|
119
|
+
quorum 'from cohort', :needs => :cohort do |characteristics|
|
120
|
+
characteristics[:cohort].weighted_average(:load_factor, :weighted_by => :passengers)
|
121
|
+
end
|
122
|
+
|
123
|
+
quorum 'default' do
|
124
|
+
BrighterPlanet::Flight.flight_model.fallback.andand.load_factor
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
committee :adjusted_distance do # returns nautical miles
|
129
|
+
quorum 'from distance', :needs => [:distance, :emplanements_per_trip] do |characteristics|
|
130
|
+
route_inefficiency_factor = BrighterPlanet::Flight.flight_model.research(:route_inefficiency_factor)
|
131
|
+
dogleg_factor = BrighterPlanet::Flight.flight_model.research(:dogleg_factor)
|
132
|
+
characteristics[:distance] * route_inefficiency_factor * ( dogleg_factor ** (characteristics[:emplanements_per_trip] - 1) )
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
committee :distance do # returns nautical miles
|
137
|
+
quorum 'from airports', :needs => [:origin_airport, :destination_airport] do |characteristics|
|
138
|
+
if characteristics[:origin_airport].latitude and
|
139
|
+
characteristics[:origin_airport].longitude and
|
140
|
+
characteristics[:destination_airport].latitude and
|
141
|
+
characteristics[:destination_airport].longitude
|
142
|
+
characteristics[:origin_airport].distance_to(characteristics[:destination_airport], :units => :kms).kilometres.to :nautical_miles
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
quorum 'from distance estimate', :needs => :distance_estimate do |characteristics|
|
147
|
+
characteristics[:distance_estimate].kilometres.to :nautical_miles
|
148
|
+
end
|
149
|
+
|
150
|
+
quorum 'from distance class', :needs => :distance_class do |characteristics|
|
151
|
+
characteristics[:distance_class].distance.kilometres.to :nautical_miles
|
152
|
+
end
|
153
|
+
|
154
|
+
quorum 'from cohort', :needs => :cohort do |characteristics|
|
155
|
+
distance = characteristics[:cohort].weighted_average(:distance, :weighted_by => :passengers).to_f.kilometres.to(:nautical_miles)
|
156
|
+
distance > 0 ? distance : nil
|
157
|
+
end
|
158
|
+
|
159
|
+
quorum 'default' do
|
160
|
+
BrighterPlanet::Flight.flight_model.fallback.distance_estimate.kilometres.to :nautical_miles
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
committee :emplanements_per_trip do # per trip
|
165
|
+
quorum 'default' do
|
166
|
+
BrighterPlanet::Flight.flight_model.fallback.emplanements_per_trip_before_type_cast
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
committee :radiative_forcing_index do
|
171
|
+
quorum 'from fuel type', :needs => :fuel_type do |characteristics|
|
172
|
+
characteristics[:fuel_type].radiative_forcing_index
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
committee :emission_factor do # returns kg CO2 / kg fuel
|
177
|
+
quorum 'from fuel type', :needs => :fuel_type do |characteristics|
|
178
|
+
#( kg CO2 / litres fuel ) * ( litres fuel / kg fuel )
|
179
|
+
characteristics[:fuel_type].emission_factor * ( 1 / characteristics[:fuel_type].density).gallons.to(:litres)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
committee :fuel_type do
|
184
|
+
quorum 'default' do
|
185
|
+
FlightFuelType.fallback
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
committee :freight_share do
|
190
|
+
quorum 'from cohort', :needs => :cohort do |characteristics|
|
191
|
+
characteristics[:cohort].weighted_average(:freight_share, :weighted_by => :passengers)
|
192
|
+
end
|
193
|
+
|
194
|
+
quorum 'default' do
|
195
|
+
FlightSegment.fallback.andand.freight_share
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
committee :trips do
|
200
|
+
quorum 'default' do
|
201
|
+
BrighterPlanet::Flight.flight_model.fallback.andand.trips_before_type_cast
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
committee :domesticity do
|
206
|
+
quorum 'from airports', :needs => [:origin_airport, :destination_airport] do |characteristics|
|
207
|
+
if [characteristics[:origin_airport], characteristics[:destination_airport]].all?(&:united_states?)
|
208
|
+
FlightDomesticity.find_by_name('domestic')
|
209
|
+
elsif [characteristics[:origin_airport], characteristics[:destination_airport]].any?(&:united_states?)
|
210
|
+
FlightDomesticity.find_by_name('international')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
quorum 'from origin', :needs => :origin_airport do |characteristics|
|
215
|
+
if characteristics[:origin_airport].all_flights_from_here_domestic?
|
216
|
+
FlightDomesticity.find_by_name('domestic')
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
quorum 'from destination', :needs => :destination_airport do |characteristics|
|
221
|
+
if characteristics[:destination_airport].all_flights_to_here_domestic?
|
222
|
+
FlightDomesticity.find_by_name('domestic')
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
quorum 'from airline', :needs => :airline do |characteristics|
|
227
|
+
if characteristics[:airline].all_flights_domestic?
|
228
|
+
FlightDomesticity.find_by_name('domestic')
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
committee :seat_class_multiplier do
|
234
|
+
quorum 'from seat class', :needs => :seat_class do |characteristics|
|
235
|
+
characteristics[:seat_class].multiplier
|
236
|
+
end
|
237
|
+
|
238
|
+
quorum 'default' do
|
239
|
+
FlightSeatClass.fallback.andand.multiplier
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
committee :date do
|
244
|
+
quorum 'from creation date', :needs => :creation_date do |characteristics|
|
245
|
+
characteristics[:creation_date]
|
246
|
+
end
|
247
|
+
|
248
|
+
quorum 'from timeframe' do |characteristics, timeframe|
|
249
|
+
timeframe.andand.from
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
committee :cohort do
|
254
|
+
quorum 'from t100', :appreciates => FlightSegment::INPUT_CHARACTERISTICS do |characteristics|
|
255
|
+
needed_characteristics = characteristics
|
256
|
+
needed_characteristics.
|
257
|
+
reject! { |k,v| !FlightSegment::INPUT_CHARACTERISTICS.include?(k) }
|
258
|
+
cohort = FlightSegment.big_cohort needed_characteristics
|
259
|
+
if cohort.any?
|
260
|
+
cohort
|
261
|
+
else
|
262
|
+
nil
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module BrighterPlanet
|
2
|
+
module Flight
|
3
|
+
module Characterization
|
4
|
+
def self.included(base)
|
5
|
+
base.characterize do
|
6
|
+
has :date, :trumps => :year
|
7
|
+
has :year
|
8
|
+
has :time_of_day
|
9
|
+
has :origin_airport do |origin_airport|
|
10
|
+
origin_airport.reveals :destination_airport,
|
11
|
+
:trumps => [:distance_class, :domesticity, :distance_estimate]
|
12
|
+
end
|
13
|
+
has :distance_class
|
14
|
+
has :distance_estimate, :trumps => :distance_class, :measures => :length, :precision => 0
|
15
|
+
has :domesticity
|
16
|
+
has :airline
|
17
|
+
has :trips
|
18
|
+
has :emplanements_per_trip
|
19
|
+
has :seat_class
|
20
|
+
has :load_factor, :measures => :percentage
|
21
|
+
has :seats_estimate, :range => 1..500
|
22
|
+
has :aircraft_class, :trumps => [:propulsion, :fuel_type]
|
23
|
+
has :aircraft, :trumps => [:propulsion, :aircraft_class, :seats_estimate, :fuel_type]
|
24
|
+
has :propulsion, :trumps => :fuel_type
|
25
|
+
|
26
|
+
has :creation_date, :hidden => true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/flight/data.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module BrighterPlanet
|
2
|
+
module Flight
|
3
|
+
module Data
|
4
|
+
def self.included(base)
|
5
|
+
base.data_miner do
|
6
|
+
schema do
|
7
|
+
string 'origin_airport_id'
|
8
|
+
string 'destination_airport_id'
|
9
|
+
integer 'trips'
|
10
|
+
integer 'emplanements_per_trip'
|
11
|
+
float 'distance_estimate'
|
12
|
+
string 'distance_class_id'
|
13
|
+
string 'aircraft_id'
|
14
|
+
string 'aircraft_class_id'
|
15
|
+
string 'propulsion_id'
|
16
|
+
string 'fuel_type_id'
|
17
|
+
string 'airline_id'
|
18
|
+
string 'seat_class_id'
|
19
|
+
integer 'seats_estimate'
|
20
|
+
float 'load_factor'
|
21
|
+
string 'domesticity_id'
|
22
|
+
date 'date'
|
23
|
+
integer 'year'
|
24
|
+
time 'time_of_day'
|
25
|
+
end
|
26
|
+
|
27
|
+
process "pull dependencies" do
|
28
|
+
run_data_miner_on_belongs_to_associations
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module BrighterPlanet
|
2
|
+
module Flight
|
3
|
+
module Summarization
|
4
|
+
def self.included(base)
|
5
|
+
base.summarize do |has|
|
6
|
+
has.adjective 'one-way', :if => lambda { |flight| flight.trips == 1 }
|
7
|
+
has.adjective 'round-trip', :if => lambda { |flight| flight.trips == 1 }
|
8
|
+
has.adjective 'nonstop', :if => lambda { |flight| flight.emplanements_per_trip == 1 }
|
9
|
+
has.identity 'flight'
|
10
|
+
has.modifier lambda { |flight| "from #{flight.origin_airport.name}" }, :if => :origin_airport
|
11
|
+
has.modifier lambda { |flight| "to #{flight.destination_airport.name}" }, :if => :destination_airport
|
12
|
+
has.modifier lambda { |flight| "on a #{flight.vehicle}" }, :if => :vehicle
|
13
|
+
has.modifier lambda { |flight| "on #{flight.date.to_formatted_s(:archive)}"}, :if => :date
|
14
|
+
has.verb :take
|
15
|
+
has.aspect :perfect
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Aircraft < ActiveRecord::Base
|
2
|
+
set_table_name 'aircraft'
|
3
|
+
set_primary_key :icao_code
|
4
|
+
|
5
|
+
belongs_to :aircraft_class, :foreign_key => 'brighter_planet_aircraft_class_code'
|
6
|
+
belongs_to :manufacturer, :foreign_key => 'manufacturer_name', :class_name => 'AircraftManufacturer'
|
7
|
+
has_many :segments, :foreign_key => 'bts_aircraft_type_code', :class_name => "FlightSegment", :primary_key => 'bts_aircraft_type_code'
|
8
|
+
|
9
|
+
falls_back_on :m3 => lambda { weighted_average(:m3, :weighted_by => [:segments, :passengers]) }, # 9.73423082858437e-08 r7110: 8.6540464368905e-8 r6972: 8.37e-8
|
10
|
+
:m2 => lambda { weighted_average(:m2, :weighted_by => [:segments, :passengers]) }, # -0.000134350543484608 r7110: -0.00015337661447817 r6972: -4.09e-5
|
11
|
+
:m1 => lambda { weighted_average(:m1, :weighted_by => [:segments, :passengers]) }, # 6.7728101555467 r7110: 4.7781966869412 r6972: 7.85
|
12
|
+
:endpoint_fuel => lambda { weighted_average(:endpoint_fuel, :weighted_by => [:segments, :passengers]) }, # 1527.81790006167 r7110: 1065.3476555284 r6972: 1.72e3
|
13
|
+
:seats => lambda { weighted_average(:seats, :weighted_by => [:segments, :passengers]) } # 62.1741
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def loose_search_columns
|
17
|
+
@_loose_search_columns ||= [primary_key, :manufacturer_name, :name]
|
18
|
+
end
|
19
|
+
|
20
|
+
# search by name
|
21
|
+
def loose_right_reader
|
22
|
+
@_loose_right_reader ||= lambda { |record| record[1,2].join ' ' }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Airline < ActiveRecord::Base
|
2
|
+
set_primary_key :iata_code
|
3
|
+
|
4
|
+
# has_many :airline_aircraft, :class_name => 'AirlineAircraft'
|
5
|
+
# has_many :seat_classes, :class_name => 'AirlineSeatClass'
|
6
|
+
has_many :segments, :class_name => "FlightSegment", :foreign_key => 'airline_iata_code'
|
7
|
+
# has_many :airline_aircraft_seat_classes, :class_name => 'AirlineAircraftSeatClass'
|
8
|
+
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def loose_search_columns
|
12
|
+
@_loose_search_columns ||= [primary_key, :name]
|
13
|
+
end
|
14
|
+
|
15
|
+
# search by name
|
16
|
+
def loose_right_reader
|
17
|
+
@_loose_right_reader ||= lambda { |record| record[1] }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def all_flights_domestic?
|
22
|
+
!international?
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class Airport < ActiveRecord::Base
|
2
|
+
set_primary_key :iata_code
|
3
|
+
|
4
|
+
acts_as_mappable :default_units => :nms,
|
5
|
+
:lat_column_name => :latitude,
|
6
|
+
:lng_column_name => :longitude
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def loose_search_columns
|
10
|
+
@_loose_search_columns ||= [primary_key, :city]
|
11
|
+
end
|
12
|
+
|
13
|
+
# search by name
|
14
|
+
def loose_right_reader
|
15
|
+
@_loose_right_reader ||= lambda { |record| record[1] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def name_and_location
|
20
|
+
[ name.to_s.titleize, city, country.andand.name ].select(&:present?).join ', '
|
21
|
+
end
|
22
|
+
|
23
|
+
# --------------------------------
|
24
|
+
# virtual has_many association
|
25
|
+
# has_many :segments won't work because there's no general way to specify the correct conditions
|
26
|
+
# even if you get clever with it, like
|
27
|
+
# has_many :segments,
|
28
|
+
# :class_name => 'FlightSegment',
|
29
|
+
# :foreign_key => 'origin_airport_id',
|
30
|
+
# :conditions => 'flight_segments.destination_airport_id = #{id}'
|
31
|
+
# you get queries like "`flight_segments`.origin_airport_id = 3654 AND (flight_segments.destination_airport_id = 3654))"
|
32
|
+
# in which you notice the AND which must be an OR
|
33
|
+
# and you can't just do finder_sql, because that breaks any other :select
|
34
|
+
def segments
|
35
|
+
FlightSegment.scoped :conditions => ['origin_airport_id = ? OR destination_airport_id = ?', id, id]
|
36
|
+
end
|
37
|
+
# --------------------------------
|
38
|
+
|
39
|
+
belongs_to :country, :foreign_key => 'country_iso_3166_code'
|
40
|
+
|
41
|
+
def all_flights_from_here_domestic?
|
42
|
+
!international_origin?
|
43
|
+
end
|
44
|
+
|
45
|
+
def all_flights_to_here_domestic?
|
46
|
+
!international_destination?
|
47
|
+
end
|
48
|
+
|
49
|
+
def united_states?
|
50
|
+
country == Country.united_states
|
51
|
+
end
|
52
|
+
end
|