Rails Devise+simple_form多对多多选注册参数处理问题
Rails Devise注册场景多对多偏好关联配置方案
你需要同时调整表单参数命名、控制器强参数规则两处,即可自动完成用户与偏好的多对多绑定,不需要额外写中间表操作逻辑。
1. 修正复选框的参数命名
当前表单的复选框name属性为preference[user_ids][],提交后参数会挂载到params[:preference]节点下,不属于用户参数范畴,无法被Devise的注册逻辑识别。
Rails的has_many :through多对多关联默认约定使用{关联模型名复数}_ids的数组参数接收关联id,自动完成中间表数据写入,修改后的表单代码如下:
- Preference.all.each do |preference| = check_box_tag "user[preference_ids][]", preference.id, resource.preference_ids.include?(preference.id) = label_tag "user_preference_ids_#{preference.id}", preference.pref
补充说明:
- 用Devise提供的
resource对象获取当前注册用户实例,自动回显选中状态,后续如果做编辑用户资料的页面这段代码也可以复用 - 搭配
label_tag可以实现点击偏好文字直接选中复选框的交互,体验更好
2. 调整注册控制器的强参数许可规则
Rails强参数接收数组类型的参数时,必须以字段名: []的格式显式声明,否则会直接过滤数组值。修改configure_sign_up_params方法如下:
def configure_sign_up_params devise_parameter_sanitizer.permit(:sign_up) do |u| u.permit( { account_attributes: [:username], invite_request_attributes: [:text], preference_ids: [] }, :company, :email, :password, :password_confirmation, :invite_code, :agreement, :website, :confirm_password ) end end
注意:数组类型的
preference_ids参数必须放在哈希格式的参数段中,不能和普通字符串、布尔值类型的平级参数放在一起,否则会触发参数不允许的报错。
前置校验
确保模型层关联配置正确即可正常运行:
- User模型中声明关联:
has_many :preferences, through: :user_preferences(别忘了对应中间表的关联声明) - Preference模型中声明关联:
has_many :users, through: :user_preferences - 中间表迁移已正确创建
user_id、preference_id两个外键字段
内容的提问来源于stack exchange,提问作者Dev Narula
相关产品推荐
相关产品推荐

