Полиморфный: has_many,: through как модуль в плагине Rails 3.1 - PullRequest
0 голосов
/ 15 ноября 2011

Я везде ищу указатель на это, но не могу его найти. По сути, я хочу делать то, что все остальные хотят делать, когда они создают полиморфные отношения в пути: has_many,: through ... но я хочу сделать это в модуле. Я продолжаю застрять и думаю, что должен упускать из виду нечто простое

Для остроумия:

module ActsPermissive
  module PermissiveUser
    def self.included(base)
      base.extend ClassMethods
    end
    module ClassMethods
      def acts_permissive
        has_many  :ownables
        has_many  :owned_circles, :through => :ownables
      end
    end
  end

  class PermissiveCircle < ActiveRecord::Base
    belongs_to    :ownable, :polymorphic => true
  end
end

С миграцией, которая выглядит следующим образом:

create_table :permissive_circles do |t|
  t.string :ownable_type
  t.integer :ownable_id
  t.timestamps
end

Идея, конечно же, заключается в том, что независимо от того, что загружает Act_permissive, он может иметь список кругов, которыми он владеет.

Для простых тестов у меня есть

it "should have a list of circles" do
  user = Factory :user
  user.owned_circles.should be_an_instance_of Array
end

, что не с:

Failure/Error: @user.circles.should be_an_instance_of Array
     NameError: uninitialized constant User::Ownable

Я пытался: использовать :class_name => 'ActsPermissive::PermissiveCircle' в строке has_many: ownables, которая завершается с:

Failure/Error: @user.circles.should be_an_instance_of Array
     ActiveRecord::HasManyThroughSourceAssociationNotFoundError:
      Could not find the source association(s) :owned_circle or 
      :owned_circles in model ActsPermissive::PermissiveCircle. 
      Try 'has_many :owned_circles, :through => :ownables, 
      :source => <name>'. Is it one of :ownable?

при следовании предложению и установке :source => :ownable завершается неудачно с

Failure/Error: @user.circles.should be_an_instance_of Array
     ActiveRecord::HasManyThroughAssociationPolymorphicSourceError:
       Cannot have a has_many :through association 'User#owned_circles' 
       on the polymorphic object 'Ownable#ownable'

Что, по-видимому, говорит о том, что необходимо делать что-то с неполиморфным эффектом. Поэтому я добавил класс circle_owner, похожий на настройки здесь :

module ActsPermissive
  class CircleOwner < ActiveRecord::Base
    belongs_to :permissive_circle
    belongs_to :ownable, :polymorphic => true
  end

  module PermissiveUser
    def self.included(base)
      base.extend ClassMethods
    end
    module ClassMethods
      def acts_permissive
        has_many  :circle_owners, :as => :ownable
        has_many  :circles, :through => :circle_owners, 
                  :source => :ownable, 
                  :class_name => 'ActsPermissive::PermissiveCircle'
      end
    end

  class PermissiveCircle < ActiveRecord::Base
    has_many :circle_owners
  end
end

С миграцией:

create_table :permissive_circles do |t|
  t.string :name
  t.string :guid

  t.timestamps
end

create_table :circle_owner do |t|
  t.string  :ownable_type
  t.string  :ownable_id
  t.integer :permissive_circle_id
end

, который по-прежнему не работает с:

Failure/Error: @user.circles.should be_an_instance_of Array
     NameError:
       uninitialized constant User::CircleOwner

Что возвращает нас к началу.

  1. Как я могу сделать то, что кажется довольно распространенным полиморфом: has_many,: through модуля?
  2. В качестве альтернативы, есть ли хороший способ, позволяющий собирать объект произвольными объектами аналогичным образом, который будет работать с модулем?

1 Ответ

1 голос
/ 08 декабря 2011

Оказывается, что добавление: class_name к обоим определениям: has_many действительно сработает (кто-то это прокомментировал, но удалил свой комментарий). Это не сработало в моей неупрощенной программе из-за чего-то еще в моей программе, что вызывало каскадную ошибку, которая, по-видимому, была локальной для определения: has_many.

Короткая история: Было много проблем для чего-то, что на самом деле не было проблемой. Blech

...