У меня есть метод в направляющих, который делает что-то вроде этого:
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)
Это сделало бы все это только в двух хитах базы данных. Существует ли простой способ сделать это в направляющих или застревает я делающий его по одному?
Вы можете попробовать использовать 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 . Последний содержит руководство по всем методам, которые получает класс при объявлении ассоциации.
Так как вам нужно выполнить несколько операций вставки, база данных будет обработана несколько раз. Задержка в вашем случае связана с тем, что каждое сохранение выполняется в разных транзакциях БД. Вы можете уменьшить задержку, заключив все свои операции в одну транзакцию.
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
родительского объекта сохраняет дочерние объекты.