我有一个用户模型,通过模型成员资格,它有很多组织:
class User < ActiveRecord::Base
has_many :memberships
has_many :organizations, through: :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
class Organization < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
在注册过程中,我想询问我的组织名称,因此,我的表单如下所示:
= simple_for_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= f.simple_fields_for :memberships do |fm|
= fm.input :kind, as: :hidden, input_html: {value: Membership::OWNER}
= fm.simple_fields_for :organization do |fo|
= fo.input :name, required: false, label: "Organization"
= f.input :name
= f.input :email
= f.input :password
= f.input :password_confirmation
我的自定义Devise注册控制器中的自定义强params定义如下所示:
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) do |u|
u.permit(:email,
:password,
:password_confirmation,
memberships: {organizations: [:name]})
end
end
当我提交表单时,我收到此错误:
Membership(#70355446274100) expected, got Array(#70355394078720)
在Devise上创建控制器动作。参数如下所示:
{"utf8"=>"✓",
"authenticity_token"=>"...",
"user"=>
{"memberships"=>
{"kind"=>"owner",
"organizations"=>{"name"=>"Organization name"}},
"name"=>"User's Name",
"email"=>"email@address.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Sign up"}
如果我添加
accepts_nested_attributes_for :memberships
accepts_nested_attributes_for :organizations
到用户模型或添加:
accepts_nested_attributes_for :memberships
到用户模型和
accepts_nested_attributes_for :organizations
对于成员模型,成员和组织简单地消失了表单,它们不会被呈现。即使我的新注册控制器操作如下所示:
def new
super
resource.memberships.build.build_organization
end
我也试着用这个来定义我的强力参数:
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) do |u|
u.permit(:email,
:password,
:password_confirmation,
memberships_attributes: [:id, organization_attributess: [:id, :name]])
end
end
并且(显然)没有出现HTML输入字段。
我错过了什么?我怎样才能做到这一点?
关于这个问题是Expected ProductField, got array issue的重复,在这个问题或答案的任何地方都没有涉及的形式问题,我在这里讨论。
答案 0 :(得分:1)
我认为你在各种地方犯了几个错误。请使用下面的更正替换您的代码(所以不要错过单数/复数个案)。不幸的是,我无法真正测试我的代码,但我认为它非常接近您的需求。
class User < ActiveRecord::Base
has_many :memberships
has_many :organizations, through: :memberships
accepts_nested_attributes_for :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :organization
accepts_nested_attributes_for :organization
end
class Organization < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
= simple_for_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= f.simple_fields_for :memberships do |fm|
= fm.input :kind, as: :hidden, input_html: {value: Membership::OWNER}
= fm.simple_fields_for :organization do |fo|
= fo.input :name, required: false, label: "Organization"
= f.input :name
= f.input :email
= f.input :password
= f.input :password_confirmation
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) do |u|
u.permit(:email,
:password,
:password_confirmation,
memberships_attributes: [:id, organization_attributes: [:id, :name]])
end
end
以下是我处理您的观点的方式(而不是在新操作中构建您的资源)。您可以在新操作中移除您的建筑物并尝试以下视图:
= simple_for_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= f.object.memberships.build if f.object.memberships.empty?
= f.simple_fields_for :memberships do |fm|
= fm.input :kind, as: :hidden, input_html: {value: Membership::OWNER}
= fm.object.build_organization unless fm.object.organization
= fm.simple_fields_for :organization do |fo|
= fo.input :name, required: false, label: "Organization"
= f.input :name
= f.input :email
= f.input :password
= f.input :password_confirmation