我在Ruby on Rails项目中有一个有点复杂的数据库结构。 用户可以有多个 EmailAccounts , EmailAccount 可以有多个订阅(通过加入多对多)表),订阅可以包含多个标记(也是多对多)
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.date "dob"
t.string "gender"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "email_accounts", force: :cascade do |t|
t.integer "user_id"
t.string "email"
t.string "provider"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "account_subscriptions", force: :cascade do |t|
t.integer "email_account_id", null: false
t.integer "subscription_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "subscriptions", force: :cascade do |t|
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.string "domain"
end
create_table "sub_tags", force: :cascade do |t|
t.integer "subscription_id", null: false
t.integer "tag_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
我希望通过此关系查看哪些标记适用于用户。什么是最有效的方法(急切加载所有关系并循环遍历它们,在Postgres中进行多级联接等)?
答案 0 :(得分:1)
假设你有合适的型号
user = User.find(user_id)
tags = Tag.where(:id => SubTag.where(:subscription_id => AccountSubscription.where(:email_account_id => user.email_accounts.map{|e| e.id}).map{|a_s| a_s.subscription_id}).map{|s_t| s_t.tag_id})
tag_name = tags.map{|t| t.name}
如果您拥有正确的索引,这应该可以正常工作。