N
N
nepster-web2014-05-09 01:31:09
Yii
nepster-web, 2014-05-09 01:31:09

How to fix crutch with relation and where in yii2?

There are 3 tables:
- Articles
- Tags
- Links (Tag-Article)
I had a task to show all entries of a particular tag. I wrote a relation and stumbled upon a problem.
The Articles and Tags tables contain after the URL, so when writing:

$query->innerJoinWith(['tagsAll'])->andWhere(['url'=>$tag]);

An error occurs:
Integrity constraint violation: 1052 Column 'url' in where clause is ambiguous
So I connected the tag model and did something like this:
$query->innerJoinWith(['tagsAll'])->andWhere([Tags::tableName().'.url'=>$tag]);

With this option, everything works. But I just smell in my ass that this is a sloppy crutch. Can you please tell me if there is a better way to solve the problem?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Sergey, 2014-05-09
@nepster-web

The problem is solved by table aliases.
In yii1, by default, the table that goes to from was assigned the alias t, for tables that you register with a join, you can explicitly specify an alias. And then it will be possible to write in where
But in Yii1 there were problems with this. If nothing is joined to the table, then the alias is not assigned, which means that queries where aliases are affixed fall. This was solved in the same way with casters (as well as any Yii problem). Whether they solved this problem in the second branch, I don’t know, but I remember the implementation of AR of the second version was not very far removed from the implementation of the first version. This was one of the reasons I left Yii - the changes were announced over two years ago, only now released.
ps use parameter binding.

N
Nikita Permin, 2014-05-09
@NekitoSP

For relationships of this kind (all records of a tag, or all tags of a record using intermediate tables), you might be better off using viaTable.
for the Article model, getting tags would look like this:

public function getTags()
{
  return $this->hasMany(Tags::className(), ['id' => 'tag_id'])
    ->viaTable('{{%article_tag}}', ['article_id' => 'id']);
}

Well, for the tag (in the Tags model), getting articles using this tag:
public function getArticles()
{
  return $this->hasMany(Article::className(), ['id' => 'article_id'])
    ->viaTable('{{%article_tag}}', ['tag_id' => 'id']);
}

It will be possible to use it like this:
where is $tag - for example $tag = Tags::findOne(['url' => $tag), after findOne, of course, do not forget to check $tag so that if it is missing, you will not get an UnknownPropertyException

S
Sergey, 2014-05-09
@TsarS

I'm sorry, maybe I didn't understand. Is it not possible to first pull out the tags from the url in the controller, and then pass them to the model in which the search will already be done?
$tags = self::find()->where(['like', 'name', $keyword])->all();,
and so on. Or am I not talking about that?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question