Yii Relationship (Belongs_To,has_Many) Olayları?

Merhaba arkadaşlar ,

Veritabanında ilişkileri anlamak için bir model deki ilişkileri inceliyorum.Ama bazı tablolara BELONGS_TO olarak bazılarıda HAS_MANY olarak ilişki kurulmuş bunun mantığını anlayan bir vatandaş yardımcı olursa minettar olurum.

has_many biden fazla kayıt içerenler, belongs_to tekil (unique) kayıt içerenler için diyebiliriz.

örneğin:

tablo1: sac_renkleri

id, renk

1, sarı

2, kahverengi

tablo2: insan_ozellikleri

id, irk, sac_rengi

1, alman, 1

2, turk, 2

3, ingiliz, 1

şeklinde 2 tablomuz olsun.

tablo 1 id’yi tablo 2 sac_rengine referans verdiğini düşünelim.

tablo 1 deki id primary key özelliğinde, yani aynı veriden bir başka satırda olamaz.

tablo 2 deki sac_rengi unique değil. yani diğer satılarda da aynı veri girilebilir.

şimdi. tablo 2 deki tüm verileri çekelim. relationadı renk0 olsun.




$model = InsanOzellikleri::model()->with('renk0')->findall();

foreach($model as $m){

   echo '<p>'.$m->irk.' ının saç rengi '.$m->renk0->renk.' dır.</p>';

}

sonuc:

Alman ırkının saç rengi sarı dır.

Turk ırkının saç rengi kahverengi dır.

burda $m->renk0->renk tekil bir sonuç olduğu için tek bir veri dönecektir. bu sebeple relation tipi belongs_to dur.

tam tersini yapalım. saç rengi sarı olan ırkları bulalım.

tablo 1 deki id si 1 olan tüm verileri çekelim. relationadı irks olsun.




$model = SacRenkleri::model()->with('irks')->findbypk(1);

echo 'sac rengi sarı olan ırklar<br />';

foreach($model->irks as $m){

   echo '<p>'.$m->irk.'</p>';

}

burada $model->irks birden fazla veri içerebilir. bu nedenle relation tipi has_many die

sonuç:

saç rengi sarı olan ırklar

Alman

İngiliz

gece vakti ancak bu kadar anlatabildim. umarım açıklayabilmişimdir.

Yani şimdi şöyle diyebilir miyiz?

BELONGS_TO :bir tablo bir tabloya çocuk olurken;(bir tabloya bağlı olan )

HAS_MANY :bir tablo bir tabloya an olurken;(başka bir tablo bu tabloya bağlı) bu ilişkiler vardır gibi düşünebilir miyiz.

2-)

Relation ismi önemli mi yani başka bir tabloya relation adıyla tek mi ulaşılır:örneğin


$model = SacRenkleri::model()->with('irks')->findbypk(1);

echo 'sac rengi sarı olan ırklar<br />';

foreach($model->irks as $m){

   echo '<p>'.$m->irk.'</p>';

}

si<in relation adınız irks

ilk sorunuz için her iki tabloda bir birine bağlı cevabını verebilirim.

ikinci sorunuz için evet relationisimleri önemlidir. bu isimler gii üzerinden model oluşturulurken otomatik tanımlanır.

Arkadaşlar konuşmalarınızdan kafamda bir şeyler oluştu. Ancak sormak istediğim bir şey var. ilişki tablolar için her modelin içinde ayrı ayrı mı Ralationship tanımı yapmak gerekiyor yoksa bir modelinde içinde yaparsak yii bunu anlıyor mu. Bir de ilişkileri tanımlamak için anlayabileceğim şekilde söz dizimini örnekleyebilir misiniz?

Arkadalar merak ettiğim bir şey daha var. Biz mysql veritabanında fiziksel ilişkendirmemi yapacağız yoksa join komutları ile felan mı halledeceğiz bu ilişkilendirmeyi

Veri tabanında ilişkilendirmeni yaptıktan sonra, gii ile model oluştururken ilişkilendirme checkbox!ını seçersen querylerin ilişkilendirmeye hazır olur. Fakat controlerda queryleri gii ilişkili bir şekilde oluşturmaz senin eklemen gerekli.

Örneğin:


$model = Uye::model()->findbyPk($id); // ilişkisiz.

$model = Uye::model()->with('uyebilgi')->findbyPk($id); //ilişkili

With ile denedim ama beceremedim. Ben üye kayıt formun adresin ve nufusun kayıtlı olduğu il ve ilçeyi combo ile seçtiriyorum. İl ve ilçenin idsini veritabanına kaydediyorum. Veri listelerkende Cgridview vw CDetailview de il ve ilçe karşısında id numaraları görünüyor. İd yerine il ve ilçenin ismini yazdırmak istiyorum. Ancak tabloları ilişkilendirdim ama yinede beceremedim. Yardımcı olabilir misiniz?


İller model


public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('ad', 'length', 'max'=>255),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('ilID, ad', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'ilceler' => array(self::HAS_MANY, 'Ilce', 'ilID'),

			'uyelerNufusIli' => array(self::HAS_MANY, 'Uyeler', 'nufus_ili'),

			'uyelersAdresIli' => array(self::HAS_MANY, 'Uyeler', 'adres_ili'),

		);

	}


ilçeler model


public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('ilID', 'numerical', 'integerOnly'=>true),

			array('ad', 'length', 'max'=>255),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('ilceID, ilID, ad', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'iller' => array(self::BELONGS_TO, 'Il', 'ilID'),

			'uyelerNufusIlcesi' => array(self::HAS_MANY, 'Uyeler', 'nufus_ilcesi'),

			'uyelersAdresIlcesi' => array(self::HAS_MANY, 'Uyeler', 'adres_ilcesi'),

		);

	}




Uyeler model


public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('uyeID, adi, soyadi, dogum_yeri, dogum_tarihi, nufus_ili, nufus_ilcesi, anne_adi, baba_adi, meslek, tel, cinsiyet, adres, adres_ili, adres_ilcesi, uye_gorevi, uye_kayit_tarihi, uye_durumu', 'required'),

			array('nufus_ili, nufus_ilcesi, meslek, kan_grubu, cinsiyet, adres_ili, adres_ilcesi, uye_gorevi, uye_durumu', 'numerical', 'integerOnly'=>true),

			array('uyeID, tel', 'length', 'max'=>11),

			array('uye_resim, adres', 'length', 'max'=>255),

			array('e_posta', 'safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('uyeID, adi, soyadi, uye_resim, dogum_yeri, dogum_tarihi, nufus_ili, nufus_ilcesi, anne_adi, baba_adi, meslek, tel, e_posta, kan_grubu, cinsiyet, adres, adres_ili, adres_ilcesi, uye_gorevi, uye_kayit_tarihi, uye_durumu', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'odemeler' => array(self::HAS_MANY, 'Odemeler', 'uyeID'),

            'meslek' => array(self::BELONGS_TO, 'Meslekler', 'meslek'),

			'nufusIli' => array(self::BELONGS_TO, 'Il', 'nufus_ili'),

			'nufusIlcesi' => array(self::BELONGS_TO, 'Ilce', 'nufus_ilcesi'),

			'adresIli' => array(self::BELONGS_TO, 'Il', 'adres_ili'),

			'adresIlcesi' => array(self::BELONGS_TO, 'Ilce', 'adres_ilcesi'),

		);

	}


Uyeler conroller


 public function actionDetayGoster($uyeID)

    {

        $this->render('detayGoster',array(

            'model'=>$this->loadModel($uyeID),

        ));

    }


    public function loadModel($uyeID)

    {




        //$uyeler=Uyeler::model()->with('nufusIli')->findByPk($uyeID);

        $uyeler=Uyeler::model()->findByPk($uyeID);




        if($uyeler===null)

            throw new CHttpException(404,'Aradığınız Sayfa Bulunamadı.');

        return $uyeler;

    }




   




Detay göster.php


h1>Detaylı Üye Bilgisi&nbsp;<br/><?php echo $model->uyeID; ?>&nbsp;<?php echo $model->adi."&nbsp;".$model->soyadi; ?></h1>


<?php $this->widget('zii.widgets.CDetailView', array(

	'data'=>$model,

	'attributes'=>array(

		'uyeID',

		'adi',

		'soyadi',

		'dogum_yeri',

        array(

            'name' => 'dogum_tarihi',

            'type' => 'raw',

            'value' => date("d/m/Y", strtotime($model->dogum_tarihi)),

        ),

		'nufus_ili',

		'nufus_ilcesi',

		'anne_adi',

		'baba_adi',

		'tel',

        array(

            'name'=>'kan_grubu',

            'teyp'=>'raw',

            'value'=>$model->kangrubu(),

                ),

		array(

            'name'=>'cinsiyet',

            'teyp'=>'raw',

            'value'=>(($model->cinsiyet=="1")?"Erkek":"Kadın"),

        ),

		'adres',

		'adres_ilcesi',

		array(

          'name'=>'adres_ili',

          'teyp'=>'raw',

          'value'=>$model->adres_ili,

        ),

        array(

            'name'=>'uye_gorevi',

            'teyp'=>'raw',

            'value'=>$model->uyegorevi(),

        ),

        array(

            'name' => 'uye_kayit_tarihi',

            'type' => 'raw',

            'value' => date("d/m/Y", strtotime($model->uye_kayit_tarihi)),

        ),

        array(

            'name'=>'uye_gorevi',

            'teyp'=>'raw',

            'value'=>(($model->uye_gorevi=="1")?"Aktif":"Pasif"),

        ),

	),

)); ?>



ilişkini yanlış görmediysem.




$model->nufusIli->ad;

$model->nufusIlcesi->ad;



olmalı

CDetailwiew içinde aşağıdaki şekilde kullandım ve yine aşağıda yazdığım hatayı aldım.


	array(

          'name'=>'adres_ili',

          'teyp'=>'raw',

          'value'=>$model->adresIli->ad,

        ),

Aldığım hata ise şu şekilde


include(Il.php): failed to open stream: No such file or directory

Sorunu çözdüm. Sorun relation kısmında tanımlama yaparken iller olması gereken sınıf ismi il şeklinde olduğu için il.php bulunamadı diyordu. iller yaptım şimdi oldu. Gii otomatik oluşturmuştu. class isminde ismini yanlış oluşturmuş sanırım. Tekrar kontol etmek yarar var diye düşünüyorum.

Gii’nin class ismini yanlış olurturması zor bir ihtimal görünüyor. Büyük bir ihtimal daha önce tablo adını güncellemiş ama gii’den tekrar modeli güncellememişsindir…

@McQueen +1