查找具有不同关系的记录[多对多]

时间:2016-03-21 09:38:10

标签: ruby-on-rails ruby

我有这个型号:

class Offer < ActiveRecord::Base
   ...
   has_and_belongs_to_many :tags
   ...
end

和此:

class Tag < ActiveRecord::Base
  ...
  has_and_belongs_to_many  :offers
  validates :name, presence: true
end

我想找到与标记有关系的所有商品,并在数组

上添加名称

例如:

Offers1 -> Tag1, Tag2
Offers2 -> Tag2, Tag3
Offers3 -> Tag2, Tag3, Tag4

Tag1.name="test1"
Tag2.name="test2"
Tag3.name="test3"
Tag4.name="test4"

如果我有这个数组["test2","test3"],我想找到Offers2Offers3

如果我有这个数组["test2","test3","test4"],我想找Offers3

我希望我已经解释得很好,谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

这是我能想到的最好的,但它仍然效率不高。

class Offer < ActiveRecord::Base
  # ...
  def has_tags?(other_tags)
    tag_names = tags.loaded? ? tags.map(&:name) : tags.pluck(:name)
    (other_tags - tag_names).empty?
  end
end

这将数组向左扩散,数组向右移动。如果商品没有所有标签,结果不为空。

names = ["test2","test3","test4"]

# take the records with any of the tag names
offers = Offer.joins(:tags).where(tag: { name: names })

# filter the offers in Ruby
offers.select { |o| o.has_tags?(names) }

答案 1 :(得分:0)

尝试以下方法:

class Offer < ActiveRecord::Base

  has_and_belongs_to_many :tags
  scope :with_tags, lambda do |tags = []|
    tags_sql = tags.collect { |tag| "tags.name = '#{tag}'" }.join(" AND ")
    joins(:tags).where(tags_sql)
  end
end 

然后你可以打电话:

@offers = Offer.with_tags(["tag1", "tag2"])