10

Rails モデルを挿入クエリに変換する方法はありますか?

たとえば、次のようなモデルがあるとします。

m = Model.new
m.url = "url"
m.header = "header"

m.save を実行した場合に ActiveRecord が生成する対応する SQL クエリを取得するにはどうすればよいですか?

取得したいのは、「INSERT INTO models(url, header) VALUES('url', 'header')」 可能であれば。

注:実際にモデルを保存してクエリを取得したくありません(ログファイルなどから)。保存することを選択した場合、クエリを取得したい。

4

4 に答える 4

2

Rails 3.2.13 でテスト済み: 今回はうまくいったと思いますが、今回は間違いなく db に永続化されません。また、検証やコールバックを起動しないため、他の方法で呼び出していない限り、それらが変更したものは結果に反映されません。

これをlibにinsert_sqlable.rbとして保存すると、次のことができます

#in your models or you can send it to ActiveRecord::Base
include InsertSqlable

それから見てみるとmodel.insert_sqlです。

#lib/insert_sqlable
module InsertSqlable
    def insert_sql
      values = arel_attributes_values
      primary_key_value = nil

      if self.class.primary_key && Hash === values
        primary_key_value = values[values.keys.find { |k|
          k.name == self.class.primary_key
        }]

        if !primary_key_value && connection.prefetch_primary_key?(self.class.table_name)
          primary_key_value = connection.next_sequence_value(self.class.sequence_name)
          values[self.class.arel_table[self.class.primary_key]] = primary_key_value
        end
      end

      im = self.class.arel_table.create_insert
      im.into self.class.arel_table

      conn = self.class.connection

      substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
      binds       = substitutes.map do |arel_attr, value|
        [self.class.columns_hash[arel_attr.name], value]
      end

      substitutes.each_with_index do |tuple, i|
        tuple[1] = conn.substitute_at(binds[i][0], i)
      end

      if values.empty? # empty insert
        im.values = Arel.sql(self.class.connectionconnection.empty_insert_statement_value)
      else
        im.insert substitutes
      end

      conn.to_sql(im,binds)
    end
end

コードは ActiveRecord::Persistence ではなく ActiveRecord::Relation にあることがわかりました。唯一の重要な変更は、SQL を実行する代わりに生成する最後の行です。

于 2013-04-23T02:46:29.090 に答える