Rails:多步骤新用户注册表单(表单中的第一个参数不能包含nil或为空)

时间:2015-07-23 04:53:39

标签: ruby-on-rails ruby ruby-on-rails-3 model-view-controller

我是初学者,在注册两个步骤时遇到严重问题。

我一直收到这个错误:

First argument in form cannot contain nil or be empty
<%= form_for(@Profile) do |f| %>

用户可以使用用户表(DB)上的用户信息进行注册。一切都很好。但我真的希望他们有个人资料。所以他们可以把他们的生物放在例如。

我尝试根据用户的MVC为配置文件创建MVC结构,但它不起作用。

我一直试图找到答案。尝试了数百种变化,但没有成功。请帮忙!

views / users / new.html.erb (这是有效的)(我只是想为用户创建个人资料,并让他们能够填写他们的信息作为第二步注册)

<div class="container">
  <% provide(:title, 'Sign up') %>
  <h1 class="center">Sign up</h1>

  <div class="row">
    <div class="col s12 m10 l8 offset-m1 offset-l2">
      <%= form_for(@user) do |f| %>
        <%= render 'shared/error_messages', object: f.object %>

        <%= f.label :first_name %>
        <%= f.text_field :first_name %>

        <%= f.label :genre %>
        <%= f.text_field :genre %>

        <%= f.label :middle_name %>
        <%= f.text_field :middle_name %>

        <%= f.label :last_name %>
        <%= f.text_field :last_name %>

        <%= f.label :preferred_name %>
        <%= f.text_field :preferred_name %>

        <%= f.label :email %>
        <%= f.text_field :email %>

        <%= f.label :password %>
        <%= f.password_field :password %>

        <%= f.label :password_confirmation, "Confirmation" %>
        <%= f.password_field :password_confirmation %>
        <div class="row center">
        <%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
        </div>
      <% end %>
    </div>
  </div>
</div>

models / user.rb

class User < ActiveRecord::Base
  has_one  :profile
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower
  before_save { self.email = email.downcase }
  before_create :create_remember_token
  validates :first_name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, length: { minimum: 6 }

  def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def User.digest(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

  def feed
    Micropost.from_users_followed_by(self)
  end

  def following?(other_user)
    relationships.find_by(followed_id: other_user.id)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by(followed_id: other_user.id).destroy
  end

  private

    def create_remember_token
      self.remember_token = User.digest(User.new_remember_token)
    end
end

controllers / users_controller.rb

    class UsersController < ApplicationController


    before_action :signed_in_user,
                    only: [:index, :edit, :update, :destroy, :following, :followers]
      before_action :correct_user,   only: [:edit, :update]
      before_action :admin_user,     only: :destroy

      def index
        @users = User.paginate(page: params[:page])
      end

      def show
        @user = User.find(params[:id])
        @microposts = @user.microposts.paginate(page: params[:page])
      end

      def new
        @user = User.new
      end



  def create
    @user = User.new(user_params)
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to the my app"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "just got destroyed."
    redirect_to users_url
  end

  def following
    @title = "Connections"
    @user = User.find(params[:id])
    @users = @user.followed_users.paginate(page: params[:page])
    render 'show_follow'
  end

  def followers
    @title = "known by"
    @user = User.find(params[:id])
    @users = @user.followers.paginate(page: params[:page])
    render 'show_follow'
  end

  private

    def user_params
      params.require(:user).permit(:first_name, :middle_name, :last_name, :preferred_name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end
  end

第二次注册页面
视图/用户/ signup2.html.erb

<div class="container">
  <% provide(:title, 'Sign up2') %>
  <h1 class="center">Sign up2</h1>

  <div class="row">
    <div class="col s12 m10 l8 offset-m1 offset-l2">
      <%= form_for(@Profile) do |f| %>
        <%= render 'shared/error_messages', object: f.object %>

        <%= f.label :primary_instrument %>
        <%= f.text_field :primary_instrument %>

        <%= f.label :bio %>
        <%= f.text_field :bio %>

        <div class="row center">
        <%= f.submit "Create my account2", class: "btn btn-large btn-primary" %>
        </div>
      <% end %>
    </div>
  </div>
</div>

models / profile.rb

class Profile < ActiveRecord::Base
  belongs_to :user
end

controllers / profiles_controller.rb

class ProfilesController < ApplicationController

  before_filter :get_user

  def get_user
    @profile = User.find(params[:user_id])
  end

  # generate new-profile form
  def new
    @user.profile = Profile.new
    @profile = @user.profile
  end

  # process new-profile-form post
  def create

    @user.profile = Profile.new(params[:profile])
    @profile = @user.profile

    respond_to do |format|
      if @profile.save
        flash[:notice] = 'Profile was successfully created.'
        format.html { redirect_to(@profile) }
        format.xml  { render :xml => @profile, :status => :created, :location => @profile }
      ...
      end
    end

  end

  # generate edit-profile form
  def edit
    @profile = Profile.find(params[:id])
  end

  # generate edit-profile-form post
  def update

    @profile = @user.profile

    respond_to do |format|
      if @profile.update_attributes(params[:profile])
        flash[:notice] = 'Profile was successfully updated.'
        # format.html { redirect_to(@profile) }
        format.html { redirect_to(user_profile(@user)) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @profile.errors, :status => :unprocessable_entity }
      end
    end

end

的routes.rb

 root to: 'static_pages#home'
  match '/signup',  to: 'users#new',            via: 'get'
  match '/signup2', to: 'profiles#new',         via: 'get'
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'
  match '/help',    to: 'static_pages#help',    via: 'get'
  match '/about',   to: 'static_pages#about',   via: 'get'
  match '/contact', to: 'static_pages#contact', via: 'get'
end

2 个答案:

答案 0 :(得分:0)

您的@Profile变量在标记中大写,而控制器中设置的变量是大写的。在标记中重写变量,如下所示:

<%= form_for(@profile) do |f| %>

希望它有所帮助!

答案 1 :(得分:0)

除了@ Zoran的答案,你可以使用以下宝石,这将使你的生活变得简单,多阶段形式。

Wicked gem