2014-03-03 88 views
0

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

用户模式:

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 %> 

我没有在配置控制器东西,除了像“新”空现有的方法。

+0

你没有你强的参数在应用程序控制器设置, 你做? – JustBasti

回答

0

更新不满意答:

由于设计使用强大的PARAMS事实上,你无法通过sign_up_params通过额外的非用户PARAMS。你可以做两件事之一。或者将名称&生物字段添加到用户模型并使用设计表单一次性保存它们。或者在注册时创建一个空白配置文件,然后让用户通过单独的表单输入生物和姓名,您可以将其保存到配置文件模型。我希望有所帮助。

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

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

你可以这样做来修改devise create方法来保存你的配置文件后,新用户已被创建。

# 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 

我认为建立新的档案应该在那里工作,但它可能没有实例化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

+0

看来current_user实际上还没有实例化。我得到错误:“nil:NilClass”的未定义方法'配置文件“。有关如何在实例化后执行此操作的任何想法? – Joe

+0

看到上面的编辑,我希望能解决问题。 – chrisfin

+0

您的编辑确实解决了current_user为零的问题,但后来发现配置文件为零的错误。我想把它设置为一个构建的配置文件会更有意义,然后尝试调用一个无对象的'构建'方法。所以不是'profile = resource.profile.build(bio:params [:bio],name:params [:name])''我有'resource.profile = Profile.new(bio:params [:bio] params [:name])',然后保存。还必须用'new'替换'build'。这似乎工作,配置文件不是零!现在只是属性:生物和:名称是零... – Joe