【问题标题】:Rails - how to order a model by its has many association?Rails - 如何通过它有很多关联来订购模型?
【发布时间】:2012-12-18 08:26:39
【问题描述】:

我有两个模型:

#Product
class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
  attr_accessible :name
  ...
end

#Category
class Category < ActiveRecord::Base
  has_and_belongs_to_many :products, :order => "name ASC"

  attr_accessible :name, :priority
end

我想按优先级最高的类别订购我的产品,然后是产品名称

例如我有: 3 类:

  • 糖果,优先级 = 3
  • 水果,优先级 = 1
  • 甜点,优先级 = 2

3 个产品:

  • 巧克力冰淇淋,有甜点和甜食类,
  • 饼干,有甜点和糖果类,
  • 猕猴桃,有糖果、水果和甜点类别

我希望它们像这样订购:

  • 猕猴桃(首先是因为水果是最高优先级)
  • 巧克力冰淇淋(第二,因为巧克力排在饼干之前,而且它们的类别都具有相同的优先级)
  • Cookie

如何在 Rails 中做到这一点? 我不希望我的产品被复制,我知道这样做很容易:

Category.order("priority ASC").each do |cat|
  cat.products.order("name ASC").each do |product|
  end
end

但在这种情况下,Kiwi、Chocolate Ice Cream 和 Cookies 将被复制,因为它们都有多个类别。 有没有一种简单的方法可以删除重复项?或者有没有办法直接按类别最高优先级订购产品?

编辑:关于我想要实现的目标的更多详细信息

事实上,我想要的是一个巨大的表格,在左侧,我有所有产品(每个唯一产品只有一行)按类别排序......所以我可以有这样的东西:

  • 类别 - 产品
  • 水果 - 香蕉
  • 水果 - 苹果
  • 水果 - 猕猴桃
  • 甜品 - 巧克力冰淇淋
  • 甜点 - 饼干
  • 甜 - 巧克力糖
  • 甜 - 苹果糖
  • ...

看到了吗?即使水果是甜点和甜食,我也希望它在这张表中只出现一次。我希望产品出现在他们的“最重要”类别中(这就是我考虑“优先级”的原因)。

由于这个巨大的表格将用于编辑产品,我希望能够轻松访问产品的属性(每个属性将有一列)。所以我真的需要尽可能减少数据库请求。


感谢任何可以帮助我的人! 库尔加

【问题讨论】:

    标签: ruby-on-rails model-associations has-and-belongs-to-many


    【解决方案1】:

    为了避免重复,你可以试试这个,

    Product.joins(:categories).group("products.name").order("categories.priority ASC, products.name ASC")
    

    【讨论】:

    • 谢谢!您的解决方案似乎非常适合我需要做的事情。我真的不知道可以在特定属性上使用“组”并像那样使用它……您总是在 Rails 的神奇世界中学习新事物! :)
    【解决方案2】:

    不妨试试这个

    products = Product.joins(:categories).order("categories.priority ASC, products.name ASC")
    

    这也会获取重复的值。假设你想获取名字,也许你可以试试这个

    products.map(&:name).uniq
    

    【讨论】:

    • 两个答案都有效,但使用 shweta 之一,更容易访问产品的属性。我投票赞成,因为您的解决方案运行良好! :)
    • 虽然分组看起来是一个优雅的解决方案,但我并不完全相信它是否具有可扩展性。通常,在开发过程中,我意识到我需要来自同一张表的超过 2-3 个参数。在这种情况下,在我看来,在一个数组中获取所有列并在整个页面中使用它可能是明智的。这只是一个查询 :) 如果您调用 group,则每次您希望获取新属性时都必须触发不同的查询。话虽如此,如果只是您想要的名称, group 绝对是一个更优雅的解决方案。如果有人可以批评我的思维过程,我会很高兴。
    • 这是一张巨大的桌子,我必须在其中访问大部分产品的属性。有没有办法通过属性循环查询?当两个不同的产品具有相同的名称时, products.man(&:name).uniq 不会也删除那些重复的名称吗?使用分组解决方案,我可以按产品 ID 分组并获取名称,因此不会删除重复的名称。我还找到了这个解决方案:Rails 指南中的 Product.joins(:categories).select(“distinct(products.id)”):guides.rubyonrails.org/… 但我只得到“id”列...
    • 啊。我没有想到许多产品具有相同的名称。在那种情况下,不同的看起来不错。映射生成的记录集以获取您需要的数组。 :)
    • 更新了我的答案。不知道这看起来是否更好。
    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多