带有Devise的Rails 3.1中的嵌套注册数据

再次问好,stackoverflow社区!

我正在研究在Rails中编写一个简单的博客系统,我正在使用Devise作为身份validation部分。

我得到了基本的电子邮件/密码注册,现在我已经建立了一个一对一的users表(由设计生成的基本表)和一个UserData表,包含用户名,权限,关于, 等等。

这很简单 – 用户表是100%设计vanilla,并且has_one UserData。 Userdata属于用户。

我尝试扩展Devise生成的注册表单,这样它就可以让用户输入,而不仅仅是他的电子邮件和密码,还有他想要的用户名。 这样,当表单将被发送时,如果表单字段的名称是正确的(嵌套哈希的正确结构,例如用户电子邮件的“email”)和用户所需名称的“UserData [name]” ),新用户将自动创建,并且Rails也会自动创建正确的相应UserData条目,对吗?

现在,我有一个巨大的问题,UserData [name]字段根本没有出现…这是我遇到问题的文件…

new.html.erb

 resource_name, :url => registration_path(resource_name)) do |f| %>  

#This is the tidbit that doesn't work


"devise/shared/links" %>

我一直在寻找一个小时和几小时的答案,但无济于事。 如果我故意拼错fields_for块中的“UserData”一词,它会打印出该字段。 这很奇怪,我不知道是什么让这个领域消失了……

我真的很感激一点帮助! 谢谢你的时间! 🙂

编辑1 + 2:

经过几次搞乱之后,我已经覆盖了设计的默认注册控制器并创建了自己的注册控制器。 我已经编辑了设计路由来调用我的自定义控制器作为timbrandes建议,但我似乎无法访问我的控制器中的@user。 这是我到目前为止的代码……

 class RegistrationsController < Devise::RegistrationsController def new resource = build_resource({}) resource.UserData = UserData.new respond_with resource end def create logger.debug "\n\n\nIN CREATE\n\n\n\n" logger.debug params.to_json super end def update super end end 

好吧,很多时间过去了,但我最终通过废弃并重新执行我的大部分Devise代码来实现它。 说实话,重写并不是那么多,现在它的效果很好。

对于任何未来的开发人员浏览这个(稍微令人困惑的)问题和答案,我可以给你的唯一建议是确保编写结构化的表单代码,特别是对于嵌套资源。 这是我当前的registrations_controller.rb有效:

 class RegistrationsController < Devise::RegistrationsController def new resource = build_resource({}) resource.build_user_data respond_with resource end def create resource = build_resource(params[:user]) if(resource.save) sign_in(resource_name, resource) respond_with resource, :location => after_sign_up_path_for(resource) else render :action => "new" end end def update super end end 

注册表单的.erb:

 
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> <%= devise_error_messages! %>
<%= f.label :email %> <%= f.email_field :email %>
<%= f.fields_for(:user_data) do |udf| %> <%= udf.label :name, "Desired user name" %> <%= udf.text_field :name %> <%= udf.label :roles, "Privileges"%> <% for role in UserData::ROLES %> <%= check_box_tag "user[user_data_attributes][roles][]" , role, resource.user_data.roles.include?(role) %> <%=h role.humanize %>
<% end %> <%= hidden_field_tag "user[user_data_attributes][roles][]" %> <% end %>
<%= f.label :password %> <%= f.password_field :password %>
<%= f.label :password_confirmation %> <%= f.password_field :password_confirmation %>
<%= f.submit "Sign up" %>
<% end %> <%= render :partial => "devise/shared/links" %>

您的字段没有出现是有原因的,也就是说,您必须在Controller( RC#196嵌套模型表单第1部分 )中的某处调用(例如) @user.user_data.build来创建user_data对象的实例与fields_for字段有关。

我能想到的方法是使用自定义设计控制器( 参见控制器列表 ),选择相应的注册方法并添加类似@user.user_data.build的内容。

另一种方法是对你的数据方案进行非规范化并将所有内容都放入用户本身(不是你的问题的答案,但无论如何;-))。 另外:没有搞乱猴子修补的Devise控制器。

确保在设计模型中定义了accepts_nested_attributes_for:user_data。