저는 코딩과 스택 오버플로에 익숙하지 않기 때문에 제가 묻는 질문이 너무 어리석지 않기를 바랍니다. 제가하려는 것은 제목에 있습니다. 사용자가 로그인 한 후 (이메일, 비밀번호), 그들은 이름, 약력 및 사진을 입력 할 수있는 새 양식. 제출을 누르고 두 가지 문제에 부딪 힐 때까지 모든 것이 계획대로 진행됩니다.
1 / 새 데이터가 고려되지 않음 2 / 리디렉션이 잘못됨
sign_up 후 사용자는 "profiles / : id / edit"로 리디렉션됩니다. 양식 제출 후 존재하지 않는 "user / : id"로 리디렉션됩니다.
컨트롤러에서 profiles # 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 / 애플리케이션 _ 컨트롤러
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 %>
감사합니다! Olivier
여기 클라라입니다 :)
그래서 나는 당신의 코드에 몇 가지 문제가 있음을 보았지만 어떤 것들이 이미 작동하는 것 같습니다. 그래서 그것은 새로운 사용자를 생성하고 그 후에 사용자를 편집하는 올바른 양식으로 리디렉션됩니다. (디바이스 등록 양식에서 user # edit 로의 리디렉션이 표시되지 않기 때문에 요청합니다.)
응용 프로그램 컨트롤러에는이 줄이 devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :bio])
필요합니다 . 이는 불필요합니다. 장치 등록 양식에 직접 추가 할 경우 장치 양식에 대한 추가 매개 변수 만 허용하면됩니다. 그러나 여기에 새 양식을 추가하고 있습니다.
이제 새 양식을 어떻게 처리 할 수 있습니까? 코드의 문제는 매우 미묘합니다. 사용자 개체를 변경하고 있지만 profiles controller
프로필 경로를 포함 하는를 사용하도록 선택했습니다 (하지만 일부 사용자 경로도 있습니다). 문제는 사용자 편집 양식에서 다음 줄이 누군가 제출을 누르 자마자 HTTP 요청이 어디로 가는지를 결정한다는 것입니다.
<%= simple_form_for(@user) do |f| %>
브라우저를 열고 html이 생성 된 검사 모드를 살펴보면 다음과 같을 것입니다 (더 많은 항목이 있지만 이것은 우리에게 흥미로운 부분입니다).
<form action="/users" accept-charset="UTF-8" method="patch">
즉, 누군가가 submit
HTTP PATCH 요청을 받았을 때 /users
현재 경로가 빌드되는 방식 으로 Now에 대해 요청 하면이를 수용하지 않습니다.
따라서 새 경로를 추가 할 수 있습니다.
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
, 당신이 지금 가지고있는이 설정에서 작동하지 않을 것이라고 가정 해 봅시다 . 왜냐하면 devise 등록 양식이 제출 될 때 사용자 객체가 이미 생성 되었기 때문입니다. 그리고이 첫 번째 지점에서 검증이 테스트되므로 바이오가 이미 있는지 여부를 테스트 할 수 없습니다. 이를 처리 할 보석이 있으며 추가 연구를 위해이 기사를 찾았습니다. https://www.honeybadger.io/blog/multi-step-forms-in-rails/
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다