Handling quotes inside of text submissions ...

Problem:

When text is submitted that has embedded quotes, the insert and update
statements fail.

Is the endemic in Rails, a "feature" of the version of rails I am using, or a
quirk (bug) in the firebird drivers?

Environment:
  Ruby 1.8.4
  Rails 1.1.6
  FireRuby 0.4.1-i586-linux
  Firebird 1.5.3
  Linux 2.6.16-gentoo-r7

Example:
  The exact text that highlighted this issue for me is the response to a
multiple part quizzing question - the quotes are a proper part of the
response. My spelling error is not :o).

"Why were you teaching in teh temple?"

Log dump of failed transaction:

Processing QuestionController#update (for 127.0.0.1 at 2006-09-17 20:31:55)
[POST]
  Session ID: d33f4dc885fcc568bb16f476a063bca3
  Parameters:
{"iscorrect"=>["off", "on", "off"], "audiofilename"=>["", "", ""], "commit"=>"Save", "answerPoints"=>["0", "5", "0"], "imagefilename"=>["", "", ""], "action"=>"update", "id"=>"33", "question"=>{"explanation_presentation"=>{"textvalue"=>""}, "tip_presentation"=>{"textvalue"=>"Acts
4:7"}, "points"=>"0", "time_allowed"=>"30", "presentation"=>{"textvalue"=>"What
question did the Sanhedrin ask Peter and John?"}, "parent"=>{"name"=>"Acts
Lesson 2 Red Level"}}, "controller"=>"question", "presentationtext"=>["\"Why
were you teaching in teh temple?\"", "\"By what power or what name did you do
this?", "Both answers are
correct."], "answerId"=>["110", "111", "112"], "parent_id"=>{"3"=>""}}
   [4;35;1mUser Load (0.008409) [0m [0mSELECT FIRST 1 * FROM users WHERE
(users.id = 1) [0m
   [4;36;1mQuestion Columns (0.007643) [0m [0;1m SELECT r.rdb$field_name,
r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type,
f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale,
COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source,
COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag
FROM rdb$relation_fields r
JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name
WHERE r.rdb$relation_name = 'QUESTIONS'
ORDER BY r.rdb$field_position
[0m
   [4;35;1mQuestion Load (0.004930) [0m [0mSELECT FIRST 1 * FROM questions
WHERE (questions."ID" = '33' ) [0m
   [4;36;1mQuiz Columns (0.006105) [0m [0;1m SELECT r.rdb$field_name,
r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type,
f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale,
COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source,
COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag
FROM rdb$relation_fields r
JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name
WHERE r.rdb$relation_name = 'QUIZZES'
ORDER BY r.rdb$field_position
[0m
   [4;35;1mQuiz Load (0.005433) [0m [0mSELECT FIRST 1 * FROM quizzes WHERE
(quizzes."ID" = 3 ) [0m
   [4;36;1mPresentations Columns (0.006095) [0m [0;1m SELECT
r.rdb$field_name, r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type,
f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale,
COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source,
COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag
FROM rdb$relation_fields r
JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name
WHERE r.rdb$relation_name = 'PRESENTATIONS'
ORDER BY r.rdb$field_position
[0m
   [4;35;1mPresentations Load (0.010192) [0m [0mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 212 ) [0m
   [4;36;1mPresentations Load (0.006519) [0m [0;1mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 214 ) [0m
   [4;35;1mPresentations Load (0.005407) [0m [0mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 213 ) [0m
   [4;36;1mAnswers Columns (0.007009) [0m [0;1m SELECT r.rdb$field_name,
r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type,
f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale,
COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source,
COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag
FROM rdb$relation_fields r
JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name
WHERE r.rdb$relation_name = 'ANSWERS'
ORDER BY r.rdb$field_position
[0m
   [4;35;1mAnswers Load (0.006408) [0m [0mSELECT FIRST 1 * FROM answers
WHERE (answers."ID" = '110' ) [0m
   [4;36;1mPresentations Load (0.005998) [0m [0;1mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 215 ) [0m
   [4;35;1mAnswers Load (0.010111) [0m [0mSELECT FIRST 1 * FROM answers
WHERE (answers."ID" = '111' ) [0m
   [4;36;1mPresentations Load (0.006531) [0m [0;1mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 216 ) [0m
   [4;35;1mAnswers Load (0.007085) [0m [0mSELECT FIRST 1 * FROM answers
WHERE (answers."ID" = '112' ) [0m
   [4;36;1mPresentations Load (0.008240) [0m [0;1mSELECT FIRST 1 * FROM
presentations WHERE (presentations."ID" = 217 ) [0m
   [4;35;1mPresentations Update (0.008904) [0m [0mUPDATE presentations
SET "AUDIO" = NULL, "TEXTVALUE" = 'What question did the Sanhedrin ask Peter
and John?', "VISUAL" = NULL WHERE id = 212 [0m
   [4;36;1mPresentations Update (0.002931) [0m [0;1mUPDATE presentations
SET "AUDIO" = NULL, "TEXTVALUE" = '', "VISUAL" = NULL WHERE id = 213 [0m
   [4;35;1mPresentations Update (0.003497) [0m [0mUPDATE presentations
SET "AUDIO" = NULL, "TEXTVALUE" = 'Acts 4:7', "VISUAL" = NULL WHERE id = 214
[0m
   [4;36;1mQuestion Update (0.003307) [0m [0;1mUPDATE questions
SET "TIP_PRESENTATION_ID" = 214, "MULTI_SELECT"
= 'N', "EXPLANATION_PRESENTATION_ID" = 213, "TIME_ALLOWED" = 30, "SEQ" =
8, "POINTS" = 0, "PRESENTATION_ID" = 212, "PARENT_ID" = 3 WHERE id = 33 [0m
   [4;35;1mPresentations Update (0.003247) [0m [0mUPDATE presentations
SET "AUDIO" = '', "TEXTVALUE" = '"Why were you teaching in teh
temple?"', "VISUAL" = '' WHERE id = 215 [0m
   [4;36;1mAnswers Update (0.004418) [0m [0;1mUPDATE answers SET "SEQ" =
1, "POINTS" = 0, "PRESENTATION_ID" = 215, "ISCORRECT" = 'N', "PARENT_ID" = 33
WHERE id = 110 [0m
   [4;35;1mPresentations Update (0.002978) [0m [0mUPDATE presentations
SET "AUDIO" = '', "TEXTVALUE" = '"By what power or what name did you do
this?', "VISUAL" = '' WHERE id = 216 [0m
   [4;36;1mAnswers Update (0.003279) [0m [0;1mUPDATE answers SET "SEQ" =
2, "POINTS" = 5, "PRESENTATION_ID" = 216, "ISCORRECT" = 'Y', "PARENT_ID" = 33
WHERE id = 111 [0m
   [4;35;1mPresentations Update (0.003111) [0m [0mUPDATE presentations
SET "AUDIO" = '', "TEXTVALUE" = 'Both answers are correct.', "VISUAL" = ''
WHERE id = 217 [0m
   [4;36;1mAnswers Update (0.009735) [0m [0;1mUPDATE answers SET "SEQ" =
3, "POINTS" = 0, "PRESENTATION_ID" = 217, "ISCORRECT" = 'N', "PARENT_ID" = 33
WHERE id = 112 [0m
Redirected to http://localhost:3000/question/list/33?parent_id=3
Completed in 0.44455 (2 reqs/sec) | DB: 0.15752 (35%) | 302 Found
[http://localhost/question/update/33]
QuestionController: missing default helper path question_helper

Are you using string interpolation or placeholders?

I mean...are you doing this:
sql = "INSERT INTO whatever VALUES(#{myvalue},#{another});"

or are you doing this...
sql = {"INSERT INTO whatever VALUES(?, ?)", myvalue, another}

You should be doing the latter, because ActiveRecord will
automatically properly escape everything.

--Jeremy

My pertinent code:

        for a in answer do
          a.presentation.save!
          a.save!
        end

<b>Rails Generated SQL (from log snip, unaltered code)</b>

UPDATE presentations SET "AUDIO" = '', "TEXTVALUE" = '"Why were you
teaching in teh temple?"', "VISUAL" = '' WHERE id = 215e

I have a workaround - I turn the double quotes into &quot;. However,
it would be interesting to know where this quirk arises from.

<b>Rails Generated SQL (altered code with workaround)</b>

UPDATE presentations SET "AUDIO" = '', "TEXTVALUE" = '&quot;Why were
you teaching in teh temple?&quot;', "VISUAL" = '' WHERE id = 215e