Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Class::DBI cascading delete problem?

by zigdon (Deacon)
on Sep 27, 2004 at 14:46 UTC ( [id://394184]=perlquestion: print w/replies, xml ) Need Help??

zigdon has asked for the wisdom of the Perl Monks concerning the following question:

Sounds like this would be a FAQ, but searching on PM, C:DBI list and wiki didn't come up with anything. Say I have the following tables:
org:
  - orgid
  - ...

parttype:
  - typeid
  - orgid
  - ...

orgpart:
  - opid
  - typeid
  - ...

And the C:DBI classes that define the following relationships:

Org->has_many(Parts => [ "PartType" => "parts"]); Org->has_many(Types => "PartType"); PartType->has_a(orgid => "Org"); PartType->has_many(parts => "OrgPart"); OrgPart->has_a(typeid => "PartType");

The problem is that when I try to delete an org, I get the following error: "org is not a column of OrgPart at /usr/lib/perl5/site_perl/5.6.1/Class/DBI/Relationship/HasMany.pm line 61". And to that I say, right, but why is C:DBI looking for it? Shouldn't it make the org object, cascade to it's PartType objects, and from there cascase to all the OrgPart objects that refer to each PartType?

(This is not the actual code, so it's possible something was lose in the translation - even though I did take great case to make sure I got all the relevant parts).

Any suggestions or pointers would be very welcome!

-- zigdon

Replies are listed 'Best First'.
Re: Class::DBI cascading delete problem?
by meredith (Friar) on Sep 27, 2004 at 16:00 UTC

    I can't say I've had the issue you're describing, but I don't have much information to work with. Could you post more of those class definitions and the code involving the delete method? I'm sure that would help the other monks and I to analyze your problem.

    Update: One of CDBI's badly-documented areas is using the has_many method. If you use two parameters, it assumes the field in the right-hand side of the relationship is the class name of the left-hand side. Thus:

    # concise class definitions FooBar->table('foobar'); FooBar->has_many(frobs => "Quux"); Quux->table('quux') #and a method on this FooBar instance... $wham->frobs #makes the (oversimplified SQL query) # SELECT * FROM quux WHERE FooBar = $wham
    If the field name in the RHS is different from the class name of the LHS, you need to use three parameters, the third defining the RHS field name.
    FooBar->has_many(frobs => "Quux", 'foobar_id'); $wham->frobs # makes the (oversimplified SQL query) # SELECT * FROM quux WHERE foobar_id = $wham
    It appears you want to use this second form for your table structure. You did some of the time, but not others, so maybe it's just a mis-copy.

    mhoward - at - hattmoward.org
      It appears you want to use this second form for your table structure. You did some of the time, but not others, so maybe it's just a mis-copy.
      I was under the understanding (perhaps incorrect?) that C:DBI will look for corresponding has_a declerations?
      When setting up the relationship we examine the foreign class's has_a() declarations to discover which of its columns reference our class... If no such has_a() declarations can be found, or none link to us, we assume that it is linking to us via a column named after the moniker() of our class. If this is not true you can pass an additional third argument to the has_many() declaration stating which column of the foreign class references us.

      (from C:DBI Docs)

      -- zigdon

        That must be something new that I haven't dealt with yet. I would stick to the explitit definitions, myself. Maybe you need to change the order, if the above-mentioned checks only happen at definition time, and not when you call the resulting accessor methods.

        mhoward - at - hattmoward.org
Re: Class::DBI cascading delete problem?
by gryphon (Abbot) on Sep 27, 2004 at 16:39 UTC

    Greetings zigdon,

    I'm still learning CBDI myself, so I don't know how helpful this will be. However, here's what I've come up with. I think the problem is with your has_many definitions for Org and PartType. The two lines should be more like:

    __PACKAGE__->has_many('PartTypes' => 'MyCDBI::PartType', 'typeid');

    To solve the problem, I had to rewrite ever so slightly some of your conventions (to help me mentally understand things because I'm still learning CDBI myself), so you'll want to translate this code back. However, here's the final code that does appear to work for me...

      __PACKAGE__->has_many('PartTypes' => 'MyCDBI::PartType', 'typeid');
      Hmm. Either I'm confused, or you are? This means (in the Org package), that the PartType is storing the orgid key in the 'typeid' column? Which is not the same as saying
      __PACKAGE__->has_many('PartTypes' => ['MyCDBI::PartType', 'typeid']);
      Which means
      return map { $_->typeid } $org->PartTypes;
      Or am I confused?

      -- zigdon

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://394184]
Approved by Corion
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2024-04-25 08:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found