Laravel 3: Having difficulty getting my head wrapped around the `has_one()` relationship

StackOverflow https://stackoverflow.com/questions/16925176

Вопрос

Goal:
My goal is to be able to call $entity->legalName()->first() and get the entities legal name.


Models:

#####  Entity  #####  
namespace Entity\Eloquent;
class Entity extends \Eloquent{

     public static $key = 'uuid';

     public function names(){
         return $this->has_many(
                'Entity\Eloquent\EntityName',
                'entity_uuid'
            );
     }

     public function legalName(){
         return $this->has_one(
                'Entity\Eloquent\EntityName',
                'entity_name_id_legal_name'
            );
     }
}

#####  EntityName  #####
namespace Entity\Eloquent;
class EntityName extends \Eloquent{

     /**
      * NOTE:   I've tried a few things, but
      *         currently, this model is empty.
      * /
}


Attempted:

$entity = Entity::find($uuid);
$legalName = $entity->legalName()->get();
echo '<pre>LegalName:<br />',var_dump($legalName),'</pre>';

###########################################
## ERROR:
##    Column not found: 1054 Unknown column 'entity_name_id_legal_name' in 'where clause'
##    SQL: SELECT * FROM `m3sandbox_company_name` WHERE `company_name_id_legal_name` = ?
##    Bindings: array ( 0 => 'a7ae2ea4-b342-11e2-9575-ba8c8f281c14')
###########################################


Also Attempted:
I also tried changing the Entity->legalName() relationship method to:

public function legalName(){
    return $this->has_one
        (
            'Entity\Eloquent\EntityName',
            'id'
        );
}

While the results were different, they were still incorrect:

$entity = Entity::find($uuid);
$legalName = $entity->legalName()->get();
echo '<pre>LegalName:<br />',var_dump($legalName),'</pre>';

###########################################
## prints: null
###########################################


Data Description:
An entity can have N names, so there is a one-to-many relationship between entity.uuid (one) and entity_name.entity_uuid (many).
An entity can only have ONE legal name, though, so there is a one-to-one relationship between entity.entity_name_id_legal_name and entity_name.id.

Data:

INSERT INTO `entity` 
(`uuid`, `entity_name_id_legal_name`, `datetime_created`) 
VALUES
('a7ae2ea4-b342-11e2-9575-ba8c8f281c14', 39657, '2011-06-29 02:12:06');

INSERT INTO `entity_name` 
(`id`, `entity_uuid`, `value`, `datetime_created`) 
VALUES
(516, 'a7ae2ea4-b342-11e2-9575-ba8c8f281c14', 'Bingo', '2011-06-29 02:12:06'),
(3965, 'a7ae2ea4-b342-11e2-9575-ba8c8f281c14', 'Bango', '2013-05-17 00:00:00'),
(39657, 'a7ae2ea4-b342-11e2-9575-ba8c8f281c14', 'Bongo', '2013-05-17 00:00:00');


Summary:
I need to get the entity-has-one-legalName relationship operational.

What am I missing?
Where am I going wrong?

Это было полезно?

Решение

The problem is that in the relationship method, the second parameter to has_one() needs to take the name of the foreign key column in the related table.

I would expect something more like:

 public function legalName(){
     return $this->has_one(
            'Entity\Eloquent\EntityName',
            'entity_id' // Name of column in the entity_names table
        );
 }

In the entity_names table you should have a column called "entity_id" or similar that contains the ID of the Entity that the EntityName.

In short, you are passing a column name from the "entity" table, you SHOULD be passing the column name used in the entity_names table.

If you want to keep your tables laid out how they are now (where the foreign key to the names table is stored in the entities table), you should be using a belongs_to relationship.

public function legalName(){
         return $this->belongs_to(
                'Entity\Eloquent\EntityName',
                'entity_name_id_legal_name' // Name of column in the entities table
            );
     }

The object with "belongs_to" always contains the foreign key in it's table, and the object with "has_one" never contains the foreign key in it's table.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top