Module: Versions::Multi::ClassMethods

Defined in:
lib/versions/multi.rb

Instance Method Summary collapse

Instance Method Details

#has_multiple(association_name, options = {}) ⇒ Object

Hide many instances behind a single current one.

Example

A page with many versions and a current one representing the latest content: has_multiple :versions

Supported options

:class_name

Specify the class name of the association. Use it only if that name can’t be inferred from the association name. So has_multiple :versions will by default be linked to the Version class

:inverse

Specify the name of the relation from the associated record back to this record. By default the name will be infered from the name of the current class. Note that this setting also defines the default the foreign key name.

:foreign_key

Specify the foreign key used for the association. By default this is guessed to be the name of this class (or the inverse) in lower-case and “_id” suffixed. So a Person class that makes a has_multiple association will use “person_id” as the default :foreign_key.

:local_key

Specify the local key to retrieve the current associated record. By default this is guessed from the name of the association in lower-case and “_id” suffixed. So a model that has_multiple :pages would use “page_id” as local key to get the current page. Note that the local key does not need to live in the database if the model defines set_current_[assoc]_before_update and set_current_[assoc]_after_create where ‘[assoc]’ represents the association name.

Raises:

  • (TypeError)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/versions/multi.rb', line 34

def has_multiple(association_name, options = {})
  name        = association_name.to_s.singularize
  klass       = (options[:class_name]  || name.capitalize).constantize
  owner_name  = options[:inverse]      || self.to_s.split('::').last.underscore
  foreign_key = (options[:foreign_key] || "#{owner_name}_id").to_s
  local_key   = (options[:local_key]   || "#{name}_id").to_s

  raise TypeError.new("Missing 'number' field in table #{klass.table_name}.") unless klass.column_names.include?('number')
  raise TypeError.new("Missing '#{foreign_key}' in table #{klass.table_name}.") unless klass.column_names.include?(foreign_key)

  has_many association_name, :order => 'number DESC', :class_name => klass.to_s, :foreign_key => foreign_key, :dependent => :destroy
  validate      :"validate_#{name}"
  after_create  :"save_#{name}_after_create"
  before_update :"save_#{name}_before_update"

  include module_for_multiple(name, klass, owner_name, foreign_key, local_key, association_name)
  klass.belongs_to owner_name, :class_name => self.to_s
end