rails的新手(使用4.1),将小型项目管理工具作为学习项目。我遇到了一个稍微复杂的模型关联,我想确保我在这里正确的轨道,并询问如何扩展它。
考虑这种情况:
型号:
class Website < ActiveRecord::Base
has_many :website_user
has_many :users, through: :website_user
has_many :tasks, through: :website_user
end
class User < ActiveRecord::Base
has_many :websites, through: :website_user
has_many :website_user
end
class WebsiteUser < ActiveRecord::Base
belongs_to :website
belongs_to :user
belongs_to :role
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :website_user
has_one :website, through: :website_user
end
class Role < ActiveRecord::Base
has_many :website_user
end
DB:
create_table "roles", force: true do |t|
t.string "name"
end
create_table "tasks", force: true do |t|
t.text "description"
t.string "title"
t.integer "website_user_id"
end
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.string "password"
t.string "password_hash"
t.string "password_salt"
end
create_table "website_users", force: true do |t|
t.integer "website_id"
t.integer "user_id"
t.integer "role_id"
end
create_table "websites", force: true do |t|
t.string "name"
t.string "url"
end
我在这里发生的事情基本上是网站让用户(在网站上工作的团队成员)通过website_user表关联。该表属于角色,因此团队成员将在此网站上拥有特定的作业,最后,任务属于website_user关联,以便您可以换出用户,但任务将与角色和网站保持关联。
我正在考虑进一步扩展它,以便任务将在website_user上关联两次,一次用于分配器,一次用于任务的分配用户。然而,在这一点上,感觉我会在中间的一个大的连接桌上附加很多东西,并且在我的腰带下没有大量的经验,它开始闻起来可能有更好的方式。
如果这一切看起来都不错,您将如何将任务加入到website_user两次,一次是针对分配者,一次是针对分配的?或者,如何重新排列模型关联?
答案 0 :(得分:1)
我无法在数据库设计中为您提供建议,但您可以使用名为class_name
的选项为用户分配两次。您可以在此处阅读更多内容:http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
但是你还必须在你的任务模型中添加额外的foreign_key。
我还建议你阅读M. Hartle书中的以下章节,因为它在模型关系之间有很好的解释:https://www.railstutorial.org/book/following_users#cha-following_users
答案 1 :(得分:1)
class Task < ActiveRecord::Base
belongs_to :assignee, class_name: WebsiteUser, foreign_key:website_user_id
belongs_to :assigner, class_name: WebsiteUser, foreign_key:assigner_user_id
end
class WebsiteUser < ActiveRecord::Base
has_many :assigned_tasks, class_name: Task, inverse_of: :assignee, dependent: :destroy, foreign_key: :website_user_id
has_many :tasks_assigned, class_name: Task, inverse_of: assigner, dependent: :destroy, foreign_key: :assigned_user_id
end
您必须在任务表中添加另一个外键..
只是一个起点,但这应该让你去..
答案 2 :(得分:1)
首先出现的一个简单的解决方案是在任务模型中保留分配者和受让人ID。
迁移 AddAssigneeAssignerToTask
class AddAssigneeAssignerToTask < ActiveRecord::Migration
change do
add_reference :task, :assignee, index: true
add_reference :task, :assigner, index: true
end
end
将 belongs_to 添加到任务模型
中class Task < ActiveRecord::Base
belongs_to :assignee, class: 'WebsiteUser'
belongs_to :assigner, class: 'WebsiteUser'
has_one :website, through: :assignee
end
修改 WebsiteUser
class WebsiteUser < ActiveRecord::Base
belongs_to :website
belongs_to :user
belongs_to :role
has_many :assigned_tasks, class_name: 'Task', foreign_key: 'assigner_id'
has_many :received_tasks, class_name: 'Task', foreign_key: 'assignee_id'
end
之后你就可以像这样使用它了
@website_user.assigned_tasks # => []
@website_user.received_tasks # => [Task1, Task2]