2

デバイスのデータベースにシリアル番号の一貫した文字列表現があることを確認するために、モデルにロジックを追加したいと思います。以下は、私が考えている種類の例です。カスタム検証を呼び出し、データベースに保存する前に、オブジェクト内のデータに対してフォーマットを実行します。

class Device < ActiveRecord::Base
  validates_presence_of :serialNumber
  validate :validate_sn
  def validate_sn
    if !serialNumber.nil? && serialNumber !~ /-/
      serialNumber = serialNumber.scan(/.{4}/).join('-')
    end
  end
end

このコードで2つの問題が発生しています。まず、次のようなエラーがスローされます

NoMethodError: undefined method `scan' for nil:NilClass

私を困惑させている6行目。その行を次のように変更することで、これを回避できます。

sn = serialNumber; serialNumber = sn.scan(/.{4}/).join('-')

しかし、誰かがそれが機能する理由を説明できても、最初の人はそれを感謝しません。本当の問題は、データがダッシュなしで保存されることです(その後、上記の修正が適用されます)。ここで基本的なことを忘れたり、誤解したりしていませんか?誰かがこれに対するより良い解決策を持っていますか?

ありがとう、

4

2 に答える 2

3

試す

def validate_sn
  if !self.serialNumber.nil? && self.serialNumber !~ /-/
    self.serialNumber = self.serialNumber.scan(/.{4}/).join('-')
  end
end
于 2011-03-23T17:23:46.457 に答える
1

2つの異なるコンテキストでserialNumberを使用しているため、最初の方法は機能しません。

この行で

if !serialNumber.nil? && serialNumber !~ /-/

メソッドserialNumberを使用していますが、このメソッドは存在しないため、rubyはmethod_missingに委任し、@attributesハッシュから値を取得します。

しかし、この行では:

serialNumber = serialNumber.scan(/.{4}/).join('-')

宣言したばかりのserialNumber変数を使用しています。もちろん、この変数はnilです。必要なことを達成する1つの方法は次のとおりです。

self.serialNumber = self.serialNumber.scan(/.{4}/).join('-')

しかし、別のユーザーがすでに言ったように、検証でデータを変更することは良い習慣ではありません。したがって、このコードはbefore_saveフィルターに含める必要があります。

于 2011-03-23T17:45:36.223 に答える