ruby - Rails 3 has_and_belongs_to_many association: how to assign related objects without saving them to the database -
working has_and_belongs_to_many_association
class category has_and_belongs_to_many :projects end
i would utilize before_filter set projects before saving categories
before_filter :set_projects, :only => [:create, :update] def set_projects @category.assign_attributes({projects: project.all}) end
this works well, except when category cannot saved , there rollback. projects still updated in database.
why line
@category.assign_attributes({projects: project.all})
generate these database records immediately?
begin insert "categories_projects" ("category_id", "project_id") values (86, 1) insert "categories_projects" ("category_id", "project_id") values (86, 2) insert "categories_projects" ("category_id", "project_id") values (86, 3) commit
i wait @category.save before commiting these new categories_projects relations. how postpone these commits?
please note can't modify main "update" action. have utilize before/after filters , callbacks in order override current functionality of app.
------ edit ----------
ok, after reading doc here, think have solution:
when objects saved?
when assign object has_and_belongs_to_many association, object automatically saved (in order update bring together table). if assign multiple objects in 1 statement, saved.
if want assign object has_and_belongs_to_many association without saving object, utilize collection.build method.
i seek utilize collection.build method. have thought how existing projects?
why not move category
model in after_save
phone call back? e.g.
class category #based on comment need virtual attribute attr_accessor :assignable_projects after_save :set_projects private def set_projects self.assign_attributes({projects: self.assignable_projects}) end end
since need set specific projects need create virtual attribute. attribute stored in instance not saved database. add together attr_accessor
line create bot getter , setter methods needed.
then in controller
class categoriescontroller < applicationcontoller before_filter :set_assignable_projects, only: [:create,:update] private def set_assignable_projects @category.assignable_projects = params[:project_ids] end end
this event fire after category
validations run , category save successfully. utilize values assigned in before_filter
create associations. since assign_attributes
not phone call save
1 time again avoid infinite loop. place in after_validation
callback create sure check self.errors.empty?
before using assign_attributes
or in same boat now.
if category
fails save assignable_projects
still set instance show in rendered view failed save.
ruby-on-rails ruby ruby-on-rails-3.2 has-and-belongs-to-many
No comments:
Post a Comment