视图中的多态关联

时间:2011-02-27 05:51:59

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

如何在视图中显示我的多态关联?我有以下模型。

class Blog < ActiveRecord::Base
  belongs_to :users
  has_one :category, :as => :categorizable
end

class Category < ActiveRecord::Base
  belongs_to :categorizable, :polymorphic => true
end

class User < ActiveRecord::Base
  has_many :blogs
  has_many :categories, :as => :categorizable
end

然而,我的问题是,在尝试显示类别时我得到一个零。

rails console
 => user = User.first
 => user.blogs
[]
 => user.categories
[]
 => category = user.categories
 => category = Category.new
 => category.name = "Education"
 => category.save!
true
 => user.categories
[#<Category id: 1, name: "Education", categorizable_id: 1, categorizable_type: "User", created_at: "...", updated_at: "...">]
 => user.blogs.create(:title => "...", :body => "...", :category => category)
[#<Blog id: 1, user_id: 1, title: "...", body: "...", created_at: "...", updated_at: "...">] 
 => blogs = user.blogs.all
 => blogs.each do |blog|
      puts blog.category
    end
nil
 => blogs.first.category
[#<Category id: 1, name: "Education", categorizable_id: 1, categorizable_type: "User", created_at: "...", updated_at: "...">]

我不明白,为什么当我使用每个块时,blog.category返回nil?如何通过我的视图显示我的多态模型的条目?

更新:

作为用户,我希望能够创建类别并将其分配给我的博客。每个博客都有一个类别,我想通过Category模型作为可分类博客访问。

它应该是非常好的,如果它按照逻辑试图说的那样工作,但目前它没有。多态模型应该是优雅的,但是现在,多态性对我来说很糟糕并且无法使用。我还在等人帮助我提供更好的解决方案。

3 个答案:

答案 0 :(得分:4)

设计存在缺陷。请考虑以下事项:

user = User.create
cat = user.categories.create(:name=>"Education")

现在有一个类别:

> cat
# Category id: 1, name: "Education" categorizable_id:1 categorizable_type: "User"

添加博客并为其指定相同类别时:

user.blogs.create(:category=>cat)

它会覆盖多态类型和id:

# UPDATE "categories" SET "categorizable_type" = 'Blog', "categorizable_id" = 1,
  "updated_at" = '2011-02-27 06:20:29.968336' WHERE ("categories"."id" = 1)

现在该类别已不再与用户关联:

user.reload
user.categories # => []

你真的想在这里建立多对多的关系模型。我建议为UserCategory和BlogCategory添加连接表,并摆脱多态,这没有帮助。

答案 1 :(得分:1)

请原谅我早些时候的回答。 zetetic的回答绝对有道理。尽量避免使用多形体。

答案 2 :(得分:0)

更新:我已经确定多态模型不是可行的方法,而且我已经用好的'STI解决了它,它做了同样的事情。