module Sequel::Plugins::AssociationPks::ClassMethods

Private Instance Methods

def_association_pks_methods(opts) click to toggle source

Define a association_pks method using the block for the association reflection

   # File lib/sequel/plugins/association_pks.rb
62 def def_association_pks_methods(opts)
63   opts[:pks_getter_method] = :"#{singularize(opts[:name])}_pks_getter"
64   association_module_def(opts[:pks_getter_method], &opts[:pks_getter])
65   association_module_def(:"#{singularize(opts[:name])}_pks", opts){_association_pks_getter(opts)}
66 
67   if opts[:pks_setter]
68     opts[:pks_setter_method] = :"#{singularize(opts[:name])}_pks_setter"
69     association_module_def(opts[:pks_setter_method], &opts[:pks_setter])
70     association_module_def(:"#{singularize(opts[:name])}_pks=", opts){|pks| _association_pks_setter(opts, pks)}
71   end
72 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
 76 def def_many_to_many(opts)
 77   super
 78 
 79   return if opts[:type] == :one_through_one
 80 
 81   # Grab values from the reflection so that the hash lookup only needs to be
 82   # done once instead of inside every method call.
 83   lk, lpk, rk = opts.values_at(:left_key, :left_primary_key, :right_key)
 84   clpk = lpk.is_a?(Array)
 85   crk = rk.is_a?(Array)
 86 
 87   opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
 88     tname = opts[:join_table]
 89     lambda do
 90       cond = if clpk
 91         lk.zip(lpk).map{|k, pk| [Sequel.qualify(tname, k), get_column_value(pk)]}
 92       else
 93         {Sequel.qualify(tname, lk) => get_column_value(lpk)}
 94       end
 95       rpk = opts.associated_class.primary_key
 96       opts.associated_dataset.
 97         naked.where(cond).
 98         select_map(Sequel.public_send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
 99     end
100   elsif clpk
101     lambda do
102       cond = lk.zip(lpk).map{|k, pk| [k, get_column_value(pk)]}
103       _join_table_dataset(opts).where(cond).select_map(rk)
104     end
105   else
106     lambda do
107       _join_table_dataset(opts).where(lk=>get_column_value(lpk)).select_map(rk)
108     end
109   end
110 
111   if !opts[:read_only] && !join_associated_table
112     opts[:pks_setter] = lambda do |pks|
113       if pks.empty?
114         public_send(opts[:remove_all_method])
115       else
116         checked_transaction do
117           if clpk
118             lpkv = lpk.map{|k| get_column_value(k)}
119             cond = lk.zip(lpkv)
120           else
121             lpkv = get_column_value(lpk)
122             cond = {lk=>lpkv}
123           end
124           ds = _join_table_dataset(opts).where(cond)
125           ds.exclude(rk=>pks).delete
126           pks -= ds.select_map(rk)
127           lpkv = Array(lpkv)
128           key_array = crk ? pks.map{|pk| lpkv + pk} : pks.map{|pk| lpkv + [pk]}
129           key_columns = Array(lk) + Array(rk)
130           ds.import(key_columns, key_array)
131         end
132       end
133     end
134   end
135 
136   def_association_pks_methods(opts)
137 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
141 def def_one_to_many(opts)
142   super
143 
144   return if opts[:type] == :one_to_one
145 
146   key = opts[:key]
147 
148   opts[:pks_getter] = lambda do
149     public_send(opts[:dataset_method]).select_map(opts.associated_class.primary_key)
150   end
151 
152   unless opts[:read_only]
153     opts[:pks_setter] = lambda do |pks|
154       if pks.empty?
155         public_send(opts[:remove_all_method])
156       else
157         primary_key = opts.associated_class.primary_key
158         pkh = {primary_key=>pks}
159 
160         if key.is_a?(Array)
161           h = {}
162           nh = {}
163           key.zip(pk).each do|k, v|
164             h[k] = v
165             nh[k] = nil
166           end
167         else
168           h = {key=>pk}
169           nh = {key=>nil}
170         end
171 
172         checked_transaction do
173           ds = public_send(opts.dataset_method)
174           ds.unfiltered.where(pkh).update(h)
175           ds.exclude(pkh).update(nh)
176         end
177       end
178     end
179   end
180 
181   def_association_pks_methods(opts)
182 end