【问题标题】:Rails Polymorphic relationship and link_toRails 多态关系和link_to
【发布时间】:2009-08-16 09:15:11
【问题描述】:

这是我的架构

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 %>

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

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

【问题讨论】:

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


【解决方案1】:

很久没有问这个问题了,但我最近遇到了同样的问题,解决方案是使用polymorphic_url。您需要找到创建链接所需的路线名称,例如“fast_car_path”,并将其从多态表中的 *_type 和 *_id 中提取出来。例如,您有一个 cmets 列表,并希望链接到它们所属的汽车。所以如果 *_type = FastCar 我们有

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

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

我是 Rails 的菜鸟,我不知道这个建议有多好,但我希望它对某人有所帮助。

【讨论】:

【解决方案2】:

你可以这样做:

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

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

但不要这样做。您围绕rails的路由机制工作,这只是不好的做法。

您应该在查找器中使用 :include 选项来急切加载您的菜单:

Menu.all :include => :menuable

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

【讨论】:

  • 急切加载是否适用于多态关系?它如何知道要加入哪个表,而不首先检索菜单表?
  • 我猜你最多可以将负载减少到存在的多态类型的数量。不幸的是,快速搜索显示这不是 ActiveRecord 中的现有行为。 :( 也许是时候回到单表继承了。
  • 我认为 ActiveRecord 首先加载所有菜单记录。在第二步中,它对第一个查询的结果集中的每个 menuable_type 进行查询。我认为在这种情况下单表继承不是解决方案,因为两个模型差异很大。
【解决方案3】:

另一种方法是使用url_for[menu.menuable, menu]。所以,链接标签看起来像这样:&lt;%= link_to menu.name, url_for([menu.menuable, menu]) %&gt;

【讨论】:

    【解决方案4】:

    你可以为此使用多态路由

    https://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html

    <%= link_to menu.name, polymorphic_path(menu.menuable) %>
    

    它会生成这样的html

    <a href="/menu.menuable_type/menu.menuable_id">menu.name</a>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多