简体   繁体   中英

creating form_for @user on different page than devise/registrations

I'm trying to build a site in which a user can signup by inputing just their email address and password (Rails app/ Devise authentication) and once they complete that they can provide additional details, such as an "about me" field, and date of birth, etc.

I was following this post on Stack overflow which seems to be asking the same exact thing: SO question

I followed the steps provided in that answer but my field are not saving to the database.

Here is the relevant code in my profiles#show page:

<%= form_for @user, url: updateprofile_path, html: { method: :put, :multipart => true } do |f| %>
  <%= f.text_area :about, class: "form-control", rows: "10", placeholder: "Tell us about yourself." %>
  <div><%= f.submit "Update", :class => "btn btn-default btn-xs" %></div>
<% end %>

The path updateprofile derives from my custom route in my routes file:

devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
    get 'register', to: 'devise/registrations#new', as: :register
    get 'signin', to: 'devise/sessions#new', as: :signin
    get 'logout', to: 'devise/sessions#destroy', as: :logout
    get 'edit', to: 'devise/registrations#edit', as: :edit
    put "update" => 'devise/registrations#update', as: :updateprofile
  end

Here is my registrations controller:

class RegistrationsController < Devise::RegistrationsController

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(current_user.id)

    successfully_updated = if needs_password?(@user, params)
      @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
    else
      # remove the virtual current_password attribute
      # update_without_password doesn't know how to ignore it
      params[:user].delete(:current_password)
      @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
    end

    if successfully_updated
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to profiles_show_path(@user)
    else
      render "edit"
    end
  end

private

  # check if we need password to update user data
  # ie if password or email was changed
  # extend this as needed
  def needs_password?(user, params)
    user.email != params[:user][:email] ||
    params[:user][:password].present? ||
    params[:user][:password_confirmation].present?
  end

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

  def account_update_params
      params.require(:user).permit(:email, :password, :date_of_birth, :about, :avatar, :password_confirmation, :current_password)
  end

end

The update method in the registrations controller I got from the devise documentation on this subject: Link

Since this hasn't worked I'm doubting if it is what I needed to do. The result of all of this is that I will click on Submit after entering in the about field, and it will route it to the /update path, which is a blank template (I just created it to override the missing template error). I ran User.all in my rails console and confirmed that the about field is still null.

Can anyone see where I am going wrong? I have spent many many hours trying to figure this out and would love any help.

Thanks,

I would not mess with any devise controllers. What you would like to do can be achieved like so:

1) Simply add the fields you would like to the User model (about_me, date_of_birth).....Then modify your Application Controller like so:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
   before_action :configure_permitted_parameters, if: :devise_controller?

   protected

   def configure_permitted_parameters
     devise_parameter_sanitizer.for(:sign_up) << :about_me, :date_of_birth
     devise_parameter_sanitizer.for(:account_update) << :about_me, :date_of_birth
   end
end

Once you have done this, you can add the fields to the registration page if you would like. Else, you can just add the fields in the form for devise/registrations/edit.html.erb

Once you provide people with a link to their edit registration path, they will be able to add the additional information and update their profile.

By default devise views uses methods such as resource and resource_name. If creating a new Registrations controller as recommended above for use with the default views generated by Devise, you may find it helpful to re-define these methods in a RegistrationsHelper:

module RegistrationsHelper
  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
end

I have read it from Devise wiki Custom Registration Controller

Hope it will help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM