【问题标题】:Polymorphic :has_many, :through as module in Rails 3.1 plugin多态 :has_many, :through 作为 Rails 3.1 插件中的模块
【发布时间】:2011-11-15 01:47:45
【问题描述】:

我到处搜索指向此的指针,但找不到。基本上,当其他人在 :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

当然,这个想法是任何加载acts_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

我尝试过:在 has_many :ownables 行上使用 :class_name =&gt; 'ActsPermissive::PermissiveCircle',但失败:

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 =&gt; :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'

这似乎表明使用非多态处理是必要的。所以我添加了一个类似于the setup here的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. 或者,有没有一种好方法可以让任意对象以与模块一起使用的类似方式收集对象?

【问题讨论】:

    标签: ruby-on-rails-3 rails-models has-many-polymorphs


    【解决方案1】:

    事实证明,将 :class_name 添加到两个 :has_many 定义实际上会起作用(有人对此发表了评论,但他们删除了他们的评论)。它在我的非简化程序中不起作用,因为我的程序中的其他东西导致了级联错误,似乎是 :has_many 定义的本地错误。

    简短的故事:对于实际上不是问题的事情来说,这是一个很大的麻烦。布莱克

    【讨论】:

      猜你喜欢
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 2010-12-14
      • 2014-09-01
      • 1970-01-01
      相关资源
      最近更新 更多