Module Zetetic::Acts::Network::ClassMethods
In: vendor/plugins/acts_as_network/lib/zetetic/acts/network.rb


Public Instance methods


ActsAsNetork expects a few things to be present before it is called. Namely, you need to establish the existance of either

  1. a HABTM join table; or
  2. an intermediate Join model


In the first case, acts_as_network will assume that your HABTM table is named in a self-referential manner based on the model name. i.e. if your model is called Person it will assume the HABTM join table is called people_people. It will also default the foreign_key column to be named after the model: person_id. The default association_foreign_key column will be the foreign_key name with _target appended.

  acts_as_network :friends

You can override any of these options in your call to acts_as_network. The following will use a join table named friends with a foreign key of person_id and an association foreign key of friend_id

  acts_as_network :friends, :join_table => :friends, :foreign_key => 'person_id', :association_foreign_key => 'friend_id'

Join Model

In the second case acts_as_network will need to be told which model to use to perform the join - this is accomplished by passing a symbol for the join model to the :through option. So, with a join model called invites use:

  acts_as_network :friends, :through => :invites

The same assumptions are made relative to the foreign_key and association_foreign_key columns, which can be overriden using the same options. It may be useful to include :conditions as well depending on the specific requirements of the join model. The following will create a network relation using a join model named Invite with a foreign_key of person_id, an association_foreign_key of friend_id, where the Invite‘s is_accepted field is true.

  acts_as_network :friends, :through => :invites, :foreign_key => 'person_id',
                  :association_foreign_key => 'friend_id', :conditions => "is_accepted = 't'"

The valid configuration options that can be passed to acts_as_network follow:

  • :through - class to use for has_many :through relationship. If omitted acts_as_network will fall back on a HABTM relation
  • :join_table - when using a simple HABTM relation, this allows you to override the name of the join table. Defaults to model_model format, i.e. people_people
  • :foreign_key - name of the foreign key for the origin side of relation - i.e. person_id.
  • :association_foreign_key - name of the foreign key for the target side, i.e. erson_id_target. Defaults to the same value as foreign_key with a _target suffix
  • :conditions - optional, standard ActiveRecord SQL contition clause


     # File vendor/plugins/acts_as_network/lib/zetetic/acts/network.rb, line 214
214:         def acts_as_network(relationship, options = {})
215:           configuration = { 
216:             :foreign_key => name.foreign_key, 
217:             :association_foreign_key => "#{name.foreign_key}_target", 
218:             :join_table => "#{name.tableize}_#{name.tableize}"
219:           }
220:           configuration.update(options) if options.is_a?(Hash)
222:           if configuration[:through].nil?
223:             has_and_belongs_to_many "#{relationship}_out".to_sym, :class_name => name,  
224:               :foreign_key => configuration[:foreign_key], :association_foreign_key => configuration[:association_foreign_key],
225:               :join_table => configuration[:join_table], :conditions => configuration[:conditions]
227:             has_and_belongs_to_many "#{relationship}_in".to_sym, :class_name => name,  
228:               :foreign_key => configuration[:association_foreign_key], :association_foreign_key => configuration[:foreign_key],
229:               :join_table => configuration[:join_table], :conditions => configuration[:conditions]
231:           else
232:             through_class = configuration[:through].to_s.classify
233:             through_sym = configuration[:through]
235:             # a node has many outbound realationships
236:             has_many "#{through_sym}_out".to_sym, :class_name => through_class, 
237:               :foreign_key => configuration[:foreign_key]
238:             has_many "#{relationship}_out".to_sym, :through => "#{through_sym}_out".to_sym, 
239:               :source => "#{name.downcase}_target",  :foreign_key => configuration[:foreign_key],
240:               :conditions => configuration[:conditions]
242:             # a node has many inbound relationships
243:             has_many "#{through_sym}_in".to_sym, :class_name => through_class, 
244:               :foreign_key => configuration[:association_foreign_key]
245:             has_many "#{relationship}_in".to_sym, :through => "#{through_sym}_in".to_sym, 
246:               :source => name.downcase, :foreign_key => configuration[:association_foreign_key],
247:               :conditions => configuration[:conditions]
249:             # when using a join model, define a method providing a unioned view of all the join
250:             # records. i.e. if People acts_as_network :contacts :through => :invites, this method
251:             # is defined as def invites
252:             class_eval "def \#{through_sym}\\#{through_sym}_in, self.\#{through_sym}_out)\nend\n"
254:           end
256:           # define the accessor method for the reciprocal network relationship view itself. 
257:           # i.e. if People acts_as_network :contacts, this method is defind as def contacts
258:           class_eval "def \#{relationship}\\#{relationship}_in, self.\#{relationship}_out)\nend\n"
259:         end