1

私はPostgresのjsonフィールドでおしゃべりしています。だから私はほとんどの検証のためにactiverecordを使用しています。しかし、私はjsonフィールドを追加して、それを検証できるようにしたいと思います。これを行うためのきれいな方法がありますか?私はいつも自分自身の検証機能を作ることができると思うが、jsonスキーマを利用する良い方法があるようだ。誰もこれで成功したのですか?RailsのPostgresqlレコード内にJSONフィールドのスキーマを適用する方法はありますか?

schema = { 
    "type" => "object", 
    "required" => ["a"], 
    "properties" => { 
    "a" => {"type" => "integer"} 
    } 
} 
JSON::Validator.validate(schema, { "a" => 5 }) 
# => true 
JSON::Validator.validate(schema, { "a" => "five" }) 
# => false 

(注)この用語の広い意味でのバリこと - ではない直接のActiveRecordを使用することができますバリ:

+1

「それを検証する」とはどういう意味ですか?あなたは、あなたがデータベースに入れているJSONが有効なJSONであることを確認したいのですか? JSONが特定の構造に準拠していることを確認したいですか? Rails/ActiveRecordで検証やデータベースを実行しますか?他に何か? –

+0

jsonフィールドを使用してユーザーを検証することを意味すると思います – user3456978

+0

JSONスキーマを使用してJSONが特定の構造に準拠していることを検証する方法について話していると思います。 https://github.com/ruby-json-schema/json-schema – max

答えて

2

あなたがjson-schema宝石を使用することができます。

Writing a custom ActiveModel validatorはしかし非常に簡単です:

require "json-schema" 
class SchemaValidator < ActiveModel::EachValidator 

    def validate_each(record, attribute, value) 
    # Looks for a JSON schema as a class constant 
    c = "#{attribute.upcase}_SCHEMA" 
    begin 
     schema = record.class.const_get(c) 
    rescue NameError => e 
     # re-raise exception with a more descriptive message 
     raise( 
     $!, 
     "Expected #{record.class.name}::#{c} to declare a JSON Schema for #{attribute}", 
     $!.backtrace 
    ) 
    end 
    unless JSON::Validator.validate(schema, value) 
     record.errors.add(attribute, 'does not comply to JSON Schema') 
    end 
    end 
end 

私たちはそのようにようにそれを使用することができます:

class Thing < ActiveRecord::Base 
    FOO_SCHEMA = { 
    "type" => "object", 
    "required" => ["a"], 
    "properties" => { 
     "a" => {"type" => "integer"} 
    } 
    } 

    validates :foo, schema: true 
end 
+0

恐ろしい答え、ありがとう!もう1つの質問。スキーマを動的にすることはできますか?支払モデルがあり、jsonフィールドが分​​割と呼ばれているとします。 1つのインスタンスで分割キーを{split_1:45、split_3:56}にして、{split_2:45、split_4:56}(異なるキー)にする方法はありますか? – kidbrax

+1

そうだね。 'validate_each'メソッドで定数を探すのではなく、スキーマを定義する' record'でクラスまたはインスタンスメソッドを探すことができます。 – max

1

また、データベース・レベルでJSONをチェックすることができます。あなたいったんSQL C言語で書かれた

  • is_jsonb_valid(私はライブラリを書いた免責事項)
  • で書かれ

    • Postgres JSON Schema:私の知る限りではPostgreSQLでJSONsを検証する2つのライブラリがありますあなたができるそれらのいずれかをインストールしました:

      ALTER TABLE my_table ADD CONSTRAINT data_is_valid CHECK (validate_json_schema('{/*your schema here */}', my_json)); 
      

      あなたはPostgresのJSONスキーマを使用して、としている場合:

      ALTER TABLE my_table ADD CONSTRAINT data_is_valid CHECK (is_jsonb_valid('{/*your schema here */}', my_json)); 
      

      is_jsonb_validを使用している場合。

    関連する問題