Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
One-to-one relations, but reversed
  • Tried explaining this in IRC, but I'm terrible at communicating, so here goes: I have models Person and Address, which are used to contain that information for other models like User, Client, and Employee, etc.
    Sounds pretty simple, right? An Employee would `$_has_one` Person, and that Person would $_has_one Address, right?
    Wrong. Here's why: The ORM requires the models that are being "had-one" to have a FK field referring to the model "having" it. So in the example above, Address would need a field "person_id", and Person would need "employee_id". Thing is, there are other things that I'd like to be able to attach the Person and Address models to, and it doesn't seem right that I'd have to add a field for each one. To get around this, I've been using `$_belongs_to` instead of `$_has_one`, so that the foreign key is being stored in the parent Model. That's been confusing, but was working fine for the most part. But as things have been getting more complex, it's falling apart: cascading actions don't happen in the right order, and so I end up having to manually trigger saves and deletes in the right order. Not cool. Yes, Fuel's ORM does allow you to specify foreign keys, in case that's what you're screaming at the monitor right now. But it doesn't allow you to do what would be required for a has-one to work the way I need it to:
    protected static $_has_one = array(
      'person' => array(
       'key_from' => 'person_id',
       'key_to' => 'id',
       'cascade_save' => true,
       'cascade_delete' => true,
      )
     );
    
    ORM complains that the primary key cannot be modified, and thus this configuration doesn't work. I think it should, but I'm open to enlightenment.
  • I may be wrong, but you might want to be using the $_has_one and $_belongs_to . A person would have one address, and an address would belong to the person.
  • Wow, like I said, I'm bad at communicating, but am I really THAT bad? I'm talking about $_has_one and $_belongs to throughout the post.
  • Would it be better to have a structure more like this?
    - Person
    -- (has one) --
    -- Client, User or Employee
    -- (has many)
    -- Addresses
    

    Person would have client_id, user_id, employee_id.
    And Client, User, Employee and Address would have person_id. Add 'type' to Address so it can be identified as either, client, user or employee. Then you could use nested relations to call any from anywhere. A Person would be the base of all, not the other way around. Person holds all of the information. Client, User and Employee adds relevant information to the Person model... and addresses are attached per person, not per Client, User or Employee... but they could still be matched to the 'type' of Model they need to be identified with... This way you could use
    Model_Person::find('first')->where('id', $id)->related('client')->related('addresses')->get_one();
    

    Would that make sense, sorry if I'm not fully following what you need.
  • Frank Bardon wrote on Tuesday 26th of July 2011:
    Would it be better to have a structure more like this?
    - Person
    -- (has one) --
    -- Client, User or Employee
    -- (has many)
    -- Addresses
    

    Person would have client_id, user_id, employee_id.
    And Client, User, Employee and Address would have person_id. Add 'type' to Address so it can be identified as either, client, user or employee. Then you could use nested relations to call any from anywhere. A Person would be the base of all, not the other way around. Person holds all of the information. Client, User and Employee adds relevant information to the Person model... and addresses are attached per person, not per Client, User or Employee... but they could still be matched to the 'type' of Model they need to be identified with... This way you could use
    Model_Person::find('first')->where('id', $id)->related('client')->related('addresses')->get_one();
    

    Would that make sense, sorry if I'm not fully following what you need.

    Because when you think of it... they are all people. And the people have the addresses, not the titles they hold.
  • And in the future, there is no reason at all to be rude to the people who are trying to help you.
  • A little off topic: I've always learned to try not to use one-to-one relations. If you think you need that relation, you can just add extra columns in the main table.
  • Peter, that's exactly what a one-to-one relationship is.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion