Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
FormObject for building complex forms
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Dmytro Piliugin
November 30, 2013
Programming
2
110
FormObject for building complex forms
FormObject for building complex forms
Dmytro Piliugin
November 30, 2013
Tweet
Share
Other Decks in Programming
See All in Programming
CSC307 Lecture 05
javiergs
PRO
0
500
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
190
MUSUBIXとは
nahisaho
0
130
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
510
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
180
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
4
2k
CSC307 Lecture 02
javiergs
PRO
1
770
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
6k
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
700
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
190
Apache Iceberg V3 and migration to V3
tomtanaka
0
150
CSC307 Lecture 07
javiergs
PRO
0
550
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Balancing Empowerment & Direction
lara
5
880
How GitHub (no longer) Works
holman
316
140k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Testing 201, or: Great Expectations
jmmastey
46
8k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
120
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
240
Transcript
FormObject for building complex forms Dmytro Piliugin @suaron
[email protected]
MVC Model Controller View
MVC Model Controller View
MVC Model Controller View FromObject
None
None
None
1 class SignupsController < ApplicationController! 2 def new! 3 @signup_form
= SignUpForm.new! 4 end! 5 ! 6 def create! 7 @signup_form = SignUpForm.new(params)! 8 if @signup_form.save! 9 redirect_to home_path! 10 else! 11 render :new! 12 end! 13 end! 14 end
1 class SignUpForm! 2 include ActiveModel::Model! 3 ! 4 attr_reader
:user! 5 attr_reader :items! 6 ! 7 def initialize(params = {})! 8 @user = User.new(user_params(params))! 9 @items = build_items(items_params(params))! 10 end! 11 ! 12 def build_items(items_attributes)! 13 items_attributes.map do |attributes|! 14 Item.new(attributes)! 15 end! 16 end! 17 ! 18 def user_params(params)! 19 params.fetch(:user, {}).slice(:email).to_hash! 20 end! 21 ! 22 def items_params(params)! 23 params.fetch(:user, {}).fetch(:items, {}).values.map do |item_hash|! 24 item_hash.slice(:title).to_hash! 25 end! 26 end! 27 ! 28 end
1 class SignUpForm! 2 include ActiveModel::Model! 3! 4 ...! 5
! 6 def save! 7 valid? && persist! 8 end! 9 ! 10 validate :at_least_one_item_should_be_presence! 12 def at_least_one_item_should_be_presence! 13 if @items.empty?! 14 errors.add(:items, 'at least one should be present')! 14 end! 15 end! 16 ! 17 def valid?! 18 super! 19 @user.valid?! 20 @items.each(&:valid?)! 21 errors.empty? && @user.errors.empty? \! 22 && @items.all?{ |item| item.errors.empty? }! 23 end! 24 ! 25 ...! 26! 27 end
1 class SignUpForm! 2 include ActiveModel::Model! 3 ! 4 ...!
18 ! 19 def save! 20 valid? && persist! 21 end! 22 ! 23 ...! 34! 41 private! 42 def persist! 43 ActiveRecord::Base.transaction do! 44 company = Company.create!! 45 order = company.orders.create!! 46 ! 47 @user.company = company! 48 @user.save!! 49 ! 50 @items.each do |item|! 51 item.order = order! 52 item.save!! 53 end! 54 ! 55 return true! 56 end! 57 end! 58 ! 59 ...! 87! 88 end
41 private! 42 def persist! 43 ActiveRecord::Base.transaction do! 44 company
= Company.create!! 45 order = company.orders.create!! 46 ! 47 @user.company = company! 48 @user.save!! 49 ! 50 @items.each do |item|! 51 item.order = order! 52 item.save!! 53 end! 54 ! 55 AdminMailer.delay.notify(order.id)! 56 ! 57 return true! 58 end! 59 end
41 private! 42 def persist! 43 ActiveRecord::Base.transaction do! 44 company
= Company.create!! 45 order = company.orders.create!! 46 ! 47 @user.company = company! 48 @user.save!! 49 ! 50 @items.each do |item|! 51 item.order = order! 52 authorize_and_save(item)! 53 end! 54 ! 55 return true! 56 end! 57 end! 58 ! 59 def authorize_and_save(object)! 60 if current_ability.can?(:create, object)! 61 object.save!! 62 else! 63 errors.add(:security, "not authorised")! 64 raise ActiveRecord::Rollback! 65 end! 66 end
slides: https://speakerdeck.com/suaron/ formobject-for-building-complex-forms/ code: http://github.com/suaron/fo
References • http://railscasts.com/episodes/416-form-objects • http://matthewrobertson.org/blog/2012/09/20/ decoupling-rails-forms-from-the-database/ • http://robots.thoughtbot.com/activemodel-form- objects •
http://pivotallabs.com/form-backing-objects-for-fun- and-profit/
Q/A