Как обновить существующую запись, если сохраняемая имеет тот же ключ? - PullRequest
2 голосов
/ 12 мая 2010

В MySQL есть очень хорошая опция для оператора INSERT, которая особенно полезна для таблиц объединения без столбца id. Он вставляет запись, но вместо того, чтобы выдать ошибку, если его ключ конфликтовал с существующим, эта запись обновляется. Вот пример:

INSERT INTO table (key1,key2,data) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE data=3;

Как добиться того же с Active Record? Результирующий код будет выглядеть следующим образом:

class Model < ActiveRecord::Base
  belongs_to :key1
  belongs_to :key2
end

record = Model.new
record.key1 = key1
record.key2 = key2
record.data = 'new data'
record.WHAT?    #Inserts or updates `data` for the existing record

Ответы [ 4 ]

3 голосов
/ 11 июня 2010

Ответ j - правильная идея, но вы, вероятно, захотите использовать find_or_initialize_by, чтобы избежать многократного сохранения объекта. Э.Г.

record = Model.find_or_initialize_by_key1_and_key2 new
record.data = 'new data'
record.save

Судя по звукам, вы также хотите проверить, чтобы модель также не допускала повторных объединений:

class Model < ActiveRecord::Base
  belongs_to :key1
  belongs_to :key2
  validates_uniqueness_of :key1, :scope => :key2
end
2 голосов
/ 12 мая 2010

Вы можете сделать следующее:

record = Model.find_or_create_by_key1_and_key2(:key1 => key1, :key2 => key2)
record.update_attribute(:data, "new data")

EDIT

zaius идея выглядит лучше, вы должны использовать find_or_initialize_by, чтобы избежать многократного сохранения, как он сказал:]

1 голос
/ 11 июня 2010

Возможно, вы захотите взглянуть на составные первичные ключи . Это плагин для ActiveRecord.

0 голосов
/ 12 мая 2010

Прежде всего, это решение для MySQL, насколько я знаю, синтаксис не работает ни с какими другими SQL-серверами. Обычно называется Upsert в обсуждениях.

Я бы пошел с созданием нового метода с именем save_or_update, а затем, если сохранение не удалось, с исключением дублирующего ключа, загрузкой и update_params.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...