Note that there are some explanatory texts on larger screens.

plurals
  1. POCatching an exception raised in custom accessor before reaching model validation (and showing it to the user in errors[])
    primarykey
    data
    text
    <p>I have trawled the API and spent two nights staring at this code and unfortunately while I sense I'm close to the solution, I can't quite get it to work. I have a model representing shifts, which among other attributes have a start time. </p> <pre><code>create_table "shifts", :force =&gt; true do |t| t.datetime "start" </code></pre> <p>The user interacts with this as a simple time as the date is set elsewhere, so I have set up virtual accessors to get and set. </p> <pre><code>class Shift &lt; ActiveRecord::Base def start_time start.strftime("%H:%M") end def start_time=(time) date = start.midnight self.start = add_string_time_to_date(date, time) end def add_string_time_to_date(date, string_time) t = DateTime.strptime(string_time, "%H:%M") DateTime.new(date.year, date.month, date.mday, t.hour, t.min) end end </code></pre> <p>This all works fine when manipulated through a standard controller with <code>@shift.update_attributes(params[:shift])</code> provided one enters the time in the expected format. </p> <p>I would like to validate the time format entered but its not as simple as using the method below as <code>strptime()</code> raises an ArgumentError before the validation is reached. </p> <pre><code>validates :start_time, :format =&gt; { :with =&gt; /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/, :message =&gt; "Invalid format." } </code></pre> <p>I can work round this by putting a conditional call in <code>start_time()</code> such as the example below, but that doesn't really work satisfactorily for two reasons.</p> <pre><code>def start_time=(time) if time =~ /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$|^/ date = start.midnight self.start = add_string_time_to_date(date, time) else errors.add :start, "format invalid." nil end end </code></pre> <p>First ActiveRecord doesn't seem to know that the setter has failed. I deduce this from the fact update_attributes() in the controller returns as if all was well, even though it wasn't. Second, there is no feedback returned to the user, so the call to errors.add is probably out of context. Its also a bit ugly. </p> <p>The desired functionality is that of a standard validation, so if it fails the user sees an error on the form just as they would with any other validation failure. So in short, <strong>how do I achieve this functionality, and am I approaching this in the right way?</strong></p> <p>Do I need to raise a specific exception in order to notify ActiveRecord of troubles, and if so where is best to do so? It is best just to rescue and use the flash? </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload