• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Programowanie obiektowe - asocjacje

VPS Starter Arubacloud
0 głosów
250 wizyt
pytanie zadane 7 sierpnia 2019 w PHP przez Vincent Nowicjusz (120 p.)

Witam,

Próbuję zrobić rozwiązanie, w którym mam przepis, każdy przepis może mieć wiele kategorii oraz wiele składników. Składniki w danym przepisie mogą mieć różne wartości np. 

Przepis: Jajecznica

Składniki: 

Jajka - 2 (szt.)

Masło - 50 (g)

Próbuję to zrobić na obiektach. I przepis, kategoria i składnik zrobiłem jako encje. Ustawiłem w przepisie asocjacje many to many zarówno dla kategorii, jak i składników. I teraz nie wiem, jak zrobić, żeby wybrany w danym przepisie składnik miał w nim przypisaną wartość. Da się zrobić asocjację kolejnego poziomu? Albo czy trzeba zrobić kolejną encję np. Ilość - i pobierać wszystkie składniki z danego przepisu i tworzyć obiekty ilość, które mają powiązanie z przepisem i składnikiem?

Czy myślę w złym kierunku? I jest prostsze/inne rozwiązanie?

Piszę to w Symfony 3.4.

Poniżej moje encje na ten moment:


namespace App\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;
use Doctrine\Common\Collections\Collection  as Collection;
use App\BlogBundle\Libs\Utils as Utils;
use App\BlogBundle\Entity\Category as Category;
use App\BlogBundle\Entity\Tag as Tag;


/**
 * @ORM\Entity(repositoryClass="App\BlogBundle\Repository\PostRepository")
 * @ORM\Table(name="blog_posts")
 * @ORM\HasLifecycleCallbacks
 * 
 * @UniqueEntity(fields={"title"})
 * @UniqueEntity(fields={"slug"})
 */
class Post {

    const DEFAULT_AVATAR = 'default-thumbnail.png';
    const UPLOAD_DIR = 'uploads/thumbnails/';

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     * 
     * @Assert\NotBlank
     * 
     * @Assert\Length(
     *      max = 120
     * )
     */
    private $title;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     * 
     * @Assert\Length(
     *      max = 120
     * )
     */
    private $slug;
    
    /**
     * @ORM\Column(type="text")
     * 
     * @Assert\NotBlank
     */
    private $content;


    /**
     * @ORM\ManyToMany(
     *      targetEntity = "Category",
     *      inversedBy = "posts"
     * )
     *
     * @ORM\JoinTable(
     *      name = "blog_posts_categories"
     * )
     *
     *
     */
    private $categories;


    /**
     * @ORM\ManyToMany(
     *      targetEntity = "Ingredient",
     *      inversedBy = "posts"
     * )
     * 
     * @ORM\JoinTable(
     *      name = "blog_posts_ingredients"
     * )
     *
     * @Assert\Count(
     *      min=1
     * )
     */
    private $ingredients;


    
    /**
     * @ORM\Column(name="create_date", type="datetime")
     */
    private $createDate;

    
    /**
     * @ORM\Column(name="update_date", type="datetime", nullable=true)
     */
    private $updateDate = null;

    
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->ingredients = new ArrayCollection();
        $this->categories = new ArrayCollection();
    }

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

    /**
     * Set title
     *
     * @param string $title
     * @return Post
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

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

    /**
     * Set slug
     *
     * @param string $slug
     * @return Post
     */
    public function setSlug($slug)
    {
        $this->slug = Utils::sluggify($slug);

        return $this;
    }

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

    /**
     * Set content
     *
     * @param string $content
     * @return Post
     */
    public function setContent($content)
    {
        $this->content = $content;

        return $this;
    }

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



    /**
     * Add category
     *
     * @param Category $category
     *
     * @return Post
     */
    public function addCategory(Category $category)
    {
        $this->categories[] = $category;

        return $this;
    }

    /**
     * Remove category
     *
     * @param Category $category
     */
    public function removeCategory(Category $category)
    {
        $this->categories->removeElement($category);
    }

    /**
     * Get categories
     *
     * @return Collection
     */
    public function getCategories()
    {
        return $this->categories;
    }

    /**
     * Add ingredients
     *
     * @param Ingredient $ingredients
     * @return Post
     */
    public function addIngredient(Tag $ingredients)
    {
        $this->ingredients[] = $ingredients;

        return $this;
    }

    /**
     * Remove ingredients
     *
     * @param Ingredient $ingredients
     */
    public function removeIngredient(Ingredient $ingredients)
    {
        $this->ingredients->removeElement($ingredients);
    }

    /**
     * Get ingredients
     *
     * @return Collection
     */
    public function getIngredients()
    {
        return $this->ingredients;
    }


    /**
     * Set createDate
     *
     * @param \DateTime $createDate
     * @return Post
     */
    public function setCreateDate($createDate)
    {
        $this->createDate = $createDate;

        return $this;
    }

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


    /**
     * Set updateDate
     *
     * @param \DateTime $updateDate
     *
     * @return Post
     */
    public function setUpdateDate($updateDate)
    {
        $this->updateDate = $updateDate;

        return $this;
    }

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

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function preSave(){
        if(null === $this->slug){
            $this->setSlug($this->getTitle());
        }
 
        if(null == $this->createDate){
            $this->createDate = new \DateTime();
        }
    }
    
    /**
     * @ORM\PostPersist
     * @ORM\PostUpdate
     */
    public function postSave(){
       
    }
    
    /**
     * @ORM\PostRemove
     */
    public function postRemove() {
    
    }

    

}

 

namespace App\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;


/**
 * @ORM\Entity(repositoryClass="App\BlogBundle\Repository\CategoryRepository")
 * @ORM\Table(name="blog_categories")
 */
class Category {

/**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     */
    private $name;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     */
    private $slug;

    /**
     * @ORM\ManyToMany(
     *      targetEntity = "Post",
     *      mappedBy = "categories"
     * )
     */
    protected $posts;

/**
     * Constructor
     */
    public function __construct()
    {
        $this->posts = new ArrayCollection();
    }

    public function __toString()
    {
        return (string) $this->name;
    }

    /**
     * Add posts
     *
     * @param Post $posts
     * @return Category
     */
    public function addPost(Post $posts)
    {
        $this->posts[] = $posts;

        return $this;
    }

    /**
     * Remove posts
     *
     * @param Post $posts
     */
    public function removePost(Post $posts)
    {
        $this->posts->removeElement($posts);
    }

    /**
     * Get posts
     *
     * @return Collection
     */
    public function getPosts()
    {
        return $this->posts;
    }

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

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

        return $this;
    }

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

    /**
     * Set slug
     *
     * @param string $slug
     * @return Category
     */
    public function setSlug($slug)
    {
        $this->slug = Utils::sluggify($slug);

        return $this;
    }

    /**
     * Get slug
     *
     * @return string 
     */
    public function getSlug()
    {
        return $this->slug;
    }
    
    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function preSave(){
        if(null === $this->slug){
            $this->setSlug($this->getName());
        }
    }


}
/**
 * @ORM\Entity(repositoryClass="App\BlogBundle\Repository\IngredientRepository")
 * @ORM\Table(name="blog_ingredients")
 */
class Ingredient {

/**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     */
    private $name;
    
    /**
     * @ORM\Column(type="string", length=120, unique=true)
     */
    private $slug;
   
    /**
     * @ORM\ManyToMany(
     *      targetEntity = "Post",
     *      mappedBy = "ingredients"
     * )
     */
    protected $posts;

 /**
     * Constructor
     */
    public function __construct()
    {
        $this->posts = new ArrayCollection();
    }

    public function __toString()
    {
        return (string) $this->name;
    }

    /**
     * Add posts
     *
     * @param Post $posts
     * @return Ingredient
     */
    public function addPost(Post $posts)
    {
        $this->posts[] = $posts;

        return $this;
    }

    /**
     * Remove posts
     *
     * @param Post $posts
     */
    public function removePost(Post $posts)
    {
        $this->posts->removeElement($posts);
    }

    /**
     * Get posts
     *
     * @return Collection
     */
    public function getPosts()
    {
        return $this->posts;
    }

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

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

        return $this;
    }

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

    /**
     * Set slug
     *
     * @param string $slug
     * @return Ingredient
     */
    public function setSlug($slug)
    {
        $this->slug = Utils::sluggify($slug);

        return $this;
    }

    /**
     * Get slug
     *
     * @return string 
     */
    public function getSlug()
    {
        return $this->slug;
    }
    
    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function preSave(){
        if(null === $this->slug){
            $this->setSlug($this->getName());
        }
    }
 

}

 

 

1 odpowiedź

–1 głos
odpowiedź 8 sierpnia 2019 przez Wraith Gaduła (4,370 p.)

Chłopie :) ale żeś kodu nawklejał hihih. Moim zdaniem jesteś w błędzie. Ja to widzę tak:

Tabela Przepis powinna mieć dwie metody

function Category { 
  return oneToMan('Category');
}

function Ingridients {
  return oneToMany('Ingridients');
}

DLaczego tak ? poniewaz dla jednego wybranego przepisu zwroci mi wszystkie kategorie i wszystkie skladniki. Tylko jesli chcesz robic manyTomany msusiz zrobic Pivot tabelke. Dlatego musisz byc tabelka przepisCategoryPivot i PrzepisIngrideientsPivot tam umieszczasz id przepisu i Id skladnika a w drugirj id przepisu i id kategorii

 

1
komentarz 8 sierpnia 2019 przez Ehlert Ekspert (212,630 p.)

Tylko jesli chcesz robic manyTomany msusiz zrobic Pivot tabelke. Dlatego musisz byc tabelka przepisCategoryPivot i PrzepisIngrideientsPivot tam umieszczasz id przepisu i Id skladnika a w drugirj id przepisu i id kategorii

Nic nie musi. Doctrine ma ManyToMany i wszystko dzieje się samo.

komentarz 9 sierpnia 2019 przez Vincent Nowicjusz (120 p.)

@Wraith,   @Ehlert dzięki.

Główne pytanie dotyczyło tego, jak dodać jakby kolejny poziom - czyli

przepisy -> kategorie

przepisy -> składniki -> ilość składnika

Stworzyłem nową encję Quantity - i pobieram wszystkie składniki dla danego przepisu a następnie tworzę obiekty quantity, które mają przypisany dany przepis i składnik, a następnie dodaję jego wartość (czyli ilość danego składnika).

Czy to dobry tok rozumowania?

komentarz 10 sierpnia 2019 przez Wraith Gaduła (4,370 p.)
ja to szczerze nic nie zrozumialem co ty chcesz zrobic.  dla mnie to tabelka przepisy jest glowna tabelka. Jesli przepis ma miec kilka kategorii to do tabelki kateogire - przepisy po srodku powinna byc tabelka pivot laczaca wiele kategorii z danym przepisem czyli mam kategoria - piwot - przepis

pozniej do tabeli przepisy mam pivot ze tabelka skladniki czyli przepisy - pivot - skladniki i tutaj wpisuje do pivota przpeis id i skladnik id i  w pivocie dodaje pole ilosc skladnika i juz

czyi ja bym mial tabelke

kategorie, pivot (kategorie - przepisy), przepisy, skladniki, pivot (skladniki - przepisy) to mi daje 5 tabelek. i tak bym to zrobil
komentarz 12 sierpnia 2019 przez Vincent Nowicjusz (120 p.)
ok, dzięki!

Podobne pytania

0 głosów
1 odpowiedź 225 wizyt
pytanie zadane 18 grudnia 2019 w PHP przez michal_php Stary wyjadacz (13,700 p.)
0 głosów
1 odpowiedź 200 wizyt
pytanie zadane 10 czerwca 2019 w PHP przez michal_php Stary wyjadacz (13,700 p.)
0 głosów
1 odpowiedź 92 wizyt
pytanie zadane 30 maja 2019 w PHP przez michal_php Stary wyjadacz (13,700 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...