/ Published in: Rails
Expand |
Embed | Plain Text
# Extend ActiveRecord::Base with this method using your preferred technique. def self.anaf_habtm(association, &block) class_eval do # Define a proc that will look up the (potentially) existing object finder = proc {|id| association.to_s.singularize.camelize.constantize.where(:id=>id).first } # Define a proc that will set the association collection set_collection = proc {|me, coll| me.send("#{association.to_s.tableize}=", coll)} # Define the actual association setter. define_method "#{association.to_s.tableize}_attributes=", lambda{|attributes_for_association| coll = [] attributes_for_association.each_value do |params| next if params["_destroy"] == "1" obj = finder.call(params["id"]) if params.has_key?("id") params.extend(HashExtension) # ActiveRecord::Base.attributes=() doesn't like extra parameters. coll << block.call(params.copy_without_destroy, obj) end set_collection.call(self, coll) } end end # Inside your model definition, define your association as such: class Person < ActiveRecord::Base has_and_belongs_to_many :web_sites, :autosave => :true, :uniq => true has_and_belongs_to_many :recreational_organizations, :autosave => :true, :uniq => true # This one has some extra parameters that will be saved to the association anaf_habtm(:web_sites) do |params, web_site| web_site = web_site ||= WebSite.find_by_url(params["url"]) web_site.attributes = params web_site.save web_site end # This one is more simple -- just make a new one if nil was passed in anaf_habtm(:recreational_organizations) do |params, org| org ||= RecreationalOrganization.new(:name => params["name"]) end module HashExtension def copy_without_destroy a = {} self.each {|key,val| a[key]=val unless key.to_s == "_destroy"} a end end
You need to login to post a comment.
