Je souhaite associer des modèles avec une relation 1: 1 afin que chaque donnée de modèle puisse être envoyée au formulaire en même temps. En d'autres termes, le but de cette fois est de pouvoir gérer deux modèles de données dans la méthode de formulaire.
Cette fois, le modèle User et le modèle User_profile ont une relation 1: 1 afin que les deux informations utilisateur puissent être modifiées en même temps dans la méthode de formulaire.
M
Fichier de migration
class CreateUserProfiles < ActiveRecord::Migration[6.0]
def change
create_table :user_profile do |t|
t.string :twitter_url
t.string :program_lang
t.string :image
t.references :user, foreign_key: true
t.timestamps
end
end
end
t.references :user, foreign_key: true
En définissant une clé externe, le modèle User et le modèle User_profile sont liés.
$ rails db:migrate
models/user_profile.rb
class Prof < ApplicationRecord
belongs_to :user
end
models/user.rb
class User < ApplicationRecord
has_one :user_profile
accepts_nested_attributes_for :user_profile
end
ʻAccepts_nested_attributes_for: user_profileest pour les données de formulaire imbriquées. Plus précisément, il peut se résumer sous la forme de
{user: {user_profile_attributes: {program_lang: 〇〇, twitter_url: 〇〇, image: 〇〇}}}` lors de paramètres forts.
C
users_controller.rb
def create
@user = User.new(user_params)
@user.build_user_profile
if @user.save
・ ・ ・
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, user_profile_attributes: [:id, :program_lang, :twitter_url, :image])
end
Ce à quoi vous devez faire attention ici est @ user.build_user_profile
.
Si vous n'avez pas créé d'instance du modèle user_profile à l'avance, le formulaire du côté Affichage ne sera pas affiché.
V
ruby:edit.html.erb
.container
= form_with model: @user, local: true do |form|
= form.fields_for :user_profile do |prof|
.form-image
= prof.file_field :image
.form-group
= form.text_field :name
= form.text_field :email
= form.fields_for :user_profile do |prof|
.form-group
= prof.text_field :program_lang
= prof.text_field :twitter_url
.row
= form.submit "Éditer"
C'est fields_for
qui reconnaît encore un autre modèle de données dans le formulaire.
En créant un formulaire à l'intérieur du formulaire, vous pouvez envoyer les données côté serveur dans un lot en appuyant simplement sur le bouton «Modifier».