手動SQLで挿入/更新する必要があるレガシーデータベースを備えたシステムがあります。今、私はこのようなものを持っています:
class Legacy < ActiveRecord::Base
establish_connection("legacy#{Rails.env}")
end
class Book < Legacy
end
book = Book.find(params[:isbn])
# CLEAN UP BELOW
Legacy.connection.exec_query("
UPDATE dbo.Book Set Title = #{Legacy.connection.quote(book.Title)}
WHERE dbo.Book.ISBN = '#{book.ISNB}')")
それをクリーンアップする方法はありますか?これは単純化された例であり、多くの場合、1つのSQLステートメントで更新されたレガシーテーブルに複数の属性があります。
新しいアクセサーを追加できます
Set Title = #{book.Title!)
または単に:
Set Title = #{book.Title.send('quoted')}
他のアイデアはありますか?
更新:これが実際の例です:
result = Aim.connection.exec_query("
DECLARE @InsuredKey_PK int;
DECLARE @ResultVal varchar(125);
EXEC dbo.spAIMImportInsured #{tmpname}
, @InsuredKey_PK OUTPUT, @ResultVal OUTPUT, NULL, 'B', '#{submission.dba}',
#{tmpaddr1}, #{tmpaddr2}, #{tmpcity}, '#{submission.state}', '#{submission.zip}' ,
#{tmpaddr1}, #{tmpaddr2}, #{tmpcity}, '#{submission.state}', '#{submission.zip}'
, NULL, NULL, NULL, '#{submission.ProducerID}',
'#{Employee.find(submission.acct_exec).first_name.downcase}',
'#{aim_name.Name}','#{aim_name.NameKeyPK}';
SELECT @InsuredKey_PK as insured_aim_key, @ResultVal as result;")
私はそのように消毒します:
class Insured < Legacy
def self.update_attributes(id,update_hash)
set_sql = ActiveRecord::Sanitization::ClassMethods.send(
:sanitize_sql_for_assignment,update_hash
)
connection.exec_query("UPDATE dbo.Insured Set " + set_sql +
"WHERE dbo.Insured.InsuredID = #{id}"
)
end
end
このように呼ばれます:
Insured.update_attributes(id,
{:Address1 => params[:submission][:address1],
:Address2 => params[:submission][:address2],
:City => params[:submission][:city],
:State => params[:submission][:state],
:Zip =>params[:submission][:zip]
})
最初に投稿したときは気づいていませんでしたが、通常のRails(MySQL)データベースに保存されているデータからレガシーデータベースにデータを挿入/更新すると、問題が発生することがわかりました。私がやったことは、このメソッドをすべてのレギュラーモデルに適用することでした。
def quoted_for_legacy(attribute)
Legacy.connection.quote(self[attribute])
end
だから今、私が通常のRails MySQLモデルに保存されているデータからレガシーを更新しているとき:
"Set Foo = #{regmodel.quoted_for_legacy(:Foo)}"