TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
Valeriy Prokopchuk: Validators in Migrations.
1. # Migration Validators
Data should always be consistent
by Valeriy Prokopchuk. Sphere Consulting Inc.
2. # Data validation in RoR app
Presentation Tier JS: Form Validations
ActiveRecord: Validation helpers
????
Application Tier
Data Tier
Controller validations, ActiveRecord validations
???
3. # 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
4. # 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
5. # DB Constraints. Complex
Between?
int_col >= 1 AND int_col <= 3
● Check
● Triggers
7. # 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
8. # 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$
9. # 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();
13. # 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
14. # 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
15. # MV. Simple. Familiar
Delete format validation...
change_table :table_name do |t|
t.string :str_column, validates: { format: :false }
end
16. # 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
17. # 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
18. # 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 }
19. # 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
На картинке вы можете наблюдать схему, которую, скорее всего, видели неоднократно. Это банальная Three - tier application model, согласно которой построены большинство Web applications, включая Rails приложения.
В данной модели есть три уровня - Presentation Tier, Application Tier & Data Tier.
Presentation Tier - это, обычно, какая то вариация JS framework, как то jQuery , Angular.js, Backbone.js, Ember.js либо их комбинация. В каждом из этих framework предусмотрены те или иные механизны проверки данных, полученных от пользователя. В подавляющем большинстве случаев все сводится к валидации данных формы перед их отправкой на сервер.
Application Tier. В Rails обыно выделяют два вида валидации уровня приложения - Validation in controller и ActiveRecord validation. В контроллере обычно производится базовая валидация данных, как то наличие или отсутсвие запрашиваемых записей либо какая то иная, достаточно примитивная проверка данных, полученных с запросом.
ActiveRecord validation - это валидация данных перед их записью в базу данных, что позволяет контролировать целостность данных одного Rails application.
Data tier. В Rails - world, обычно, считают что проверки данных на уровне presentation tier & application tier вполне достаточно и нет смысла определять еще одну, на уровне базы данных.
Рассмотрим