同一张表Gas Orm的多个外键

2022-01-20 00:00:00 sql orm foreign-keys mysql codeigniter

自从今天早上以来,我面临着一个非常大的问题.我正在使用 CodeIgniter 开发网站,并使用 GAS ORM 开发数据库.我基本上有两张桌子.一个名为pool",一个名为partners".我在这两个表之间有两个关联,因此我的表 Partners 中有两个外键引用表池.

Since this mornong i am facing a very big problem. I am using CodeIgniter to develop a website, and GAS ORM for the database. I have basically two tables. One named "pool", and one named "partners". I am having two associations between these two tables, so I have two foreign keys in my table Partners referencing the table pool.

池(#id:整数,名称:varchar)合作伙伴(#id:integer, associated_pool_id=>Pool, futur_associated_pool_id=>Pool).

Pool(#id:integer, name:varchar) Partners(#id:integer, associated_pool_id=>Pool, futur_associated_pool_id=>Pool).

因为我有两个对同一个表的引用,所以我不能将外键命名为pool_id".所以在我与 Gas ORM 的关系中,我必须指定列的名称.我这样做了,但它不起作用......这是我的工作:

As I have two references to the same table, I can't name the foreign keys "pool_id". So in my relationships with Gas ORM, I have to specify the names of the columns. I do it, but it doesn't work... Here is what I do:

class Partner extends ORM {

public $primary_key = 'id';
public $foreign_key = array('\Model\Pool' => 'associated_pool_id', '\Model\Pool' => 'future_associated_pool_id');

function _init()
{

    // Relationship definition
    self::$relationships = array(
            'associated_pool' => ORM::belongs_to('\Model\Pool'),
            'future_association_pool'  => ORM::belongs_to('\Model\Pool'),
    );

    self::$fields = array(
        'id' => ORM::field('auto[11]'),
        'name' => ORM::field('char[255]'),
        'associated_pool_id' => ORM::field('int[11]'),
        'future_associated_pool_id' => ORM::field('int[11]')
    );

}

在我的 Pool 课中:

and in my Pool class :

class Pool extends ORM {

public $primary_key = 'id';

function _init()
{
    // Relationship definition
    self::$relationships = array(
            'associated_partner' => ORM::has_many('\Model\Partner'),
            'future_associated_partner'  => ORM::has_many('\Model\Partner'),
    );

    self::$fields = array(
        'id' => ORM::field('auto[11]'),
        'name' => ORM::field('char[50]'),
    );

}

我有一个测试控制器测试一切是否正常:

I have a test controller testing if everything is okay:

class Welcome extends CI_Controller {
public function index()
{

    $pool = ModelPool::find(1);
    echo $pool->name;
    $partners = $pool->associated_partner();
    var_dump($partners);
}

但我有一个错误说:

错误号:1054

Champ 'partner.pool_id' inconnu dans where 子句

Champ 'partner.pool_id' inconnu dans where clause

SELECT * FROM partner WHERE partner.pool_id IN (1)

SELECT * FROM partner WHERE partner.pool_id IN (1)

我不知道如何向 Gas ORM 指定它不应该采用pool_id"而是associated_pool_id"......

I don't know how to specify to Gas ORM that it shouldn't take "pool_id" but "associated_pool_id"....

感谢您的帮助!!!!!!!!!!!!

Thank you for your help!!!!!!!!!!!!

推荐答案

我不知道,这个话题是否仍然是最新的并且对你们中的一些人来说是有趣的,但总的来说,我遇到了完全相同的问题.

I don't know, if this topic is still up to date and interesting to some of you, but in general, I had the exact same problem.

我决定将 Gas ORM 与 CodeIgniter 结合使用作为我的映射器.由于给出了我的数据库结构并且它没有遵循 Gas 的 table_pk 约定,我必须自己定义一个 外键 来引用我的自定义数据库外键.但是,它的定义对任何事情都没有影响.就像上面的错误一样,映射器无法构建正确的 SQL 语句.该声明与您的声明相似:

I decided Gas ORM to be my mapper in combination with CodeIgniter. As my database structure was given and it was not following the table_pk convention of Gas, I had to define a foreign key by myself which shall refer to my custom database foreign key. However, the definition of it had no impact on anything. Like your error above, the mapper was not able to build the right SQL-statement. The statement looked similar to yours:

   SELECT * FROM partner WHERE partner.pool_id IN (1)

好吧,Gas 似乎忽略了自定义外键并尝试使用默认的 table_pk 约定.这意味着,它通过将表与下划线字符合并来获取表(在您的情况下:池)和主键(id).

Well, it seems like Gas ignores the self-defined foreign keys and tries to use the default table_pk convention. This means, it takes the table (in your case: pool) and the primary key (id) by merging it with a underscore character.

我发现,orm.php 的构造函数处理实体中定义的每个主键和外键.在第 191 行,代码调用了 if 子句与 empty 函数php.由于始终定义主键并且语句中没有否定,因此它每次都跳过子句的内部部分.但是,内部部分负责自定义外键.

I figured out, that the constructor of orm.php handles every primary and foreign key defined within the entities. In line 191, the code calls an if clause combined with the empty function of php. As the primary key is defined always and there is no negation in the statement, it skips the inner part of the clause every time. However, the inner part takes care of the self-defined foreign keys.

长话短说,我在 orm.php 的第 191 行添加了一个否定(!),这导致我得到以下代码:

Long story short, I added a negation (!) in line 191 of orm.php which leads me to the following code:

if ( ! empty($this->primary_key))
    {
        if ( ! empty($this->foreign_key))
        {
            // Validate foreign keys for consistency naming convention recognizer
            $foreign_key = array();

            foreach($this->foreign_key as $namespace => $fk)
            {
                $foreign_key[strtolower($namespace)] = $fk;
            }

            $this->foreign_key = $foreign_key;
        }
        else
        {
            // If so far we didnt have any keys yet, 
            // then hopefully someone is really follow Gas convention
            // while he define his entity relationship (yes, YOU!)
            foreach ($this->meta->get('entities') as $name => $entity)
            {
                if ($entity['type'] == 'belongs_to')
                {
                    $child_name     = $entity['child'];
                    $child_instance = new $child_name;
                    $child_table    = $child_instance->table;
                    $child_key      = $child_instance->primary_key;

                    $this->foreign_key[strtolower($child_name)] = $child_table.'_'.$child_key;
                }
            }
        }
    }

嗯,这个小修复帮助了我很多,我希望你们中的一些人也可以利用这个提示.

Well, this little fix helped me out a lot and I hope some of you can take advantage of this hint as well.

相关文章