Вы можете захотеть структурировать свои ассоциации следующим образом:
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">