【问题标题】:Rails: has_many association through array of object IDs from formRails:通过表单中的对象ID数组进行has_many关联
【发布时间】:2017-12-20 16:53:31
【问题描述】:

我有一个模型Group,其中has_manyUsers。

class Group < ApplicationRecord
  belongs_to :user
  has_many :users
  serialize :user_ids, Array
end

我在前端使用 JS 将User ids 添加到数组user_ids。隐藏字段如下所示:

 = f.hidden_field :user_ids, id: "ids_field"

选择几个用户后,将他们添加到 JS 数组并将隐藏字段的值分配给该数组,我使用强参数(将 user_ids 作为数组)提交以从参数创建一个新对象:

@group = Group.new(group_params)

def group_params
  params.require(:group).permit(:name, :user_id, :user_ids=>[])
end

日志在逗号分隔列表中显示了带有 user_ids 的提交:

Processing by GroupsController#create as JS

Parameters: {"utf8"=>"✓", "group"=>{"name"=>"", "user_ids"=>["25,1"]}, "commit"=>"Save Squad"}

在控制台中检查Group 显示只有数组中的第一个ID 被分配给组。

irb(main):128:0> Group.last.user_ids
..
[
    [0] 25
]

在过去的两天里,我一直在这个问题上撞墙,根本无法解决问题。我尝试了以下变化: - 在前端使用 JSON - 删除后端的序列化 - 使用 .split(",") 拆分数组参数 - 使用 group_params,包括/排除 user_ids 上的“=> []”,并将显式名称添加到我的隐藏字段。通常我会在这里得到一个不允许的参数错误。 - 使用 Group.users 将数组分配给组模型

非常感谢任何帮助或指导。我觉得我在某个时候已经把所有部分都弄对了,只是不是同时。如果我完全离开并且有更好的方法来做到这一点,我准备放弃这个并继续前进。

提前谢谢你:)


编辑:更多玩弄表明 user_ids 数组确实是一个数组,但只包含一个条目:“25,1”。我解决了我的问题,采用params[:user_ids][0] 并用逗号分隔符将其拆分,循环遍历索引,并将每个用户保存到组关联中。我认为这不是一个很好的解决方案,并且仍然希望在不进行任何操作的情况下传递直接数组。

【问题讨论】:

  • 有什么原因你没有使用某种 collection_check_boxes 形式而不是 JS 吗?然后,ID 将实际作为 params 哈希中的数组发送,您可以使用内置方法进行保存等。有一些带有复选框的陷阱,但您只需要注意这些数据是如何传递的。

标签: javascript ruby-on-rails arrays ruby activerecord


【解决方案1】:

这似乎是经典的 Has and Belongs to Many 情况,因为用户可以“拥有”一个组并属于多个组。我会做一些类似的事情:

class Group < ApplicationRecord
  belongs_to :user
  has_many :users_groups
  has_many :users, through: :users_groups
  accepts_nested_attributes_for :users
end

Class User < ApplicationRecord
  belongs_to :group
  has_many :users_groups
  has_many :groups, through: :users_groups
  accepts_nested_attributes_for :groups
end

在您的终端中创建迁移:

rails g 迁移 CreateUsersGroupsJoinTable 用户组

这将创建一个包含列的连接表:

|id|user_ids|group_ids|

这将为您提供各种 Rails 方法,例如:

u = User.find(1)
 #returns user with ID 1

u.groups
 #will a result of joining Group with UsersGroups ON groups.id = users_groups.group_id WHERE users_groups.user_ids = 1

你也可以反过来:

g = Group.find(1)

g.users
 #returns all user objects that belong to that group.

然后,当您处理表单时,它会为您提供 collection_check_boxes 之类的内容,它将根据 Group.all 或 User.all 之类的内容自动构建复选框,返回一个数组,该数组将自动更新连接表并执行所有这些操作看起来你在用 JS 做的工作。

【讨论】:

  • 感谢您的周到回复。我确实设置了 has_many 和 belongs_to 关系。我以前使用 collection_check_boxes 创建组,它按预期工作,但我需要通过搜索而不是复选框来创建数组。我让用户从网站上的任何用户创建一个组,并且不能有一千个复选框让他们滚动浏览。
  • 啊,我没有意识到它是这样设置的。但是collection_check_boxes 允许您使用任何东西作为集合,即您不必使用User.all。你可以让你的搜索结果是通过 AJAX 的查询,所以User.where(...)。或者由于就 HTML 而言复选框的重量很轻,您可以使用User.all,然后使用 JQuery UI 搜索来缩小结果范围。它只是隐藏了那些与你想要的不匹配的东西。而且由于collection_check_boxes 只提交勾选了复选框的复选框,这将是一个轻量级的回复。
  • 我可以为您提供更多示例,但我必须知道您如何进行搜索以缩小选择范围。
【解决方案2】:

虽然有答案,但我认为真正的问题是

"user_ids"=>["25,1"]

应该是

"user_ids"=>["25", "1"]

在前端我使用 JS 来组合一个逗号分隔的字符串,比如

"25,1"

在控制器中我使用 Ruby 将其解析为数组

params[:user_ids].split(",").uniq

我可以将它分配给实例。 Rails 将创建关联。

group.user_ids = params[:user_ids].split(",").uniq

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多