views:

158

answers:

2

I have the following simple form:

<% form_for(@weight) do |f| %>
  <%= f.error_messages %>
  <%= f.label :weight %>:
  <%= f.text_field :weight, :size => 5 %> kg.
  <%= f.submit "Add weight" %>
  <%= f.error_message_on :weight %>
<% end %>

which displays a form of only one field: weight.

Normally it renders like this:

<form action="/weights" class="new_weight" id="new_weight" method="post">
  <div style="margin:0;padding:0;display:inline"><input name="authenticity_token" type="hidden" value="jYoVJkDnv4a1DMGnelJpGPElbH0XWKPNlESTt9GvzdA=" /></div>

  <label for="weight_weight">Weight</label>:
  <input id="weight_weight" name="weight[weight]" size="5" type="text" /> kg.
  <input id="weight_submit" name="commit" type="submit" value="Add weight" />
</form>

which is fine. When I submit this form without setting any weight I get a validation error. f.error_messages and f.error_messages_on :weight correctly display the error messages, but the label and text field are not surrounded in a div with the class fieldWithError as I normally expect in forms in Rails. I instead get this:

<form action="/weights" class="new_weight" id="new_weight" method="post">
  <div style="margin:0;padding:0;display:inline"><input name="authenticity_token" type="hidden" value="jYoVJkDnv4a1DMGnelJpGPElbH0XWKPNlESTt9GvzdA=" /></div>

  <div class="errorExplanation" id="errorExplanation">
    <h2>1 error prohibited this weight from being saved</h2>
    <p>There were problems with the following fields:</p>
    <ul><li>Weight can't be blank</li></ul>
  </div>

  <label for="weight_weight">Weight</label>:
  <input id="weight_weight" name="weight[weight]" size="5" type="text" /> kg.
  <input id="weight_submit" name="commit" type="submit" value="Add weight" />

  <div class="formError">can't be blank</div>
</form>

For reference, what I've should have gotten is this:

<form action="/weights" class="new_weight" id="new_weight" method="post">
  <div style="margin:0;padding:0;display:inline"><input name="authenticity_token" type="hidden" value="jYoVJkDnv4a1DMGnelJpGPElbH0XWKPNlESTt9GvzdA=" /></div>

  <div class="errorExplanation" id="errorExplanation">
    <h2>1 error prohibited this weight from being saved</h2>
    <p>There were problems with the following fields:</p>
    <ul><li>Weight can't be blank</li></ul>
  </div>

  <div class="fieldWithErrors"><label for="weight_weight">Weight</label></div>:
  <div class="fieldWithErrors"><input id="weight_weight" name="weight[weight]" size="5" type="text" /></div> kg.
  <input id="weight_submit" name="commit" type="submit" value="Add weight" />
  <div class="formError">can't be blank</div>
</form>

Any ideas why I don't get those divs? I have formtastic installed and it's in use in other forms, but as far as I know that shouldn't interfere with this form.

Update: just to be sure, I printed out debug(@weight), it has the errors:

--- &id002 !ruby/object:Weight 
attributes: 
  created_at: 
  updated_at: 

  weight: 
  measured_on: &id001 !timestamp 
    at: "2009-11-22 01:30:13.522589 +01:00"
    "@marshal_with_utc_coercion": false
  user_id: 1
attributes_cache: 
  measured_on: *id001
changed_attributes: 

  measured_on: 
  user_id: 
errors: !ruby/object:ActiveRecord::Errors 
  base: *id002
  errors: 
    weight: 
    - !ruby/object:ActiveRecord::Error 
      attribute: :weight

      base: *id002
      message: :blank
      options: {}

      type: :blank
new_record: true

Update: the model is

class Weight < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :weight, :measured_on
  attr_accessible :weight, :measured_on

  def after_initialize
    self.measured_on ||= Time.now
  end

end

A: 

You may need to enclose your label & field in a block tag like p or div.

<p>
  <%= f.label :weight %>:
  <%= f.text_field :weight, :size => 5 %> kg.
</p>

This way rails has a place to slip the error back into, else it falls back to the form as it is doing now.

nowk
Probably doesn't have to be a "block" tag, any enclosure should do.
nowk
That didn't help. Actually rails put the label inside one div and the text field inside another div. I don't think rails can modify HTML code, like the p, that it's already written in the view; it can only generate more code.
J. Pablo Fernández
My apologies, I should have read your post a little closer. My mind was thinking of something else. But it seems you figured it out. I'm not familiar with that plugin or what you can configure to get those back, but you can look into ActionView::Base.field_error_proc if you want to do some custom jobby yourself.
nowk
+1  A: 

This is a bug in Formtastic. It was fixed but it seems that at this moment no released version of Formtastic has the fix.

My own bug report is on http://github.com/justinfrench/formtastic/issues/closed/#issue/132

The fix can be seen on http://github.com/grimen/formtastic/commit/2b81d9af385dadf8b37dc14f387afe3d43e4958a

Ultimately the problem was using justinfrench-formtastic from github, which is outdated and abandoned instead of formtastic from gemcutter.

J. Pablo Fernández