我有一个项目应用程序,允许团队中的所有用户创建任务,我希望用户能够将用户添加到任务中(例如,如果有多个人参加会议)。本质上,新任务表单将具有团队成员的所有用户名,并且用户可以在每个名称旁边选中一个框,以查找参与任务的其他任何人。
最初,我认为最好的方法可能是与我建立的has_many through:
关系:
任务:
class Task < ApplicationRecord
has_many :user_tasks
has_many :users, through: :user_tasks
用户:
class User < ApplicationRecord
has_many :user_tasks
has_many :tasks, through: :user_tasks
和User_Tasks:
class UserTask < ApplicationRecord
belongs_to :user
belongs_to :task
end
想法是,当创建新任务时,在任务中标记的任何user_id将在User_Tasks中创建新条目。但是我不确定100%如何在“任务创建动作”中执行此操作,并且我开始怀疑这是否使事情复杂化了?
有没有更简单的方法来做到这一点?如果不是,围绕这个create
关联来组织has_many through:
动作的最佳方法是什么?
答案 0 :(得分:1)
我认为您与协会的联系非常紧密。每次将对象添加到集合(分配给用户的任务集合或分配给任务的用户)时,Rails都会自动更新UserTask表。因此,使用您当前的设置,您应该可以做到:
user = User.first
task = Task.first
user.tasks << task
,它还会自动在UserTask
表中创建一条记录。
这样,您应该能够在“任务创建操作”中执行以下操作:
task.users << User.find([1,2])
答案 1 :(得分:1)
它实际上比您想象的简单得多。 ActiveRecord为_ids
关联创建一个has_many
setter和getter。设置器将自动在联接表中添加/删除记录。例如:
@task = Task.create!(user_ids: [1,2,3])
@task.user_ids # => [1,2,3]
将在连接表中创建一个任务和三行。
您可以在collection helpers的表单中使用它:
<%= form_for(@task) do |f| %>
...
<%= f.collection_checkboxes(:user_ids, User.all, :id, :name) %>
...
<% end %>
在这里,我只是在猜测您的用户具有name属性(用于复选框的文本)。您可以使用所需的任何集合来代替User.all
。
要将user_ids参数(是一个数组)列入白名单,请使用带有数组作为值的哈希选项:
def task_params
params.require(:task).permit(:foo, :bar, user_ids: [])
end
这允许一个允许的标量类型数组。