0

为具有多对多关系的模型创建表单的最佳方法是什么?

详细地:

我有 3 个模型:用户、任务、任务分配:


用户模型

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

任务分配模型(联接表)

我不能使用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

  1. 那是应该保存 n:m 数据的方式,还是有其他神奇的轨道功能?
  2. 如何从选择框中获取数据?我试图通过将选择框的名称设置为来接收它们name="task[users]",但变量task_params只包含note-field
4

2 回答 2

1

您不需要以任何特殊方式保存对象。只要记住允许:user_ids => []在你的task_params.

此外,使用表单助手,您的生活可能会更轻松一些collection_select

<%= f.collection_select :user_ids, @users, :id, :email, {}, { :multiple => true, :size => 5 } %>
于 2013-09-16T17:58:04.450 回答
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一对多中解释的那样。

于 2013-09-16T18:13:59.373 回答