SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
Objectify Your Forms:
Beyond Basic User Input
DannyOlson
dbolson@gmail.com
Corporate Sponsorship
Sharethrough
In-feed advertisingexchange.
Background
Forms are common in web applications
Forms often end up savingdatato multiple tables
Rails gives us #accepts_nested_attributes_for
Much magic and potentialconfusion
tl;dr
We don'talways have to do things The Rails Way™
Ice Cream
Memes
Online Meme-Based Ice Cream
Ordering Service
Class Diagram
First Implementation
The Rails Way™
classIceCreamsController<ApplicationController
defnew
@ice_cream=IceCream.new
respond_with@ice_cream
end
defcreate
@ice_cream=IceCream.new(valid_params)
if@ice_cream.save
Meme.create_defaults(@ice_cream)
redirect_toedit_ice_cream_path(@ice_cream),
notice:'Icecreamwascreated.'
else
render:new
end
end
=form_forice_creamdo|f|
-#otherfieldsomitted
-ifice_cream.persisted?
=f.fields_for:memesdo|fields|
=fields.label:name
=fields.text_field:name
=fields.label:rating
=fields.select:rating,
options_for_select(10.downto(1),fields.object.rating)
-iffields.object.persisted?
=fields.label:_destroy,'Delete'
=fields.check_box:_destroy
=f.submit'MakeItSo(Delicious)'
classIceCream<ActiveRecord::Base
accepts_nested_attributes_for:memes,
reject_if:proc{|attr|
attr['name'].blank?||attr['rating'].blank?
},
allow_destroy:true
validates:flavor_id,:serving_size_id,presence:true
validates:scoops,presence:true,inclusion:{in:[1,2,3]}
validate:more_scoops_than_toppings
before_save:set_price
deftopping_ids=(toppings)
filtered_toppings=toppings.reject{|t|!Topping.exists?(t)}
super(filtered_toppings)
end
private
defmore_scoops_than_toppings
ifscoops.to_i<toppings.size
errors.add(:toppings,"can'tbemorethanscoops")
end
end
defset_price
self.price=scoops*100
end
Responsibilities
classIceCream<ActiveRecord::Base
reject_if:proc{|attr|
attr['name'].blank?||attr['rating'].blank?
},
allow_destroy:true
Responsibilities
classIceCream<ActiveRecord::Base
before_save:set_price
private
defset_price
self.price=scoops*100
end
Responsibilities
classIceCream<ActiveRecord::Base
deftopping_ids=(toppings)
filtered_toppings=toppings.reject{|t|!Topping.exists?(t)}
super(filtered_toppings)
end
Responsibilities
classIceCream<ActiveRecord::Base
validates:flavor_id,presence:true
validates:serving_size_id,presence:true
validates:scoops,presence:true,inclusion:{in:[1,2,3]}
validate:more_scoops_than_toppings
private
defmore_scoops_than_toppings
ifscoops.to_i<toppings.size
errors.add(:toppings,"can'tbemorethanscoops")
end
end
Single Responsibility Principle
Every class should have one, and only one,
reason to change.
1. formatdata
2. save the data
3. check values of associated objects
4. validations
Concerning...
Early on, SRPis easy to apply. ActiveRecord
classes handle persistence, associations and not
much else. Butbit-by-bit, they grow. Objects
thatare inherently responsible for persistence
become the de facto owner of all business logic
as well. And ayear or two later you have aUser
class with over 500 lines of code, and hundreds
of methods in it’s public interface.
- 7 Patterns to Refactor FatActiveRecord
Models
#accepts_nested_attributes_foris
used, in ActiveRecord classes, to reduce the
amountof code in Rails applications needed to
create/update records across multiple tables
with asingle HTTPPOST/PUT. As with many
things Rails, this is convention-driven...
While this sometimes results in less code, itoften
results in brittle code.
- #accepts_nested_attributes_for (Often)
Considered Harmful
New Feature Request
We need to base the price off of both
the memes and the amountof scoops.
From this:
#app/models/ice_cream.rb
classIceCream<ActiveRecord::Base
defset_price
self.price=scoops*100
end
#app/controllers/ice_creams_controller.rb
classIceCreamsController<ApplicationController
defcreate
@ice_cream=IceCream.new(valid_params)
if@ice_cream.save
Meme.create_defaults(@ice_cream)
redirect_toedit_ice_cream_path(@ice_cream),
notice:'Icecreamwascreated.'
else
render:new
end
end
To this:
#app/models/ice_cream.rb
classIceCream<ActiveRecord::Base
defratings_sum
memes.reduce(0){|sum,meme|sum+=meme.rating}
end
defset_price
unlessprice_changed?
self.price=scoops*100
end
end
#app/controllers/ice_creams_controller.rb
classIceCreamsController<ApplicationController
defcreate
@ice_cream=IceCream.new(valid_params)
if@ice_cream.save
Meme.create_defaults(@ice_cream)
meme_ratings=@ice_cream.ratings_sum
@ice_cream.update_attributes!({
price:@ice_cream.price+meme_ratings
})
redirect_toedit_ice_cream_path(@ice_cream),
notice:'Icecreamwascreated.'
else
render:new
end
end
There's Another Way
Form Object
An objectthatencapsulates context-specific
logic for user input.
Ithas onlythe attributes displayed in the form
Itsets up its own data
Itvalidates thatdata
Itdelegates to persistence butdoesn'tknow specifics
Second Implementation
With a Form Object
classNewOrderForm
includeVirtus.model
attribute:flavor_id,Integer
attribute:serving_size_id,Integer
attribute:scoops,Integer
attribute:topping_ids,Array[Integer]
end
classNewOrderForm
extendActiveModel::Naming
includeActiveModel::Conversion
includeActiveModel::Validations
validates:flavor_id,:serving_size_id,presence:true
validates:scoops,presence:true,inclusion:{in:[1,2,3]}
validate:more_scoops_than_toppings
private
defmore_scoops_than_toppings
ifscoops.to_i<topping_ids.delete_if{|attr|attr==''}.size
errors.add(:topping_ids,"can'tbemorethanscoops")
end
end
classNewOrderForm
defsave
ifvalid?
@model=OrderCreating.call(attributes)
true
else
false
end
end
classOrderCreating
defself.call(attributes)
IceCream.transactiondo
ice_cream=IceCream.create!(flavor_id:flavor_id,
serving_size_id:serving_size_id,
topping_ids:topping_ids,
scoops:scoops,
price:scoops*100)
Meme.create_defaults(ice_cream)
ice_cream
end
end
end
classEditOrderForm
attribute:memes,Array[EditMemeForm]
classEditMeme
attribute:id,Integer
attribute:name,String
attribute:rating,Integer
attribute:_destroy,Boolean,default:false
validates:name,presence:true
validates:rating,
presence:true,
inclusion:{in:1..10,message:'mustbebetween1and10'}
end
classOrdersController<ApplicationController
defnew
@order=NewOrderForm.new
respond_with@order
end
defcreate
@order=NewOrderForm.new(valid_params)
if@order.save
redirect_toedit_order_path(@order),
notice:'Yourorderwascreated.'
else
render:new
end
end
end
-iforder.persisted?
-order.memes.each_with_indexdo|meme,index|
-ifmeme.id
=hidden_field_tag"order[memes][][id]",meme.id
=label_tag"order[memes][][name]",'Name'
=text_field_tag"order[memes][][name]",meme.name
=label_tag"order[memes][][rating]",'Rating'
=select_tag"order[memes][][rating]",meme_rating_options
-ifmeme.id
=label_tag"memes_destroy_#{index}"do
=check_box_tag"order[memes][][_destroy]"
Delete
classIceCream<ActiveRecord::Base
belongs_to:flavor
belongs_to:serving_size
has_and_belongs_to_many:toppings
has_many:memes,dependent::destroy
end
New Feature Request Redux
We need to base the price off of the meme ratings
notjustthe amountof scoops.
From this:
classOrderCreating
defself.call(attributes)
IceCream.transactiondo
ice_cream=IceCream.create!(flavor_id:flavor_id,
serving_size_id:serving_size_id,
topping_ids:topping_ids,
scoops:scoops,
price:scoops*100)
Meme.create_defaults(ice_cream)
ice_cream
end
end
end
To this:
classOrderCreating
defself.call(attributes)
IceCream.transactiondo
ice_cream=IceCream.create!(flavor_id:flavor_id,
serving_size_id:serving_size_id,
topping_ids:topping_ids,
scoops:scoops,
price:scoops*100)
Meme.create_defaults(ice_cream)
IceCreamPriceUpdating.call(ice_cream)
end
end
end
classIceCreamPriceUpdating
defself.call
meme_ratings=ice_cream.memes.reduce(0){|sum,meme|
sum+=meme.rating
}
ice_cream.update_attributes!(price:ice_cream.price+meme_ratings)
ice_cream
end
Benefits
Clearer domain model
Less magic
Simpler to test
Onlyneed to consider the specific context
Easier to maintain and change
When to Use a Form Object
A Rule (if you want one):
Use a form object when persisting
multiple ActiveRecord models
What's Out There?
redtape gem
activeform-rails gem
Thank You
Links
dbolson@gmail.com
https://github.com/dbolson/form-object-presentation
https://github.com/solnic/virtus
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-
activerecord-models
http://evan.tiggerpalace.com/articles/2012/11/07/accepts_nested_attributes_for-
often-considered-harmful/
https://github.com/ClearFit/redtape
https://github.com/GCorbel/activeform-rails

Weitere ähnliche Inhalte

Ähnlich wie Objectify Your Forms: Beyond Basic User Input

DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEF
DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEFDrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEF
DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEFccmcnerdy
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin GeneratorJohn Cleveley
 
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP Apps
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP AppsOptimizing and Extending Xamarin.Forms iOS, Android, and UWP Apps
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP AppsJames Montemagno
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsSalesforce Developers
 
War of the Indices- SQL Server and Oracle
War of the Indices-  SQL Server and OracleWar of the Indices-  SQL Server and Oracle
War of the Indices- SQL Server and OracleKellyn Pot'Vin-Gorman
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015Fernando Hamasaki de Amorim
 
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...SugarCRM
 
extending-and-optimizing-xamarin-forms-apps
extending-and-optimizing-xamarin-forms-appsextending-and-optimizing-xamarin-forms-apps
extending-and-optimizing-xamarin-forms-appsMatthew Soucoup
 
Masterclass Webinar: Amazon DynamoDB July 2014
Masterclass Webinar: Amazon DynamoDB July 2014Masterclass Webinar: Amazon DynamoDB July 2014
Masterclass Webinar: Amazon DynamoDB July 2014Amazon Web Services
 
Os piores códigos Ruby já vistos - TDC Florianópolis 2016
Os piores códigos Ruby já vistos - TDC Florianópolis 2016Os piores códigos Ruby já vistos - TDC Florianópolis 2016
Os piores códigos Ruby já vistos - TDC Florianópolis 2016Fernando Hamasaki de Amorim
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindValentine Matsveiko
 
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...LEDC 2016
 
Evolutionary db development
Evolutionary db development Evolutionary db development
Evolutionary db development Open Party
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on RailsMark Menard
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 
An approach to implement model classes in zend
An approach to implement model classes in zendAn approach to implement model classes in zend
An approach to implement model classes in zendswiss IT bridge
 
AngularJS: What's the Big Deal?
AngularJS: What's the Big Deal?AngularJS: What's the Big Deal?
AngularJS: What's the Big Deal?Jim Duffy
 
Drupal tips 'n tricks
Drupal tips 'n tricksDrupal tips 'n tricks
Drupal tips 'n tricksJohn Tsevdos
 

Ähnlich wie Objectify Your Forms: Beyond Basic User Input (20)

DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEF
DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEFDrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEF
DrupalCamp LA 2012: COOK UP SOME STACKS OF DRUPAL GOODNESS WITH CHEF
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin Generator
 
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP Apps
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP AppsOptimizing and Extending Xamarin.Forms iOS, Android, and UWP Apps
Optimizing and Extending Xamarin.Forms iOS, Android, and UWP Apps
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
 
War of the Indices- SQL Server and Oracle
War of the Indices-  SQL Server and OracleWar of the Indices-  SQL Server and Oracle
War of the Indices- SQL Server and Oracle
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...
Sugar U: Session 7: An Introduction to Sugar Development, Going Way Beyond St...
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
extending-and-optimizing-xamarin-forms-apps
extending-and-optimizing-xamarin-forms-appsextending-and-optimizing-xamarin-forms-apps
extending-and-optimizing-xamarin-forms-apps
 
Masterclass Webinar: Amazon DynamoDB July 2014
Masterclass Webinar: Amazon DynamoDB July 2014Masterclass Webinar: Amazon DynamoDB July 2014
Masterclass Webinar: Amazon DynamoDB July 2014
 
Os piores códigos Ruby já vistos - TDC Florianópolis 2016
Os piores códigos Ruby já vistos - TDC Florianópolis 2016Os piores códigos Ruby já vistos - TDC Florianópolis 2016
Os piores códigos Ruby já vistos - TDC Florianópolis 2016
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mind
 
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
 
Evolutionary db development
Evolutionary db development Evolutionary db development
Evolutionary db development
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
An approach to implement model classes in zend
An approach to implement model classes in zendAn approach to implement model classes in zend
An approach to implement model classes in zend
 
AngularJS: What's the Big Deal?
AngularJS: What's the Big Deal?AngularJS: What's the Big Deal?
AngularJS: What's the Big Deal?
 
Drupal tips 'n tricks
Drupal tips 'n tricksDrupal tips 'n tricks
Drupal tips 'n tricks
 

Kürzlich hochgeladen

Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Kürzlich hochgeladen (20)

Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

Objectify Your Forms: Beyond Basic User Input