ассоциация рефакторинга рельсов - PullRequest
0 голосов
/ 25 мая 2018

Привет, я работаю над устаревшим проектом, в котором мне нужно провести рефакторинг какой-то старой ассоциации ассоциаций моделей, чтобы получить полезные данные.

У нас есть модель пользователя

class User
 has_many :user_task
end

class Project
 has_many :task
end

class Task
 belongs_to :project
 has_many :user_task
end

class UserTask
 belongs_to :user
 belongs_to :task
end

Я хочуполучить имя проекта и количество задач, над которыми работает пользователь, над которым работает пользователь проекта.

Я попробовал использовать has_many :through, но все еще не получил то, что ожидал.

Может ли кто-нибудь дать мне подсказку на это?

1 Ответ

0 голосов
/ 25 мая 2018

Вы можете захотеть структурировать свои ассоциации следующим образом:

class User < ActiveRecord::Base
 has_many :user_tasks # should be plural
 has_many :tasks, through: :user_tasks
 has_many :projects, through: :user_tasks
end

class Project < ActiveRecord::Base
 has_many :tasks # should be plural
end

class Task < ActiveRecord::Base
 belongs_to :project # `tasks` table should have project_id
 has_many :user_tasks # should be plural
end

class UserTask < ActiveRecord::Base
 belongs_to :user
 belongs_to :task
 has_one :project, through: :task
end

Фрагмент некоторых примеров команд:

:022 > User.create(name: 'kiddorails')
   (0.0ms)  begin transaction
  SQL (2.4ms)  INSERT INTO "users" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "kiddorails"], ["created_at", "2018-05-25 12:22:21.079472"], ["updated_at", "2018-05-25 12:22:21.079472"]]
   (0.7ms)  commit transaction
 => #<User id: 1, name: "kiddorails", created_at: "2018-05-25 12:22:21", updated_at: "2018-05-25 12:22:21">

 :023 > Project.create name: 'production'
   (0.0ms)  begin transaction
  SQL (1.2ms)  INSERT INTO "projects" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "production"], ["created_at", "2018-05-25 12:22:37.653901"], ["updated_at", "2018-05-25 12:22:37.653901"]]
   (0.6ms)  commit transaction
 => #<Project id: 1, name: "production", created_at: "2018-05-25 12:22:37", updated_at: "2018-05-25 12:22:37">

 :024 > Project.create name: 'staging'
   (0.1ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "projects" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "staging"], ["created_at", "2018-05-25 12:22:40.349378"], ["updated_at", "2018-05-25 12:22:40.349378"]]
   (2.4ms)  commit transaction
 => #<Project id: 2, name: "staging", created_at: "2018-05-25 12:22:40", updated_at: "2018-05-25 12:22:40">

 :025 > Task.create name: 'orchestration', project_id: 1
   (0.0ms)  begin transaction
  Project Load (0.1ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  SQL (0.3ms)  INSERT INTO "tasks" ("project_id", "name", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["project_id", 1], ["name", "orchestration"], ["created_at", "2018-05-25 12:22:55.606865"], ["updated_at", "2018-05-25 12:22:55.606865"]]
   (1.0ms)  commit transaction
 => #<Task id: 1, project_id: 1, name: "orchestration", created_at: "2018-05-25 12:22:55", updated_at: "2018-05-25 12:22:55">

 :026 > Task.create name: 'deploy', project_id: 2
   (0.1ms)  begin transaction
  Project Load (0.1ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  SQL (1.2ms)  INSERT INTO "tasks" ("project_id", "name", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["project_id", 2], ["name", "deploy"], ["created_at", "2018-05-25 12:23:00.446630"], ["updated_at", "2018-05-25 12:23:00.446630"]]
   (2.5ms)  commit transaction
 => #<Task id: 2, project_id: 2, name: "deploy", created_at: "2018-05-25 12:23:00", updated_at: "2018-05-25 12:23:00">

 :027 > Project.first.tasks
  Project Load (0.2ms)  SELECT  "projects".* FROM "projects" ORDER BY "projects"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Task Load (0.1ms)  SELECT "tasks".* FROM "tasks" WHERE "tasks"."project_id" = ?  [["project_id", 1]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Task id: 1, project_id: 1, name: "orchestration", created_at: "2018-05-25 12:22:55", updated_at: "2018-05-25 12:22:55">]>

 :028 > User.first.tasks
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Task Load (0.2ms)  SELECT "tasks".* FROM "tasks" INNER JOIN "user_tasks" ON "tasks"."id" = "user_tasks"."task_id" WHERE "user_tasks"."user_id" = ?  [["user_id", 1]]
 => #<ActiveRecord::Associations::CollectionProxy []>

 :029 > UserTask.create user_id: 1, task_id: 1
   (0.1ms)  begin transaction
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Task Load (0.1ms)  SELECT  "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  SQL (0.4ms)  INSERT INTO "user_tasks" ("user_id", "task_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 1], ["task_id", 1], ["created_at", "2018-05-25 12:23:19.931540"], ["updated_at", "2018-05-25 12:23:19.931540"]]
   (2.2ms)  commit transaction
 => #<UserTask id: 1, user_id: 1, task_id: 1, created_at: "2018-05-25 12:23:19", updated_at: "2018-05-25 12:23:19">

 :030 > User.first.tasks
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Task Load (0.1ms)  SELECT "tasks".* FROM "tasks" INNER JOIN "user_tasks" ON "tasks"."id" = "user_tasks"."task_id" WHERE "user_tasks"."user_id" = ?  [["user_id", 1]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Task id: 1, project_id: 1, name: "orchestration", created_at: "2018-05-25 12:22:55", updated_at: "2018-05-25 12:22:55">]>

 :031 > User.first.projects
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Project Load (0.2ms)  SELECT "projects".* FROM "projects" INNER JOIN "tasks" ON "projects"."id" = "tasks"."project_id" INNER JOIN "user_tasks" ON "tasks"."id" = "user_tasks"."task_id" WHERE "user_tasks"."user_id" = ?  [["user_id", 1]]
 => #<ActiveRecord::Associations::CollectionProxy [#<Project id: 1, name: "production", created_at: "2018-05-25 12:22:37", updated_at: "2018-05-25 12:22:37">]>

 :032 > UserTask.first.project
  UserTask Load (0.2ms)  SELECT  "user_tasks".* FROM "user_tasks" ORDER BY "user_tasks"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Project Load (0.2ms)  SELECT  "projects".* FROM "projects" INNER JOIN "tasks" ON "projects"."id" = "tasks"."project_id" WHERE "tasks"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 => #<Project id: 1, name: "production", created_at: "2018-05-25 12:22:37", updated_at: "2018-05-25 12:22:37">
...