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