2013-11-03 2 views
2

Я хочу реализовать простую полиморфность. Моя цель состоит в том, что пользователь, группа и, возможно, другие модели могут совместно использовать один пул идентификаторов, так что все представляет собой GlobalObject. Я построил что-то вроде этого:«Неизвестный ключ: полиморфный» во время работы rake

  • global_object.rb порожденной $ rails generate scaffold GlobalObject mode:integer:

    class GlobalObject < ActiveRecord::Base 
        attr_accessible :mode 
        has_many :identifyable, :polymorphic => true, :dependent => :destroy 
    end 
    
  • user.rb порожденной $ rails generate scaffold User login password:

    class User < ActiveRecord::Base 
        attr_accessible :login, :password, :salt 
        belongs_to :global_object, :as => :permittable 
    end 
    

и модель группы будет следовать с очень аналогичная структура. Я не изменял файлы переноса из папки db, а просто выполнил $ rake db:migrate.

  • 20131102224115_create_global_objects.rb:

    class CreateGlobalObjects < ActiveRecord::Migration 
        def change 
        create_table :global_objects do |t| 
         t.integer :mode 
         t.timestamps 
        end 
        end 
    end 
    
  • 20131102224332_create_users.rb:

    class CreateUsers < ActiveRecord::Migration 
        def change 
        create_table :users do |t| 
         t.string :login 
         t.string :password 
         t.timestamps 
        end 
        end 
    end 
    

Когда я исполняю $ rake, он показывает две впечатляющие следы с этими началами:

(...)hash/keys.rb:51:in `block in assert_valid_keys': Unknown key: polymorphic (ArgumentError) 
    from /Users(...) 
    ... 

(...)hash/keys.rb:51:in `block in assert_valid_keys': Unknown key: polymorphic (ArgumentError) 
    from /Users(...) 
    ... 

Когда я удаляю :polymorphic => true в global_object.rb, происходят те же ошибки, но вместо Unknown key: polymorphic говорится: Unknown key: as. Что не так?

+0

По крайней мере, вы должны указать свое имя класса, потому что я не вижу никакого идентифицируемого класса. Это должно быть 'has_many: identable,: class_name => 'User',: polymorphic => true, ...' – zishe

+1

@zishe: вся точка полиморфного отношения заключается в том, что он не должен относиться к определенному классу ... – PinnyM

+0

ОК, извините за недоразумение =) – zishe

ответ

2

Есть несколько проблем:

  • Вы пропускаете полиморфные столбцы отношений в вас миграции, следует обратиться к identifyable_id и identifyable_type.
  • Вы имеете в виду полиморфную ассоциацию под разными названиями - identifyable и permittable.
  • Полиморфные отношения предназначены для дочерних элементов (belongs_to) и упоминаются несколькими родительскими классами (has_many). У вас есть другой путь, вокруг которого не поддерживается (и не имеет смысла с точки зрения моделирования).

Было бы полезно понять, что означает GlobalObject, чтобы помочь определить, подходят ли полиморфные ассоциации здесь. Но если вы хотите использовать их, вам нужно либо сделать property_to identable (и добавить туда необходимые столбцы), либо вам нужно будет переместить его на User и добавить туда столбцы.

+0

Затем я должен добавить 'identable_id' и' identable_type' для миграции GlobalObject, не так ли? Поскольку GlobalObject может иметь много пользователей, но пользователь может иметь только один объект GlobalObject. Позже может быть также группа, которая имеет один объект GlobalObject, но GlobalObject может иметь много пользователей и групп. – Tygaz

+0

Исправить все три точки. Я на 99% уверен, что ошибка вызывается, потому что ': polymorphic' не является опцией для' has_many' - просто опция для 'own_to'. – tybro0103

+1

@Tygaz: Нет, это неверно. Сущность, поддерживающая полиморфные ассоциации _must_, использует объявление 'own_to' для определения ассоциации. Это означает, что 'GlobalObject' не может« иметь много »пользователей, как вы его настраиваете. – PinnyM

Смежные вопросы