【问题标题】:Double Nested Includes双嵌套包含
【发布时间】:2018-11-10 21:17:15
【问题描述】:

我有一个存储在数据库中的导航结构。有两种模型 Navigation 和 Navigation Items。

class Navigation < ApplicationRecord

  has_many :navigation_items

  scope :all_items, -> { 
    includes(navigation_items: [:translations, children: :translations])
      .order('navigation_items.position asc')
      .where(navigation_items: { parent_id: nil })
    }

end

class NavigationItem < ApplicationRecord

  has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
  belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
  belongs_to :navigation
end

我像这样在应用程序控制器中设置导航

def set_navigation
  @navigations = Navigation.all_items
  @navigation = []
  @footer_navigation = []
  @header_navigation = []

  if (main = @navigations.detect { |n| n.handle == "main" })
    @navigation = main.navigation_items
  end
  if (footer = @navigations.detect { |n| n.handle == "footer" })
    @footer_navigation = footer.navigation_items
  end
  if (header = @navigations.detect { |n| n.handle == "header" })
    @header_navigation = header.navigation_items
  end
end

然后,我循环遍历布局中的每个 navigation_item,并为子级嵌套循环。

除了一件事,一切都运行良好。导航项都有一个与之相关的位置。父项以正确的顺序显示,但是子项不服从该顺序。有没有办法将子导航项的范围也按位置排序?

【问题讨论】:

  • default_scopeNavigationItem 有效吗?在调用navigation_items 时添加order 怎么样?我相信all_items 范围的order 仅适用于Navigation 的初始查询,不适用于includes 关系的后续查询。
  • 我错了 order 仅适用于初始查询,至少在 Rails 5.2.1 上。您使用的是哪个版本的 ActiveRecord?
  • 嘿@shanecav,也在rails 5.2.1上。它适用于第一级导航项,但有问题的是子项。我试过 default_scope 没有运气。

标签: ruby-on-rails navigation sql-order-by rails-activerecord model-associations


【解决方案1】:

试试这个

您可以使用default_scope 或关联condition

class Navigation < ApplicationRecord
  # has_many :navigation_items, -> { where(parent_id: nil).order(position: :asc) }
  has_many :navigation_items, -> { where(parent_id: nil) }

  scope :all_items, -> { includes(navigation_items: [children: :children]) }
end

class NavigationItem < ApplicationRecord

  # has_many :children, -> { order position: :asc }, class_name: "NavigationItem", foreign_key: "parent_id"
  has_many :children, class_name: "NavigationItem", foreign_key: "parent_id"
  belongs_to :parent, class_name: "NavigationItem", foreign_key: 'parent_id', optional: true
  belongs_to :navigation

  default_scope -> { order position: :asc }
end

【讨论】:

  • 谢谢@PGill。不幸的是,它仍然错误地命令孩子。我想我需要以某种方式将默认顺序更改为按 parent.position 然后按位置排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多