Posted By

da_huang on 07/09/10


Tagged

habtm hasandbelongstomany


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

stevenh512


HABTM Association in Rails 3.0


 / Published in: Rails
 

  1. # Extend ActiveRecord::Base with this method using your preferred technique.
  2. def self.anaf_habtm(association, &block)
  3. class_eval do
  4. # Define a proc that will look up the (potentially) existing object
  5. finder = proc {|id| association.to_s.singularize.camelize.constantize.where(:id=>id).first
  6. }
  7.  
  8. # Define a proc that will set the association collection
  9. set_collection = proc {|me, coll| me.send("#{association.to_s.tableize}=", coll)}
  10. # Define the actual association setter.
  11. define_method "#{association.to_s.tableize}_attributes=", lambda{|attributes_for_association|
  12. coll = []
  13.  
  14. attributes_for_association.each_value do |params|
  15. next if params["_destroy"] == "1"
  16. obj = finder.call(params["id"]) if params.has_key?("id")
  17. params.extend(HashExtension)
  18. # ActiveRecord::Base.attributes=() doesn't like extra parameters.
  19. coll << block.call(params.copy_without_destroy, obj)
  20. end
  21. set_collection.call(self, coll)
  22. }
  23. end
  24. end
  25.  
  26.  
  27. # Inside your model definition, define your association as such:
  28. class Person < ActiveRecord::Base
  29. has_and_belongs_to_many :web_sites, :autosave => :true, :uniq => true
  30. has_and_belongs_to_many :recreational_organizations, :autosave => :true, :uniq => true
  31.  
  32. # This one has some extra parameters that will be saved to the association
  33. anaf_habtm(:web_sites) do |params, web_site|
  34. web_site = web_site ||= WebSite.find_by_url(params["url"])
  35. web_site.attributes = params
  36. web_site.save
  37. web_site
  38. end
  39.  
  40. # This one is more simple -- just make a new one if nil was passed in
  41. anaf_habtm(:recreational_organizations) do |params, org|
  42. org ||= RecreationalOrganization.new(:name => params["name"])
  43. end
  44.  
  45. module HashExtension
  46. def copy_without_destroy
  47. a = {}
  48. self.each {|key,val| a[key]=val unless key.to_s == "_destroy"}
  49. a
  50. end
  51. end

Report this snippet  

You need to login to post a comment.