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 eo = Hash[eo] 341 eo[:loader] = false 342 343 eager_load_results(opts, eo) do |assoc_record| 344 if pks = assoc_record.get_column_value(key) 345 pks.each do |pkv| 346 id_map[pkv].each do |object| 347 object.associations[name].push(assoc_record) 348 end 349 end 350 end 351 end 352 end 353 354 join_type = opts[:graph_join_type] 355 select = opts[:graph_select] 356 opts[:cartesian_product_number] ||= 1 357 358 if opts.include?(:graph_only_conditions) 359 conditions = opts[:graph_only_conditions] 360 graph_block = opts[:graph_block] 361 else 362 conditions = opts[:graph_conditions] 363 conditions = nil if conditions.empty? 364 graph_block = proc do |j, lj, js| 365 Sequel.pg_array_op(Sequel.deep_qualify(j, key_column)).contains([Sequel.deep_qualify(lj, opts.primary_key)]) 366 end 367 368 if orig_graph_block = opts[:graph_block] 369 pg_array_graph_block = graph_block 370 graph_block = proc do |j, lj, js| 371 Sequel.&(orig_graph_block.call(j,lj,js), pg_array_graph_block.call(j, lj, js)) 372 end 373 end 374 end 375 376 opts[:eager_grapher] ||= proc do |eo| 377 ds = eo[:self] 378 ds = ds.graph(eager_graph_dataset(opts, eo), conditions, eo.merge(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep), &graph_block) 379 ds 380 end 381 382 return if opts[:read_only] 383 384 save_opts = {:validate=>opts[:validate]} 385 save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false 386 387 unless opts.has_key?(:adder) 388 opts[:adder] = proc do |o| 389 if array = o.get_column_value(key) 390 array << get_column_value(pk) 391 else 392 o.set_column_value("#{key}=", Sequel.pg_array([get_column_value(pk)], opts.array_type)) 393 end 394 o.save(save_opts) 395 end 396 end 397 398 unless opts.has_key?(:remover) 399 opts[:remover] = proc do |o| 400 if (array = o.get_column_value(key)) && !array.empty? 401 array.delete(get_column_value(pk)) 402 o.save(save_opts) 403 end 404 end 405 end 406 407 unless opts.has_key?(:clearer) 408 opts[:clearer] = proc do 409 pk_value = get_column_value(pk) 410 db_type = opts.array_type 411 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))) 412 end 413 end 414 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 417 def def_pg_array_to_many(opts) 418 name = opts[:name] 419 opts[:key] = opts.default_key unless opts.has_key?(:key) 420 key = opts[:key] 421 key_column = opts[:key_column] ||= key 422 opts[:eager_loader_key] = nil 423 if opts[:uniq] 424 opts[:after_load] ||= [] 425 opts[:after_load].unshift(:array_uniq!) 426 end 427 opts[:dataset] ||= lambda do 428 opts.associated_dataset.where(opts.predicate_key=>get_column_value(key).to_a) 429 end 430 opts[:eager_loader] ||= proc do |eo| 431 rows = eo[:rows] 432 id_map = {} 433 pkm = opts.primary_key_method 434 435 Sequel.synchronize_with(eo[:mutex]) do 436 rows.each do |object| 437 if associated_pks = object.get_column_value(key) 438 associated_pks.each do |apk| 439 (id_map[apk] ||= []) << object 440 end 441 end 442 end 443 end 444 445 eo = Hash[eo] 446 eo[:id_map] = id_map 447 eager_load_results(opts, eo) do |assoc_record| 448 if objects = id_map[assoc_record.get_column_value(pkm)] 449 objects.each do |object| 450 object.associations[name].push(assoc_record) 451 end 452 end 453 end 454 end 455 456 join_type = opts[:graph_join_type] 457 select = opts[:graph_select] 458 opts[:cartesian_product_number] ||= 1 459 460 if opts.include?(:graph_only_conditions) 461 conditions = opts[:graph_only_conditions] 462 graph_block = opts[:graph_block] 463 else 464 conditions = opts[:graph_conditions] 465 conditions = nil if conditions.empty? 466 graph_block = proc do |j, lj, js| 467 Sequel.pg_array_op(Sequel.deep_qualify(lj, key_column)).contains([Sequel.deep_qualify(j, opts.primary_key)]) 468 end 469 470 if orig_graph_block = opts[:graph_block] 471 pg_array_graph_block = graph_block 472 graph_block = proc do |j, lj, js| 473 Sequel.&(orig_graph_block.call(j,lj,js), pg_array_graph_block.call(j, lj, js)) 474 end 475 end 476 end 477 478 opts[:eager_grapher] ||= proc do |eo| 479 ds = eo[:self] 480 ds = ds.graph(eager_graph_dataset(opts, eo), conditions, eo.merge(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep), &graph_block) 481 ds 482 end 483 484 return if opts[:read_only] 485 486 save_opts = {:validate=>opts[:validate]} 487 save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false 488 489 if opts[:save_after_modify] 490 save_after_modify = proc do |obj| 491 obj.save(save_opts) 492 end 493 end 494 495 unless opts.has_key?(:adder) 496 opts[:adder] = proc do |o| 497 opk = o.get_column_value(opts.primary_key) 498 if array = get_column_value(key) 499 modified!(key) 500 array << opk 501 else 502 set_column_value("#{key}=", Sequel.pg_array([opk], opts.array_type)) 503 end 504 save_after_modify.call(self) if save_after_modify 505 end 506 end 507 508 unless opts.has_key?(:remover) 509 opts[:remover] = proc do |o| 510 if (array = get_column_value(key)) && !array.empty? 511 modified!(key) 512 array.delete(o.get_column_value(opts.primary_key)) 513 save_after_modify.call(self) if save_after_modify 514 end 515 end 516 end 517 518 unless opts.has_key?(:clearer) 519 opts[:clearer] = proc do 520 if (array = get_column_value(key)) && !array.empty? 521 modified!(key) 522 array.clear 523 save_after_modify.call(self) if save_after_modify 524 end 525 end 526 end 527 end