【问题标题】:Cleanest way to query polymorphic association?查询多态关联的最简洁方法?
【发布时间】:2018-12-12 22:13:43
【问题描述】:

问题:我有一个可行的解决方案,但偷偷怀疑它可能计算量很大。希望听到任何更有效的方法来实现这一目标。

目标:我想拉出按优先级排序的书籍列表,其中书籍与学校或类。

  • 学校:有很多课程,通过主题
  • 类:有一所学校,通过主题
  • 书籍:可按班级或学校预订

当前类视图文件:

<%  @school_class_books.order("priority ASC").each do |book| %>
    <b><a href="<%= book.url %>"><%= book.name %></a></b><br />
    <%= book.long %><br /><br />
<% end %>

当前 class.rb 控制器:

@school_class_books = Book.all.where(bookable_type: ["School","Class"],
 bookable_id: [@class.school.id,@class.id])

【问题讨论】:

  • 根据您的怀疑,我没有看到任何繁重的计算。

标签: ruby-on-rails polymorphic-associations


【解决方案1】:

在考虑任何性能问题之前,您应该知道您编写的代码会通过查找不应找到的书籍而导致错误。

例如,如果 @school.id = 10 和 @class.id = 15,则此查询将返回一本书,其可预订字段设置为:bookable_id = 15 和 bookable_type = "School"。

那本书属于不同的学校!

这样做可能更简单:

@books = Book.where(bookable: @school).to_a.concat(Book.where(bookable: @class).to_a)

这是多态语法糖:

@books = Book.where(bookable_type: @school.class.to_s, bookable_id: @school.id).to_a.concat(Book.where(bookable_type: @class.class.to_s, bookable_id: @class.id).to_a)

换句话说,只需进行两次查找并组合结果。

就性能而言,使用where(my_attribute: [value1, value2, value3]) 之类的语法会产生WHERE books.my_attribute IN (value1, value2, value3) 之类的SQL。

使用 IN 的 SQL 语句可能效率低下,因为它们使数据库服务器更难使用 my_attribute 字段(在本例中为 bookable_id)上的索引。

最后,您应该考虑将您的 Class 模型重命名为 Course 以避免命名空间与 Ruby 的 class 关键字冲突,或在读取变量名时程序员混淆。想想bookable_type: @class.class.to_s的尴尬

【讨论】:

    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2010-10-06
    • 2013-08-10
    • 2011-03-20
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 2010-10-15
    相关资源
    最近更新 更多