module ActiveLdap::Associations::ClassMethods

def associated_class(name)

def associated_class(name)
  @associated_classes[name.to_s]
end

def association_accessor(name, &make_association)

def association_accessor(name, &make_association)
  define_method("__make_#{name}") do
    make_association.call(self)
  end
  associations << name
  association_reader(name, &make_association)
  association_writer(name, &make_association)
end

def association_reader(name, &make_association)

def association_reader(name, &make_association)
  class_eval(<<-EOM, __FILE__, __LINE__ + 1)
    def #{name}
      @#{name} ||= __make_#{name}
    end
  EOM
end

def association_writer(name, &make_association)

def association_writer(name, &make_association)
  class_eval(<<-EOM, __FILE__, __LINE__ + 1)
    def #{name}=(new_value)
      association = defined?(@#{name}) ? @#{name} : nil
      association ||= __make_#{name}
      association.replace(new_value)
      @#{name} = new_value.nil? ? nil : association
      @#{name}
    end
  EOM
end

def belongs_to(association_id, options={})


:primary_key => "gidNumber" # Group#gidNumber
:foreign_key => "gidNumber", # User#gidNumber
belongs_to :primary_group, :class_name => "Group",
# dn attribute value is used by default
## :foreign_key => "uid" # User#uid
## deprecated since 1.1.0. Use :primary_key instead.
# :primary_key => "uid" # User#uid
:many => "memberUid" # Group#memberUid
belongs_to :groups, :class_name => "Group",
Example:

|:class_name|.
|:foreign_key| in the other LDAP entry covered by class
attribute value on to multiple items which reference it by
This defines a method for an extension class map its DN key

belongs_to
def belongs_to(association_id, options={})
  validate_belongs_to_options(options)
  klass = options[:class]
  klass ||= (options[:class_name] || association_id.to_s).classify
  foreign_key = options[:foreign_key]
  primary_key = options[:primary_key]
  many = options[:many]
  set_associated_class(association_id, klass)
  opts = {
    :association_id => association_id,
    :foreign_key_name => foreign_key,
    :primary_key_name => primary_key,
    :many => many,
    :extend => options[:extend],
  }
  if opts[:many]
    association_class = Association::BelongsToMany
    foreign_key_name = opts[:foreign_key_name]
    if foreign_key_name
      message = _(":foreign_key belongs_to(:many) option is " \
                  "deprecated since 1.1.0. Use :primary_key instead.")
      ActiveLdap.deprecator.warn(message)
      opts[:primary_key_name] ||= foreign_key_name
    end
    opts[:primary_key_name] ||= dn_attribute
  else
    association_class = Association::BelongsTo
    opts[:foreign_key_name] ||= "#{association_id}_id"
    before_save do
      if instance_variable_defined?(:"@#{association_id}")
        association = instance_variable_get(:"@#{association_id}")
        if association and association.updated?
          self[association.__send__(:primary_key)] =
            association[opts[:foreign_key_name]]
        end
      end
    end
  end
  association_accessor(association_id) do |target|
    association_class.new(target, opts)
  end
end

def has_many(association_id, options = {})

:wrap => "memberUid" # Group#memberUid
has_many :members, :class_name => "User",
# :foreign_key => "gidNumber" # Group#gidNumber
# :primary_key => "gidNumber", # User#gidNumber
## are inverted.
## deprecated since 1.1.0. Those options
:foreign_key => "gidNumber" # User#gidNumber
:primary_key => "gidNumber", # Group#gidNumber
has_many :primary_members, :class_name => "User",
Example:

don't exist in LDAP!
This discards any calls which result in entries that
existing multi-element attribute into ActiveLdap objects.
This defines a method for an extension class expand an

has_many
def has_many(association_id, options = {})
  validate_has_many_options(options)
  klass = options[:class]
  klass ||= (options[:class_name] || association_id.to_s).classify
  foreign_key = options[:foreign_key]
  primary_key = options[:primary_key]
  set_associated_class(association_id, klass)
  opts = {
    :association_id => association_id,
    :foreign_key_name => foreign_key,
    :primary_key_name => primary_key,
    :wrap => options[:wrap],
    :extend => options[:extend],
  }
  if opts[:wrap]
    association_class = Association::HasManyWrap
  else
    association_class = Association::HasMany
    primary_key_name = opts[:primary_key_name]
    foreign_key_name = opts[:foreign_key_name]
    if primary_key_name != foreign_key_name and
        primary_key_name != "dn" and
        !new.have_attribute?(primary_key_name)
      message = _(":primary_key and :foreign_key has_many options are " \
                  "inverted their mean since 1.1.0. Please invert them.")
      ActiveLdap.deprecator.warn(message)
      opts[:foreign_key_name] = primary_key_name
      opts[:primary_key_name] = foreign_key_name
    end
  end
  association_accessor(association_id) do |target|
    association_class.new(target, opts)
  end
end

def set_associated_class(name, klass)

def set_associated_class(name, klass)
  @associated_classes ||= {}
  @associated_classes[name.to_s] = klass
end

def validate_belongs_to_options(options)

def validate_belongs_to_options(options)
  options.assert_valid_keys(VALID_BELONGS_TO_OPTIONS)
end

def validate_has_many_options(options)

def validate_has_many_options(options)
  options.assert_valid_keys(VALID_HAS_MANY_OPTIONS)
end