Rails has_and_belongs_to_many всегда вставляется в базу данных - PullRequest
1 голос
/ 14 декабря 2011

Вот моя проблема:

class Facility < ActiveRecord::Base
...
has_and_belongs_to_many :languages, :autosave => false, :join_table => 'facilities_languages'
... 
end

Когда я делаю что-то вроде этого:

facility = Facility.find(1)
language = Language.find(1)
facility.languages << language

Rails всегда делает запрос SQL:

"INSERT INTO `facilities_languages` (`language_id`,`facility_id`) VALUES (1, 1)"

Есть ли способ избежать запросов к базе данных, если я не назову 'entity.save'?

По-видимому, опция автосохранения здесь делает что-то еще.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Если вы используете оператор лопатой << Rails автоматически сохраняет связанный объект. </p>

Из документации http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

коллекция << (объект,…) </p>

Добавляет один или несколько объектов в коллекцию создание ассоциаций в объединяемой таблице (collection.push и collection.concat - это псевдонимы этого метода). Обратите внимание, что это Операция мгновенно запускает обновление SQL, не дожидаясь сохранения или вызов обновления для родительского объекта.

1 голос
/ 14 декабря 2011

Ваша проблема в том, что вы используете has_and_belongs_to_many, который не основан на Model, поэтому вы не можете получить к нему доступ как к объекту. Вы можете создать Model, который выполняет ассоциации, а затем вы можете создать новые объекты этой модели ассоциации. e.g.:

rails g scaffold JoinClass faculty_id:integer language_id:integer

В модели

class JoinClass < ActiveRecord::Base
     belongs_to :faculty
     belongs_to :language
end

В других моделях:

Факультет

class Faculty < ActiveRecord::Base
     has_many :join_classes
     has_many :languages, :though => :join_classes
end

Язык

class Language < ActiveRecord::Base
     has_many :join_classes
     has_many :faculties, :through => :join_classes
end

Тогда вы сможете добавлять ассоциации, создавая объекты ассоциаций, которые не сохраняются автоматически. Например, у вас есть String, содержащий идентификаторы, которые содержат идентификаторы языковых объектов, которые должны быть связаны, называемые language_ids в FacultyController:

language_ids.split(",").each do |language_id|
    JoinClass.create(:faculty_id => @faculty.id, :language_id => language_id)
end

Конечно, этот код должен быть обусловлен и помещен после сохранения факультета.

0 голосов
/ 14 декабря 2011

facility.languages ​​= [язык]

...