使用rails进行设计,尝试在注册后添加第二步,以使用名称,个人简历和照片更新用户

问题描述 投票:0回答:1

我是编码和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, only: [:show, :create, :new]
    resources :messages, only: [:create]
  end
  resources :participations, only: [:create, :update]

  resources :profiles, only: [:show, :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, :index, :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, :last_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, class_name: "Review", 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 %>

谢谢!奥利维尔

ruby-on-rails ruby devise rubygems simple-form
1个回答
0
投票

这里是克拉拉:)

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

© www.soinside.com 2019 - 2024. All rights reserved.