module Sequel::Plugins::AssociationPks::ClassMethods

Private Instance Methods

def_association_pks_getter(opts, &block) click to toggle source

Define a association_pks method using the block for the association reflection

# File lib/sequel/plugins/association_pks.rb, line 38
def def_association_pks_getter(opts, &block)
  association_module_def(:"#{singularize(opts[:name])}_pks", opts, &block)
end
def_association_pks_setter(opts, &block) click to toggle source

Define a association_pks= method using the block for the association reflection, if the association is not read only.

# File lib/sequel/plugins/association_pks.rb, line 44
def def_association_pks_setter(opts, &block)
  association_module_def(:"#{singularize(opts[:name])}_pks=", opts, &block) unless opts[:read_only]
end
def_many_to_many(opts) click to toggle source

Add a getter that checks the join table for matching records and a setter that deletes from or inserts into the join table.

Calls superclass method
# File lib/sequel/plugins/association_pks.rb, line 50
def def_many_to_many(opts)
  super
  # Grab values from the reflection so that the hash lookup only needs to be
  # done once instead of inside ever method call.
  lk, lpk, rk = opts.values_at(:left_key, :left_primary_key, :right_key)

  # Add 2 separate implementations of the getter method optimized for the
  # composite and singular left key cases, and 4 separate implementations of the setter
  # method optimized for each combination of composite and singular keys for both
  # the left and right keys.
  if lpk.is_a?(Array)
    def_association_pks_getter(opts) do
      h = {}
      lk.zip(lpk).each{|k, pk| h[k] = send(pk)}
      _join_table_dataset(opts).filter(h).select_map(rk)
    end

    if rk.is_a?(Array)
      def_association_pks_setter(opts) do |pks|
        pks = convert_cpk_array(opts, pks)
        checked_transaction do
          lpkv = lpk.map{|k| send(k)}
          ds = _join_table_dataset(opts).filter(lk.zip(lpkv))
          ds.exclude(rk=>pks).delete
          pks -= ds.select_map(rk)
          h = {}
          lk.zip(lpkv).each{|k, v| h[k] = v}
          pks.each do |pk|
            ih = h.dup
            rk.zip(pk).each{|k, v| ih[k] = v}
            ds.insert(ih)
          end
        end
      end
    else
      def_association_pks_setter(opts) do |pks|
        pks = convert_pk_array(opts, pks)
        checked_transaction do
          lpkv = lpk.map{|k| send(k)}
          ds = _join_table_dataset(opts).filter(lk.zip(lpkv))
          ds.exclude(rk=>pks).delete
          pks -= ds.select_map(rk)
          h = {}
          lk.zip(lpkv).each{|k, v| h[k] = v}
          pks.each do |pk|
            ds.insert(h.merge(rk=>pk))
          end
        end
      end
    end
  else
    def_association_pks_getter(opts) do
      _join_table_dataset(opts).filter(lk=>send(lpk)).select_map(rk)
    end

    if rk.is_a?(Array)
      def_association_pks_setter(opts) do |pks|
        pks = convert_cpk_array(opts, pks)
        checked_transaction do
          lpkv = send(lpk)
          ds = _join_table_dataset(opts).filter(lk=>lpkv)
          ds.exclude(rk=>pks).delete
          pks -= ds.select_map(rk)
          pks.each do |pk|
            h = {lk=>lpkv}
            rk.zip(pk).each{|k, v| h[k] = v}
            ds.insert(h)
          end
        end
      end
    else
      def_association_pks_setter(opts) do |pks|
        pks = convert_pk_array(opts, pks)
        checked_transaction do
          lpkv = send(lpk)
          ds = _join_table_dataset(opts).filter(lk=>lpkv)
          ds.exclude(rk=>pks).delete
          pks -= ds.select_map(rk)
          pks.each{|pk| ds.insert(lk=>lpkv, rk=>pk)}
        end
      end
    end
  end
end
def_one_to_many(opts) click to toggle source

Add a getter that checks the association dataset and a setter that updates the associated table.

Calls superclass method
# File lib/sequel/plugins/association_pks.rb, line 137
def def_one_to_many(opts)
  super
  return if opts[:type] == :one_to_one

  key = opts[:key]

  def_association_pks_getter(opts) do
    send(opts.dataset_method).select_map(opts.associated_class.primary_key)
  end

  def_association_pks_setter(opts) do |pks|
    primary_key = opts.associated_class.primary_key

    pks = if primary_key.is_a?(Array)
      convert_cpk_array(opts, pks)
    else
      convert_pk_array(opts, pks)
    end

    pkh = {primary_key=>pks}

    if key.is_a?(Array)
      h = {}
      nh = {}
      key.zip(pk).each do|k, v|
        h[k] = v
        nh[k] = nil
      end
    else
      h = {key=>pk}
      nh = {key=>nil}
    end

    checked_transaction do
      ds = send(opts.dataset_method)
      ds.unfiltered.filter(pkh).update(h)
      ds.exclude(pkh).update(nh)
    end
  end
end