1

私はジオコーダーを使用していて、Locationというモデルがあります。このモデルには、経度、緯度、および住所が含まれています。私が欲しいのは、経度と緯度、または住所のいずれかを入力するオプションをユーザーに提供することです。それらの1つがいっぱいになっている場合は、残りの情報を入力します。だからここで私がしたこと

  before_validation :check
  def check
    if self.address.blank?
        reverse()
    else
        geo()
    end
  end

  def reverse
    reverse_geocoded_by :latitude, :longitude,
    :address => :address
    after_validation :reverse_geocode
  end

  def geo
    geocoded_by :address
    after_validation :geocode
  end

しかし、私は次のことを取得していますundefined method reverse_geocoded_by私は何をすべきかわかりません!

4

1 に答える 1

3

インスタンスメソッド内でクラスメソッドを呼び出すことはできません。geocoded_byそれはおそらくモデルクラスに対して定義されていることを忘れないでください。モデルのすべてのインスタンスに影響を与えずに1つのインスタンスの検証を任意に変更することはできないため、これは一般的に悪い考えと見なされます。

2つの異なる方法のいずれかでジオコーディングできる「ロケーション」モデルを用意し、エンコードタイプごとにサブクラスを作成する方がよい場合があります。つまり、これらのそれぞれに対して個別にルールを確立できます。これらの保存は、単一テーブル継承(STI)を使用して簡単に行えます。

だからあなたは持つことができます:

class Location < ActiveRecord::Base
end

class ForwardLocation < Location
  geocoded_by :address
  after_validation :geocode
end

class ReverseLocation < Location
  reverse_geocoded_by :latitude, :longitude,
    :address => :address
  after_validation :reverse_geocode
end

次に、それに応じて適切な場所を追加します。

self.location = self.address? ? ReverseLocation.create(...) : ForwardLocation.create(...)

このようなサブクラスを使用するよりも直接フィールドへの入力を処理するメソッドを作成することもできますが、それは受信して処理するデータの種類に完全に依存します。

原則として、クラスには、前後のコールバックのセットを1つだけ含める必要があります。:ifコールバック定義がスタイル宣言をサポートしている場合は、これらのコールバックの一部を条件付きでトリガーできます。before_validationよりエキゾチックな要件を処理するために、独自のルーチンを作成する必要がある場合があります。

于 2013-02-11T01:29:15.197 に答える