为具有多对多关系的模型创建表单的最佳方法是什么?
我有3个模型:User,Task,TaskAssignment:
用户模型
class User < ActiveRecord::Base
has_many :task_assignments
has_many :tasks, through: :task_assignments
end
任务模型
class Task < ActiveRecord::Base
has_many :task_assignments
has_many :users, through: :task_assignments
end
TaskAssignment模型(加入表格)
我无法使用has_and_belongs_to_many
,因为我需要在TaskAssignment模型中添加其他字段。
class TaskAssignment < ActiveRecord::Base
belongs_to :task
belongs_to :user
end
通过创建一个新任务,应该可以为一个任务分配多个用户,所以我创建了这个表单视图:
任务编辑表单视图
<%= form_for(@task) do |f| %>
<div class="field">
<%= f.label :note %><br>
<%= f.text_field :note %>
</div>
<select name="task[users]" size="5" multiple>
<% @users.each do |user| %>
<option value="<%= user.id %>"><%= user.email %></option>
<% end %>
</select>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
现在,我想知道如何继续使用我的控制器:
任务控制器
def create
@task = Task.new(task_params)
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render action: 'show', status: :created, location: @task }
else
format.html { render action: 'new' }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
我想我必须做那样的事情:
@task = Task.new(task_params)
users = ???
@task.users << users
name="task[users]"
来接收它们,但变量task_params
仅包含note
- 字段答案 0 :(得分:1)
您无需以任何特殊方式保存对象。请记住在:user_ids => []
中允许task_params
。
此外,使用表单助手collection_select
可能会让您的生活更轻松。
<%= f.collection_select :user_ids, @users, :id, :email, {}, { :multiple => true, :size => 5 } %>
答案 1 :(得分:1)
有一个名为accepts_nested_attributes_for
的帮助器,允许父对象创建和更新其嵌套对象。在这种情况下,您希望Task
能够创建和更新TaskAssignment
首先,允许Task
接受其孩子的属性并为其分配属性。
class Task < ActiveRecord::Base
has_many :task_assignments
has_many :users, through: :task_assignments
accepts_nested_attributes_for :task_assignments
end
这应该指向正确的方向。创建表单看起来就像在fields_for
for one-to-many中解释的那样。