gpt4 book ai didi

ruby-on-rails - 对记录进行排序/分组以具有很多基于关联的限制

转载 作者:行者123 更新时间:2023-12-01 02:42:48 25 4
gpt4 key购买 nike

我正在开发一个用作场所目录的应用程序,并且(当前但可能并非始终如此)允许基于1个城市,1个社区和1个类别过滤特定企业的场所。类别可以嵌套,因此它们具有parent_id。可以通过查看下面的模型代码来理解关联(一切都非常简单)。到目前为止,一切运行顺利,但还剩下一个障碍。

首先,一些重要的注释会影响答案。

1.我正在使用will_paginate对场地协会进行分页。话虽如此,我不能在数组上分页。好吧,我可以,但是性能将是一个问题。

2.我将Tag模型用作企业及其相关类别之间的链接对象。当前,该接口仅被设置为允许将一个类别附加到任何给定的业务,并且至少必须附加一个。我计划稍后扩展面向公众页面的界面,以允许按多个类别进行过滤,因此除非有很多更好的方法可以完成,否则无法对应用程序结构的这一部分进行更改。

3.可能(希望)存在的一种可能的解决方案是在Arel中别名化表联接,或者在范围内允许类别自行进行自我联接以获得父级。目前,如果解决方案假设嵌套的层数不超过1个,我将认为是可以接受的。不过,这种牺牲是不得已的选择,因为这确实会阻碍我将来要介绍的功能。

4.关于最后一点,我看过will_paginate/array,但是被他们的免责声明吓了一跳(“如果您知道自己在做什么,并且确实需要对数组进行分页,则需要明确地使用此功能”)。记住过去尝试滚动自己的分页插件时遇到的性能噩梦,我想避免这种情况,除非有人可以向我充分说明这种解决方案的性能影响。

5.该站点必须能够承受重击。目前,所有内容都已缓存,数据库非缓存命中率相对较低且相差甚远。它必须保持这种方式。

现在,我想提出的问题。

背景:某些面向公众的视图的设计规范要求将当前城市中的所有场所都显示在列表中,并按父类别进行分组(不显示任何子类别,但是所有带有业务标签的场所都应属于一个子类别)并与属于父项的地点分组。然后,根据父类别对这些场所进行排序,然后根据场所所属的企业名称进行第二次排序。这需要是一个平面关联,然后将其输入will_paginate中。这个场所ActiveRecord查询(在下文中称为@venues)随后被转储到JSON中,进行缓存并呈现到页面上。

问题:如何使用指定的分组/顺序构造@venues,以便可以根据此界面的规范正确分页和显示这些场所?

app / models / business.rb:

# Fields: id, name, description, keywords, ...
class Business < ActiveRecord::Base
has_many :tags, :dependent => :destroy
has_many :categories, :through => :tags

has_many :venues, :dependent => :destroy

has_many :cities, :through => :venues
has_many :neighborhoods, :through => :venues
end


app / models / venue.rb:

# Fields: id, business_id, city_id, neighborhood_id, ...
class Venue < ActiveRecord::Base
belongs_to :business
belongs_to :city
belongs_to :neighborhood
end


app / models / tag.rb:

# Fields: id, category_id, business_id, ...
class Tag < ActiveRecord::Base
belongs_to :business
belongs_to :category
belongs_to :venue
end


app / models / category.rb:

# Fields: id, parent_id, name, description, ...
class Category < ActiveRecord::Base
has_many :tags, :dependent => :destroy
end


app / models / city.rb:

# Fields: id, name, description, ...
class City < ActiveRecord::Base
has_many :neighborhoods, :dependent => :destroy
has_many :venues
end


app / models / neighborhood.rb:

# Fields: id, city_id, name, description
class Neighborhood < ActiveRecord::Base
belongs_to :city
has_many :venues
has_many :businesses, :through => :venues
end


这是一个解释,我可以根据需要提供更多信息。

附言在MySQL中将此应用程序使用Rails 3.0.9。

P.S.S.我也对基于多个嵌套关联字段的可能值简化这种过滤的模式或gem感兴趣。我将授予可以使用嵌套集模型宝石(例如Awesome嵌套集)以这种方式进行分组/排序/分页的确切解决方案的任何人以upvote + accept + bunty。

最佳答案

不会显示任何子类别,但是所有具有业务标记的场所都属于子类别的场所也应与具有父标记的场所进行分组。


正如Xavier在评论中所说,您应该使用嵌套集合模型。我正在使用这个:

https://github.com/collectiveidea/awesome_nested_set

这使我能够像往常一样进行分页和排序:

module Category
extend ActiveSupport::Concern
included do
belongs_to :category
scope :sorted, includes(:category).order("categories.lft, #{table_name}.position")
end

module ClassMethods
def tree(category=nil)
return scoped unless category
scoped.includes(:category).where([
"categories.lft BETWEEN ? AND ?",category.lft, category.rgt
])
end
end # ClassMethods
end

#then with some category
@animals = Animal.tree(@mamal_category)


它将在一个sql调用中为您提供所有食草动物,食肉动物,杂食动物等以及子子类别,并且由于它是一个作用域,因此它可轻松进行分页,可排序。

另请参阅: get all products of category and child categories (rails, awesome_nested_set)

关于ruby-on-rails - 对记录进行排序/分组以具有很多基于关联的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7712988/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com