#416 Form Objects pro
Jun 03, 2013 | 18 minutes | Refactoring, Forms
Models have a tendency to become a complex mess as an application grows. In this episode you will learn a couple of techniques to extract form-behavior out into its own class.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
http://brainspec.com/blog/2012/07/09/activerecord-inheritance-contexts/
What do you think about using this technique?
I've analyze this, it's good.
great for newbie
how did u put this?
Thank you for sharing this interesting information. thanks for posting this
This is pretty good
Its a pretty good technique !
thanks
You always seem to release just the right episode for the problem I'm trying to solve. Thanks for all the help over the years!
true!
i agree
You agree what ?
+1
+1
+1
+1
hidden object
Its really great !
Thanks, this is really well done and helpful. I especially like that the whole process is a refactoring of old code. I've found it difficult to design loading, authorization, presenters, service_objects, etc. into the beginning of a complex project. It always seems to work better to refactor code as it becomes complex into a set of objects that work well together. Form objects must really work well with form builders and form presenters.
And it's good to do it that way, otherwise you start running into premature optimization.
Ryan, definitely have to agree with some of the others that you have a very uncanny knack for always going over issues I'm working on right now. I had a simple signup form that created an account and user which works but the code isn't as "elegant" as I would like. However, I think a form object would be more complex for my simple use case.
But this gets me thinking in that fashion; instead of throwing it all into one big object because it's all "related", I'll now be thinking about ways to separate logically-related chunks of code into separate objects. Did like the fact that you could "enforce" strong parameters by individually assigning values...it's something I innately knew but didn't fully realize until you pointed it out.
Really enjoy the casts on refactoring/organizing code. They help me a lot as I tend to write it for a deadline, and then maintain it later.
referring to yours
This is very appropriate for apps backed by web services where the app may not have a direct database connection. I'm currently working on such an app and the API serves JSON, so building form objects that are custom for the purpose is definitely the way to go. Thanks for showing us this technique.
Are form objects just as usable in edit actions?
Yes, Adam, it is.
I do like Form Objects, but all examples of it forget the edit action, which increases the complexity of the Form Object and decreases its beauty.
Your "edit" form object can often be a subclass of your "new"/"create" form object, that simply sets certain fields as read-only. Virtus, for one, makes that easy (where they're called private attributes).
Can you show an example without using Virtus?
so cool john
Welcome back, Ryan!
I really enjoy refactoring videos, they are so full of content.
I get to see how you initially thought, how you improved it, how it ended up looking, and how that still fits the same slot as before.
Another vote for refactoring-themed videos in the future, here!
+1 to Refactoring videos :)
+1
thats cool
I have to disagree with some of this concept: Now the validations apply only to those forms, so if you somehow introduce another way to sign up (maybe an email gateway auto creates?) your validations do not run. I think in many cases it would be better to leave the the non form specific validations on the model and delegate them.
I think that in the best case, you would use a UserValidator class to perform general validations - this way it can be re-used by anything that needs to perform them.
Adding the ability to use a separate Validator class was a great change in Rails 3.. unfortunately I don't think it is used enough.
+1 this. I like the idea of form objects but I also like having the validations defined on the models to help make sure things like Rake tasks obey the business rules. I might try leaving the validations defined on the model and then having the form object delegate the valid? and errors() methods to the model.
+1 as well. I don't see why the pattern requires validations to be moved out of the model. If the validation keeps the persisted form of the data consistent, it should be part of any interaction with the model. If it is a validation that acts only on the form data, then I can see moving it into the form object. The password form object was a good example of that.
There's a really excellent pattern here, specifically I am thinking of a complicated sign-up process that is part of a single-page app. If you want to have a user fill in form data that goes to several models, the form model abstraction is perfect. Just make sure that it operates at the proper level of abstraction.
Hi Ryan,
thanks for one more nice video!
I don't like to remove everything from Models and put it inside another class. At the end the Form Object's classes will do a lot.
I prefer to remove only the logic from the Model and keep all validations, callbacks, and stuffs like that there.
I forked your code and implement what I think is necessary to remove from Model: https://github.com/willian/416-form-objects/tree/master/signup-willian
What you think about it?
Thanks again,
Don't forget to wrap up the
save!
in a transaction.If something went wrong in the
profile.save!
theuser
must be rolledback.I do like Form Objects, but all examples of it forget the edit action, which increases the complexity of the Form Object and decreases its beauty.
Welcome back, Ryan!
Awesome episode!
if the user has a longer list of attributes, this might make the code cleaner:
+1
h
send("#{attr}=", params[attr])
I love railscasts, but not this episode. I think it is wrong that "testing is out of the scope of this episode". You should have had tests at the start of the refactoring and ran them instead of going to the browser all the time.
It is about the mind set.
A lot of times we need to get some tings up in a hurry, and skip testing (because it is out of the "scope of things").
I guess almost all rails developers in the world watch railscasts. So, railscasts has a responsibility to show the "right" work flow.
I understand that the episode is a bit long. But it would be better and shorter if you skipped the sign_up form and did TDD on the PasswordForm.
+1 to that
I am a pretty virgin rails developer, coming from PHP (Laravel) and i have to agree that thats a nice approach.
Sometimes I feel confusing when to use Service Object vs Form Object?
she is rough around the edges; but some of you might be interested in
https://github.com/hookercookerman/form_model
I'm running into a problem. This is a good One to one nested form, but we usually do one to many nested forms.
I've had trouble using this because I can't assign multiple things. How would I deal with features like "link_to_add" or "link_to_remove" and assigning multiple, say salaries, to a player? Unlike nested forms(with simple form) doing f.input :amount passes in ONE value for the :amount since it does not recognize that there are multiple salaries.
I agree, I would like to see an example with more than one nested form, and eventually adding an arbitrary number of nested forms via js using a form object
+1 I'm looking for a sample as well. Would be really helpful to get this kind of example because I like the forms object approach that much.
Can anyone provide anything on this subject? I'm really looking myself.
Fairly simple to achieve.
Assuming your
Player
modelhas_many :salaries
, you can enable the expectedf.fields_for :salaries
behaviour in your form by adding the appropriate attributes:I can't believe how much pain this episode saved me this week. Using traditional methods was taking me down a twisted complex path that was dramatically simplified with a form object. This is right up there with presenters and service objects as the most significant changes in mindset for me.
Hi Ryan, Thanks for this great episode. In your submit code:
I think you better use @user.save instead of save!. The reason is that your submit method can then only return true or false:
As someone who reads your code, i dont expect to see user validation errors on password submit method.
Some notes on SignupForm. Each model has its own validations. When I want to use the same validations I should copy-past them?
Just a heads up, I'm adding this to a Rails 4 project and the params slice portion (e.g.)
Is resulting in
ActiveModel::ForbiddenAttributesError
Seems mass assignment protection might still need to be cared for even though I'm not delegating any security-critical properties.
Hey Gant,
In Rails 4 (and 4.1) you still need to use strong parameters and allow the properties in the controller. If you aren't at all worried about security you can just call params.permit! and that should work out just fine for you.
Assuming this is form for editing users, is there any good reason why I can't do what's below?
How can I deal with locales regarding form objects?
My labels and error messages don't use what's defined in the YAML like they do with normal active record models.
I would really like some input on this, since to work around it I had to bake my own solution and replace every validation with my own.
Include the error messages in your YAML under activemodel, not activerecord.
For my
LookupForm
form object, I've got some YAML that looks like this:I'm trying to use Form Objects for something more complicated than what is in this railscast. I'm interacting with multiple models and in this case it doesn't make sense for me to move the validations from each model or to replicate them in the form object. I've tried using a validate do block and going through each object i'm creating, seeing if its valid? then adding the validation errors to the errors of the form, but I'm having a lot of trouble getting this to display properly. Has anyone else run into this issue?
Thanks for a great episode. You constantly amaze me with these ideas.
I think I found a small typo though. In /app/views/users/new.html.erb you have:
@user.errors.full_messages.each
I think you mean
@signup_form.errors.full_messages.each
Thanks again!
Thanks, that was just what i needed! Having faced design loader,service authorization and presenters.. This really helped me, i am going to recommend my peers to go through this episode too!
Hey. Thanks a lot for the timely info.
I want to to thank you for this very good read!! I certainly enjoyed
every little bit of it. I have you book-marked to check out new things you post…
wowowo i like it
good job
I like this article because it is very helpful to me bandarkiu.pro
Quester is a Pakistan-based questioning answering website where people can ask questions and we try our best to provide them with the best answers. Anyone can ask any legit question in English or Roman Urdu and we provide answers in the same language format.
What the heck has happened to the comments here the last three months!?
Post is Excellent .Keep Visiting.I would like to say thanks for this wonderful information.Download FL Studio 12 HTTP://CRACKSLINK.COM
It's a very nice episode I understood everything
Since this is pro-only, are these actually paid subscribing people spamming the comments page!?
Thank you so much for the post you do. I like your post and all you share with us is up to date and quite informative
very nice every thing is good
ok i know
Thanks have been given the opportunity to comment. Hopefully what you provided is useful for all those who need them. Visit my website if you want to know more about:
on my first visit i really got surprised while stumbling upon these categories of blog.
Thank you for the information.
today I learn from your site, very interested :D
Thank you for the information! very good article!
COOL
nice nice
Good
Thanks a lot for this episode, love the way you present your informations. Really usefull for people like me
I enjoyed on reading your blog post. Your blog has a lot of useful information for me, I got good ideas from this great blog.
Nice article thank you
nice article..
Very good, I think I found the knowledge I needed. I will see and refer some information in your post. thank you.
I am very much pleased with the contents you have mentioned. I enjoyed every little bit part of it. It contains truly information. I want to thank you for this informative read; I really appreciate sharing this great.
test
thank you
very cool
very nice and well done dear nice work keep it up
DAPATKAN BONUS REFERRAL SPESIAL TERBESAR DI TAMBAH BONUS CASHBACK HINGGA 15%
HANYA DENGAN MENGAJAK TEMANMU DI WWW.SARANAPLAY.COM
HUB KAMI VIA LIVECHAT/BBM 2BE38B68
MARI GABUNG SEKARANG JUGA DI ROYALKASINO.COM DAPATKAN BONUS ROLLINGAN SEBESAR 0.8% DAN KAMI MASIH BANYAK BONUS LAIN NYA TERMASUK BONUS CASHBACK TERBESAR. DI JAMIN DENGAN PELAYANAN NYA ANDA PASTI PUAS MAIN DI ROYALKASINO.COM
Hobby main poker ? tapi belum dapat agen online terpercaya? ayo gabung di ERAQQ ..
Minimal DP Cuma 20rb Sudah Bisa Main 7 Games Dalam 1 ID
Bonus Turnover Terbesar 0.3% + Referral 15%
LIVECHAT : ERAQQ
PIN BBM : 2BE32005
Hobby main poker ? tapi belum dapat agen online terpercaya? ayo gabung di toyotaqq.. Kemenangan Berapa pun pasti kami bayar ^.^
Dapatkan Banyak Bonus Menarik Menanti Anda, & Tersedia permainan Sabung Ayam Juga Lho..
BONUS TURNOVER 0.5%
BONUS REFERRAL 15%
PIN BBM : 2BE327EC
Come , Visit and try to play on my site agen-bandarq.win , thanks a lot
Interesting articles easy to understand & Good topic .
Thanks have been given the opportunity to comment. Hopefully what you provided is useful for all those who need them. Visit my website if you want to know more about:
Bandar Poker - toyotaqq.net
Thanks for the information
daftar
i think, this information very usefull :)
Nice Article…thanks for sharing
ARMANITOGEL menyediakan 12 Pasaran & memiliki keuntungan sebagai berikut :
- Cepat, Aman dan Terpercaya.
- Kemenangan Berapapun akan DIBAYAR TUNTAS & LUNAS ( Point TERPENTING )
- Minimal deposit Rp 20.000,- dan withdraw Rp 50.000,-.
- Diskon 27% s/d 65%
- Proses DEPOSIT dan WITHDRAW cepat dan 24 jam ( terkecuali BANK OFFLINE .
- Dilayani oleh Customer Service yang ramah dan berpengalaman.
Intriguing post. I Have Been pondering about this issue, so much obliged for posting. Really cool post.It "s truly extremely pleasant and Useful post.Thanks husky pit bull mix
Nice Article, thanks for sharing
Masterdomino88 Judi DominoQQ Online yang biasanya dikenal dengan Masterdomino88 atau Mdo88 adalah situs judi DominoQQ yang menggunakan server yang berkualitas dan memberikan jaminan keamanan dan kenyamanan bagi member setia yang telah bergabung.Masterdomino88 juga menyediakan permainan menarik seperti Judi Domino Online atau, Poker Online, Capsa Susun serta Sakong online dengan menggunakan uang asli.Pencarian Google dengan Keyword Domino99 dan BandarQ atau Bandarkiu telah sangat banyak tetapi yang terpercaya cuma Masterdomino88.
situs judi online
your content is good
Great work
your website is really amazing, let me share this to my friends so they can check this out too.
The information you have posted is very useful. The sites you have referred was good. Thanks for sharing...
looking forward to seeing more from you.
Great job for publishing such a beneficial website.
ciri ciri sipilis pada pria dan wanita
ciri ciri wasir
Wonderful Information in this post !!
This is a great post. I like this topic.This site has lots of advantage.I found many interesting things from this site. It helps me in many ways. Thanks
From : Vanessa Angela ( goo.gl/FKBwTT )
nice share