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
73 def def_association_pks_methods(opts)
74   association_module_def(opts[:pks_dataset_method], &opts[:pks_dataset])
75 
76   opts[:pks_getter_method] = :"#{singularize(opts[:name])}_pks_getter"
77   association_module_def(opts[:pks_getter_method], &opts[:pks_getter])
78   association_module_def(:"#{singularize(opts[:name])}_pks", opts){|dynamic_opts=OPTS| _association_pks_getter(opts, dynamic_opts)}
79 
80   if opts[:pks_setter]
81     opts[:pks_setter_method] = :"#{singularize(opts[:name])}_pks_setter"
82     association_module_def(opts[:pks_setter_method], &opts[:pks_setter])
83     association_module_def(:"#{singularize(opts[:name])}_pks=", opts){|pks| _association_pks_setter(opts, pks)}
84   end
85 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
 89 def def_many_to_many(opts)
 90   super
 91 
 92   return if opts[:type] == :one_through_one
 93 
 94   # Grab values from the reflection so that the hash lookup only needs to be
 95   # done once instead of inside every method call.
 96   lk, lpk, rk = opts.values_at(:left_key, :left_primary_key, :right_key)
 97   clpk = lpk.is_a?(Array)
 98   crk = rk.is_a?(Array)
 99 
100   dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
101 
102   opts[:pks_dataset] = if join_associated_table = opts[:association_pks_use_associated_table]
103     tname = opts[:join_table]
104     lambda do
105       cond = if clpk
106         lk.zip(lpk).map{|k, pk| [Sequel.qualify(tname, k), get_column_value(pk)]}
107       else
108         {Sequel.qualify(tname, lk) => get_column_value(lpk)}
109       end
110       rpk = opts.associated_class.primary_key
111       opts.associated_dataset.
112         naked.where(cond).
113         select(*Sequel.public_send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
114     end
115   elsif clpk
116     lambda do
117       cond = lk.zip(lpk).map{|k, pk| [k, get_column_value(pk)]}
118       _join_table_dataset(opts).where(cond).select(*rk)
119     end
120   else
121     lambda do
122       _join_table_dataset(opts).where(lk=>get_column_value(lpk)).select(*rk)
123     end
124   end
125 
126   opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
127     lambda do
128       public_send(dataset_method).map(opts.associated_class.primary_key)
129     end
130   else
131     lambda do
132       public_send(dataset_method).map(rk)
133     end
134   end
135 
136   if !opts[:read_only] && !join_associated_table
137     opts[:pks_setter] = lambda do |pks|
138       if pks.empty?
139         public_send(opts[:remove_all_method])
140       else
141         checked_transaction do
142           if clpk
143             lpkv = lpk.map{|k| get_column_value(k)}
144             cond = lk.zip(lpkv)
145           else
146             lpkv = get_column_value(lpk)
147             cond = {lk=>lpkv}
148           end
149           ds = _join_table_dataset(opts).where(cond)
150           ds.exclude(rk=>pks).delete
151           pks -= ds.select_map(rk)
152           lpkv = Array(lpkv)
153           key_array = crk ? pks.map{|pk| lpkv + pk} : pks.map{|pk| lpkv + [pk]}
154           key_columns = Array(lk) + Array(rk)
155           ds.import(key_columns, key_array)
156         end
157       end
158     end
159   end
160 
161   def_association_pks_methods(opts)
162 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
166 def def_one_to_many(opts)
167   super
168 
169   return if opts[:type] == :one_to_one
170 
171   key = opts[:key]
172 
173   dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
174 
175   opts[:pks_dataset] = lambda do
176     public_send(opts[:dataset_method]).select(*opts.associated_class.primary_key)
177   end
178 
179   opts[:pks_getter] = lambda do
180     public_send(dataset_method).map(opts.associated_class.primary_key)
181   end
182 
183   unless opts[:read_only]
184     opts[:pks_setter] = lambda do |pks|
185       if pks.empty?
186         public_send(opts[:remove_all_method])
187       else
188         primary_key = opts.associated_class.primary_key
189         pkh = {primary_key=>pks}
190 
191         if key.is_a?(Array)
192           h = {}
193           nh = {}
194           key.zip(pk).each do|k, v|
195             h[k] = v
196             nh[k] = nil
197           end
198         else
199           h = {key=>pk}
200           nh = {key=>nil}
201         end
202 
203         checked_transaction do
204           ds = public_send(opts.dataset_method)
205           ds.unfiltered.where(pkh).update(h)
206           ds.exclude(pkh).update(nh)
207         end
208       end
209     end
210   end
211 
212   def_association_pks_methods(opts)
213 end