嵌套表单注册过程出现问题

时间:2011-09-04 21:50:17

标签: ruby-on-rails-3 login nested-forms

在研究了SO之后,我发现我希望注册过程如下:

  1. 用户填写表格
  2. 用户点击“加入”
  3. 创建/登录用户并重定向以填写个人资料
  4. 点击按钮
  5. 用户定向到个人资料
  6. 如果我要在rails console中创建用户和用户的个人资料,它将如下所示:

    user = User.new
    user.email = ""
    user.password = ""
    user.profile = Profile.new
    user.profile.info = ""
    user.profile.save
    user.save
    

    问题:我在主页上使用嵌套模型表单来创建用户并添加该用户的个人资料名/姓。现在发生的事情是:用户单击“加入”,将它们重定向到/ users,然后重定向到/ signup。那就是我被困住的地方。它给了我以下错误:

    Action Controller: Exception caught
    NoMethodError in ProfilesController#new
    undefined method `profile=' for nil:NilClass
    app/controllers/profiles_controller.rb:5:in `new'
    

    我希望/注册成为填写个人资料的表单,但它不起作用。

    我的代码如下......

    用户#new.html.erb(首页表单):

    <%= form_for(@user, :html => {:multipart => true, :id => 'homesign'}) do |f| %>
      <%= f.hidden_field :id %>
      <% if @user.errors.any? %>
      <% end %>
      <div>
        <%= f.label :email %>
        <%= f.text_field :email, :size => 38 %>
      </div>
      ...
      <%= f.fields_for :profile do |profile| %>
        <%= profile.label :first_name %>
        <%= profile.text_field :first_name, :size => 18 %>
        ...
      <% end %>
    <% end %>
    

    个人资料#new.html.erb(注册表单):

    <%= form_for @profile, :html => { :multipart => true } do |f| %>
      <table id="signupTable">
        <tbody>
          <tr>
            <td class="label"><%= f.label :gender, "Gender:" %></td>
            <td>
            <fieldset>
              <%= select(:gender, :gender_type, [['Female', 1], ['Male', 2], ['Rather not say', 3]], :class => 'optionText') %>
            </fieldset>
            </td>
          </tr>
          <tr>
            <td class="label"><%= f.label :birthday, "Birthday:" %></td>
            <td>
            <fieldset>
              <%= select_month(14, :prompt => 'Month', :field_name => 'Month', :id => 'Date.mon') %>
              <%= select_day(32, :prompt => 'Day') %>
              <%= select_year(0, {:prompt => "Year", :start_year => DateTime.now.year, :end_year => DateTime.now.year - 115}, {:field_name => 'Year', :id => 'Date.year'}) %>
            </fieldset>
    <% end %>
    

    User.rb:

    class User < ActiveRecord::Base
      attr_accessor :password
      has_one :profile, :dependent => :destroy
      accepts_nested_attributes_for :profile
    
      validates :email, :uniqueness => true, 
                    :length => { :within => 5..50 }, 
                    :format => { :with => /^[^@][\w.-]+@[\w.-]+[.][a-z]{2,4}$/i }
      validates :password, :confirmation => true,
                       :length => { :within => 4..20 },
                       :presence => true,
                       :if => :password_required?
    end
    

    Profile.rb:

    class Profile < ActiveRecord::Base
      belongs_to :user
      accepts_nested_attributes_for :user
    end
    

    UsersController:

    class UsersController < ApplicationController
      before_filter :authenticate, :only => [:edit, :update]
    
      def new
        @user = User.new
        @user.profile = Profile.new
        if logged_in?
          redirect_to current_user.profile
        end
      end
    
      def index
        @user = User.all
      end
    
      def create
        @user = User.new(params[:user])
        if @user.save
          session[:user_id] = user.id
          redirect_to new_user_profile_path(:user_id => @user), :notice => 'User successfully added.'
        else
          render :action => 'new'
        end
      end
    end
    

    ProfilesController:

    class ProfilesController < ApplicationController
      before_filter :authenticate, :only => [:edit, :update]
    
      def new
        @user.profile = Profile.new
      end
    
      def create
        @profile = Profile.new(params[:profile])
        if @profile.save
          redirect_to profile_path(@profile), :notice => 'User successfully added.'
        else
          render :action => 'new'
        end
      end
    
      def index
        @profile = current_user.profile
      end
    end
    

    SessionsController(仅限创建):

    class SessionsController < ApplicationController
      def create
        if user = User.authenticate(params[:email], params[:password])
          session[:user_id] = user.id
          redirect_to user.profile, :notice => "Logged in successfully"
        else
          flash.now[:alert] = "Invalid login/password. Try again!"
          render :action => 'new'
        end
      end
    end
    

    routes.rb中:

    match "/signup" => "profiles#new", :as => "signup"
    post "/profiles/new" => "profiles#create"
    match "skip/signup", :to => "info#signupskip"
    match "skip/profiles/new", :to => "profiles#newskip"
    get "/profiles/:id" => "profiles#show", :as => "profile"
    get "profiles/new"
    root :to => "users#new"
    

0 个答案:

没有答案