我是编码和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 %>
谢谢!奥利维尔
这里是克拉拉:)
所以我发现您的代码存在一些问题,但似乎有些东西已经在起作用,这很好。因此,它正在创建一个新用户,然后重定向到您在其中编辑用户的正确表单,对吗? (只是问一下,因为我看不到从装置注册表单到用户#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
中。
现在,这将给我们带来一种奇怪的情况,其中编辑部分位于配置文件控制器中,而更新部分位于用户控制器中。您可以通过两种方式解决这个问题
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/