drn1008 2015-06-30 05:31
浏览 54

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

I've been trying to solve this for a few days with no luck.

First a few clarifications:

Basically I want to create relation between "Users" and "Stores", My plan in to identify favorites shops to a particular user and Also from the Store perspective, who shops in one particular store as their favorite shop. My guess was to use a ManyToMany Relation, But after looking for examples about this, many sites describe that if you require a ManyToMany relation with additional fields (in my case I have 3 additional fields) you have to use OneToMany/ManyToOne instead

I'm using SQLITE for my DB just for development and I'm writing REST API in PHP using Slim Framework

Everything works fine when getting a particular entity using something like this.

/**
     * 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;
    }
}

or

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

or

$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 

Once I get any entity i can read their attributes. Except when i try to obtain the:

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

if I try

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

if I try

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

If i understand the call to getShopsAt() should return all instance of "UserStore" entity that match the User id, But I'm not able to access any of its properties. Everything I've tried fails, Also i want to point out that I used the User Id "1" that has 2 entries on the "UserStore" Table. So why is count returning 1.

I've created the 3 Schema using YML format, since i find it to be more clear than PHP.

With these Schema i have created my entities using the command "vendor/bin/doctrine orm:generate-entities ./src" (See resulting entities at the bottom)

Then I create the database schema using vendor/bin/doctrine orm:schema-tool:update --force (See database SQL, and data at the bottom)

After this I have created some data on the Database using the Advaced REST Client extension on Chrome Browser. BUT I've created all of them independently. This mean, First create the Users without setting anything on to shopsAt attribute, then created some Stores without setting anything to the shoppers attribute and then created some UserStores

IMPORTANT QUESTIONS: During the creation of UserStore i have to recover the actual User and Store to set their inversed side of the relation?

or

No just adding the correct keys to the UserStore and Doctrine will do the match during a read of the User/Store, since the creation of UserStore is enough because because it's the Owning side of the relation?

or

I have to manually modify the entity auto generated by the orm:generate-entities command and in the methods setStore and setUser of the UserStore to update the inversed side? as mentioned Here

My database looks like this:

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条回答 默认 最新

  • douyan4470 2015-06-30 22:40
    关注

    When you call:

    $User->getShopsAt()

    you will receive back a single \Doctrine\Common\Collections\ArrayCollection() object which represents an array of results. You can iterate through it like this:

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

    etc., or test how many results like this:

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

    When you were trying to count in your example above, you were wrapping the object in [] for some reason, so it was counting the number of elements in that array - which is 1, a single ArrayCollection object.

    Edit:

    If you really want to use an array, you can do this:

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

    which will convert the ArrayCollection of UserStore objects into a simple array of UserStore objects.

    评论

报告相同问题?

悬赏问题

  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)