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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Dmytro Piliugin
November 30, 2013
Programming
130
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
Agents on Rails - Rails at Scale 2026
irinanazarova
0
530
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
220
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.1k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
パーソナライズPodcastを作った話
repunit11
0
130
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
160
R8 の設定見直しでアプリサイズ削減
andpad
0
200
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.2k
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
190
Java 27新機能 / Java 27 new features
kishida
2
220
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
300
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
370
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
530
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
350
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