flight 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|