Model Relations question, users->friends

I have a user system setup that offers a friends system to the users. The frist table is very simple ( id, user1, user2, status ). I want to setup a relation between the friends and users models but the problem I am facing is that the ID of the user can show up in either the user1 or user2 column of the friends table.

Is it possible to setup a relation that can link the user’s ID to user1 OR user2 of the friends table? Or, is it possible to set user->friends object based on a function that grabs all the users friends? ( I know it is possible but I want to do it the correct way for the Yii framework ).

Any suggestions would be greatly appreciated.

I have the same Problem, i want to model a relationship between users so i can show later all Users who have a certain relation to the current User. So I need for my view an (Active)Dataprovider filled with Users who have the certain relationship to the certain user.

I tried different things but i am failing always, by joining on different attributes.

For now i have my Table User and a Table Relation. So this relationship is normally m:n, so by moddeling this i failed first.

My next step was, focussing on the Relation Table, so I tried to define 1:n relations between the relationclass and the Userclasses by doing:

Relationtable fields: (personfrom, personto, description)




public function relations(){

   return array(

        "knows" => array(self::HAS_ONE, 'Person', 'id'),

        "isknown" => array(self::HAS_ONE, 'Person', 'id'

             'on'=>'personfrom'), //sth like this would be nice to join id with personfrom here

	);

}



So the Problem is, that the Relation always join Relation.personfrom with Person.id and i don’t know how to tell yii to use in the other case Relation.personto with Person.id.

I searched the whole day in the Forum and at the Documentary but i didn’t found anything usefull.

There is an interesting Option here called “on” but i dont know the Syntax. Im hoping that this is the keyword i’m searching for.

Another Opportunity is the join statement but i dont know the syntax here either.

So please help us, this is so important for my current Project.

Thank you

In this case you should write 2 join statment:


JOIN  relations  r1 ON (t.id=r1.user1)

JOIN  person     p1 ON  (p1.id= r1.user2) //whis for select the first category of friends


JOIN  relations  r2 ON (t.id=r2.user2)

JOIN  person     p2 ON  (p2.id= r2.user1) //whis for select the second category of friends



You can set it using the property join.

So if I understand you right, this is the solution to put it in the Dataprovider on the join statement like:




$dataProvider=new CActiveDataProvider('Person',

   array('criteria'=>array(

        'join'=>'JOIN  relations  r1 ON (t.id=r1.user1)

                 JOIN  person     p1 ON  (p1.id= r1.user2)',

   )

));



Or is there a way to implement it as a m:n or at leas 1:n relation, because that would be my favourite to keep the modellogic in the modellayer. But its very annoying that the foreignkey parameter is required. So if nobody has any further ideas i’ll try the join-statement this afternoon, even if its not the way to be in my opinion.

But thank you for your reply

P.S: welcome to the forum (I didn’t noticed the previous post).

I can advice you to use a custom solution for this issue, as it doesn’t seems to be supported by relations.

Approaching to the framework you have the impression that the framework will do all the job, and you will just configure, buy that’s not the true.

The framework will help you to write less code and working faster, but you have to do a lot of work anyway. If you have the doubt that you are going to implement something that already exist in the framework, ask in the forum as you did, and we will help you.

For what is my experience, the easiest solution here is to write 2 lines of sql and do the job, there are no ready helps in the framework for it.

Ok thank you.

Maybe there is an opportunity to extend the framework by an additional Parameter, so its possbile to choose the joined attribute.

I saw somewhere a place to create Tickets for the Yii-Team. Maybe its usefull to add this option to the Yii framework.

But for now I’ll try and use your suggestion.

Thank you very much

Ok so it works!

I put the code into the model so i don’t violate the MVC-Pattern.




public static function getKnownProvider($myid) {

  $knownProvider = new CActiveDataProvider('Person',

	array('criteria'=>array(

	'join'=>'JOIN `person_person` r ON (t.id = r.personto)',

		'condition' => 'r.personfrom = :myid',

		'params'=> array(':myid'=>$myid),

		'order'=>'name ASC',

	  )

	));


	return $knownProvider;

}



I made this method static because i know the id at the controller and i don’t want to create a new user or send a query but it will also work if you put it in object-context and use $this->id instead of $myid.

If this method should only give back an array of known-Users just change $knownProvider into $knownProvider->getData().

So one more thank you to zaccaria!




public function relations(){

   return array(

        "relations" => array(self::HAS_Many, 'person_person', 'personto','condition'=>'personfrom = :myid'),

        );

}