скопируйте объекты has_many одним SQL INSERT - PullRequest
0 голосов
/ 17 мая 2011

У меня есть следующее (это было упрощено, чтобы сделать вопрос под рукой более очевидным):

user model has_many favorites
favorite model belongs_to user

После создания нового пользователя я хочу скопировать все избранное из существующего пользователя вновый пользователь.Прямо сейчас у меня есть следующий код:

# bob is the existing user and sam is the new user
bob.favorites.each do | f |
  u = Favorite.new(f.attributes)
  u.user_id = sam.user_id
  u.save!
end

Это создает SQL INSERT для каждого фаворита, который есть у bob.

Я знаю, что SQL может сделать это в одной команде с чем-то вроде:

INSERT INTO favorites SELECT url, sam.user_id AS user_id FROM
favorites WHERE user_id = bob.user_id

Имеет ли ActiveRecord что-то для меня, чтобы сделать это?Было бы неплохо хранить код на Ruby, а не на SQL.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 19 мая 2011

Продолжайте и делайте это в SQL. Этот синтаксис "insert_select" из "ar-extensions" (ответ aNoble) гораздо менее читабелен, чем простой оператор SQL.

Храните SQL в методе модели User, и если "bob" всегда один и тот же пользователь, то кодируйте его и добавьте в обратный вызов after_create, чтобы ваш контроллер также был чистым. E.g.:

Class User < ActiveRecord::Base
  ...
  after_create :copy_favorites_from_bob
  def copy_favorites_from_bob
    connection.execute "INSERT INTO favorites SELECT url, #{id} AS user_id FROM
favorites WHERE user_id = '{{put bob's user id here}}'"
  end
end

Если вы используете PostgreSQL, вам нужно убедиться, что новый user_id является целым числом:

connection.execute "INSERT INTO favorites SELECT url, integer '#{id}' AS user_id FROM
favorites WHERE user_id = '{{put bob's user id here}}'"
0 голосов
/ 17 мая 2011

гем под названием ar-extensions поддерживает INSERT SELECT SQL satements.

Favorite.insert_select(
  :from => :favorites,
  :conditions => ['favorites.user_id = ?', bob.user_id],
  :select => ['favorites.url, ?', sam.user_id],
  :into => [:url, :user_id]
)

Я не уверен на 100%, что это будет работать именно так, как должно, но это будет возможно, если вы покопаетесь в документации .

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