-1

I have one method in several models, implemented in different ways. I only know the name of table in database. I must find model of this table. How to do?

interface BaseIndexedModel
{
    public function writeSometext();
}

and some models implement it. Example

class First extends \yii\db\ActiveRecord implements BaseIndexedModel
{
    public function writeSometext(){
       return "1";
    }
}

class Second extends \yii\db\ActiveRecord implements BaseIndexedModel
{
    public function writeSometext(){
       return "2";
    }
}

Next on a certain event I need to call the desired model and this method. But when I call, I will only know the database table, but not the model.

If table "first", First::writeSometext(); If table "second", Second:: writeSometext();

Mary
  • 37
  • 9
  • if you made model correctly then name is always firstletter capital of tablename – Ahmed Sunny Jan 29 '19 at 15:17
  • Hi! Yes, I know it, but I was still looking for another option. – Mary Jan 29 '19 at 15:54
  • ok but explain the scenerio more why and how you want to use it. – Ahmed Sunny Jan 29 '19 at 16:09
  • I edited the question. – Mary Jan 29 '19 at 16:23
  • i think either you have a list of models somewhere, or the method i told you, because you only know table name from db, so best would be same name as table and model. which is more dynamic – Ahmed Sunny Jan 29 '19 at 16:44
  • Why not crate array which maps AR classes to related tables? – rob006 Jan 29 '19 at 17:25
  • @rob006 because it will be difficult to maintain, constantly append new tables – Mary Jan 30 '19 at 09:08
  • @AhmedSunny I will create a function to which I will transfer the name of the table and from it generate the name of the model. I will process the first letter of the capital and _ simbol in table name... 'tirst' (table) - First (model), 'second_table' - SecondTable (model) etc... – Mary Jan 30 '19 at 09:09
  • yes that what i wwould do – Ahmed Sunny Jan 30 '19 at 09:12
  • ucfirst() use this. if you need help with function, you can add details to question regarding table names – Ahmed Sunny Jan 30 '19 at 09:15
  • Tnx, I think I can do it – Mary Jan 30 '19 at 09:23
  • @AhmedSunny If you want you can make your comment to answer so I would be able to accept it. Thank you for advices! – Mary Jan 30 '19 at 09:25
  • @Mary It should be more flexible and less magic than generating model FQN based on table name (you need to follow strict conventions if you want to support that, which is not always that simple). Adding new entry to models map should not be a big deal when you compare this to creating model class (and probably CRUD) and could be partially automated. – rob006 Jan 30 '19 at 09:43

2 Answers2

0

You can do it this way when you get the table name

public function getModelName($table_name) {
    $table_name = 'first_table';  
    // $table_name = 'first';// if name is single word then comment the next line
    $table_split = explode("_",$table_name);
    $model = ucfirst($table_split[0]).ucfirst($table_split[1]);
    return $model;
}

you can call this function and check if it exists

$model = getModelName($table_name);
var_dump($model);
Ahmed Sunny
  • 2,160
  • 1
  • 21
  • 27
  • yes, but model name is without prefix in Yii, and also he is getting table name, and you can customize this according to your need, you can add an extra step, removing prefix from table name and do the rest – Ahmed Sunny Jan 30 '19 at 14:27
  • Models does not have prefixes, but table names does. This is how Gii generates model name, and it is still not perfect: https://github.com/yiisoft/yii2-gii/blob/60c53d399ebf12cac9b8daa1fa9d81b8b1ee9a91/src/generators/model/Generator.php#L870-L912 – rob006 Jan 30 '19 at 14:44
  • i know, for this question this is fine, but not for all. as i am using different schemas and i cant use crud, yii cant handle it. – Ahmed Sunny Jan 30 '19 at 14:50
0

This one allows you to have 1+ words in the table name. In contrast to the solution posted by Ahmed Sunny, which only works for 2 words.

public function getModelName($tableName) {
    $tableSplit = explode("_",$ruleTableName);
    $className = '';

    foreach ($tableSplit as $word){
        $className .= ucfirst($word);
    }

    return $className;
}
Alfred Landik
  • 454
  • 4
  • 7