【问题标题】:Rails create multiple records based on user inputRails 根据用户输入创建多条记录
【发布时间】:2018-12-22 22:09:29
【问题描述】:

我有一个项目应用程序,允许团队中的所有用户创建任务,我希望用户能够将用户添加到任务(例如,如果多人参加会议)。基本上,新的任务表单将包含团队成员的所有用户名,并且用户可以为参与任务的其他任何人选中每个名称旁边的框。

最初,我认为最好的方法可能是我拥有的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_ids 都会在 User_Tasks 中创建新条目。但我不是 100% 确定如何在任务创建操作中做到这一点,我开始怀疑这是否过于复杂了?

有没有更简单的方法来做到这一点?如果不是,围绕这个has_many through: 关联构建create 操作的最佳方式是什么?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    它实际上比你想象的要简单得多。 ActiveRecord 为 has_many 关联创建一个 _ids setter 和 getter。 setter 将自动添加/删除连接表中的记录。例如:

    @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 %>
    

    在这里我只是猜测您的用户有一个名称属性(用于复选框的文本)。你可以使用任何你想要的集合来代替User.all

    要将 user_ids 参数(它是一个数组)列入白名单,请使用带有数组作为值的哈希选项:

    def task_params
      params.require(:task).permit(:foo, :bar, user_ids: [])
    end
    

    这允许一个允许的标量类型的数组。

    【讨论】:

    • 那么我需要在任务中创建一个:user_ids 列吗?每当我使用:user_ids 执行collection_check_boxes 时,我都会收到错误消息,询问我是否将:user_id 设置为user_ids: 作为参数有效,但它似乎没有被记录在任何地方。
    • 这个答案和上面的内容确实帮助了我,我将其标记为正确,因为我认为它提供了更多的上下文。
    【解决方案2】:

    我认为您对自己的联想非常满意。每次将对象添加到集合(分配给用户的任务集合或分配给任务的用户)时,Rails 都会自动更新 UserTask 表。因此,使用您当前的设置,您应该能够做到:

    user = User.first 
    task = Task.first
    user.tasks << task
    

    这也会自动在UserTask 表中创建一条记录。

    这样你应该能够在任务创建操作中完成类似这样的操作:

    task.users &lt;&lt; User.find([1,2])

    【讨论】:

    • 感谢您的建议,我认为我已经设置好了所有内容,但是在设置任务控制器的创建操作时遇到了问题:@task = current_user.tasks.build(task_params) `@user_task = @task.UserTask.build`
    • 您根本不必执行 @user_task 部分 - 如果您运行第一行 (tasks.build) 然后运行 ​​@task.save,它应该会自动创建。你保存了吗?
    • 我在控制台中玩耍,因为我无法让它工作。如果我执行以下操作:Task.new(comments: "hello world", users: [1, 2]) 我会收到错误ActiveRecord::AssociationTypeMismatch: User(#70229507233400) expected, got Integer(#70229476918020) 如果我执行t1 = Task.new(comments: "hello world", users: [User.first, User.second]),它将开始保存它,但事务将回滚。
    • 您收到的消息是一个指示 - 用户对象是预期的,但它只获得整数 [1,2]。它应该与users: User.find([1,2]) 一起使用。如果回滚可能是因为某些验证 - 请阅读您收到的错误消息,如果仍有疑问,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多