Я пытаюсь определить несколько полиморфных отношений (has_many_polymorphs plugin) от одного родителя к одним и тем же дочерним элементам.

У заметки много читателей
У Note много редакторов
Зрители могут быть либо пользователями, либо группами
Редакторы могут быть либо пользователями, либо группами
Разрешение — это модель ассоциации с полями note_id, viewer_id, viewer_type, editor_id, editor_type.

Все работает так, как и ожидалось, пока у меня есть только одно отношение has_many_polymorphs, определенное в модели Note.

class User < ActiveRecord::Base; end
class Group < ActiveRecord::Base; end

class Note < ActiveRecord::Base
    has_many_polymorphs :viewers, :through => :permissions, :from => [:users, :groups]
end

class Permission < ActiveRecord::Base
    belongs_to :note
    belongs_to :viewer, :polymorphic => true
end


Note.first.viewers << User.first # =>  [#<User id: 1, ....>]
Note.first.viewers << Group.first # =>  [#<User id: 1, ....>, #<Group ...>]
Note.first.viewers.first # => #<User ....>
Note.first.viewers.second # => #<Group ....>

Теперь проблемы начинают появляться, когда я добавляю второе отношение

class Note < ActiveRecord::Base
    has_many_polymorphs :viewers, :through => :permissions, :from => [:users, :groups]
    has_many_polymorphs :editors, :through => :permissions, :from => [:users, :groups]
end

class Permission < ActiveRecord::Base
    belongs_to :note
    belongs_to :viewer, :polymorphic => true
    belongs_to :editor, :polymorphic => true
end

Note.first.viewers << User.first # => [#<User id: ....>]

# >>>>>>>>
Note.first.editors << User.first

NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.constantize
... vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb:18:in `instantiate'

Я пытался уточнить определение has_many_polymorphs, но это не сработало. Даже с моделью STI для ViewPermission < Permission и EditPermission < Permission.

Приветствуются любые мысли/обходные пути/указатели проблем.

Рельсы 2.3.0

0
tamersalama 11 Июн 2009 в 23:46
Я думаю, вам нужно добавить некоторые знаки препинания во втором абзаце...
 – 
Jason Punyon
11 Июн 2009 в 23:49

2 ответа

Вам не нужно добавлять

has_many :permissions

К вашей заметке. к вашему сведению. Я использовал has_many_polymorphs один раз, но затем бросил его, он не работал должным образом.

Можете ли вы опубликовать схему, которую вы используете для разрешения? Я предполагаю, что корень проблемы лежит там, вам нужно иметь несколько пар типов и идентификаторов в схеме, поскольку у вас есть два разных belongs_to в определении.

Редактировать:

Я вижу, вы также разместили вопрос на github. Не уверен, что вы пытались использовать двухсторонний полиморфизм. Вы, вероятно, слышали... как я уже сказал, меня не впечатлил этот плагин, так как он вызывал некоторую нестабильность, когда я его использовал.

== Double-sided polymorphism

Double-sided relationships are defined on the join model:

      class Devouring < ActiveRecord::Base
        belongs_to :guest, :polymorphic => true
        belongs_to :eaten, :polymorphic => true

        acts_as_double_polymorphic_join(
          :guests =>[:dogs, :cats], 
          :eatens => [:cats, :birds]
        )       
      end


Now, dogs and cats can eat birds and cats. Birds can't eat anything (they aren't <tt>guests</tt>) and dogs can't be 
eaten by anything (since they aren't <tt>eatens</tt>). The keys stand for what the models are, not what they do. 
0
Ryan Oberoi 12 Июн 2009 в 01:21
has_many :permissions не требуется. Схема, описанная во втором абзаце, выглядит следующим образом: целое число :note_id целое число :viewer_id строка :viewer_type целое число :editor_id строка :editor_type
 – 
tamersalama
12 Июн 2009 в 00:21
Спасибо, Райан - да - я опубликовал на github как проблему (github.com/fauna/ has_many_polymorphs/issues/#issue/3) Я не уверен, что двусторонние отношения будут работать. Насколько я понимаю, они предназначены для полиморфных родительских отношений. то есть: вместо того, чтобы иметь только Note в качестве родителя, я мог бы также сказать Post в качестве родителя; что сделало бы его двусторонним полиморфизмом. Заметка может иметь либо пользовательское, либо групповое средство просмотра. Пост может иметь просмотрщик пользователя или группы. Таблица отношений Permission должна иметь authorizable_id и authorizable_type для хранения ссылок Note или Post.
 – 
tamersalama
12 Июн 2009 в 20:33

@Укротитель

Я получал ту же ошибку. Проблема заключалась в том, что has_many_polymorphs создает запись в таблице соединений, используя массовую ассоциацию, и это не удалось. Я добавил attr_accessible :note_id, :editor_id и :editor_type в свой класс Permission, и впоследствии это заработало. (Примечание: я заменил свои названия моделей на свои.)

Я не особо вникал в это, но мне было бы любопытно, есть ли способ изменить это поведение. Я довольно новичок в этой структуре, и массовое назначение чего-либо чувствительного (например, ассоциации «Заказ-оплата») похоже на просьбу выстрелить себе в ногу. Дайте мне знать, решило ли это вашу проблему, и если вы выясните что-нибудь еще.

Лучший,
Стив

0
Steve DeWaldSteve DeWald 27 Июн 2009 в 18:26