Quand j'ai fait un site de copie de Furima, j'ai eu du mal car j'ai rendu la structure un peu difficile, alors j'ai décidé de le garder comme un disque. Si vous avez des suggestions, comme le rendre plus beau, s'il vous plaît.
--devise est déjà installé
profiles`` envoi_destinations`Column | Type | Options |
---|---|---|
name | string | null: false, unique: true, index:true |
string | null: false, unique: true, index:true | |
password | string | null: false |
Column | Type | Options |
---|---|---|
first_name | string | null: false |
family_name | string | null: false |
first_name_kana | string | null: false |
family_name_kana | string | null: false |
introduction | string | null: true |
year | integer | null: false |
month | integer | null: false |
day | integer | null: false |
Column | Type | Options |
---|---|---|
first_name | string | null :false |
family_name | string | null: false |
first_name_kana | string | null: false |
family_name_kana | string | null: false |
post_code | string | null: false |
prefecture | string | null: false |
city | string | null:false |
house_number | string | null: false |
building_name | string | - |
phone_number | string | unique: true, null: true |
user_id | references | null: false, foreign_key: true |
--Créer un contrôleur «utilisateurs» sous la gestion de la devise
Terminal
$ rails g devise:controllers users
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'users/registrations' }
root to: 'items#index'
end
--Description de l'association dans chaque modèle de ʻUser,
Profile,
Sending_destination`
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :profile
accepts_nested_attributes_for :profile
has_one :sending_destination
end
profile.rb
class Profile < ApplicationRecord
belongs_to :user, optional: true
end
sending_destination.rb
class SendingDestination < ApplicationRecord
belongs_to :user, optional: true
end
ʻOptional: true` est une option qui permet à la clé externe d'être nulle.
--Écrire une nouvelle action dans users / registrations_controller.rb
users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
#réduction
def new
@user = User.new
@user.build_profile
end
#réduction
end
--Modifier les inscriptions / new.html.haml correspondant à la nouvelle action
ruby:devise/registrations/new.haml.html
= form_for(@user, url: user_registration_path) do |f|
= render "devise/shared/error_messages", resource: @user
= f.text_field :nickname
= f.email_field :email
= f.password_field :password
= f.password_field :password_confirmation
= f.fields_for :profile do |p|
= p.text_field :family_name
= p.text_field :first_name
= p.text_field :family_name_kana
= p.text_field :first_name_kana
= p.select :year
= p.select :month
= p.select :day
= f.submit "prochain"
En fait, il existe des descriptions de div, d'étiquette et de classe, mais elles sont écrites simplement.
Nous utilisons fields_for
pour gérer les deux modèles. Je me réfère aux articles suivants.
[Rails] Comment envoyer des valeurs à deux modèles en même temps en utilisant le formulaire de devise (exemple: modèle utilisateur et modèle de profil)
[Rails] Comment enregistrer des données sur plusieurs modèles avec un seul form_for
users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
#réduction
def create
@user = User.new(sign_up_params)
@user.build_profile(sign_up_params[:profile_attributes])
unless @user.valid?
flash.now[:alert] = @user.errors.full_messages
render :new and return
end
session["devise.regist_data"] = {user: @user.attributes}
session["devise.regist_data"][:user]["password"] = params[:user][:password]
session[:profile_attributes] = sign_up_params[:profile_attributes]
@sending_destination = @user.build_sending_destination
render :new_sending_destination
end
#réduction
protected
#réduction
end
Vérifiez si le paramètre viole la validation avec la méthode «valide?».
La fonction session
qui conserve les informations côté client est utilisée pour que les informations ne soient pas perdues même si la page change.
Pour que la session contienne les informations sous la forme d'un objet de hachage, les données sont formatées à l'aide de la méthode des attributs. En outre, bien que les informations de mot de passe soient incluses dans les paramètres, les informations de mot de passe ne sont pas incluses lorsque les données sont formatées par la méthode des attributs. Vous devez donc attribuer à nouveau le mot de passe à la session.
Créez une instance du modèle send_destination
associé à l'instance @ user
créée cette fois avec build_sending_destination
.
Ensuite, affichez la vue de l'action new_sending_destination
qui affiche la page sur laquelle vous souhaitez enregistrer vos informations d'adresse.
--Définir le routage de l'action new_sending_destination
qui affiche la page d'enregistrement de l'adresse
--Définir le routage de l'action create_sending_destination
pour enregistrer l'adresse
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'users/registrations' }
devise_scope :user do
get 'sending_destinations', to: 'users/registrations#new_sending_destination'
post 'sending_destinations', to: 'users/registrations#create_sending_destination'
end
root to: 'items#index'
end
--Créez le fichier de vue correspondant new_sending_destination.html.haml
ruby:devise/registrations/new_sending_destination.html.haml
= form_for @sending_destination do |f|
= render "devise/shared/error_messages", resource: @sending_destination
= f.text_field :family_name
= f.text_field :first_name
= f.text_field :family_name_kana
= f.text_field :first_name_kana
= f.text_field :post_code
= f.text_field :prefecture
= f.text_field :city
= f.text_field :house_number
= f.text_field :building_name
= f.number_field :phone_number
= f.submit "s'inscrire"
users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
#réduction
def create_sending_destination
@user = User.new(session["devise.regist_data"]["user"])
@profile = @user.build_profile(session[:profile_attributes])
@sending_destination = SendingDestination.new(sending_destination_params)
unless @sending_destination.valid?
flash.now[:alert] = @sending_destination.errors.full_messages
render :new_sending_destination and return
end
@user.build_sending_destination(@sending_destination.attributes)
@user.save
@profile.save
session["devise.regist_data"]["user"].clear
session[:profile_attributes].clear
sign_in(:user, @user)
redirect_to root_path
end
protected
def sending_destination_params
params.require(:sending_destination).permit(
:first_name,
:family_name,
:first_name_kana,
:family_name_kana,
:post_code,
:prefecture, :city,
:house_number,
:building_name,
:phone_number
)
end
end
Les informations conservées en session sont attribuées à chaque instance de «@ user» et «@ prfile».
Vérifiez les informations d'adresse sur la deuxième page avec «valide?».
Attribuez les paramètres envoyés à l'aide de build_sending_destination à @ user
, qui contient la session suspendue. Puis enregistrez-le dans le tableau en utilisant la méthode save
.
Supprimez la session en utilisant la méthode «clear».
Connectez-vous avec sign_in (: user, @user)
et passez à la première page avec redirect_to root_path
.
Il peut être implémenté par la méthode ci-dessus. En utilisant fields_for
sur la première page, j'ai eu beaucoup de mal à assigner une session, mais grâce à cela, j'ai pu réfléchir à son fonctionnement. Je ne l'ai pas expliqué en détail, mais j'ai essayé d'écrire un article qui sert également de sortie, donc j'espère qu'il sera utile autant que possible.
Recommended Posts