Rails设计模型不以嵌套形式保存模型?

时间:2014-03-03 00:05:22

标签: ruby-on-rails ruby forms devise nested-forms

我有一个简单的模型User,通过Devails(版本3.0.4)gem为Rails(版本4.0.2)生成。我还创建了一个名为Profile的非Devise模型。配置文件有两个字符串属性namebio。每个用户has_one个人资料,以及每个个人资料belongs_to用户。我正在尝试让用户注册表单包含配置文件属性,因此在新用户表单中有一个嵌套的配置文件表单。我正确设置了表单,并且所有用户和配置文件属性都正确地传递给:params一切似乎都有效,除了配置文件,它的属性不会保存到数据库。日志显示用户:profile为零。 我做了很多研究,我觉得我已经尝试过所有的东西,所以我希望有人能解决这个问题。这是代码:

用户模型:

class User < ActiveRecord::Base

    has_one :profile, dependent: :destroy, :autosave => true
    accepts_nested_attributes_for :profile

    devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

end

个人资料模型:

class Profile < ActiveRecord::Base

    belongs_to :user, :autosave => true
    validates :user_id, presence:true

end

注册控制器:

class RegistrationsController < Devise::RegistrationsController


    def new
        resource = build_resource({})
        resource.build_profile
        respond_with resource

    end



end

新用户表单,位于views/devise/registrations/new.html.erb

<h2>Sign up</h2>


<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, :autofocus => true %></div>

  <div><%= f.label :password %><br />
  <%= f.password_field :password %></div>

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation %></div>


 <%= f.fields_for :profile do |builder| %>

      <h2><%= builder.label :bio%></h2>
      <p><%= builder.text_field :bio %></p>

      <h2><%= builder.label :name %></h2>
      <p><%= builder.text_field :name %></p>
    <% end %>


  <div><%= f.submit "Sign up" %></div>
<% end %>

除了像'new'这样的空现有方法之外,我在配置文件控制器中没有任何内容。

1 个答案:

答案 0 :(得分:0)

更新了令人不满意的答案:

鉴于Devise使用强params,你不能通过sign_up_params传递额外的非用户参数。你可以做两件事之一。添加名称&amp;用户模型的生物字段,并使用设计表单一次保存。或者在注册时创建空白配置文件,然后让用户通过单独的表单输入生物和名称,您可以将其保存到配置文件模型。我希望有所帮助。

设计表单提供由Create收集和处理的注册参数。 请在此处查看完整的设计控制器:https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb

在您的表单中,您还会生成另外两个参数:bio和:name。但是,除了内置注册之外,您还需要捕获和处理这些参数并生成/保存新的配置文件。

您可以执行以下操作来修改设计创建方法,以便在创建新用户后保存您的个人资料。

# POST /resource
def create
build_resource(sign_up_params)

if resource.save
  @profile = current_user.profile.build(bio: params[:bio], name: params[:name])
  @profile.save

  yield resource if block_given?
  if resource.active_for_authentication?
    set_flash_message :notice, :signed_up if is_flashing_format?
    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}" if is_flashing_format?
    expire_data_after_sign_in!
    respond_with resource, location: after_inactive_sign_up_path_for(resource)
  end
else
  clean_up_passwords resource
  respond_with resource
end

我认为构建新的Profile应该在那里工作,尽管它可能没有实例化的current_user。 (确认的current_user不可用)

编辑 - 尝试此操作 - 无法正常工作

def create
super  
  profile = resource.profile.build(bio: params[:bio], name: params[:name])
  profile.save
end

(资料来源:Rails, Devise: current_user is nil when overriding RegistrationsController