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
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
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
480
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
620
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.4k
5分で問診!Composer セキュリティ健康診断
codmoninc
0
910
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
490
メールのエイリアス機能を履き違えない
isshinfunada
0
230
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
480
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
460
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
190
yield再入門 #phpcon
o0h
PRO
0
990
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
170
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
1.1k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
First, design no harm
axbom
PRO
2
1.2k
A Modern Web Designer's Workflow
chriscoyier
698
190k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
360
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.5k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Bash Introduction
62gerente
615
220k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
200
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
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