获得用户标签的最有效方式

时间:2016-02-01 20:28:08

标签: sql ruby-on-rails postgresql activerecord

我在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中进行多级联接等)?

1 个答案:

答案 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}

如果您拥有正确的索引,这应该可以正常工作。