Sunday 15 June 2014

ruby - Rails 3 has_and_belongs_to_many association: how to assign related objects without saving them to the database -



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