【问题标题】:Rails display similar products using tagsRails 使用标签显示类似产品
【发布时间】:2016-03-06 22:21:42
【问题描述】:

我有一个带有标签的产品模型,该模型使用 has_many :through 关联。我想根据选定的标签在展示页面上显示类似的产品(为每个产品选择标签)。

class Product < ActiveRecord::Base    
    has_many :product_tags
    has_many :tags, through: :product_tags
end

假设我有 3 个产品和 2 个标签 - “狗”和“猫”(用于狗粮和猫粮)。

产品 1 和 2 的标签设置为“狗”。产品 3 的标签设置为“猫”。

因此,产品 1 显示页面上所需的输出是产品 2 显示在“您可能还感兴趣的项目”部分中。产品 3 不应在那里显示。

我的控制器中的正确方法是什么?

我现在的想法是使用 & - 运算符,即

(@product_1.product_tags & @product_2.product_tags).empty?

如果不为空,则显示产品。但是如何在我的控制器中通过查询来完成此操作?

这是我的尝试

def show
    @product = Product.find(params[:id])
    @similar_products = Product.where(!(tags & @product.tags).empty?)
  end

但它显然不起作用。如何访问查询中的关联模型?我也找到了this 解决方案,但它对我不起作用:

Product.joins(:tags).where((:tags & @pr1.tags).empty?).all
NoMethodError: undefined method `&' for :tags:Symbol

【问题讨论】:

    标签: ruby-on-rails activerecord associations


    【解决方案1】:

    您的 ActiveRecord 关系的问题是您试图在 where 子句中使用 Ruby 代码。它可以处理简单的散列或 SQL 字符串,但没有什么比你做的更复杂了。

    但是,出于您上面提到的目的,我不认为您需要对此进行查询;你可以用 Ruby 数组来做到这一点。

    如果您的Tag 模型具有反比关系:

    Class Tag
      has_many :product_tags
      has_many :products, through: :product_tags
    end
    

    ...那么您应该能够使用此获取产品标签的产品(在map,它开始使用 Ruby 数组而不是 ActiveRecord 关系):

    @similar_products = @product.tags.map(&:products).flatten.uniq - [@product]
    

    然后你只需要在视图中遍历@similar_products 来显示它们。


    如果您确实需要查询(例如,如果您的数据最终需要花费大量时间或内存来处理),您需要:

    @similar_products = Product.joins(:tags).where('tags.id' => @product.tag_ids).where.not('products.id' => @product.id)
    

    (免责声明:我尚未对此进行测试。)


    注意。 如果您的ProductTag 模型上没有其他逻辑,您可以完全省去product_tag.rb,将表格重命名为products_tags(部分为复数,并按字母顺序),然​​后改用这些:

    class Product
      has_and_belongs_to_many :tags
    end
    class Tag
      has_and_belongs_to_many :products
    end
    

    【讨论】:

    • 我认为你已经编辑并添加了这部分:where.not('products.id' =&gt; @product.id) 这实际上是超级有用的,我没有想到它:) 我最后用了查询,似乎更“正确” “对我来说。
    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多