1

データベースのシードを支援するために、次のコードを使用しようとしています。開発中に継続的にデータを追加する必要があり、seeds.rb ファイルに何か新しいものを追加するたびにデータを完全に再シードする必要はありません。そのため、データがまだ存在しない場合にデータを挿入するために、次の関数を追加しました。

def AddSetting(group, name, value, desc)
    Admin::Setting.create({group: group, name: name, value: value, description: desc}) unless Admin::Setting.find_by_sql("SELECT * FROM admin_settings WHERE group = '#{group}' AND name = '#{name}';").exists?
end

AddSetting('google', 'analytics_id', '', 'The ID of your Google Analytics account.')
AddSetting('general', 'page_title', '', '')
AddSetting('general', 'tag_line', '', '')

この関数は db/seeds.rb ファイルに含まれています。これはこれを行う正しい方法ですか?

ただし、レーキで実行しようとすると、次のエラーが発生します。

rake aborted!
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group = 'google' AND name = 'analytics_id'' at line 1: SELECT * FROM admin_settings WHERE group = 'google' AND name = 'analytics_id';

Tasks: TOP => db:seed
(See full trace by running task with --trace)

Process finished with exit code 1

私を混乱させているのは、私が知る限り正しい SQL を生成していることです。実際、私のコードは SQL を生成し、それをモデルの find_by_sql 関数に渡します。Rails 自体が SQL を変更することはできませんか?

SELECT * FROM admin_settings WHERE group = 'google' AND name = 'analytics_id';

私は何年にもわたって多くのSQLを書いてきましたが、ここで同様の質問を見てきました。たぶん私は何かを見逃したのですが、それを見ることができません。

4

2 に答える 2

2

「group」はキーワードであるため、そのままでは識別子として使用できません。バッククォートで引用する必要があります(少なくともMySQLの場合)。

SELECT *
FROM admin_settings
WHERE `group` = 'google'
  AND name    = 'analytics_id'

Rails / ActiveRecordが生成するSQLはすべて、引用符で囲まれたバージョンの列名を使用するため、SQL(またはWHERE句のSQLのスニペット)を生成し、列名の引用符を無視していると思います。

列名として使用するのはお勧めしgroupません。コード内のいたるところにバッククォートが散らばる心配がないように、他の名前を使用することをお勧めします。

于 2012-09-26T03:36:15.287 に答える
1

groupSQLキーワードであるため、引用符で囲まないままにすると無効なフィールド名になります。修正するには、find_by_sqlクエリでバッククォートで囲み、DBがそれをGROUPキーワードとして解釈しようとしないようにします。

于 2012-09-26T03:36:00.960 に答える