Я изучаю все глубже и глубже RoRails, и я застрял перед данными, которые мы дали мне воспроизвести на этой прекрасной основе.Позвольте мне сначала показать вам мои таблицы и партнеров по моделям.
create_table "skills", force: :cascade do |t|
t.string "name"
t.bigint "parent_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["parent_id"], name: "index_skills_on_parent_id"
end
create_table "skills_users", id: false, force: :cascade do |t|
t.bigint "skill_id", null: false
t.bigint "user_id", null: false
t.index ["skill_id", "user_id"], name: "index_skills_users_on_skill_id_and_user_id"
end
create_table "users", force: :cascade do |t|
t.integer "points"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
И модели:
class Skill < ApplicationRecord
validates :name, presence: true
has_many :children, class_name: "Skill", foreign_key: :parent_id
belongs_to :parent, class_name: "Skill", foreign_key: :parent_id, optional: true
has_and_belongs_to_many :users
end
class User < ApplicationRecord
validates :points, presence: true
has_and_belongs_to_many :skills
end
Цель состоит в том, чтобы классифицировать навыки, выбирать детей навыков и подсчитывать баллы пользователей в каждойродительский навык.Вот пример данных
SKILLS
+-----------------------+
|ID|NAME |PARENT_ID|
+-----------------------+
|1 |Football | |
+-----------------------+
|2 |Basketball| |
+-----------------------+
|3 |Foot |1 |
+-----------------------+
|4 |Basket |2 |
+-----------------------+
|5 |Soccer |1 |
+-----------------------+
SKILLS_USERS
+-------------------+
|ID|SKILL_ID|USER_ID|
+-------------------+
|1 |1 |1 |
+-------------------+
|2 |1 |2 |
+-------------------+
|3 |3 |3 |
+-------------------+
|4 |2 |4 |
+-------------------+
|5 |5 |5 |
+-------------------+
USERS
+---------+
|ID|POINTS|
+---------+
|1 |100 |
+---------+
|2 |200 |
+---------+
|3 |100 |
+---------+
|4 |50 |
+---------+
|5 |10 |
+---------+
Ожидаемый запрос должен выглядеть следующим образом:
+--------------------------------+
|ID|NAME |POINTS|USERS_COUNT|
+--------------------------------+
|1 |Football |410 |4 |
+--------------------------------+
|2 |Basketball|50 |1 |
+--------------------------------+
Сначала я пытаюсь ответить на него в чистом SQL с помощью этого запроса:
SELECT id , Name , count ( points) as POINTS , count (USER_ID ) as USERS_COUNT
FROM SKILLS
INNER JOIN SKILLS as SK ON id = SK.parent_id
INNER JOIN SKILLS_USERS AS su ON su.skill_id = id
INNER JOIN USERS AS User ON SU.USER_ID = User.id
Но, похоже, я где-то не прав.
Я думаю, что путь ActiveRecord очень положительный, рубин - это магия.Как ActiveRecord может выполнить этот вид запроса через соединительную таблицу и где мы выбираем только родительские навыки?