.build method

I have gone to the api and have searched the internet and looked
through the books that I have, but I am having trouble finding an
explanation on what the .build method actually does and how it is
used.

I guess the best example is if I want to create a todo list
application where I can create a new todo list and add to do items all
at the same time.

I would post to the todolist controller to create the todo list but
then it would error out as I have multiple todo items in the params
hash that look like this params[:todo_items].. It would say that there
is no method for todo_items=

So i would create my accessor method in the todolist model like this:

# located in Todolist model

def todo_items=(todo_items)
  todo_items.each do |todo_items|
    todo_lists.build(todo_items)
  end
end

But what is that build actually doing!?! Why am i using the plural
form of todo_lists? Any help would be MUCH appreciated!

Thanks!

The model that the method #todo_items= is being defined on has an association called todo_lists, set as this:

has_many :todo_lists

or some variant of that. Now calling #build on that association will give you something exactly like:

TodoList.new(:model_id => model.id)

It's just a neater way of writing the above code, works exactly like new (in fact I might even be right in saying it's an alias for new). You can also call create in much the same manner as the "normal" kind of create.

Oh thats great. Thanks Ryan. Moving from non-oo to oo has some great
perks (except for the learning curve)..

Coming from PHP, I am used to having to pass variables and foreign_key
id's to these kinds of functions, so I find my self asking "how does
it know the foreign key id" a lot. Hopefully that will become clearer
over time.

Thanks again!

one more thing. If I am creating a todolist and todo items for that
todolist in the same form, how does the controller know to build the
todo items after the todo list is created? In other words, if the
controller tries to run that todo_items= method before it saves the
todo list, there would be no todo_list_id for the .build method.

Look at this screencast:

http://railscasts.com/episodes/75

I think the short answer is--ActiveRecord is smart enough to save the parent object first, retrieve its ID, copy it to the fk field of the new children, and then save them. Check out the SQL in your log--that should bear that out.