如何使用跨命名空间模型的多态关联?

时间:2013-04-24 00:08:43

标签: ruby-on-rails-3 polymorphic-associations refinerycms

我理解如何使用active目录中的class_name选项来引用名称空间模型:

has_one :slide, :class_name => '::Refinery::Slides::Slide'

如何使用多态关联

has_one :slide, :as => :slideable

你能一起使用它们吗?

has_one :slide, :class_name => '::Refinery::Slides::Slide', :as => :slideable

如果是这样,你如何定义多态关联?

belongs_to :slideable, :polymorphic => true, class_name='::Refinery::Slideables::Slideable' #NO   

我正在使用RefineryCMS,你添加的每个引擎都在Refinery :: PluralModel :: SingularModel中被命名空间。基本上,我希望能够将幻灯片与案例研究或工作相关联。以下是实际模型。

module Refinery
  module CaseStudies
    class CaseStudy < Refinery::Core::BaseModel
      attr_accessible :title, :description, :position
      has_one :slide, :class_name => '::Refinery::Slides::Slide', :as => :slideable
    end
  end
end

module Refinery
  module Works
    class Work < Refinery::Core::BaseModel
      attr_accessible :title, :description, :position, 
      has_one :slide, :class_name => '::Refinery::Slides::Slide', :as => :slideable
    end
  end
end

module Refinery
  module Slides
    class Slide < Refinery::Core::BaseModel
      attr_accessible :slide_id, :caption, :position, :slideable_id, :slideable
      belongs_to :slide, :class_name => '::Refinery::Image'
      belongs_to :slideable, :polymorphic => true
    end
  end
end

好像我应该可以说slide.slideable.title但是我收到一个错误: nil的未定义方法`title':NilClass

apidoc指定inverse_of不能与多态一起使用,但对class_name没有任何说明

1 个答案:

答案 0 :(得分:0)

要使多态关联工作,您需要在'belongs_to'另一个模型上添加一个类型列和一个id列。 type列将存储类名,因此无需在泛型关联中指定。

例如,Comment可以属于QuestionAnswer。让我们称问题和答案“可评论”。评论应包含:commentable_id:commentable_type的列。

class Comment < ActiveRecord::Base
  # has columns :commentable_id and :commentable_type
  belongs_to :commentable, :polymorphic => true
end

class Question < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

class Answer < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

# example
comment = Comment.new(:body => "Nice answer!")
comment.commentable = Answer.find(1)
comment.save

因此,在您的情况下,您可以从:class_nameWork中删除CaseStudy个选项,并确保添加列:slide_type(与{{1}一起使用}}和:slide_id(与:slideable_type一起使用)到:slideable_id。它应该只与命名空间的类名“一起工作”。

Slide