default values and text_field

I have a model and I set defaults for some values by overriding the
read accessor. For example

def heading
    read_attribute(:heading).nil? ? 'Please select from:' :
read_attribute(:heading)
end

The problem I have found is that text_field ignores this.

    <%= f.text_field :heading %>

is empty even when heading is nil

now I can easily add :value and it works

    <%= f.text_field :heading, :value => @site.heading %>

but it seems like this shouldn't be necessary. I also override read
accessors for values that I use in select statements on the same form
and it works fine.

def text_color
    read_attribute(:text_color).nil? ? SiteColors::TEXT_DEFAULT :
read_attribute(:text_color)
end

<%= f.select :text_color, SiteColors::COLORS%>

This picks up the default fine

Is this a bug in text_field or am I just doing something stupid?

Tony

I have a model and I set defaults for some values by overriding the
read accessor. For example

def heading
read_attribute(:heading).nil? ? 'Please select from:' :
read_attribute(:heading)
end

Have you double checked this works by calling heading directly on the
object in question?

Fred

> I have a model and I set defaults for some values by overriding the
> read accessor. For example

> def heading
> read_attribute(:heading).nil? ? 'Please select from:' :
> read_attribute(:heading)
> end

Have you double checked this works by calling heading directly on the
object in question?

yes.

This works

<%= f.text_field :heading, :value => @site.heading %>

and if I set it in the controller it works fine too.

@site.heading = 'testing'

Maybe text_field is using read_attribute instead of calling the
method?

are you sure that heading is nil? could you double check if it’s not an empty string?

The string is nil. I even created a new rails project to test this
out.

(Rails 3 / 1.9.2)

rails generate scaffold test value1:string value2:integer

app/models/test.rb
class Test < ActiveRecord::Base
  def value1
    read_attribute(:value1).nil? ? 'hello' : read_attribute(:value1)
  end
  def value2
    read_attribute(:value2).nil? ? 3 : read_attribute(:value2)
  end
end

app/views/tests/_form.html.erb
<%= form_for(@test) do |f| %>
  value 1 is <%= @test.value1.inspect %> and value 2 is <%=
@test.value2.inspect %>
<div class="field">
    <%= f.label :value1 %><br />
    <%= f.text_field :value1 %>
  </div>
  <div class="field">
    <%= f.label :value2 %><br />
    <%= f.select :value2, (1..10) %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

At the top of the form we see
value 1 is "hello" and value 2 is 3

the select statement has 3 selected but the text field has nothing.

Adding ':value => @test.value1' fixes the issue but shouldn't be
necessary AFAIK
<%= f.text_field :value1, :value => @test.value1 %>

Sorry, I can’t help you out as I’m not on my dev box. One thing off the top of my mind (so you wont have to worry about that) is to use a placeholder attribute instead of doing that check. Good luck!

http://davidwalsh.name/html5-placeholder