TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
ORM Has Many Through, где foreign_key != primary_key
  • Всем привет. Есть 2 таблицы. table_1 PK id FK gid table_2 PK id И связующая таблица relation_table_1_table_2 PK id FK1 table1_gid FK2 table2_id

    Использую ORM. Связь has_many. protected $_has_many = array( 'relation1' => array( 'model' => 'Table2', 'through' => 'relation_table_1_table_2', 'foreign_key' => 'table1_gid', 'far_key' => 'table2_id', )

    Мне необходимо что бы в качестве внешнего ключа при построении JOIN выступал не PRIMARY KEY , а GID. Я конечно же написал свой велосипед, но теперь я не могу работать со связями с помощью стандартных методов - add(), remove()

    Возможно ли использовать какое-нибуть элегантное решение для данной проблемы что бы в дальнейшем я мог пользоваться add, remove ?

    P.S. Вот здесь, на сколько я понимаю, аналогичная проблема http://forum.kohanaframework.org/discussion/6377/orm-has-many-through-where-primary-keys-are-not-id/p1. Правда ни кто так и не ответил.

    Буду очень благодарен за любую помощь!

  •     /**
         * A post has many tags and categories
         * @var array Relationhips
         */
        protected $_has_many = array(
            'tags' => array(
                'model'   => 'Tag',
                'through' => 'posts_tags',
            ),
            'categories' => array(
                'model'   => 'Category',
                'through' => 'posts_categories',
            ),
        );
    
        /**
         * Post author
         * @var array Relationhips
         */
        protected $_has_one = array(
            'user' => array(
                'model'       => 'User',
                'foreign_key' => 'user_id',
            ),
        );
    

    в двух первых случаях ключ id, во втором user_id

  • В вашем примере используется связь один-к-одному. Я все еще не вижу решения моей проблемы.

  • http://brotkin.ru/2009/04/18/orm-svyazi/ Custom’изация ORM-моделей

    В этой статье описано то, что мне кажется решением. Но в ней говорится о дочерней таблице. У меня же необходимо выбрать GID вместо ID в родительской таблице.

    Возможно я несколько не правильно поставил вопрос.

  • @serieznyi скорректировать пример под свои нужны ты конечно не догадался

  • Млин, таки надо свой кастом ORMa выкладывать в паблик, а то действительно многим эта фича нужна.

  • WinterSilence, во втором случае user_id потому что foreign_key явно указан как user_id. У меня он тоже указан, но при выборке ORM::factory('Table_1', 1)->relation_1->find_all() все равно подставляется PRIMARY_KEY, а не значение из foreign_key который я указал.

    SELECT * FROM table_2 JOIN relation_table_1_table_2 ON (relation_table_1_table_2.table_2_id = table_2.id) WHERE relation_table_1_table_2.table1_gid = '13' В данном случае 13 это PR, а не FK.

  • Видится мне что готового решения нет. Придется переписать парочку ORM методов.

  • far_key задай тогда

  • Задал. Результат 0й. Задав foreign_key я всего лишь указываю имя поля в связывающей таблице которое будет хранить foreign_key родительской таблицы. Я не искал метод который обрабатывает запрос ORM::factory("Table", 1)->relation->find_all(), но если добавлять связь с помощью add() то в теле функции явно берется pk().

  • Недавно решал это проблему, добавив клон модели в которой нужно сменить ключ:

    class Model_Table1clone extends Model_Table1 {
        protected $_primary_key = 'gid';
    
        protected $_has_many = array(
            'relation1' => array(
                'model' => 'Table2',
                'through' => 'relation_table_1_table_2',
                'foreign_key' => 'table1_gid',
                'far_key' => 'table2_id',
            )
    }
    
  • protected $_primary_key = 'gid'; не будет работать, когда Вы сохраните новую запись в таблице, и ORM попытается сохранить в gid значение автоинкрементного поля id.

  • Как мне кажется, тут наиболее правильное решение - это исправить ORM (в методах add/remove/has он вместо pk() должен дергать соответствующие поля исходя из объявления связей) и отправить pull request.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion