#32
May 16, 2007

Time in Text Field

Although Rails does allow you to edit time attributes with text fields, it's not very flexible. In this episode you will learn how to use a virtual attribute to format the time to your liking.
Download (15.1 MB, 5:22)
alternative download for iPod & Apple TV (8 MB, 5:22)
<!-- tasks/_form.rhtml -->
<%= f.text_field :due_at_string %>
# models/task.rb
def due_at_string
  due_at.to_s(:db)
end

def due_at_string=(due_at_str)
  self.due_at = Time.parse(due_at_str)
rescue ArgumentError
  @due_at_invalid = true
end

def validate
  errors.add(:due_at, "is invalid") if @due_at_invalid
end

RSS Feed for Episode Comments 27 comments

1. chineseGuy May 16, 2007 at 00:13

Sofa!
沙发!


2. Trueke May 16, 2007 at 03:22

This one is one of the best Railscasts.

Congratulations!


3. Rob May 16, 2007 at 07:04

Thanks again. I love these screencasts because they're short (so I don't fall asleep) and tackle 'real-life' problems.


4. Simon Russell May 16, 2007 at 07:05

Thanks for these RailsCasts, they're very well done. Just a couple of points/questions on this one:

- should you be redefining the "validate" method, or just calling it? It was my understanding that if you redefine it, that basically cuts out all other validation.

- you can actually get the same effect just by using a text field (without doing the virtual attributes) if you just want the basic parsing behaviour.


5. Ryan Bates May 16, 2007 at 07:27

@Simon, good comments!

Overriding "validate" still allows all other validations to get through, think of it as just a place to define your own custom validations. The main thing you need to watch out for is if you are subclassing another model (STI) and overriding it there.

True about using the text field without the virtual attribute pretty much works. I realized this after I recorded the episode, otherwise I would have mentioned it. But the technique is still useful if you want to customize the behavior (add Chronic for example).

Also, I should have added a "nil?" check on the getter method so it doesn't cause any errors while creating a new task.

Another thing I should probably have done is to store the entered string in an instance variable so, if there is a validation error, the time doesn't revert back to the original one.


6. Bryce May 16, 2007 at 08:21

YAGR (Yet another great Railscast) Ryan. Thanks a lot. It's improved my coding quite a bit.

Is there another episode where you cover getter and setter methods? I'm a little confused on why you would use them in the first place and how rails knows how to access them. I've got most of the Rails books so if anyone knows references from those, that could help too.


7. Ryan Bates May 16, 2007 at 09:15

Virtual attributes are also covered on episode 16:

http://railscasts.com/episodes/16

It just so happens that Rails uses getter and setter methods for setting and retreiving attributes (columns) so you can create your own attributes by making your own getter and setter methods.


8. Joe P Jun 29, 2007 at 14:32

Ryan, When entering an invalid date and the form is redisplayed with the error, the invalid date string is lost and replaced with the old date value. What would be the best way to keep the text value that the user entered so they can more easily see and correct their mistake?


9. Ryan Bates Jun 29, 2007 at 16:07

@Joe, good question. If you want the user submitted date to stick around for an invalid entry you should store it in an instance variable in the setter method. Then read from that instance variable in the getter method if it's set. You can see the code here:

http://pastie.caboo.se/74917


10. zzeroo Aug 01, 2007 at 23:17

Hi@all,

I think theres an error in the code snippets above.

<!-- tasks/_form.rhtml -->
<%= f.text_field :due_at %>

must bee

<!-- tasks/_form.rhtml -->
<%= f.text_field :due_at_string %>

or isn't it.

Secondly ever time when I use

# models/task.rb
def due_at_string
  due_at.to_s(:db)
end

I run in an ugly :
ArgumentError in Overtimes#new
wrong number of arguments (1 for 0)

with...

# models/task.rb
def due_at_string
  due_at
end

... in my Models this happens not. Can Somebody explain me that?


11. Ryan Bates Aug 02, 2007 at 07:49

@zzeroo, thanks, fixed the error. As for your problem, I'm not sure what it could be. Is the due_at column a datetime type? Is it considered a Time object by Ruby? Try playing with it in script/console and repeating the error.


12. August Lilleaas Aug 11, 2007 at 10:31

I wrote a short plugin for something kind of similar. It's parses date strings, such as "2208", "22.08/2009", "15-07" and so on.

It's pretty rough, and it does some silly things. For instance, it doesn't use Active Records validation system, it just raises stuff when things go bad.

Anyway, it sorta works =P

http://lilleaas.net/svn/plugins/date_parser/


13. Cupertino Miranda Sep 04, 2007 at 09:36

Ryan, thanks for this great "casts" and all the effort spent in teaching us cool tricks from Rails.
I am having the same kind of problem as zzeroo. As I am still new to Rails and only develop on it in my part-times, I would wonder if the problem (at least in my case) is because I am using class Date instead of DateTime. Please, tell me what you think.


14. Cupertino Miranda Sep 04, 2007 at 09:51

Solved my problem, as it seems method to_s from Date does not accept any parameters and for this reason it was giving me this strange problem. Now I wonder how to change date format. Something to be solved with a quick look at the library reference. Thanks again


15. Power to The Peaceful May 14, 2008 at 17:13

what does the :db in to_s(:db) do?


16. Lawrence Pit May 16, 2008 at 16:25

Rails has extended the Time class so you can do to_s(:db). See also http://api.rubyonrails.com/classes/ActiveSupport/CoreExtensions/Time/Conversions.html

Instead of using :db which also includes seconds (which seems a bit too much) you could also try :long. Or make up your own string like to_s("%Y-%m-%d %H:%M")


17. Lawrence Pit May 16, 2008 at 16:38

So the due_at_string that I would have is:

http://pastie.caboo.se/198554


18. Lawrence Pit May 18, 2008 at 17:37

I've turned this into a rails plugin which also support Chronic. See http://lawrencepit.com/2008/05/19/rails-plugin-validates_as_time/


19. Rick Sep 05, 2008 at 11:04

Can someone post their working validation example? Actually, I have it all working, EXCEPT for the extra parent level messages of "Tasks is invalid" (in my case not Tasks, but you get the idea.)

I know some others earlier in this thread have mentioned the same thing, but I'm looking for what people have done about it. Does someone have a snippet of code that shows the best way to handle this? I would think it would just involve iterating over the errors and removing the messages I don't want? I'd like to see the best way to handle this, though.


20. rick Sep 05, 2008 at 11:06

Oooops! I'm embarrassed.

I had two different railscasts tabs open and posted my previous comment in the wrong one (it was meant for http://railscasts.com/episodes/75-complex-forms-part-3). Please delete it if possible. Once again, sorry.


21. Jorostoimenov Sep 13, 2009 at 23:18

If anybody gets "wrong number of arguments 1 for 0" like zzeroo's case, that should only happen when you try to create new object and that is because Rails is trying to parse nil.to_s(:db) and raises that error. As Rayn mentioned if you add nil? check on the getter method it should wotk fine!
Cheers


22. Matt Sep 21, 2009 at 18:43

"As Rayn mentioned if you add nil? check on the getter method it should wotk fine!"

No. The code is outdated for use today. There are more efficient ways to do this now.


23. mod converter Nov 26, 2009 at 17:09

surely you are.


24. Mario Zaizar Dec 11, 2009 at 09:52

Hello!, I have a question: Why you create a new method called "validate" instead put the "Error.add" code directly into rescue block?

Thanks a lot for this excellent podcasts.


25. Keylogger Software Mar 30, 2010 at 19:40

nice post here,thanks for share!thanks again!


26. cara meninggikan badan May 31, 2010 at 21:21

In this episode you will learn how to use a virtual attribute to format the time to your liking.


27. tinggi badan Jun 01, 2010 at 20:39

Although Rails does allow you to edit time attributes with text fields, it's not very flexible.


28. </br><a href="http://www.volumerates.com/">Cables & Chargers</a></br> Jul 12, 2010 at 23:25

volumerates.com,best DS flashcarts,Flash Memory,video Games and Cell Phone online store, Provide the latest electronic product, the hottest price and best service. We will give you the best shopping experience.
http://www.volumerates.com/
http://www.volumerates.com/product/new


29. </br><a href="http://www.volumerates.com/">Sony PSP</a></br> Jul 12, 2010 at 23:27

volumerates.com,best DS flashcarts,Flash Memory,video Games and Cell Phone online store, Provide the latest electronic product, the hottest price and best service. We will give you the best shopping experience.
http://www.volumerates.com/


30. seojustme Jul 14, 2010 at 05:12

http://www.volumerates.com


31. <a href="http://www.ndscardstore.com">NDS</a> Jul 19, 2010 at 20:09

Do you know where to buy cheap and better Nintendo DS Lite (NDSL),NDS Lite carts, DS Lite Console Accessories,I know a super site http://www.ndscardstore.com/,have a look and you find what you like!


32. <a href="http://www.r4fords.co.uk/">r4i</a> Jul 28, 2010 at 17:31

i know a site,there has many game cards as <a href="http://www.r4fords.co.uk/">r4itt</a>,r4 revolution sdhc,r4i dsi xl v2.0,r4 ultra sdhc and so on! it makes me so happy! if you like play game too,you can visit the site. http://www.r4fords.co.uk/ i believe you can have your fun.


33. tiffany notes Jul 30, 2010 at 02:21

Great site. This could probably have the refactoring tag added t it.


34. <a href="http://www.r4fords.co.uk/">r4itt</a> Aug 02, 2010 at 02:06

i have buy a game card name <a href="http://www.r4fords.co.uk/">r4 ultra sdhc</a> for 6 days,but i havn't receive the card,do you bought game

cards of the website named http://www.r4fords.co.uk?


36. logo design Aug 04, 2010 at 18:33

great info really helpful....


37. free directory list Aug 11, 2010 at 22:08

David Heinemeier Hansson


38. free directory list Aug 11, 2010 at 22:08

David Heinemeier Hansson


39. free directory list Aug 11, 2010 at 22:08

David Heinemeier Hansson


40. 90x workout Aug 12, 2010 at 09:27

I am not much into reading, but somehow I got to read nice information on your site. Simple to understand and helpful. We will look forward for your future updates.Thanks!


41. jordan shoes on sale Aug 16, 2010 at 00:32

Thanks for these RailsCasts, they're very well done. really helpful....


42. louis vuitton shoes Aug 26, 2010 at 21:11

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


43. snow boots Aug 31, 2010 at 01:49

I'm a little confused on why you would use them in the first place and how rails knows how to access them.


44. louis vuitton sunglasses Sep 01, 2010 at 22:23

Good post, I can’t say that I agree with everything that was said, but very good information overall:)

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source