module Sequel::Plugins::PgArrayAssociations::ClassMethods
Public Instance Methods
many_to_pg_array(name, opts=OPTS, &block)
click to toggle source
Create a many_to_pg_array
association, for the case where the associated table contains the array with foreign keys pointing to the current table. See associate for options.
# File lib/sequel/plugins/pg_array_associations.rb 309 def many_to_pg_array(name, opts=OPTS, &block) 310 associate(:many_to_pg_array, name, opts, &block) 311 end
pg_array_to_many(name, opts=OPTS, &block)
click to toggle source
Create a pg_array_to_many
association, for the case where the current table contains the array with foreign keys pointing to the associated table. See associate for options.
# File lib/sequel/plugins/pg_array_associations.rb 316 def pg_array_to_many(name, opts=OPTS, &block) 317 associate(:pg_array_to_many, name, opts, &block) 318 end
Private Instance Methods
def_many_to_pg_array(opts)
click to toggle source
Setup the many_to_pg_array-specific datasets, eager loaders, and modification methods.
# File lib/sequel/plugins/pg_array_associations.rb 323 def def_many_to_pg_array(opts) 324 name = opts[:name] 325 model = self 326 pk = opts[:eager_loader_key] = opts[:primary_key] ||= model.primary_key 327 raise(Error, "no primary key specified for #{inspect}") unless pk 328 opts[:key] = opts.default_key unless opts.has_key?(:key) 329 key = opts[:key] 330 key_column = opts[:key_column] ||= opts[:key] 331 if opts[:uniq] 332 opts[:after_load] ||= [] 333 opts[:after_load].unshift(:array_uniq!) 334 end 335 opts[:dataset] ||= lambda do 336 opts.associated_dataset.where(Sequel.pg_array_op(opts.predicate_key).contains(Sequel.pg_array([get_column_value(pk)], opts.array_type))) 337 end 338 opts[:eager_loader] ||= proc do |eo| 339 id_map = eo[:id_map] 340 341 eager_load_results(opts, Hash[eo].merge!(:loader=>false)) do |assoc_record| 342 if pks ||= assoc_record.get_column_value(key) 343 pks.each do |pkv| 344 next unless objects = id_map[pkv] 345 objects.each do |object| 346 object.associations[name].push(assoc_record) 347 end 348 end 349 end 350 end 351 end 352 353 join_type = opts[:graph_join_type] 354 select = opts[:graph_select] 355 opts[:cartesian_product_number] ||= 1 356 357 if opts.include?(:graph_only_conditions) 358 conditions = opts[:graph_only_conditions] 359 graph_block = opts[:graph_block] 360 else 361 conditions = opts[:graph_conditions] 362 conditions = nil if conditions.empty? 363 graph_block = proc do |j, lj, js| 364 Sequel.pg_array_op(Sequel.deep_qualify(j, key_column)).contains([Sequel.deep_qualify(lj, opts.primary_key)]) 365 end 366 367 if orig_graph_block = opts[:graph_block] 368 pg_array_graph_block = graph_block 369 graph_block = proc do |j, lj, js| 370 Sequel.&(orig_graph_block.call(j,lj,js), pg_array_graph_block.call(j, lj, js)) 371 end 372 end 373 end 374 375 opts[:eager_grapher] ||= proc do |eo| 376 ds = eo[:self] 377 ds = ds.graph(eager_graph_dataset(opts, eo), conditions, Hash[eo].merge!(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block) 378 ds 379 end 380 381 return if opts[:read_only] 382 383 save_opts = {:validate=>opts[:validate]} 384 save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false 385 386 opts[:adder] ||= proc do |o| 387 if array = o.get_column_value(key) 388 array << get_column_value(pk) 389 else 390 o.set_column_value("#{key}=", Sequel.pg_array([get_column_value(pk)], opts.array_type)) 391 end 392 o.save(save_opts) 393 end 394 395 opts[:remover] ||= proc do |o| 396 if (array = o.get_column_value(key)) && !array.empty? 397 array.delete(get_column_value(pk)) 398 o.save(save_opts) 399 end 400 end 401 402 opts[:clearer] ||= proc do 403 pk_value = get_column_value(pk) 404 db_type = opts.array_type 405 opts.associated_dataset.where(Sequel.pg_array_op(key).contains(Sequel.pg_array([pk_value], db_type))).update(key=>Sequel.function(:array_remove, key, Sequel.cast(pk_value, db_type))) 406 end 407 end
def_pg_array_to_many(opts)
click to toggle source
Setup the pg_array_to_many-specific datasets, eager loaders, and modification methods.
# File lib/sequel/plugins/pg_array_associations.rb 410 def def_pg_array_to_many(opts) 411 name = opts[:name] 412 opts[:key] = opts.default_key unless opts.has_key?(:key) 413 key = opts[:key] 414 key_column = opts[:key_column] ||= key 415 opts[:eager_loader_key] = nil 416 if opts[:uniq] 417 opts[:after_load] ||= [] 418 opts[:after_load].unshift(:array_uniq!) 419 end 420 opts[:dataset] ||= lambda do 421 opts.associated_dataset.where(opts.predicate_key=>get_column_value(key).to_a) 422 end 423 opts[:eager_loader] ||= proc do |eo| 424 rows = eo[:rows] 425 id_map = {} 426 pkm = opts.primary_key_method 427 428 rows.each do |object| 429 if associated_pks = object.get_column_value(key) 430 associated_pks.each do |apk| 431 (id_map[apk] ||= []) << object 432 end 433 end 434 end 435 436 eager_load_results(opts, Hash[eo].merge!(:id_map=>id_map)) do |assoc_record| 437 if objects = id_map[assoc_record.get_column_value(pkm)] 438 objects.each do |object| 439 object.associations[name].push(assoc_record) 440 end 441 end 442 end 443 end 444 445 join_type = opts[:graph_join_type] 446 select = opts[:graph_select] 447 opts[:cartesian_product_number] ||= 1 448 449 if opts.include?(:graph_only_conditions) 450 conditions = opts[:graph_only_conditions] 451 graph_block = opts[:graph_block] 452 else 453 conditions = opts[:graph_conditions] 454 conditions = nil if conditions.empty? 455 graph_block = proc do |j, lj, js| 456 Sequel.pg_array_op(Sequel.deep_qualify(lj, key_column)).contains([Sequel.deep_qualify(j, opts.primary_key)]) 457 end 458 459 if orig_graph_block = opts[:graph_block] 460 pg_array_graph_block = graph_block 461 graph_block = proc do |j, lj, js| 462 Sequel.&(orig_graph_block.call(j,lj,js), pg_array_graph_block.call(j, lj, js)) 463 end 464 end 465 end 466 467 opts[:eager_grapher] ||= proc do |eo| 468 ds = eo[:self] 469 ds = ds.graph(eager_graph_dataset(opts, eo), conditions, Hash[eo].merge!(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block) 470 ds 471 end 472 473 return if opts[:read_only] 474 475 save_opts = {:validate=>opts[:validate]} 476 save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false 477 478 if opts[:save_after_modify] 479 save_after_modify = proc do |obj| 480 obj.save(save_opts) 481 end 482 end 483 484 opts[:adder] ||= proc do |o| 485 opk = o.get_column_value(opts.primary_key) 486 if array = get_column_value(key) 487 modified!(key) 488 array << opk 489 else 490 set_column_value("#{key}=", Sequel.pg_array([opk], opts.array_type)) 491 end 492 save_after_modify.call(self) if save_after_modify 493 end 494 495 opts[:remover] ||= proc do |o| 496 if (array = get_column_value(key)) && !array.empty? 497 modified!(key) 498 array.delete(o.get_column_value(opts.primary_key)) 499 save_after_modify.call(self) if save_after_modify 500 end 501 end 502 503 opts[:clearer] ||= proc do 504 if (array = get_column_value(key)) && !array.empty? 505 modified!(key) 506 array.clear 507 save_after_modify.call(self) if save_after_modify 508 end 509 end 510 end