Сохранение нескольких объектов в единственном вызове в направляющих

У меня есть метод в направляющих, который делает что-то вроде этого:

a = Foo.new("bar")
a.save

b = Foo.new("baz")
b.save

...
x = Foo.new("123", :parent_id => a.id)
x.save

...
z = Foo.new("zxy", :parent_id => b.id)
z.save

Проблема, это занимает больше времени и дольше больше объектов, которые я добавляю. Я подозреваю, что это вызвано тем, что это должно поразить базу данных для каждой записи. Так как они вкладываются, я знаю, что не могу сохранить детей, прежде чем родители будут сохранены, но я хотел бы сохранить всех родителей сразу и затем всех детей. Было бы хорошо сделать что-то как:

a = Foo.new("bar")
b = Foo.new("baz")
...
saveall(a,b,...)

x = Foo.new("123", :parent_id => a.id)
...
z = Foo.new("zxy", :parent_id => b.id)
saveall(x,...,z)

Это сделало бы все это только в двух хитах базы данных. Существует ли простой способ сделать это в направляющих или застревает я делающий его по одному?

77
задан captncraig 24 March 2010 в 16:11
поделиться

2 ответа

Вы можете попробовать использовать Foo.create вместо Foo.new. Создать «Создает объект (или несколько объектов) и сохраняет его в базе данных, если проверки пройдены. Результирующий объект возвращается независимо от того, был ли объект успешно сохранен в базе данных или нет»

. Вы можете создать несколько таких объектов:

# Create an Array of new objects
  parents = Foo.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])

Затем для каждого родителя вы также можете использовать create для добавления к его ассоциации:

parents.each do |parent|
  parent.children.create (:child_name => 'abc')
end

Я рекомендую прочитать документацию ActiveRecord и руководства Rails по интерфейсу запросов ActiveRecord и ассоциации ActiveRecord . Последний содержит руководство по всем методам, которые получает класс при объявлении ассоциации.

62
ответ дан 24 November 2019 в 10:53
поделиться

Так как вам нужно выполнить несколько операций вставки, база данных будет обработана несколько раз. Задержка в вашем случае связана с тем, что каждое сохранение выполняется в разных транзакциях БД. Вы можете уменьшить задержку, заключив все свои операции в одну транзакцию.

class Foo
  belongs_to  :parent,   :class_name => "Foo"
  has_many    :children, :class_name => "Foo", :foreign_key=> "parent_id"
end

Ваш метод сохранения может выглядеть следующим образом:

# build the parent and the children
a = Foo.new(:name => "bar")
a.children.build(:name => "123")

b = Foo.new("baz")
b.children.build(:name => "zxy")

#save parents and their children in one transaction
Foo.transaction do
  a.save!
  b.save!
end

Вызов save родительского объекта сохраняет дочерние объекты.

90
ответ дан 24 November 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: