ruby-on-rails 如何查找与另一个对象共享公共关系的对象的示例?

hm2xizp9  于 2022-11-19  发布在  Ruby
关注(0)|答案(1)|浏览(111)

我的问题可以说明如下:
我有三个模型,用户,流派和音乐会。
UserConcert的示例都可以与任意数量的genres相关联,因此它们与Genre具有连接表,具有has_and_belongs_to_many关系。
我的目标是实现一个过滤器,该过滤器将接受User的一个示例,并返回与一个或多个genres关联的Concert的每个示例,这些genres与所述User相同。
我的代码:

  • #音乐会.rb:*
class Concert < ApplicationRecord
  has_and_belongs_to_many :genres
end
  • #用户.rb:*
class User < ApplicationRecord
  has_and_belongs_to_many :genres
end
  • #架构.rb:*
create_table "genres_concerts", id: false, force: :cascade do |t|
  t.bigint "genre_id", null: false
  t.bigint "concert_id", null: false
end

create_table "genres_users", id: false, force: :cascade do |t|
  t.bigint "genre_id", null: false
  t.bigint "user_id", null: false
  t.index ["genre_id", "user_id"], name: "index_genres_users_on_genre_id_and_user_id"
  t.index ["user_id", "genre_id"], name: "index_genres_users_on_user_id_and_genre_id"
end

因此,我可以在任一示例上调用.genres,例如,User.find(1).genres返回

[#<Genre:0x00000001086f1068 id: 440, name: "rock", created_at: Thu, 17 Nov 2022 01:51:38.092415000 UTC +00:00, updated_at: Thu, 17 Nov 2022 01:51:38.092415000 UTC +00:00>,

#<Genre:0x00000001086f0bb8 id: 444, name: "jazz", created_at: Thu, 17 Nov 2022 01:51:38.115169000 UTC +00:00, updated_at: Thu, 17 Nov 2022 01:51:38.115169000 UTC +00:00>,

#<Genre:0x00000001086f0ac8 id: 418, name: "electronica", created_at: Thu, 17 Nov 2022 01:50:49.304427000 UTC +00:00, updated_at: Thu, 17 Nov 2022 01:50:49.304427000 UTC +00:00>]

Concert.find(1).genres返回

[#<Genre:0x00000001086f1068 id: 440, name: "rock", created_at: Thu, 17 Nov 2022 01:51:38.092415000 UTC +00:00, updated_at: Thu, 17 Nov 2022 01:51:38.092415000 UTC +00:00>,

#<Genre:0x00000001086f1bc8 id: 469, name: "punk", created_at: Thu, 17 Nov 2022 01:50:49.304427000 UTC +00:00, updated_at: Thu, 17 Nov 2022 01:50:49.304427000 UTC +00:00>]

在上面的例子中,使用id: 1的用户与名为“摇滚”、“爵士”和“电子音乐”的流派相关联,所以我会查找与这些流派相关联的每个Concert
经过相当多的阅读和搜索,我仍然坚持试图找出这一个,所以任何输入是非常感谢。提前感谢!

pgx2nnw8

pgx2nnw81#

我会尝试以下方法:

# new scope in models/concert.rb
scope :suggestions_for_user, ->(user) {
  joins(:genres).where(genres: { id: user.genres.select(:id) })
}

并像这样使用它:

user = User.find(...)
Concert.suggestions_for_user(user).distinct

请注意,由于数据库连接的性质,可能会返回重复的音乐会,因此需要distinct

相关问题