Question about setting field values for a belongs_to model

I have two tables, applicants, and skills where each applicant
“has_many” skills, and each skill “belongs_to” an applicant.

When I have a reference to an applicant and a (skill) id for one of
their skills, I thought to update their skills by using

@applicant.skills.find(id_of_skill).description = ‘new description’

even adding @applicant.skills.find(id_of_skill).save here doesn’t help

…other processing

This sounds to me like it should lead to the description of the skill
being updated in the database, and indeed an update statement is in the
log, but with the original value. The description of the skill is not
updated in the database.

Instead, this works

@applicant.skills.find(id_of_skill).update_attributes(:description =>
‘new description’)
…other processing

So somewhere my intuition is wrong. How should I think about this? Why
does the straightforward statement not work?

Code to pour over is below. This is on ruby 1.8.4 (2005-12-24)
[i386-linux] / Rails 1.1.2



Following are

  1. mysql table definitions
  2. method update in ApplicantController
  3. rhtml file, app/views/applicant/edit.rhtml
  4. Applicant and Skill models

create table if not exists applicants (
id int not null auto_increment,
name varchar(20) not null,
primary key(id),
unique index uniq_index(id)

create table if not exists skills (
id int not null auto_increment,
applicant_id int not null,
description varchar(30) not null,
primary key(id),
unique index uniq_index(id)

class ApplicantController < ApplicationController
: methods generated by scaffold

def update
@applicant = Applicant.find(params[:id])

if !params[:newskill][:description].blank?
@applicant.skills <<[:newskill])
if params[:skill]
params[:skill].each do |skillid, newdescription|
:description=> newdescription )
# The following two lines do not work, but they don’t crash either
# The log file shows update statements to the skill table
# but with the original values, not the new values
# @applicant.skills.find(skillid.to_i).description = newdescription
# @applicant.skills.find(skillid.to_i).save
if params[:deleteskill]
params[:deleteskill].each do |id, todelete|
if todelete == “1”
if (
flash[:notice] = ‘Applicant was successfully updated.’
redirect_to :action => ‘show’, :id => @applicant
render :action => ‘edit’

: other ApplicantController methods defined by scaffold

File app/views/applicant/edit.rhtml

Editing applicant

<%= start_form_tag :action => ‘update’, :id => @applicant %>
<%= render :partial => ‘form’ %>

<% if @applicant.skills.length > 0 %>

Skills: <% for skill in @applicant.skills %> Delete? <%= check_box :deleteskill, %> Change? <%= text_field :skill,, :size=>20, :value=>skill.description %>
<% end %> <% end %> Add skill? <%= text_field :newskill, :description, :size=>20 %>
<%= submit_tag 'Edit' %> <%= end_form_tag %>

<%= link_to ‘Show’, :action => ‘show’, :id => @applicant %> |
<%= link_to ‘Back’, :action => ‘list’ %>

The two models:

class Applicant < ActiveRecord::Base
has_many :skills, :dependent => :destroy

class Skill < ActiveRecord::Base
belongs_to :applicant