我在Rails中有一个创建用户和项目的表单。
以下是用户模型的表单代码:
class User < ActiveRecord::Base
has_many :projects, :dependent => :destroy
accepts_nested_attributes_for :projects, allow_destroy: true
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable, :timeoutable
def with_project
self.projects.build
self
end
end
和表单视图:
= form_for [resource_name, resource], url: registration_path(resource_name) do |u|
= u.fields_for :projects do |p|
.field = p.text_field :service
.field = p.text_field :location
.field = u.email_field :email
.actions = u.submit "Click to continue"
和用户registrations_controller.rb
:
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters
def new
build_resource({}).with_project
set_minimum_password_length
yield resource if block_given?
respond_with self.resource
end
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
end
private
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u|
u.permit(:email, project: [:id, :service, :location, :_destroy])
}
end
end
表单按预期工作;但是,在没有电子邮件的情况下提交时,该视图会显示:service
和:location
有关为何发生这种情况的任何想法?
更新 - 这是我的routes.rb
(现在的问题是project_fields根本没有出现在我的表单视图中)。
devise_for :users, controllers: {registrations: "users/registrations"}
devise_scope :user do
root 'users/registrations#new'
end
答案 0 :(得分:3)
我要在你的控制器上做一个假设,代码可能不是这个。
def new
@user = User.new.with_projects
end
def create
@user = User.new(params[:user]).with_projects #this is where your problem is.
end
params[:user]
包含project_attributes
,它们已分配给项目但不会保留。当您致电with_projects
时,它会在您的User
个实例上添加另一个未加载的项目。由于projects
是has_many
字段,因此将其视为集合。所以fields_for
基本上对现有项目执行循环,并保持未加载状态。这就是您看到服务和位置的重复字段的原因。你有两个项目。
正如我之前提到的,这可能不完全是你设置的方式,但它 正在发生的事情。
问题已经更新......
问题在于表格。与上述完全相同但发生在不同的地方。表单在new
视图(由new
操作呈现)中呈现一次,该视图在Project
实例上构建User
实例。论坛已提交,将Project
的一个实例分配给@user
。然后create
操作失败,因为没有有效的电子邮件字段。 create
操作然后呈现创建视图(反过来又会再次呈现form
部分。然后表单构建另一个与用户关联的project
实例。
您可以通过将问题移动到唯一需要的地方来解决问题。 new
行动。def new
@user = User.new.with_projects
end
def create
@user = User.new(params[:user])
#..... etc
end
参见示例。
完成的代码应该类似于: 控制器:
= form_for [resource_name, resource], url: registration_path(resource_name) do |u|
// etc.....
形式:
Ctrl + . from query design to datasheet
Ctrl + , from datasheet to query design
答案 1 :(得分:0)
当with_project呈现新动作时,RegistersController可能会再次调用该方法,因此表单会显示两个位置和服务字段。