Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
FormObject for building complex forms
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Dmytro Piliugin
November 30, 2013
Programming
110
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
FormObject for building complex forms
FormObject for building complex forms
Dmytro Piliugin
November 30, 2013
Other Decks in Programming
See All in Programming
すこし踏み込む CancellationToken
htkym
0
270
App Intentsのビルドプロセスを支える技術
kntkymt
0
380
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
320
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
140
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.4k
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.8k
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
250
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
290
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
290
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2k
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
180
一人だけ、Kiroが静止する日
hideg
0
110
Featured
See All Featured
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
Rails Girls Zürich Keynote
gr2m
96
14k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Mind Mapping
helmedeiros
1
360
A Soul's Torment
seathinner
8
3.6k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Facilitating Awesome Meetings
lara
57
7.1k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
Code Review Best Practice
trishagee
74
20k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
500
Building Adaptive Systems
keathley
44
3.2k
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