教义一对多/多对一。不工作

时间:2015-06-30 05:31:32

标签: php orm doctrine-orm

我一直试图解决这个问题几天没有运气。

首先澄清几点:

基本上我想在"用户"之间创建关系。和"商店",我计划识别特定用户的收藏商店,并且从商店的角度来看,谁在一个特定商店购物作为他们最喜欢的商店。 我的猜测是使用ManyToMany关系,但在查找了关于此的示例之后,许多网站描述如果你需要与其他字段的ManyToMany关系(在我的情况下我有3个额外的字段)你必须使用OneToMany / ManyToOne

我正在使用SQLITE为我的数据库进行开发,并且我使用Slim Framework在PHP中编写REST API

使用类似的东西获取特定实体时,一切正常。

/**
     * Fetching user by email
     * @param String $email User email
     */
    public function getUserByEmail($email) {
    $user = $this->getEntityManager()->getRepository('User')
                                     ->findOneBy(array('email' => $email));
    if ($user === null) {
        return null;
    } else {
        return $user;
    }
}

$ProductStore = $this->getEntityManager()->getRepository('ProductStore')
                      ->findOneBy(array('product' => $product, 
                                        'store' => $store));

$Store = $this->getEntityManager()->getRepository('Store')
                      ->findOneBy(array('state' => $State->getId(), 
                                        'city' => $City->getId(),
                                        'streetname' => $streetname,
                                        'streetnumber' => $streetnumber));

//Store has many ManyToOne relations to other Entities 
//like State or City, but all of them works as expected 

一旦我得到任何实体,我就可以阅读他们的属性。除非我试图获得:

echo $User->getShopsAt(); i get an error saying "Object of class Doctrine\ORM\PersistentCollection could not be converted to string"

如果我尝试

echo [$User->getShopsAt()]; i get "Array" as reponse

如果我尝试

echo count([$User->getShopsAt()]); i get 1

如果我理解对getShopsAt()的调用应返回" UserStore"的所有实例。与用户ID匹配的实体,但我无法访问其任何属性。 我尝试过的所有内容都失败了,我还想指出我使用了用户ID" 1"在" UserStore"上有2个条目;表。那么为什么计数返回1。

我使用YML格式创建了3个Schema,因为我发现它比PHP更清晰。

使用这些Schema,我使用命令" vendor / bin / doctrine orm:generate-entities ./src"创建了我的实体。 (请参阅底部的结果实体)

然后我使用vendor / bin / doctrine orm创建数据库模式:schema-tool:update --force (参见数据库SQL和底部的数据)

在此之后,我使用Chrome浏览器上的Advaced REST Client扩展程序在数据库上创建了一些数据。但我已经独立创造了所有这些。这意味着,首先创建用户而不在店铺属性上设置任何内容,然后创建一些商店而不向购物者属性设置任何内容然后创建一些用户商店

重要问题: 在创建UserStore期间,我必须恢复实际的用户和商店以设置它们的关系的反面?

不只是将正确的密钥添加到UserStore和Doctrine将在读取用户/商店期间进行匹配,因为创建UserStore就足够了,因为它是关系的Owning方面吗?

我必须手动修改orm:generate-entities命令自动生成的实体,并在UserStore的方法setStore和setUser中更新反向端?如上所述Here

我的数据库如下所示:

USER:

CREATE TABLE users (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, email VARCHAR(50) NOT NULL, password_hash VARCHAR(255) NOT NULL, api_key VARCHAR(32) NOT NULL, status INTEGER NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL, PRIMARY KEY(id))

ROW 1 = "1","user1","user1@mail.com","xxxxxxxxxxxxxxxx","yyyyyyyyyyyyyy","1","2015-06-27 17:16:01","2015-06-27 17:16:01"
ROW 2 = "2","user2","user2@mail.com","xxxxxxxxxxxxxxxx","yyyyyyyyyyyyyy","1","2015-06-27 17:38:36","2015-06-27 17:38:36"

STORE:

CREATE TABLE stores (id INTEGER NOT NULL, brand_id INTEGER DEFAULT NULL, neighborhood_id INTEGER DEFAULT NULL, county_id INTEGER DEFAULT NULL, city_id INTEGER DEFAULT NULL, state_id INTEGER DEFAULT NULL, streetname VARCHAR(255) NOT NULL COLLATE BINARY, streetnumber VARCHAR(255) NOT NULL COLLATE BINARY, cp VARCHAR(255) NOT NULL COLLATE BINARY, lat VARCHAR(255) NOT NULL COLLATE BINARY, lng VARCHAR(255) NOT NULL COLLATE BINARY, favorite INTEGER NOT NULL, status INTEGER NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_D5907CCC44F5D008 FOREIGN KEY (brand_id) REFERENCES brands (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_D5907CCC803BB24B FOREIGN KEY (neighborhood_id) REFERENCES neighborhoods (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_D5907CCC85E73F45 FOREIGN KEY (county_id) REFERENCES counties (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_D5907CCC8BAC62AF FOREIGN KEY (city_id) REFERENCES cities (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_D5907CCC5D83CC1 FOREIGN KEY (state_id) REFERENCES states (id) NOT DEFERRABLE INITIALLY IMMEDIATE)

ROW 1 = "1","1","1","1","1","1","streetname 1","11111","1234","0.0000000","1.1111111","1","1","2015-06-06 02:32:19","2015-06-06 02:32:19"
ROW 2 = "2","4","2","2","2","2","streetname 2","2222","1234","0.000000","1.000000","0","1","2015-06-27 17:50:24","2015-06-27 17:50:24"

USERSTORE:

CREATE TABLE UsersStores (user_id INTEGER NOT NULL, store_id INTEGER NOT NULL, status INTEGER NOT NULL, createdAt DATETIME NOT NULL, updatedAt DATETIME NOT NULL, PRIMARY KEY(user_id, store_id), CONSTRAINT FK_39EFBEF8A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_39EFBEF8B092A811 FOREIGN KEY (store_id) REFERENCES stores (id) NOT DEFERRABLE INITIALLY IMMEDIATE)

VALUES:
ROW 1 = "2","1","1","2015-06-28 17:51:40","2015-06-28 17:51:40"
ROW 2 = "1","2","1","2015-06-28 17:51:51","2015-06-28 17:51:51"
ROW 3 = "1","1","1","2015-06-28 20:51:53","2015-06-28 20:51:53"



User:
  type: entity
  table: users

  id:
    id:
      type: integer
      generator:
        strategy: auto
  fields:
    name:
      type: string(255)
    email:
      type: string(50)
    password_hash:
      type: string(255)
    api_key:
      type: string(32)
    status:
      type: integer(1)
    createdAt:
      type: datetime
    updatedAt:
      type: datetime

  oneToMany:
    shopsAt:
      targetEntity: UserStore
      mappedBy: product

///////////////////////////////////

Store:
  type: entity
  table: stores
  id:
    id:
      type: integer
      generator:
        strategy: AUTO
  fields:
    streetname:
      type: string
    streetnumber:
      type: string(255)
    cp:
      type: string(255)
    lat:
      type: string(255)
    lng:
      type: string(255)
    favorite:
      type: integer(1)
    status:
      type: integer(1)
    createdAt:
      type: datetime
    updatedAt:
      type: datetime

  oneToMany:
    productsAvailable:
      targetEntity: ProductStore
      mappedBy: store
    shoppers:
      targetEntity: UserStore
      mappedBy: store

  manyToOne:
    brand:
      targetEntity: Brand
      joinColumn:
        name: brand_id
        referencedColumnName: id
    neighborhood:
      targetEntity: Neighborhood
      joinColumn:
        name: neighborhood_id
        referencedColumnName: id
    county:
      targetEntity: County
      joinColumn:
        name: county_id
        referencedColumnName: id
    city:
      targetEntity: City
      joinColumn:
        name: city_id
        referencedColumnName: id
    state:
      targetEntity: State
      joinColumn:
        name: state_id
        referencedColumnName: id


//////////////////////////////////////

UserStore:
  type: entity
  table: UsersStores

  id:
    user:
      associationKey: true
    store:
      associationKey: true
  fields:
    status:
      type: integer(1)
    createdAt:
      type: datetime
    updatedAt:
      type: datetime

  manyToOne:
    user:
      targetEntity: User
      inversedBy: shopsAt
      joinColumn:
        name: user_id
        referencedColumnName: id
    store:
      targetEntity: Store
      inversedBy: shoppers
      joinColumn:
        name: store_id
        referencedColumnName: id


//////////////////////////////////////

use Doctrine\ORM\Mapping as ORM;

/**
 * User
 */
class User
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $email;

    /**
     * @var string
     */
    private $password_hash;

    /**
     * @var string
     */
    private $api_key;

    /**
     * @var integer
     */
    private $status;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return User
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set password_hash
     *
     * @param string $passwordHash
     * @return User
     */
    public function setPasswordHash($passwordHash)
    {
        $this->password_hash = $passwordHash;

        return $this;
    }

    /**
     * Get password_hash
     *
     * @return string 
     */
    public function getPasswordHash()
    {
        return $this->password_hash;
    }

    /**
     * Set api_key
     *
     * @param string $apiKey
     * @return User
     */
    public function setApiKey($apiKey)
    {
        $this->api_key = $apiKey;

        return $this;
    }

    /**
     * Get api_key
     *
     * @return string 
     */
    public function getApiKey()
    {
        return $this->api_key;
    }

    /**
     * Set status
     *
     * @param integer $status
     * @return User
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return User
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return User
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $shopsAt;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->shopsAt = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add shopsAt
     *
     * @param \UserStore $shopsAt
     * @return User
     */
    public function addShopsAt(\UserStore $shopsAt)
    {
        $this->shopsAt[] = $shopsAt;

        return $this;
    }

    /**
     * Remove shopsAt
     *
     * @param \UserStore $shopsAt
     */
    public function removeShopsAt(\UserStore $shopsAt)
    {
        $this->shopsAt->removeElement($shopsAt);
    }

    /**
     * Get shopsAt
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getShopsAt()
    {
        return $this->shopsAt;
    }
}

///////////////////////////////////////

use Doctrine\ORM\Mapping as ORM;

/**
 * Store
 */
class Store
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $streetname;

    /**
     * @var string
     */
    private $streetnumber;

    /**
     * @var string
     */
    private $cp;

    /**
     * @var string
     */
    private $lat;

    /**
     * @var string
     */
    private $lng;

    /**
     * @var integer
     */
    private $favorite;

    /**
     * @var integer
     */
    private $status;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $productsAvailable;

    /**
     * @var \Brand
     */
    private $brand;

    /**
     * @var \Neighborhood
     */
    private $neighborhood;

    /**
     * @var \County
     */
    private $county;

    /**
     * @var \City
     */
    private $city;

    /**
     * @var \State
     */
    private $state;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->productsAvailable = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set streetname
     *
     * @param string $streetname
     * @return Store
     */
    public function setStreetname($streetname)
    {
        $this->streetname = $streetname;

        return $this;
    }

    /**
     * Get streetname
     *
     * @return string 
     */
    public function getStreetname()
    {
        return $this->streetname;
    }

    /**
     * Set streetnumber
     *
     * @param string $streetnumber
     * @return Store
     */
    public function setStreetnumber($streetnumber)
    {
        $this->streetnumber = $streetnumber;

        return $this;
    }

    /**
     * Get streetnumber
     *
     * @return string 
     */
    public function getStreetnumber()
    {
        return $this->streetnumber;
    }

    /**
     * Set cp
     *
     * @param string $cp
     * @return Store
     */
    public function setCp($cp)
    {
        $this->cp = $cp;

        return $this;
    }

    /**
     * Get cp
     *
     * @return string 
     */
    public function getCp()
    {
        return $this->cp;
    }

    /**
     * Set lat
     *
     * @param string $lat
     * @return Store
     */
    public function setLat($lat)
    {
        $this->lat = $lat;

        return $this;
    }

    /**
     * Get lat
     *
     * @return string 
     */
    public function getLat()
    {
        return $this->lat;
    }

    /**
     * Set lng
     *
     * @param string $lng
     * @return Store
     */
    public function setLng($lng)
    {
        $this->lng = $lng;

        return $this;
    }

    /**
     * Get lng
     *
     * @return string 
     */
    public function getLng()
    {
        return $this->lng;
    }

    /**
     * Set favorite
     *
     * @param integer $favorite
     * @return Store
     */
    public function setFavorite($favorite)
    {
        $this->favorite = $favorite;

        return $this;
    }

    /**
     * Get favorite
     *
     * @return integer 
     */
    public function getFavorite()
    {
        return $this->favorite;
    }

    /**
     * Set status
     *
     * @param integer $status
     * @return Store
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Store
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return Store
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Add productsAvailable
     *
     * @param \ProductStore $productsAvailable
     * @return Store
     */
    public function addProductsAvailable(\ProductStore $productsAvailable)
    {
        $this->productsAvailable[] = $productsAvailable;

        return $this;
    }

    /**
     * Remove productsAvailable
     *
     * @param \ProductStore $productsAvailable
     */
    public function removeProductsAvailable(\ProductStore $productsAvailable)
    {
        $this->productsAvailable->removeElement($productsAvailable);
    }

    /**
     * Get productsAvailable
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getProductsAvailable()
    {
        return $this->productsAvailable;
    }

    /**
     * Set brand
     *
     * @param \Brand $brand
     * @return Store
     */
    public function setBrand(\Brand $brand = null)
    {
        $this->brand = $brand;

        return $this;
    }

    /**
     * Get brand
     *
     * @return \Brand 
     */
    public function getBrand()
    {
        return $this->brand;
    }

    /**
     * Set neighborhood
     *
     * @param \Neighborhood $neighborhood
     * @return Store
     */
    public function setNeighborhood(\Neighborhood $neighborhood = null)
    {
        $this->neighborhood = $neighborhood;

        return $this;
    }

    /**
     * Get neighborhood
     *
     * @return \Neighborhood 
     */
    public function getNeighborhood()
    {
        return $this->neighborhood;
    }

    /**
     * Set county
     *
     * @param \County $county
     * @return Store
     */
    public function setCounty(\County $county = null)
    {
        $this->county = $county;

        return $this;
    }

    /**
     * Get county
     *
     * @return \County 
     */
    public function getCounty()
    {
        return $this->county;
    }

    /**
     * Set city
     *
     * @param \City $city
     * @return Store
     */
    public function setCity(\City $city = null)
    {
        $this->city = $city;

        return $this;
    }

    /**
     * Get city
     *
     * @return \City 
     */
    public function getCity()
    {
        return $this->city;
    }

    /**
     * Set state
     *
     * @param \State $state
     * @return Store
     */
    public function setState(\State $state = null)
    {
        $this->state = $state;

        return $this;
    }

    /**
     * Get state
     *
     * @return \State 
     */
    public function getState()
    {
        return $this->state;
    }
    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $shoppers;


    /**
     * Add shoppers
     *
     * @param \UserStore $shoppers
     * @return Store
     */
    public function addShopper(\UserStore $shoppers)
    {
        $this->shoppers[] = $shoppers;

        return $this;
    }

    /**
     * Remove shoppers
     *
     * @param \UserStore $shoppers
     */
    public function removeShopper(\UserStore $shoppers)
    {
        $this->shoppers->removeElement($shoppers);
    }

    /**
     * Get shoppers
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getShoppers()
    {
        return $this->shoppers;
    }
}


//////////////////////////////////////////////////


use Doctrine\ORM\Mapping as ORM;

/**
 * UserStore
 */
class UserStore
{
    /**
     * @var integer
     */
    private $status;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var \User
     */
    private $user;

    /**
     * @var \Store
     */
    private $store;


    /**
     * Set status
     *
     * @param integer $status
     * @return UserStore
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer 
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return UserStore
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return UserStore
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set user
     *
     * @param \User $user
     * @return UserStore
     */
    public function setUser(\User $user)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \User 
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set store
     *
     * @param \Store $store
     * @return UserStore
     */
    public function setStore(\Store $store)
    {
        $this->store = $store;

        return $this;
    }

    /**
     * Get store
     *
     * @return \Store 
     */
    public function getStore()
    {
        return $this->store;
    }

}

1 个答案:

答案 0 :(得分:0)

致电时:

  

$用户 - > getShopsAt()

您将收到一个\ Doctrine \ Common \ Collections \ ArrayCollection()对象,它代表一组结果。您可以像这样迭代它:

foreach ($User->getShopsAt() as $user_store) {
   echo $user_store->getStatus();
   echo $user_store->getCreate at();
}

等,或者测试这样的结果:

$User->getShopsAt()->count()
count($User->getShopsAt()) <-- note I am NOT wrapping it in []

当您尝试在上面的示例中进行计数时,由于某种原因,您将对象包装在[]中,因此它计算了该数组中的元素数量 - 即1,一个ArrayCollection对象。

编辑:

如果你真的想使用数组,你可以这样做:

$user->getShopsAt()->toArray()

将UserStore对象的ArrayCollection转换为UserStore对象的简单数组。