I had a simple datetime field set up in my model, it displays fine and saves fine after an edit... If I entered an invalid date rails crashed indicating ArgumentError and had the strace stack etc.. So now I wanted to show the errror in a user friendly approach, staying on the page for the user to re-enter his date.
After viewing the railscast on virtual attributes, I wanted to add my own date_text virtual attributes and capture an ArgumentError if the user enters a bad date. I got stuck on the following: the code works, and when I render the "show" page, all fields show up, and the date field is blank. This is expected, although not my end goal, I want to to re-render the page with a friendly error message.
The following code is simply not good enough, as after the user enters a bad date, the "show" page displays with all data except a blank date. Here is my model with the virtual attributes coded. Also after this code segment I listed a code snipet that is in my show view that I thought was to check for errors..
def due_date_text self.due_date.strftime("%Y-%m-%d %I:%M %p") if self.due_date.present? end def due_date_text=(inDate) begin self.due_date = DateTime.parse(inDate) rescue ArgumentError self.errors.add(:ERROR, "Date out of range") end end
<% if @task.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@task.errors.count, "error") %> prohibited this task from being saved:</h2> <ul> <% @task.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> ....
The save does work, data for this record is placed in the database, so in the create method after I do if task.save, process enters the true condition and then renders the "show" page as mentioned above with all data and blank date.
How do I get this error message to appear on the "new" page so the user can re-enter his date? Probably a better question is, how do I stop the save from inserting a record in the database and process the rescue code as a "hard" error? Based on the railscast I might need to create an attr_writer rather than a due_date_trext= .... I've actually tried many variations of that and very little worked for me, so now im just trying thigns one step at a time, perhaps if I can get through this problem I can code it up more elegantly...