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
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
Vue・React マルチプロダクト開発を支える Vite
andpad
0
100
Honoアップデート 2025年夏
yusukebe
1
870
Infer入門
riru
4
1.6k
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
9
2.7k
オープンセミナー2025@広島「君はどこで動かすか?」アンケート結果
satoshi256kbyte
0
220
testingを眺める
matumoto
1
120
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
1
130
Claude Codeで挑むOSSコントリビュート
eycjur
0
180
MLH State of the League: 2026 Season
theycallmeswift
0
170
サーバーサイドのビルド時間87倍高速化
plaidtech
PRO
0
650
KessokuでDIでもgoroutineを活用する / Go Connect #6
mazrean
0
120
コーディングエージェント時代のNeovim
key60228
1
110
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Music & Morning Musume
bryan
46
6.8k
RailsConf 2023
tenderlove
30
1.2k
Balancing Empowerment & Direction
lara
2
600
4 Signs Your Business is Dying
shpigford
184
22k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
The Cost Of JavaScript in 2023
addyosmani
53
8.8k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.4k
Designing for humans not robots
tammielis
253
25k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
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