Big hole in my understanding of RoR

Hi,

After skim reading your post, is your question "How do I set default
values for ActiveRecord?". Which I find a bit more concise.

If so, a quick Google search indicates that you have merely used the
wrong way to access the attributes, you should use their accessor as I
don't believe they are stored in "@" variables.

See here:
http://made-of-stone.blogspot.com/2007/01/default-values-in-your-models.html

Ignore me if I've missed the point of your post.

Regards,
Andrew

  def initialize (params = nil)
    super
    self.text="default text from init" unless self.text
    self.color="#999999" unless self.color
  end

and the "new" form now provides a default for color, but not for text.
This just makes me more confused...! And, I still haven't got this
working with the Uri relationship!

I'm not sure if this has any bearing on your particular problem, but
"text" may no be a very "safe" column name to use. I have had issues
in the past with MySQL when using keywords as column names. It's best
to use column names that are not database specific keywords.

I've put some thought into this and have done some experimenting and
thought I would bring up a few points of discussion:

It seems to me there are multiple definitions of a "default value."

1. Database/Model level defaults:
In relation to a model object it would be values that would define the
"natural state" of an attribute. Take for example an attribute
access_level on a User object. A natural default state may be a value
representing a "regular" user (say 1 = "Regular user").

This type of default value can be provided right in your database
migration like:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :created_at, :datetime #<< Notice that Rails will
automatically take care of the default value
      t.column :first_name, :string
      t.column :last_name, :string
      t.column :access_level, :integer, :default => 1 #<< 1 = Regular
user
    end
  end

  def self.down
    drop_table :users
  end
end

It is also possible (although it seems unnecessary given the above) to
set these types of defaults in the model class like:

class User < ActiveRecord::Base
  def initialize(params = nil)
    super
    self.access_level ||= 1
  end
end

In other cases the "default value" may actually be related more to a
particular view.

I recently ran into an example like this: I had a event scheduler
that I wanted a default value for the current time to be set on the
datatime selection control. In my opinion this is not a model level
default value. To create an event, expecting people to subscribe to
the event later, it is not the "natural state" of the Event object to
have a start_time = Time.now. However, it is convenient to initialize
the form's control to default to the current date and time to make the
user's selection process easier.

It just happens that the built-in time widgets do this (I think so
anyway). But in any case the initial state of the model object's
start_time attribute to be nil and not Time.now.

So assuming that this behavior is not built into the form's control
object Rails provides a convenient way to construct a new object with
some attributes initialized that can be set from with the controller
like:

  # GET /people/new
  def new
    @person = User.new(access_level => 1)
  end

Maybe some purist MVC guys would say that is breaking the MVC design
pattern, and maybe it is, but sometimes the convenience is so great
that it's worth bending the rules a bit. However, this is similar to
many "factory constructor" design patterns that I often see in use.

It would be more "pure" if the form's control were extended to provide
a default option.

Something like:
  <p>
    <b>Access Level</b><br />
    <%= f.text_field :access_level, :options => {:default => 1 }%> #
DON'T do this it's just made up to illustrate a point
  </p>

I recently ran across the problem of needing to initialize a model's
relation on creation and used the 'faux accessor' solution because
you really shouldn't be overriding an AR initialize method.

Josh outlines the technique here:

http://blog.hasmanythrough.com/2007/1/22/using-faux-accessors-to-
initialize-values

-Michael
http://javathehutt.blogspot.com

  def text
    self[:text] or "default text"
  end
don't appear to be called by the form builders? If @text isn't used by
ActiveRecord, I'd have thought the first one would at least return the
default text, and if ActiveRecord does use a hash, then I'd have thought
the second one does work...

I think the form builders use the "attribute_before_type_cast"
accessor methods. Actually I tried submitting a patch for it: http://
dev.rubyonrails.org/ticket/5427

    self.text="default text from init" unless self.text
    self.color="#999999" unless self.color
  end

Just a guess, maybe self.text.empty?

Best regards,
Andrew