Need help understanding Rails magic!

Hi,

I’ve just been pleasantly surprised, again, by how much Rails does for
me, but I am really surprised. Surprised as in “how the heck did that
happen?” I’d really like to understand this and would appreciate any
help.

Big picture… the user is presented with a form that allows them to
select one or more check boxes to record their allergies. The form uses
the “allergy_items” table to present the form. allergy_items has
columns for each allergy a user may have (name of column = name of
allergy), and the value of each field in the record is ‘y’ or ‘n’. When
the user submits the form, the params are read and a record is created
in the “allergies” table for each allergy they’ve selected. If the user
returns to that form, the allergy_items record supplies the current
values the user has selected. If the user deselects any of the
previously selected items, the record that was previously added to the
allergies table for that allergy needs to be deleted.

The good news is that the code I’ve got works. The bad news is that I
have no idea how or why :stuck_out_tongue_winking_eye: I never consciously included any code to
test whether the selections had changed, nor to delete the records, and
only those records, based on the result of that test.

I’ve included the code below and would really appreciate it if someone
would help me understand why the deletion is working the way it is. I
didn’t think I’d included any code to delete the specific records I
wanted deleted. I thought the code I’ve got would delete all the
records.

Thanks in advance for any help you can give me.

Best regards,
Bill

------------------------ controller code -------------------------

class AllergyController < ApplicationController

model :emrec
model :allergy
model :allergy_item

def new
@allergy_item = find_allergies
end

def update
@allergy_item = find_allergies
@emrec = find_emrec

######
#  This is the code I don't understand.  My intention was to check 

the new params entry for each
# allergy record to see if it had been deselected. If it had, I’d
delete the associated allergy record
# I assumed the code below would destroy all the allergy records.
In fact, it only destroys the
# ones that had been deselected. How the heck is THAT happening
?!?!?!?
######

@allergy_list = Allergy.find(:all,
            :conditions => ["emrec_id = ?", @emrec.id])
@allergy_list.each do |allergy|
  allergy.destroy
end

######
# now add any new items.  the model as a
# validate_uniqueness_of condition on description
# to avoid duplicate records
######

@allergy_item.update_attributes(params[:allergy_item])
for column in AllergyItem.content_columns
  selected = @allergy_item.send(column.name)
  if selected == 'y'
    @allergy = Allergy.new
    @allergy.emrec_id = @emrec.id
    @allergy.description = column.human_name
    @allergy.save
  end
end
redirect_to :controller => 'creation', :action => 'show_emrec'

end

private

def find_allergies
session[:allergy_item] ||= AllergyItem.new
end

def find_emrec
session[:emrec] ||= Emrec.new
end

end

Hi James,

James L. wrote:

I don’t think this is a case of Ruby magic.

Well, now that you explain it like that, I can see you’re right.

Maybe now would be a good time to take a break :stuck_out_tongue_winking_eye:

Thanks,
Bill

On 3/5/06, Bill W. [email protected] wrote:

@allergy_list = Allergy.find(:all,
            :conditions => ["emrec_id = ?", @emrec.id])
@allergy_list.each do |allergy|
  allergy.destroy
end

Looks like you destroy all of them here.

    @allergy = Allergy.new
    @allergy.emrec_id = @emrec.id
    @allergy.description = column.human_name
    @allergy.save
  end
end
redirect_to :controller => 'creation', :action => 'show_emrec'

end

Then here you just added the checked Allergies back into your database.

I don’t think this is a case of Ruby magic.

– James