У меня есть две таблицы с отношениями HABTM в направляющих. Что-то как следующее:
class Foo < ActiveRecord::Base
has_and_belongs_to_many :bars
end
class Bar < ActiveRecord::Base
has_and_belongs_to_many :foos
end
Теперь у меня есть новое Foo
объект, и хочет к массе - присваивают тысячи панелей ему, которые я предварительно загрузил:
@foo = Foo.create
@bars = Bar.find_all_by_some_attribute(:a)
Что самый быстрый путь состоит в том, чтобы сделать это? Я попробовал:
@foo.bars = @bars
@foo.bars << @bars
И оба выполненных действительно замедляются с записью как следующее для каждого bar
:
Столбцы bars_foos (1,1 мс) ПОКАЗЫВАЮТ ПОЛЯ ОТ
bars_foos
SQL (0,6 мс) INSERT INTObars_foos
(bar_id
,foo_id
) ЗНАЧЕНИЯ (100, 117200)
Я посмотрел на расширения площади, но import
функция, кажется, не работает без модели (Model.import), который устраняет его использование для объединяющей таблицы.
Я должен записать SQL, или направляющие имеют более симпатичный путь?
Я думаю, что лучше всего с точки зрения производительности использовать SQL и массовую вставку нескольких строк на запрос. Если вы можете создать оператор INSERT, который выполняет что-то вроде:
INSERT INTO foos_bars (foo_id,bar_id) VALUES (1,1),(1,2),(1,3)....
Вы должны иметь возможность вставлять тысячи строк в один запрос. Я не пробовал ваш метод mass_habtm, но похоже, что вы могли бы сделать что-то вроде:
bars = Bar.find_all_by_some_attribute(:a)
foo = Foo.create
values = bars.map {|bar| "(#{foo.id},#{bar.id})"}.join(",")
connection.execute("INSERT INTO foos_bars (foo_id, bar_id) VALUES #{values}")
Кроме того, если вы ищете Bar по "some_attribute", убедитесь, что это поле проиндексировано в вашей базе данных.
Это было быстрее, чем эквивалентный собственный код rails в 7 раз:
class << Foo
def mass_habtm(attr_array)
attr_str = attr_array.map{|a| %Q{'#{a}'} }.uniq.join(",")
self.connection.execute(%Q{insert into foos_bars (foo_id,bar_id)
select distinct foos.id,bars.id from foos,bars
where foos.id = #{self.id}
and bars.some_attribute in (#{attr_str})})
end
end
Мне кажется, что это достаточно простая операция, и она должна поддерживаются эффективно в Rails, я хотел бы услышать, есть ли у кого-нибудь более чистый способ.
Я использую 2.2.2, может быть, это более эффективно реализовано в 3.x? и обнаружил то же самое в 3.0.2.
При использовании PHP не имеет значения, какой тип был у формы. Вы всегда получаете пары ключ/значение.
Поэтому, если более жесткое кодирование является единственной причиной отказа и вы используете PHP, просто используйте enctype = «multipart/form-data».
Есть ли другая причина?
-121--1264830-Другим интересным решением для PHP 5,2 и выше является использование расширения фильтра: http://www.php.net/manual/en/book.filter.php
Это позволяет проверить и очистить пользовательские вводы. Имеется множество встроенных фильтров, которые можно комбинировать с флагами для изменения их поведения. Кроме того, эти фильтры могут также использоваться для проверки/очистки входов, поплавков, сообщений электронной почты и определенных регулярных выражений.
Я лично начал использовать их в своих проектах для проверки форм и вывода введенных пользователем данных, и я очень рад, что это сделал. Хотя, когда я вставляю значения в базу данных MySQL, я использую подготовленные запросы для дополнительной безопасности. Эти решения вместе помогут избежать большинства инъекций SQL и атак типа XSS.
-121--3853777- Честно говоря, имеет _ и _ принадлежит _ ко _ многим
- это очень устаревший способ делать вещи. Вы, вероятно, должны посмотреть на _ много: через
, который является новым способом объединения таблиц, и уже довольно давно.
class Foo < ActiveRecord::Base
has_many :foobars
has_many :bars, :through => :foobars
def add_many_bars(bars)
bars.each do |bar|
self.bars << bar
end
end
end
class Bar < ActiveRecord::Base
has_many :foobars
has_many :foos, :through => :foobars
end
class FooBar < ActiveRecord::Base
belongs_to :foo
belongs_to :bar
end
Также вы должны попробовать запустить то же самое в производстве и посмотреть, какую производительность вы получаете, так как много кэширования продолжается в производстве, что не обязательно происходит в разработке.