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