Class: Hold::Sequel::PropertyMapper::ForeignKey

Inherits:
Hold::Sequel::PropertyMapper show all
Defined in:
lib/hold/sequel/property_mapper/foreign_key.rb

Overview

Maps to an associated object which is fetched by id from a target repository using a foriegn key column

Instance Attribute Summary collapse

Attributes inherited from Hold::Sequel::PropertyMapper

#property, #property_name, #repository

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Hold::Sequel::PropertyMapper

#post_delete, #post_insert, #post_update, #pre_delete

Constructor Details

#initialize(repo, property_name, options) ⇒ ForeignKey

auto_store_new: where the value for this property is an object without an ID,

automatically store_new the object in the target_repo before trying to store
the object in question with this foreign key property. In the absence of this
setting, values without an ID will cause an exception


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 18

def initialize(repo, property_name, options)
  super(repo, property_name)

  @table = options[:table] || @repository.main_table
  @column_name = options[:column_name] || :"#{property_name}_id"
  @column_alias = :"#{@table}_#{@column_name}"
  @column_qualified = Sequel::SQL::QualifiedIdentifier.new(@table, @column_name)
  @columns_aliases_and_tables_for_select = [
    [@column_qualified],
    [Sequel::SQL::AliasedExpression.new(@column_qualified, @column_alias)],
    [@table]
  ]

  @auto_store_new = options[:auto_store_new] || false
  @model_class = options[:model_class] or raise ArgumentError
end

Instance Attribute Details

#auto_store_newObject (readonly)

Returns the value of attribute auto_store_new.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def auto_store_new
  @auto_store_new
end

#column_aliasObject (readonly)

Returns the value of attribute column_alias.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def column_alias
  @column_alias
end

#column_nameObject (readonly)

Returns the value of attribute column_name.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def column_name
  @column_name
end

#column_qualifiedObject (readonly)

Returns the value of attribute column_qualified.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def column_qualified
  @column_qualified
end

#columns_aliases_and_tables_for_selectObject (readonly)

Returns the value of attribute columns_aliases_and_tables_for_select.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def columns_aliases_and_tables_for_select
  @columns_aliases_and_tables_for_select
end

#model_classObject (readonly)

Returns the value of attribute model_class.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def model_class
  @model_class
end

#tableObject (readonly)

Returns the value of attribute table.



11
12
13
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 11

def table
  @table
end

#target_repoObject

Returns the value of attribute target_repo.



9
10
11
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 9

def target_repo
  @target_repo
end

Class Method Details

.setter_dependencies_for(options = {}) ⇒ Object



4
5
6
7
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 4

def self.setter_dependencies_for(options={})
  features = [*options[:model_class]].map {|klass| [:get_class, klass]}
  {:target_repo => [Hold::IdentitySetRepository, *features]}
end

Instance Method Details

#build_insert_row(entity, table, row, id = nil) ⇒ Object Also known as: build_update_row



57
58
59
60
61
62
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 57

def build_insert_row(entity, table, row, id=nil)
  if @table == table && entity.has_key?(@property_name)
    value = entity[@property_name]
    row[@column_name] = value && value.id
  end
end

#ensure_value_has_id_where_present(value) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 39

def ensure_value_has_id_where_present(value)
  if value && !value.id
    if @auto_store_new
      target_repo.store_new(value)
    else
      raise "value for ForeignKey mapped property #{@property_name} has no id, and :auto_store_new not specified"
    end
  end
end

#load_value(row, id = nil, properties = nil) ⇒ Object



35
36
37
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 35

def load_value(row, id=nil, properties=nil)
  fkey = row[@column_alias] and target_repo.get_by_id(fkey, :properties => properties)
end

#load_values(rows, ids = nil, properties = nil, &b) ⇒ Object

efficient batch load which takes advantage of get_many_by_ids on the target repo



85
86
87
88
89
90
91
92
93
94
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 85

def load_values(rows, ids=nil, properties=nil, &b)
  fkeys = rows.map {|row| row[@column_alias]}
  non_nil_fkeys = fkeys.compact
  non_nil_fkey_results = if non_nil_fkeys.empty? then [] else
    target_repo.get_many_by_ids(non_nil_fkeys, :properties => properties)
  end
  fkeys.each_with_index do |fkey, index|
    yield(fkey ? non_nil_fkey_results.shift : nil, index)
  end
end

#make_filter(value, columns_mapped_to = nil) ⇒ Object

for now ignoring the columns_mapped_to, since Identity mapper is the only one for which this matters at present



68
69
70
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 68

def make_filter(value, columns_mapped_to=nil)
  {@column_qualified => value && value.id}
end

#make_filter_by_id(id, columns_mapped_to = nil) ⇒ Object



76
77
78
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 76

def make_filter_by_id(id, columns_mapped_to=nil)
  {@column_qualified => id}
end

#make_filter_by_ids(ids, columns_mapped_to = nil) ⇒ Object



80
81
82
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 80

def make_filter_by_ids(ids, columns_mapped_to=nil)
  {@column_qualified => ids}
end

#make_multi_filter(values, columns_mapped_to = nil) ⇒ Object



72
73
74
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 72

def make_multi_filter(values, columns_mapped_to=nil)
  {@column_qualified => values.map {|v| v.id}}
end

#pre_insert(entity) ⇒ Object



49
50
51
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 49

def pre_insert(entity)
  ensure_value_has_id_where_present(entity[@property_name])
end

#pre_update(entity, update_entity) ⇒ Object



53
54
55
# File 'lib/hold/sequel/property_mapper/foreign_key.rb', line 53

def pre_update(entity, update_entity)
  ensure_value_has_id_where_present(update_entity[@property_name])
end