Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a8670166

Von Moritz Bunkus vor mehr als 12 Jahren hinzugefügt

  • ID a867016676febc197579586e202ddaac84bb7d50
  • Vorgänger f1d475ff
  • Nachfolger 7beb1ac3

Primärschlüsselspaltennamen aus Meta-Informationen holen

Benutzerdefinierte Variablen verweisen auf die Primärschlüsselspalte
ihrer Bezugstabelle. Dieser Spaltenname kann beim Helper mit der
Option 'id' überschrieben werden. Allerdings defaultete er vorher auf
'id', was für viele Tabellen stimmte, nicht aber z.B. für 'contacts',
wo es die Spalte 'cp_cv_id' ist.

Für 'contacts' passierte dann Folgendes, wenn man
'$contact->custom_variables' aufrief:

Die Funktion 'custom_variables' ist eine one-to-many-Relation, sie
erfordert also einen DB-Zugriff. Dafür wird die Spaltenbeziehung
'cvar.trans_id == contacts.primary_key_column_name' herangezogen. Der
'primary_key_column_name' ist nicht angegeben, Defaultwert ist
'id'. RDBO versucht also, die Spalte 'id' aus dem Objekt '$contact'
auszulesen, mappt dafür den Spaltennamen auf den Methodennamen dafür.

Dieses Mapping liefert den leeren String. Das überprüft RDBO in dem
Moment aber nicht, sondern ruft "$object->$method()" auf. Das wirft
eine Exception, RDBO fängt diese ab, überprüft dann, ob '$AUTOLOAD'
einen Paketnamen enthält. Und dann kommt diese wenig erhellende
Fehlermeldung heraus:

Can't locate object method "Contact::" via package "SL::DB" at /usr/share/perl5/Rose/DB/Object.pm line 1646

Unterschiede anzeigen:

SL/DB/Helper/CustomVariables.pm
18 18

  
19 19
  $params{module}     ||= _calc_modules_from_overloads(%params) if $params{overloads};
20 20
  $params{sub_module} ||= '';
21
  $params{id}         ||= 'id';
21
  $params{id}         ||= _get_primary_key_column($caller_package);
22 22

  
23 23
  $params{module} || $params{sub_module}  or croak 'need param module or sub_module';
24 24

  
......
51 51
    custom_variables => {
52 52
      type         => 'one to many',
53 53
      class        => 'SL::DB::CustomVariable',
54
      column_map   => { ($params{id} || 'id') => 'trans_id' },
54
      column_map   => { $params{id} => 'trans_id' },
55 55
      query_args   => [ sub_module => $params{sub_module}, @module_filter ],
56 56
    }
57 57
  );
......
165 165
  return [ keys %modules ];
166 166
}
167 167

  
168
sub _get_primary_key_column {
169
  my ($caller_package) = @_;
170
  my $meta             = $caller_package->meta;
171

  
172
  my $column_name;
173
  $column_name = $meta->{primary_key}->{columns}->[0] if $meta->{primary_key} && (ref($meta->{primary_key}->{columns}) eq 'ARRAY') && (1 == scalar(@{ $meta->{primary_key}->{columns} }));
174

  
175
  croak "Unable to retrieve primary key column name: meta information for package $caller_package not set up correctly" unless $column_name;
176

  
177
  return $column_name;
178
}
168 179

  
169 180
1;
170 181

  

Auch abrufbar als: Unified diff