6

アプリには複数行の ActiveRelation クエリ メソッドが多数ありますが、これらのメソッドを記述する最も慣用的な方法がわかりません。次の例を見てください。

def postal_code_ids_within(miles)
  nearby_postal_codes = PostalCode.where("latitude > :min_lat and latitude < :max_lat",
    min_lat: (latitude - (miles.to_f / MILES_PER_DEGREE_LATITUDE.to_f / 2.to_f)),
    max_lat: (latitude + (miles.to_f / MILES_PER_DEGREE_LATITUDE.to_f / 2.to_f)))
  nearby_postal_codes = nearby_postal_codes.where("longitude > :min_lon and longitude < :max_lon",
    min_lon: (longitude - (miles.to_f / MILES_PER_DEGREE_LONGITUDE.to_f / 2.to_f)),
    max_lon: (longitude + (miles.to_f / MILES_PER_DEGREE_LONGITUDE.to_f / 2.to_f)))
  nearby_postal_codes.pluck(:id)
end

私には少しずれているように感じます。ActiveRelation オブジェクトが返されるブロックは慣用的なように見えますが、そのアプローチは見たことがありません。

標準とは何ですか?

4

2 に答える 2

11

ブライアンの提案に基づいて、これははるかに読みやすく、うまく機能します。

scope :near, lambda { |postal_code, miles|
  degree_offset = miles / MILES_PER_DEGREE / 2
  where("latitude > :min_lat and latitude < :max_lat and longitude > :min_lon and longitude < :max_lon",
    min_lat: postal_code.latitude - degree_offset,
    max_lat: postal_code.latitude + degree_offset,
    min_lon: postal_code.longitude - degree_offset,
    max_lon: postal_code.longitude + degree_offset)
}

def postal_code_ids_within(miles)
  self.class.near(self, miles).pluck(:id)
end
于 2012-08-20T15:50:55.627 に答える
0

スコープに分割することをお勧めします。別の回答とは対照的に、ラムダ、ブロック、優先順位ルールをいじるよりも、複雑なスコープを関数として定義することを好みます。

def self.near(postal_code, miles)
  degree_offset = miles / MILES_PER_DEGREE / 2
  where("latitude > :min_lat and latitude < :max_lat and longitude > :min_lon and longitude < :max_lon",
    min_lat: postal_code.latitude - degree_offset,
    max_lat: postal_code.latitude + degree_offset,
    min_lon: postal_code.longitude - degree_offset,
    max_lon: postal_code.longitude + degree_offset)
end

def postal_code_ids_within(miles)
  self.class.near(self, miles).pluck(:id)
end
于 2014-04-08T08:30:19.680 に答える