devise in rails를 사용하여 가입 후 두 번째 단계를 추가하여 이름, 약력 및 사진으로 사용자 업데이트 시도

올리비에 지라르 도트

저는 코딩과 스택 오버플로에 익숙하지 않기 때문에 제가 묻는 질문이 너무 어리석지 않기를 바랍니다. 제가하려는 것은 제목에 있습니다. 사용자가 로그인 한 후 (이메일, 비밀번호), 그들은 이름, 약력 및 사진을 입력 할 수있는 새 양식. 제출을 누르고 두 가지 문제에 부딪 힐 때까지 모든 것이 계획대로 진행됩니다.

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">

즉, 누군가가 submitHTTP PATCH 요청을 받았을 때 /users현재 경로가 빌드되는 방식 으로 Now에 대해 요청 하면이를 수용하지 않습니다.

따라서 새 경로를 추가 할 수 있습니다.

resources :users, only [:update]

에 현재 users_controller#update가지고있는 코드를 입력 할 수 있습니다 profiles_controller#update.

이제 편집 부분이 프로필 컨트롤러에 있고 업데이트 부분이 사용자 컨트롤러에있는 이상한 상황이 발생합니다. 두 가지 방법으로 뿌릴 수 있습니다

  1. 모든 것을 사용자 컨트롤러로 이동하십시오. 사용자 컨트롤러에 대한 경로를 편집하고 업데이트 할 수 있도록 작업 (코드의 profile_controller # edit 및 #update와 동일 함) 및보기를 편집하고 업데이트합니다. 프로필에서 항목을 삭제하는 것을 잊지 마십시오. 또는 2 주 후에는 매우 혼란 스러울 것입니다.)
  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, 당신이 지금 가지고있는이 설정에서 작동하지 않을 것이라고 가정 해 봅시다 . 왜냐하면 devise 등록 양식이 제출 될 때 사용자 객체가 이미 생성 되었기 때문입니다. 그리고이 첫 번째 지점에서 검증이 테스트되므로 바이오가 이미 있는지 여부를 테스트 할 수 없습니다. 이를 처리 할 보석이 있으며 추가 연구를 위해이 기사를 찾았습니다. https://www.honeybadger.io/blog/multi-step-forms-in-rails/

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관