使用Rails中的devise,尝试在注册后添加第二步以使用名称,个人简介和照片更新用户

我是编码和stackoverflow的新手,所以我希望我要问的问题不会太愚蠢 我正在尝试做的是在标题中:用户登录(电子邮件,密码)后,他们将被重定向到新表单,可以在其中填写姓名,个人简历和图片。 一切按计划进行,直到他们点击提交并遇到两个问题:

1 /不考虑新数据 2 /重定向错误

注册后,用户将被重定向到“ profiles /:id / edit”。提交表单后,它将重定向到“ user /:id”,该名称不存在。

它不应该重定向到控制器中的profile#update吗?

这是我的不同代码:

1 /路线

Rails.application.routes.draw do
  devise_for :users
  root to: "pages#home"
  # For details on the DSL available within this file,see http://guides.rubyonrails.org/routing.html
  resources :jam_sessions,only: [:show,:index,:new,:create] do
    resources :spots,:create,:new]
    resources :messages,only: [:create]
  end
  resources :participations,only: [:create,:update]

  resources :profiles,:edit,:update]
  resources :dashboards,only: [:index,:show]


  resources :reviews,only: [:create]


  mount actionCable.server => "/cable"

  get 'users/:id',:to => 'profiles#edit',:as => :user

  patch 'profiles#edit',:to => 'profiles#update'
end 

2 / profiles_controller

class ProfilesController < ApplicationController
  def show

    @user = User.find(params[:id])
    @reviews = Review.where(receiver_id: @user.id)
    @instruments = UserInstrument.where(user_id: @user.id)
    @participations = Participation.where(user_id: @user.id)
    date = Time.now

    if @participations != nil
      @jam_sessions = []

      @participations. each do |participation|
        spot = Spot.find_by(id: participation.spot_id)
        @jam_sessions << JamSession.find_by(id: spot.jam_session_id)

      end
      @future_jam_sessions = []
      @past_jam_sessions = []
      @jam_sessions.each do |jam_session|
        if jam_session.starts_at > date
          @future_jam_sessions << jam_session
        else
          @past_jam_sessions << jam_session
        end
      end
    else
      puts "no jam"
    end
  end

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

  def update
    @user = User.find(params[:id])
    @user.update(user_params)
    raise
    if @user.save
      redirect_to profiles_path(@user)
    else
      render "new"
    end
  end
  private

    def user_params
      params.require(:user).permit(:first_name,:last_name,:bio)
    end
end

3 / application_controller

class ApplicationController < actionController::Base
  before_action :authenticate_user!,except: [:home,:show]

  before_action :configure_permitted_parameters,if: :devise_controller?
  def configure_permitted_parameters
    # For additional fields in app/views/devise/registrations/new.html.erb
    devise_parameter_sanitizer.permit(:sign_up,keys: [:first_name,:bio])
    # For additional in app/views/devise/registrations/edit.html.erb
    devise_parameter_sanitizer.permit(:account_update,keys: [:username])
  end

  def default_url_options
    { host: ENV["DOMAIN"] || "localhost:3000" }
  end

end

4 /用户模型

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable,:lockable,:timeoutable,:trackable and :omniauthable
  devise :database_authenticatable,:registerable,:recoverable,:rememberable,:validatable
  has_many :user_instruments,dependent: :destroy
  has_many :instruments,through: :user_instruments
  has_many :messages,dependent: :destroy
  has_one_attached :photo,dependent: :destroy
  has_many :reviews_written,class_name: "Review",foreign_key: :writer_id
  has_many :reviews_received,foreign_key: :receiver_id
  has_many :jam_sessions,dependent: :destroy

  def profile_picture
    if photo.attached?
      photo.key
    else
      "avatar-unknown.png"
    end
  end

  def full_name
    "#{first_name} #{last_name}"
  end
end

5 /编辑视图

<%= simple_form_for(@user) do |f| %>
  <%= f.input :first_name %>
  <%= f.input :last_name %>
  <%= f.input :bio %>
  <%= f.input :photo,as: :file %>
    <%= f.submit 'Update profile' %>
<% end %>

谢谢! 奥利维尔

xiaanping 回答:使用Rails中的devise,尝试在注册后添加第二步以使用名称,个人简介和照片更新用户

这里是克拉拉:)

所以我看到您的代码存在一些问题,但是似乎有些东西已经在起作用,这很好。 因此,它正在创建一个新用户,然后将其重定向到您在其中编辑用户的正确表单,对吗? (只是问一下,因为我看不到从装置注册表单到用户#edit的重定向)。

在应用程序控制器中,您确实有此行,这是不必要的: devise_parameter_sanitizer.permit(:sign_up,keys: [:first_name,:last_name,:bio]) 如果您将其他参数直接添加到devise注册表中,则只需要允许它们用于devise表单即可。但是这里您要添加一个新表单。

那么现在,我们如何处理新表格? 您的代码中的问题非常细微。您正在更改用户对象,但选择使用profiles controller包括配置文件路由(但您也有一些用户路由)。关键是,在编辑用户表单中,以下一行决定了有人点击“提交”后,HTTP请求将转到何处。

<%= simple_form_for(@user) do |f| %>

打开浏览器,并在检查模式下查看生成html的内容,它会像这样(它将有更多内容,但这对我们来说是有趣的部分)

<form action="/users" accept-charset="UTF-8" method="patch">

这意味着,当有人点击submit时,会对/users发出HTTP PATCH请求 现在,您当前的路线构建方式已无法满足要求。

因此您可以添加新路线

resources :users,only [:update]

users_controller#update中,您可以将目前拥有的代码放入profiles_controller#update中。

现在,这将使我们处于一种奇怪的情况,其中编辑部分位于配置文件控制器中,而更新部分位于用户控制器中。您可以通过两种方式播种

  1. 将所有内容移至用户控制器。这样就可以为用户控制器编辑和更新路由,编辑和更新操作(与代码中的profile_controller#edit和#update相同)和视图。别忘了删除个人资料中的内容,否则两周之内会非常混乱。
  2. 讲一个简单的表格,而不是转到users_controller,而是转到profiles_controller,您可以按自己的意愿保留设置。您可以通过添加以下行来做到这一点
 simple_form_for :user,url: user_path,method: "PATCH" ```

现在有更多评论:

routes.rb中,最后一行不正确。而且,除了手动定义常规的CRUD操作外,还应使用以下语法:

...
resources :users,only: [:edit,:update]
...

然后在profiles controller动作的update中,需要更改渲染。 (无论您将其保留在此处还是将其移动到users_controller)。应该是:

 if @user.save
   redirect_to profiles_path(@user)
 else
   render "edit"
 end

不保存用户时,您要呈现edit而不是new

最后,创建两种不同的表单有一个弊端,但我认为这不是一个很大的问题:验证。

如果您想对:bio进行验证,那么它将无法使用您当前拥有的此设置,因为在提交设备注册表格时已经创建了用户对象。在这一点上,将对验证进行测试-因此您无法测试生物是否已经存在。有很多宝石可以解决这个问题,我也找到了这篇文章以作进一步研究。 https://www.honeybadger.io/blog/multi-step-forms-in-rails/

本文链接:https://www.f2er.com/2563062.html

大家都在问