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