valeriy prokopchuk: validators in migrations

21
# Migration Validators Data should always be consistent by Valeriy Prokopchuk. Sphere Consulting Inc.

Upload: sphere-consulting-inc

Post on 13-Jul-2015

82 views

Category:

Technology


1 download

TRANSCRIPT

# Migration Validators

Data should always be consistent

by Valeriy Prokopchuk. Sphere Consulting Inc.

# Data validation in RoR app

????

ActiveRecord: Validation helpers

Data Tier

Application Tier

Presentation Tier JS: Form Validations

Controller validations, ActiveRecord validations

???

# DB Constraints. Out of the box

● Unique, Not Null, Primary Key, Default:

create_table, { primary_key: :primary_key_column } do |t|

t.integer int_column, nil: false, default: 5

end

add_index :table_name, :int_column, unique: true

# DB Constraints. Foreign Keys

● Rails < 4

https://github.com/matthuhiggins/foreigner

change_table :comments do |t|

t.foreign_key :posts, dependent: :delete

end

● Rails 4

t.references :posts, index: :true

# DB Constraints. Complex

Between?

int_col >= 1 AND int_col <= 3

● Check

● Triggers

# DB Constraints. NO?

Performance

RDBMS dialects

# DB Constraints. NO?

Trigger in MySQL …

CREATE TRIGGER trigger_name BEFORE INSERT ON table_name FOR EACH ROW

BEGIN

DECLARE var INT;

IF NOT(NEW.int_col IS NOT NULL AND NEW.int_col >= 1 AND NEW.int_col <= 3)

THEN SET var = (SELECT MAX(1) FROM `inclusion violated`);

END IF;

END

# DB Constraints. NO?

Function first in PostgreSQL …

CREATE OR REPLACE FUNCTION trg_mgr_validates_table_name_ins_func() RETURNS trigger AS $BODY$

BEGIN

IF NOT(NEW.int_column IS NOT NULL AND NEW.int_column >= 1 AND NEW.int_column <= 3)

THEN RAISE EXCEPTION 'inclusion violated for table_name field int_column';

END IF;

RETURN NEW;

END;

$BODY$

# DB constraints in migrations?

And trigger after that …

CREATE TRIGGER trg_mgr_validates_table_name_ins

BEFORE INSERT

ON table_name

FOR EACH ROW

EXECUTE PROCEDURE trg_mgr_validates_table_name_ins_func();

# DB Constraints. YES!

Shared DB

Complex DB

# DB constraints in migrations?

Let’s imagine…

create_table :table_name do |t|

t.integer :int_column, validates: { uniqueness: :true,

inclusion: { in: 1..3 } }

t.column :column_name, :integer, validates: { exclusion: { in: [1,2,3]} }

end

# Migration Validators (MV) Project

● RDBMs:

● Helpers

validates: { uniqueness: true, exclusion: true, inclusion: true,

length: true, format: true, presence: true }

# MV. Simple. Familiar

Create format validation...

create_table :table_name do |t|

t.change :str_column, validates: {

format: { with: /interesting/,

message: "value should be interesting"}

}

end

# MV. Simple. Familiar

Update format validation...

change_table :table_name do |t|

t.string :str_column, validates: {

format: { with: /VERY interesting/,

message: "value should be VERY interesting" }

}

end

# MV. Simple. Familiar

Delete format validation...

change_table :table_name do |t|

t.string :str_column, validates: { format: :false }

end

# MV. Configurable

Everything we already know…

create_table :table_name do |t|

t.string :column_name, validates: {

length: { in: 5..8,

too_long: 'Should be <= 8', too_short: 'Should be >= 5',

on: :save, allow_nil: true, allow_blank: true }

}

end

# MV. Configurable

And something related to db...

create_table :table_name do |t|

t.string :column_name, validates: {

length: { in: 5..8, on: [:create, :update], as: :trigger,

update_trigger_name: :upd_trg,

create_trigger_name: :upd_trg }

}

end

# MV. RDBMS agnostic

Same declaration:

create_table do |t|

t.integer :int_column, validates: { inclusion: { in: 1..3 } }

end

Different definitions:

{ MySQL: :trigger, SQLite: :trigger, PostgreSQL: :check }

# MV. Not supported yet

Change...

class Order < ActiveRecord::Migration

def change

create_table :orders do |t|

t.integer :int_column, validates: { uniqueness: true }

end

end

end

# MV. Homepage

● Corehttps://github.com/vprokopchuk256/mv-test

https://github.com/vprokopchuk256/mv-core

● Drivershttps://github.com/vprokopchuk256/mv-mysql

https://github.com/vprokopchuk256/mv-postgresql

https://github.com/vprokopchuk256/mv-sqlite

# MV. Epilogue. Questions