bugfix> ruby-on-rails > 投稿

こんにちは、私は有用なデータを取得するために古いモデルの関連付けをリファクタリングする必要があるレガシープロジェクトに取り組んでいます。

ユーザーモデルがあります

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 件
  • 次のように関連付けを構造化できます。

    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">
    
    

あなたの答え