1

カスタムスコープまたは仮想スコープを使用して属性の一意性を検証するにはどうすればよいですか?仮想属性を使用することを考えましたが、データベースでaudit_yearをクエリしようとし続けます。この一意性の制約のためだけに、別のデータベース列を作成したくはありません。

各場所でスケジュールできる監査は1年に1つだけなので、スケジュールされた属性から年を抽出し、そのスコープでの一意性を検証する必要があります。

class Audit
    attr_accessible :location_name, :scheduled_date, :completion_date ...

    validates :location_name, :presence => true, :uniqueness => { :scope => :audit_year }

    ...

    def audit_year
        scheduled_date.year
    end

end

仮想属性の試行では、正しいパスにたどり着かない可能性があります。Railsでこれを行う「正しい」方法は何でしょうか?

4

1 に答える 1

0

これは少し遅いことは知っていますが、私はピッチインすると思いました。私はこれをメモリから行っているので、これを少しねじ込む必要があるかもしれません。

私の最初の考えは、audit_yearメソッドにあります。すべての年について、データベースにクエリを実行できます。何かのようなもの:

def audit_year
  !self.class.select('selected_date').map{ |a| a.selected_date.year }.include?(selected_date.year)
  # or using Rails 3.2 and Ruby 1.9.3:
  # !self.class.pluck('created_at').map(&:year).include?(selected_date.year)
end

ユニークなメソッドの私の仮定は、それがfalseを返す場合、検証に失敗するということです。このコードは、クラスからその1つの列だけを選択し(Auditの代わりにself.classを使用したため、再利用しやすくなります)、年を配列にマップします。含まれている場合(true)、反対の値(!)を返します。uniqを使用してクエリを最適化することもできますが、それが必要かどうかは、テーブルの大きさによって異なります。

もう1つのオプションは、属性に対して独自のバリデーターをロールすることですが、これはそれほど難しいことではありません。唯一の違いは、上記に加えて条件付きでチェックする行を追加することですselected_date.present?。優れたリソースは、方法がわからない場合のコールバックとエラーに関するRailsガイドです。http://guides.rubyonrails.org/active_record_validations_callbacks.html

お役に立てば幸いです。

于 2012-05-15T21:58:27.663 に答える