2012-06-13 2 views
4
sql = DmozCategory.send(:sanitize_sql_array, ["INSERT INTO dmoz_categories (id, dmoz_category_title, dmoz_category_name, dmoz_category_description, created_at, updated_at, dmoz_category_lastupdate) VALUES (?, ?, ?, ?, NOW(), NOW(), ?)", result['catid'], result['title'], result['name'], result['description'], result['lastupdate']]) 

res = DmozCategory.connection.execute(sql) 
$stderr.puts res.inspect 

res всегда nil, несмотря на то, что я могу видеть DmozCategory вставляет в базу данных. Как получить id после моей вставки?Rails ActiveRecord: Получение идентификатора необработанного вставки

Я понимаю, что я мог использовать другой SQL-запрос SELECT LAST_INSERT_ID(), чтобы получить идентификатор, но мне было интересно, есть ли способ получить идентификатор через Rails. M

фона: с помощью Rails 2.3.14

UPDATE: Хм, я думаю, что проблема лежит с плагином я использую называется Octopus. Извините за дисконтирование некоторых ваших ответов. Похоже, мне нужно найти, как получить последний идентификатор вставки с помощью этого плагина. Моя полная соя:

desc "load all categories from dmoz" # With this one we're loading all the 'structure' table in, not the parent-child relationships. 
    task :load_categories_from_dmoz, [ :offset, :limit ] => :environment do |t, args| 
    offset = !args[:offset].blank? ? args[:offset].to_i : 0 # Take offset from args. Default of 0 
    limit = !args[:limit].blank? ? args[:limit].to_i : 1 # Take limit from args. Default of 1 
    ActiveRecord::Base.octopus_establish_connection(:adapter=> "mysql", :host=> "localhost", :database => "dmoz", :username => "dmoz", :password => "dmoz") 

    results = ActiveRecord::Base.connection.select_all("SELECT * FROM structure LIMIT #{ offset }, #{ limit }") # Fetches it directly from the dmoz database. 
    count = offset 
    conn = ActiveRecord::Base.octopus_establish_connection(:adapter=> "mysql", :host=> "localhost", :database => "talon_development", :username => "rails_shadow", :password => "husky") 
    results.each do |result| 
     if count % 1000 == 0 
     puts count 
     end 
     count +=1 

     begin 
     sql = DmozCategory.send(:sanitize_sql_array, ["INSERT INTO dmoz_categories (id, dmoz_category_title, dmoz_category_name, dmoz_category_description, created_at, updated_at, dmoz_category_lastupdate) VALUES (?, ?, ?, ?, NOW(), NOW(), ?)", result['catid'], result['title'], result['name'], result['description'], result['lastupdate']]) #We leave parent_id NULL for the next task to handle relationships 

     DmozCategory.connection.execute(sql) #doesn't get the ID.. 

     end 
    end 
    end 
+0

попробовать '' exec_query' и last_inserted_id (разрешение) ' –

+0

@YuriBarbashov Я не думаю, что это доступно в Rails 2.3.14? – babonk

+0

Вы не вставляете идентификатор самостоятельно? 'INSERT INTO dmoz_categories (id, ...) VALUES (?, ...), result ['catid'], ...'? –

ответ

-1

Предполагая, что вы используете MYSQL и приращение таблицы авто, вы можете использовать:

SELECT LAST_INSERT_ID() 

делать то, что он говорит, возьмите последний вставленный ID в таблицу. Это добавит еще один запрос к вашему коду, но, похоже, он использует ваш сырой SQL-код.

+0

предпочтет рельсовый способ сделать это, если это возможно .. это единственный способ? – babonk

+0

Вы можете сделать что-то вроде этого: 'DmozCategory.find (: last).id' – BK22

+0

Я не уверен, если это возможно, извините. – BK22

0

попробовать это, то есть, как AR определяет идентификатор, прежде чем вставка в 2.3

ID = DmozCategory.connection.next_sequence_value (DmozCategory.sequence_name)

+0

'undefined method' next_sequence_value 'для # ' – babonk

12

В общем случае вместо использования connection.execute, использовать connection.insert

Это вернет сгенерированный идентификатор последней вставленной строки. Как это зависит от базы данных. В MySQL последний идентификатор вставки является свойством соединения. В Postgres к запросу добавляется предложение «return» (со старыми версиями postgres резерв запрашивает последовательность для последнего id).

Использование вставки, а не выполнения также очищает кеш запросов рельсов.

На MySQL, по крайней мере, это будет работать even if you set the id yourself.

+0

Как я могу получить идентификатор? 'DmozCategory.connection.id' и' DmozCategory.connection.last_id', похоже, не имеют идентификатора, который я вставляю – babonk

+0

connection.insert «INSERT ...» должен возвращать идентификатор (если ваш идентификатор является обычным авто increment column) –

+0

ой, поэтому мне не нужно сначала использовать '.send'? он как отправляет, так и выполняет в одном? – babonk

0

Если это драгоценный камень mysql2, а DmozCategory.connection - это экземпляр клиента, то будет работать DmozCategory.connection.last_id.

+0

Я использую' mysql', поэтому 'undefined метод 'last_id 'для # ' – babonk

0

Поскольку вы знаете id уже, вы не можете просто сделать это?

dmoz_category = DmozCategory.find(result['id']) 
$stderr.puts dmoz_category.inspect 
+0

, он начинает выглядеть так: это единственный способ. не знаю, почему, но все остальное возвращает либо 0, либо огромный/неправильный номер – babonk