2016-01-22 64 views
0

我有一个现有的数据库,我正试图映射到Ruby on Rails ActiveRecords。其中一个表格是一个“富裕连接”表,它具有预先计算出的邮政编码和机场之间的距离。 'zipcode'(char)列是邮政编码数据库表的主键。表格定义如下。Ruby on Rails丰富许多:很多,使用WHERE子句

现在我有以下的Rails模型(他们只要工作,我可以检索链接到邮政编码的所有机场):

zipcode.rb:

class Zipcode < ActiveRecord::Base 
    has_many :zipcode_airports, :foreign_key => :zipcode 
    has_many :airports, :through => :zipcode_airports 
end 

zipcode_airport.rb

class ZipcodeAirport < ActiveRecord::Base 
    self.table_name = "airport_zip_distances" 
    belongs_to :zipcode, :foreign_key => :zipcode 
    belongs_to :airport 
end 

所以此工程:

irb(main):001:0> z = Zipcode.find("90210") 
    Zipcode Load (0.7ms) SELECT `zipcodes`.* FROM `zipcodes` WHERE `zipcodes`.`zipcode` = '90210' LIMIT 1 
=> #<Zipcode zipcode: "90210", latitude: 34.0901, longitude: -118.406> 

至于做这个的:

irb(main):002:0> z.airports 
    Airport Load (738.4ms) SELECT `airports`.* FROM `airports` INNER JOIN `airport_zip_distances` ON `airports`.`airport_id` = `airport_zip_distances`.`airport_id` WHERE `airport_zip_distances`.`zipcode` = '90210' 
=> #<ActiveRecord::Associations::CollectionProxy [#<Airport airport_id: 11, name: "RIO VISTA MUNI", latitude: 38.1933, longitude: -121.704>, #<Airport airport_id: 12, name: "MARBLE CANYON", latitude: 36.8108, longitude: -111.645>, #<Airport airport_id: 13, name: "MONTEREY RGNL", latitude: 36.587, longitude: -121.843>, #<Airport airport_id: 14, name: "HOOPA", latitude: 41.0415, longitude: -123.668>, #<Airport airport_id: 15, name: "LEACH", latitude: 37.785, longitude: -106.047>, #<Airport airport_id: 16, name: "MANTI–EPHRAIM", latitude: 39.3315, longitude: -111.613>, #<Airport airport_id: 17, name: "MEADOWS FLD", latitude: 35.4338, longitude: -119.058>, #<Airport airport_id: 18, name: "GRAVELLY VALLEY", latitude: 39.4507, longitude: -122.955>, #<Airport airport_id: 19, name: "GUSTINE", latitude: 37.2605, longitude: -120.964>, #<Airport airport_id: 20, name: "CALIFORNIA PINES", latitude: 41.4122, longitude: -120.684>, ...]> 

现在,我试图找出如何限制返回的记录到那些,例如,airport_zip_distances.distance_in_miles < 7英里。

此查询的工作,我只是不知道如何正确地把一切设置在Rails中得到它的制定是:

mysql> SELECT `airports`.* FROM `airports` INNER JOIN `airport_zip_distances` ON `airports`.`airport_id` = `airport_zip_distances`.`airport_id` WHERE `airport_zip_distances`.`zipcode` = '90210' AND `airport_zip_distances`.`distance_in_miles` < 7; 
+------------+-------------------+----------+-----------+ 
| airport_id | name    | latitude | longitude | 
+------------+-------------------+----------+-----------+ 
|   37 | SANTA MONICA MUNI | 34.0158 | -118.451 | 
+------------+-------------------+----------+-----------+ 

这里的数据库表的布局,如果它很重要...

mysql> describe airports; 
+------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+------------+--------------+------+-----+---------+----------------+ 
| airport_id | int(11)  | NO | PRI | NULL | auto_increment | 
| name  | varchar(255) | YES |  | NULL |    | 
| latitude | float  | YES |  | NULL |    | 
| longitude | float  | YES |  | NULL |    | 
+------------+--------------+------+-----+---------+----------------+ 

mysql> describe zipcodes; 
+-----------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+-----------+---------+------+-----+---------+-------+ 
| zipcode | char(5) | NO | PRI | NULL |  | 
| latitude | float | YES |  | NULL |  | 
| longitude | float | YES |  | NULL |  | 
+-----------+---------+------+-----+---------+-------+ 

mysql> describe airport_zip_distances; 
+-------------------+---------+------+-----+---------+----------------+ 
| Field    | Type | Null | Key | Default | Extra   | 
+-------------------+---------+------+-----+---------+----------------+ 
| id    | int(11) | NO | PRI | NULL | auto_increment | 
| airport_id  | int(11) | NO | MUL | NULL |    | 
| zipcode   | char(5) | YES | MUL | NULL |    | 
| distance_in_miles | int(11) | YES | MUL | NULL |    | 
+-------------------+---------+------+-----+---------+----------------+ 

帮忙?!谢谢!

回答

0

这简直就是如果我们在Airport定义一些范围是这样的:

class Airport < ActiveRecord::Base 
    scope :with_zipcode, -> (zipcode) { where(zipcode: zipcode) } 
    scope :in_distance, -> (miles) { 
    joins(:airport_zip_distances).where('airport_zip_distances.distance_in_miles < ?', miles) 
} 
end 

之后,我们可以:

  1. 查找与邮政编码

    Airport.with_zipcode(12345) 
    
  2. 机场距离查找机场

    Airport.in_distance(5) 
    
  3. 查找与邮政编码&距离机场

    Airport.with_zipcode(12345).in_distance(5)