Rails多态关系和link_to

时间:2009-08-16 09:15:11

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

这是我的架构

class Menu < ActiveRecord::Base
  belongs_to :menuable, :polymorphic => true
end

class Page < ActiveRecord::Base
  has_one :menu, :as => :menuable
end

class Links < ActiveRecord::Base
  has_one :menu, :as => :menuable
end

我想使用link_to链接到菜单视图中的多态类,例如

<%= link_to menu.name, menu.menuable %>

这样可行,但是当我想要的是生成链接时,这将从数据库中检索可菜单对象。你可以想象如果我的菜单很大,这将会让我的应用程序陷入困境。

当我将可菜单字段视为多态时,Rails创建了menuable_type和menuable_id。我可以使用什么来生成多态页面的链接,而不是使用巨型switch语句编写辅助函数(例如,如果我有大量可菜单的'子类'?)

2 个答案:

答案 0 :(得分:7)

问题被问到很久但我最近遇到了同样的问题,解决方法是使用polymorphic_url。您需要找到创建链接所需路径的名称,例如“fast_car_path”,并从多态表中的* _type和* _id中删除它。例如,您有一个评论列表,并希望链接到他们所属的汽车。所以如果* _type = FastCar我们有

@comments.each do |comment|
  link_to polymorphic_url(comment.commentable_type.tableize.singularize, :id => comment.commentable_id) 

将生成“fast_car_path”而不从数据库下载汽车。

我是铁杆的菜鸟,我不知道这个建议有多好,但我希望它对某些人有用。

答案 1 :(得分:1)

你可以这样做:

def my_menu_url(menu)
  "/#{menu.menuable_type.tableize}/#{menu.menuable_id}"
end

如果使用rails约定来命名与模型相对应的控制器。

但不要这样做。你解决了rails的路由机制,这简直就是不好的做法。

你应该在你的发现者中使用:include选项来急切加载你的菜单:

Menu.all :include => :menuable

如果这还不够,您可以使用某种缓存。