Я пишу приложение на ruby on rails. И мне не очень...

Créé le : 7 décembre 2025

Répondu en utilisant GPT-5.1 Thinking par Chat01

Question

image.png
image.png
image.png
image.png

Я пишу приложение на ruby on rails. И мне не очень нравятся вьюхи. они выглядят хорошо но кривовато. Я хочу, чтобы во первых email помещался в карточку а не вылазил. также хотелось бы чтобы соседние карточки были одного размера снизу, а не разных. также я не хочу вообще использовать style="" во вьюхах, а хочу перенести все в стили в .scss файлы. Но также, я хочу, чтобы все стили, которые можно написать с помщью бутстрап, а не с помощью .scss. Также я хочу, чтобы ты убрал все строгие размеры и сделал размеры адаптивными.

_address_card.html.erb:

<div class="col-md-6"> <div class="border rounded-3 p-3 h-100"> <h6 class="mb-2"> <%= address.country %>, <%= address.city %> </h6>
text
<p class="mb-1"> <%= "#{address.street} #{address.house}" %> <% if address.apartment.present? %> , <%= t('account.addresses.apartment') %> <%= address.apartment %> <% end %> </p> <p class="mb-1 text-muted"> <%= t('account.addresses.zip') %>: <%= address.zip_code %> </p> <% if address.entrance.present? || address.floor.present? %> <p class="mb-0 text-muted"> <%= [ (address.entrance.present? && "#{t('account.addresses.entrance')} #{address.entrance}"), (address.floor.present? && "#{t('account.addresses.floor')} #{address.floor}") ].compact.join(', ') %> </p> <% end %>
</div> </div>

_tabs.html+desktop.erb:

<div class="account-sidebar-card"> <div class="account-user-header"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar" %> <% else %> <div class="account-user-avatar d-flex align-items-center justify-content-center bg-light"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %>
text
<h5 class="mb-0"> <%= current_user.profile&.nickname || current_user.email %> </h5> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small>
</div> <div class="list-group account-tabs"> <%= link_to t('account.tabs.my_profile'), account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :profile}" %>
text
<%= link_to t('account.tabs.edit_user'), edit_user_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :edit_user}" %> <%= link_to t('account.tabs.edit_profile'), edit_profile_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :edit_profile}" %> <%= link_to t('account.tabs.addresses'), addresses_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :addresses}" %>
</div> </div>

_tabs.html+mobile.erb:

<div class="mb-3 text-center"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar mb-2" %> <% else %> <div class="account-user-avatar d-inline-flex align-items-center justify-content-center bg-light mb-2"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %> <div class="fw-semibold"> <%= current_user.profile&.nickname || current_user.email %> </div> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small> </div> <div class="nav nav-pills justify-content-between flex-wrap gap-2 mb-3"> <%= link_to t('account.tabs.my_profile'), account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :profile}" %>

<%= link_to t('account.tabs.edit_user'),
edit_user_account_path,
class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_user}" %>

<%= link_to t('account.tabs.edit_profile'),
edit_profile_account_path,
class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_profile}" %>

<%= link_to t('account.tabs.addresses'),
addresses_account_path,
class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :addresses}" %>

</div>

addresses.html.erb:

<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout" style="max-width: 1100px; width: 100%;"> <div class="account-sidebar"> <%= render 'account/tabs', active: :addresses %> </div>
text
<div class="account-main"> <div class="account-main-card"> <h3 class="mb-4"><%= t('account.addresses.title') %></h3> <% if @addresses.present? %> <div class="row g-3 mb-4"> <%= render partial: 'account/address_card', collection: @addresses, as: :address %> </div> <% else %> <p class="text-muted mb-4"> <%= t('account.addresses.empty') %> </p> <% end %> <hr class="my-3"> <h5 class="mb-3"> <%= t('account.addresses.new_title') %> </h5> <%= render 'devise/shared/error_messages', resource: @address %> <%= form_for(@address, url: create_address_account_path, html: { method: :post, novalidate: true, data: { turbo: false } }) do |f| %> <%= render 'devise/registrations/address_fields', f: f, context: :edit %> <div class="d-grid"> <%= f.submit t('account.addresses.save_new'), class: 'btn btn-success' %> </div> <% end %> </div> </div>
</div> </div>

edit_profile.html.erb:

<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout" style="max-width: 1100px; width: 100%;"> <div class="account-sidebar"> <%= render 'account/tabs', active: :edit_profile %> </div>
text
<div class="account-main"> <div class="account-main-card"> <h3 class="mb-4"><%= t('account.edit_profile.title') %></h3> <%= render 'devise/shared/error_messages', resource: @profile %> <%= form_for(current_user, url: update_profile_account_path, html: { method: :patch, novalidate: true, multipart: true, data: { turbo: false } }) do |f| %> <%= f.fields_for :profile, @profile do |pf| %> <%= render 'devise/registrations/profile_fields', f: pf, context: :edit %> <% end %> <div class='d-grid mb-2'> <%= f.submit t('account.edit_profile.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div>
</div> </div>

edit_user.html.erb:

<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout" style="max-width: 1100px; width: 100%;"> <div class="account-sidebar"> <%= render 'account/tabs', active: :edit_user %> </div>
text
<div class="account-main"> <div class="account-main-card"> <h3 class="mb-4"><%= t('account.edit_user.title') %></h3> <%= render 'devise/shared/error_messages', resource: current_user %> <%= form_for(current_user, url: update_user_account_path, html: { method: :patch, novalidate: true, data: { turbo: false } }) do |f| %> <div class="mb-3"> <%= f.email_field :email, autocomplete: 'email', placeholder: t('devise.registrations.edit.email_placeholder'), class: 'form-control' %> </div> <hr class="my-3"> <h5 class="mb-3"><%= t('account.edit_user.security_title') %></h5> <div class='mb-3'> <%= f.password_field :password, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.new_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :password_confirmation, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.confirm_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :current_password, autocomplete: 'current-password', placeholder: t('devise.registrations.edit.current_password_placeholder'), class: 'form-control' %> </div> <div class='d-grid mb-2'> <%= f.submit t('devise.registrations.edit.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div>
</div> </div>

show.html.erb:

<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout" style="max-width: 1100px; width: 100%;"> <div class="account-sidebar"> <%= render 'account/tabs', active: :profile %> </div>
text
<div class="account-main"> <div class="account-main-card"> <h3 class="mb-4"><%= t('account.my_profile.title') %></h3> <div class="row gy-4"> <div class="col-md-4 text-center"> <% if @profile&.avatar&.attached? %> <%= image_tag @profile.avatar.variant(:preview), class: "img-fluid rounded-3 mb-3" %> <% else %> <div class="bg-light rounded-3 d-flex align-items-center justify-content-center" style="height: 220px;"> <span class="text-muted"> <%= t('account.my_profile.no_avatar') %> </span> </div> <% end %> <p class="mt-2 mb-0 fw-semibold"> <%= @profile&.nickname || current_user.email %> </p> <small class="text-muted"><%= current_user.email %></small> </div> <div class="col-md-8"> <h5 class="mb-3"><%= t('account.my_profile.basic_info') %></h5> <dl class="row mb-4"> <dt class="col-sm-4"><%= t('account.labels.full_name') %></dt> <dd class="col-sm-8"> <%= [@profile&.first_name, @profile&.last_name].compact.join(' ').presence || '—' %> </dd> <dt class="col-sm-4">Email</dt> <dd class="col-sm-8"><%= current_user.email %></dd> <dt class="col-sm-4"><%= t('account.labels.birthday') %></dt> <dd class="col-sm-8"><%= @profile&.birthday&.strftime('%d.%m.%Y') || '—' %></dd> <dt class="col-sm-4"><%= t('account.labels.metrics') %></dt> <dd class="col-sm-8"> <% if @profile&.weight || @profile&.height %> <%= [@profile&.weight && "#{@profile.weight} kg", @profile&.height && "#{@profile.height} cm"].compact.join(' / ') %> <% else %> <% end %> </dd> </dl> <h5 class="mb-3"><%= t('account.my_profile.about') %></h5> <p class="mb-0"> <%= @profile&.description.presence || t('account.my_profile.no_description') %> </p> </div> </div> </div> </div>
</div> </div>

account.scss:
.account-layout {
display: flex;
gap: 1.5rem;
align-items: flex-start;
}

.account-sidebar {
width: 260px;
}

.account-main {
flex: 1;
}

.account-sidebar-card,
.account-main-card {
background: #ffffff;
border-radius: 0.75rem;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
padding: 1.5rem;
}

.account-user-header {
text-align: center;
margin-bottom: 1.5rem;
}

.account-user-avatar {
width: 95px;
height: 95px;
border-radius: 50%;
object-fit: cover;
box-shadow: 0 0 0 4px #ffffff, 0 4px 10px rgba(0, 0, 0, 0.15);
margin: 0 auto 1rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
}

.account-tabs .list-group-item {
border: none;
border-radius: 0.5rem;
margin-bottom: 0.25rem;
font-weight: 500;
}

.account-tabs .list-group-item.active {
background-color: #198754;
color: #ffffff;
}

.account-tabs .list-group-item:hover {
background-color: #e9f5ef;
}

@media (max-width: 768px) {
.account-layout {
flex-direction: column;
}

.account-sidebar,
.account-main {
width: 100%;
}

.account-sidebar-card {
margin-bottom: 1rem;
}

.account-tabs {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}

.account-tabs .list-group-item {
margin-bottom: 0;
flex: 1 1 calc(50% - 0.5rem);
text-align: center;
}
}

devise/form_card.scss:
.auth-card {
width: 400px;
z-index: 1;
overflow: visible;
}

.auth-card::before {
content: "";
position: absolute;
top: -50px;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 60px;
background: #f7edb6;
border-radius: 50% 50% 0 0;
box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.1);
}

.auth-card::after {
content: "";
position: absolute;
top: -70px;
left: 50%;
transform: translateX(-50%);
width: 75px;
height: 75px;
border-radius: 50%;
background-size: contain;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
background-color: #abf5f5;
background-image: url("/assets/shared/logo.png");
}

@media (max-width: 600px) {
.auth-card {
width: 330px;
margin: 0 auto;
}
}

.auth-card--wide {
width: 800px;
max-width: 100%;
}

@media (max-width: 768px) {
.auth-card--wide {
width: 100%;
max-width: 100%;
margin: 0 auto;
padding-inline: 1rem;
}
}

сюда кидай полностью измененные файлы без комментов, чтобы я их копировал и вставлял. также не меняй структуру и названия переменных

Réflexion

Addressing layout and style adjustments

The user wants their email in the profile card to either wrap or truncate to avoid overflowing. For the neighbor cards, they want equal height with bottom alignment. Adjusting the layout with flexible styles, I could apply flex: 1 to the cards, ensuring they match heights. I’ll move inline styles to SCSS as requested.

Adjusting inline styles to SCSS

The user provided inline styles for elements like .account-layout and wants them moved to SCSS, without changing structure or variable names. I’ll move the width and max-width rules to .account-layout in SCSS, ensuring it’s centered by applying margin-inline: auto. For the outside wrapper, I'll adjust styles accordingly without altering the layout’s markup.

Making widths more responsive in SCSS

The user prefers responsive design rather than strict fixed widths or heights. I’ll adjust the account-sidebar and account-user-avatar to be more flexible, using relative units or max-width for layout flexibility. For avatars, I’ll apply clamp() for responsive sizing, avoiding functions if older CSS. I’ll convert strict sizes in devise/form_card.scss to max-width or width: 100%.

Balancing strict sizes and using Bootstrap utilities

The user wants to avoid strict sizes, but decorative pseudo-elements' shapes might remain fixed. It's safe to convert them to relative units with rem or percentages. They prefer using Bootstrap utility classes rather than custom SCSS where possible, though they also want layout modifications in SCSS. I'll provide fully modified files, sticking to constraints like not changing logic or variable names where possible.

Using Bootstrap and adjustments for layout

I’ll rely on Bootstrap classes for width/spacing instead of custom SCSS where possible, keeping classes like .account-layout, with minimal changes. For email wrapping, I can use .text-truncate or .text-break to manage overflow. For equal card heights, I’ll apply h-100 and d-flex without inline styles, ensuring both cards stretch to the same height.

Making cards equal height and adjusting dimensions

To match card heights, I’ll use flex: 1 for both .account-sidebar and .account-main while setting .account-layout to have align-items: stretch. For widths, I'll avoid strict pixel values; instead, I plan to use min-width, rem, or percentages. For the sidebar, flex: 0 0 260px with responsive adjustments should work, ensuring uniform bottom edges.

Making layout fully responsive with Bootstrap

To meet the responsive design need, I’ll adjust .account-layout to use a container class from Bootstrap, which automatically handles width breakpoints. I’ll also switch from custom width values to Bootstrap’s layout classes, keeping everything fluid and more in line with user preferences. The .account-layout will no longer control width directly.

Ensuring equal heights with Bootstrap utilities

To make the cards have equal heights, I’ll use the Bootstrap h-100 class on the .account-sidebar-card and .account-main-card. I’ll also adjust .account-layout by adding the align-items-stretch class to ensure the cards stretch to fill the available height. This should keep things simple without altering the structure.

Simplifying layout with Bootstrap utility classes

I can simplify the layout by adding d-flex and other Bootstrap classes directly to the .account-layout container. This lets me remove custom CSS for display, gap, and align-items, as Bootstrap handles it for me. I'll adjust the .account-layout class for align-items: stretch and keep changes minimal in SCSS.

Adjusting avatar placeholder and handling flexbox in small screens

For the avatar placeholder, I'll switch from inline style to using Bootstrap's min-vh class as the user prefers. I'll also set an aspect ratio with custom CSS to maintain the square shape while keeping it responsive. For small screens, I'll adjust flex properties, ensuring the layout remains consistent.

Handling layout adjustments for responsiveness

To meet the user's request, we'll avoid strict heights and instead use relative min-height for components. I'll also fix the email's display overflow by applying the text-break class. For the profile page, I’ll ensure the layout responds to different screen sizes with Bootstrap's utilities. I'll clean up any inline styles and adjust SCSS for flexibility.

Adjusting layout and using Bootstrap classes

We’re adopting Bootstrap's responsive layout for different screen sizes, replacing custom CSS with classes like d-flex, flex-column, and gap-4. We’ll adjust the .account-sidebar by adding appropriate classes and keeping the layout responsive. I’ll simplify the CSS by removing direct width settings and use Bootstrap for flexibility, ensuring a cleaner and more adaptable design.

Unifying card heights and aligning layout

I’ll ensure both the sidebar and main cards have the same height by adding h-100 and using Bootstrap classes like align-items-stretch to ensure the layout stretches correctly. For the avatar placeholder, I’ll set min-height: 12rem for a responsive and simple design. Most changes will focus on adjusting classes without altering the overall structure.

Streamlining layout styles and simplifying code

I’m modifying the structure to align the sidebar and main card heights, ensuring responsiveness using Bootstrap while minimizing custom CSS. I’ll adjust the avatar placeholder to ensure it’s consistent across devices, and remove unnecessary styling for .account-sidebar and .account-main. The goal is to rely more on Bootstrap for cleanliness and simplicity.

Simplifying mobile layout changes and cleanup

I'm removing unnecessary adjustments for .account-layout in the media query, focusing on cleaner mobile design with Bootstrap's flex utilities. I'll also implement some minor updates, especially for the .auth-card styling, ensuring proper width settings based on screen size. Some files need careful review before finalizing to prevent errors.

Crafting the final files

For the _address_card.html.erb, the structure remains unchanged with no major tweaks needed, just some necessary values to display address details clearly.

Moving to the _tabs.html+desktop.erb, we'll adjust the classes as discussed earlier to align with the new layout decisions. It seems like a straightforward change to ensure proper styling. I'll proceed carefully with these updates.

Finalizing account pages updates

It looks like I've carefully gone through the account pages and adjusted everything as needed, adding classes where appropriate, maintaining the structure, and ensuring the layout is consistent. I’ve also eliminated inline styles and replaced them where necessary. All looks good for the final version! Now I can proceed with any extra adjustments if needed or just confirm everything's set.

Thought for 8m 57s

Réponse

_address_card.html.erb

erb
<div class="col-md-6"> <div class="border rounded-3 p-3 h-100"> <h6 class="mb-2"> <%= address.country %>, <%= address.city %> </h6> <p class="mb-1"> <%= "#{address.street} #{address.house}" %> <% if address.apartment.present? %> , <%= t('account.addresses.apartment') %> <%= address.apartment %> <% end %> </p> <p class="mb-1 text-muted"> <%= t('account.addresses.zip') %>: <%= address.zip_code %> </p> <% if address.entrance.present? || address.floor.present? %> <p class="mb-0 text-muted"> <%= [ (address.entrance.present? && "#{t('account.addresses.entrance')} #{address.entrance}"), (address.floor.present? && "#{t('account.addresses.floor')} #{address.floor}") ].compact.join(', ') %> </p> <% end %> </div> </div>

_tabs.html+desktop.erb

erb
<div class="account-sidebar-card h-100 d-flex flex-column"> <div class="account-user-header"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar" %> <% else %> <div class="account-user-avatar d-flex align-items-center justify-content-center bg-light"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %> <h5 class="mb-0 text-break"> <%= current_user.profile&.nickname || current_user.email %> </h5> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small> </div> <div class="list-group account-tabs"> <%= link_to t('account.tabs.my_profile'), account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :profile}" %> <%= link_to t('account.tabs.edit_user'), edit_user_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :edit_user}" %> <%= link_to t('account.tabs.edit_profile'), edit_profile_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :edit_profile}" %> <%= link_to t('account.tabs.addresses'), addresses_account_path, class: "list-group-item list-group-item-action #{'active' if local_assigns[:active] == :addresses}" %> </div> </div>

_tabs.html+mobile.erb

erb
<div class="mb-3 text-center"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar mb-2" %> <% else %> <div class="account-user-avatar d-inline-flex align-items-center justify-content-center bg-light mb-2"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %> <div class="fw-semibold text-break"> <%= current_user.profile&.nickname || current_user.email %> </div> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small> </div> <div class="nav nav-pills justify-content-between flex-wrap gap-2 mb-3"> <%= link_to t('account.tabs.my_profile'), account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :profile}" %> <%= link_to t('account.tabs.edit_user'), edit_user_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_user}" %> <%= link_to t('account.tabs.edit_profile'), edit_profile_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_profile}" %> <%= link_to t('account.tabs.addresses'), addresses_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :addresses}" %> </div>

addresses.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :addresses %> </div> <div class="account-main flex-fill"> <div class="account-main-card h-100"> <h3 class="mb-4"><%= t('account.addresses.title') %></h3> <% if @addresses.present? %> <div class="row g-3 mb-4"> <%= render partial: 'account/address_card', collection: @addresses, as: :address %> </div> <% else %> <p class="text-muted mb-4"> <%= t('account.addresses.empty') %> </p> <% end %> <hr class="my-3"> <h5 class="mb-3"> <%= t('account.addresses.new_title') %> </h5> <%= render 'devise/shared/error_messages', resource: @address %> <%= form_for(@address, url: create_address_account_path, html: { method: :post, novalidate: true, data: { turbo: false } }) do |f| %> <%= render 'devise/registrations/address_fields', f: f, context: :edit %> <div class="d-grid"> <%= f.submit t('account.addresses.save_new'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

edit_profile.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :edit_profile %> </div> <div class="account-main flex-fill"> <div class="account-main-card h-100"> <h3 class="mb-4"><%= t('account.edit_profile.title') %></h3> <%= render 'devise/shared/error_messages', resource: @profile %> <%= form_for(current_user, url: update_profile_account_path, html: { method: :patch, novalidate: true, multipart: true, data: { turbo: false } }) do |f| %> <%= f.fields_for :profile, @profile do |pf| %> <%= render 'devise/registrations/profile_fields', f: pf, context: :edit %> <% end %> <div class='d-grid mb-2'> <%= f.submit t('account.edit_profile.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

edit_user.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :edit_user %> </div> <div class="account-main flex-fill"> <div class="account-main-card h-100"> <h3 class="mb-4"><%= t('account.edit_user.title') %></h3> <%= render 'devise/shared/error_messages', resource: current_user %> <%= form_for(current_user, url: update_user_account_path, html: { method: :patch, novalidate: true, data: { turbo: false } }) do |f| %> <div class="mb-3"> <%= f.email_field :email, autocomplete: 'email', placeholder: t('devise.registrations.edit.email_placeholder'), class: 'form-control' %> </div> <hr class="my-3"> <h5 class="mb-3"><%= t('account.edit_user.security_title') %></h5> <div class='mb-3'> <%= f.password_field :password, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.new_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :password_confirmation, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.confirm_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :current_password, autocomplete: 'current-password', placeholder: t('devise.registrations.edit.current_password_placeholder'), class: 'form-control' %> </div> <div class='d-grid mb-2'> <%= f.submit t('devise.registrations.edit.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

show.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :profile %> </div> <div class="account-main flex-fill"> <div class="account-main-card h-100"> <h3 class="mb-4"><%= t('account.my_profile.title') %></h3> <div class="row gy-4"> <div class="col-md-4 text-center"> <% if @profile&.avatar&.attached? %> <%= image_tag @profile.avatar.variant(:preview), class: "img-fluid rounded-3 mb-3" %> <% else %> <div class="bg-light rounded-3 d-flex align-items-center justify-content-center account-avatar-placeholder"> <span class="text-muted"> <%= t('account.my_profile.no_avatar') %> </span> </div> <% end %> <p class="mt-2 mb-0 fw-semibold text-break"> <%= @profile&.nickname || current_user.email %> </p> <small class="text-muted text-break"><%= current_user.email %></small> </div> <div class="col-md-8"> <h5 class="mb-3"><%= t('account.my_profile.basic_info') %></h5> <dl class="row mb-4"> <dt class="col-sm-4"><%= t('account.labels.full_name') %></dt> <dd class="col-sm-8"> <%= [@profile&.first_name, @profile&.last_name].compact.join(' ').presence || '—' %> </dd> <dt class="col-sm-4">Email</dt> <dd class="col-sm-8 text-break"><%= current_user.email %></dd> <dt class="col-sm-4"><%= t('account.labels.birthday') %></dt> <dd class="col-sm-8"><%= @profile&.birthday&.strftime('%d.%m.%Y') || '—' %></dd> <dt class="col-sm-4"><%= t('account.labels.metrics') %></dt> <dd class="col-sm-8"> <% if @profile&.weight || @profile&.height %> <%= [@profile&.weight && "#{@profile.weight} kg", @profile&.height && "#{@profile.height} cm"].compact.join(' / ') %> <% else %> <% end %> </dd> </dl> <h5 class="mb-3"><%= t('account.my_profile.about') %></h5> <p class="mb-0"> <%= @profile&.description.presence || t('account.my_profile.no_description') %> </p> </div> </div> </div> </div> </div> </div>

account.scss

scss
.account-layout { width: 100%; } .account-sidebar-card, .account-main-card { background: #ffffff; border-radius: 0.75rem; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); padding: 1.5rem; } .account-user-header { text-align: center; margin-bottom: 1.5rem; } .account-user-avatar { width: 6rem; height: 6rem; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 4px #ffffff, 0 4px 10px rgba(0, 0, 0, 0.15); margin: 0 auto 1rem; display: flex; align-items: center; justify-content: center; font-size: 2rem; } .account-tabs .list-group-item { border: none; border-radius: 0.5rem; margin-bottom: 0.25rem; font-weight: 500; } .account-tabs .list-group-item.active { background-color: #198754; color: #ffffff; } .account-tabs .list-group-item:hover { background-color: #e9f5ef; } .account-avatar-placeholder { min-height: 12rem; } @media (max-width: 768px) { .account-sidebar-card { margin-bottom: 1rem; } .account-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; } .account-tabs .list-group-item { margin-bottom: 0; flex: 1 1 calc(50% - 0.5rem); text-align: center; } }

devise/form_card.scss

scss
.auth-card { width: 100%; max-width: 25rem; z-index: 1; overflow: visible; margin: 0 auto; } .auth-card::before { content: ""; position: absolute; top: -3.125rem; left: 50%; transform: translateX(-50%); width: 6.25rem; height: 3.75rem; background: #f7edb6; border-radius: 50% 50% 0 0; box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.1); } .auth-card::after { content: ""; position: absolute; top: -4.375rem; left: 50%; transform: translateX(-50%); width: 4.6875rem; height: 4.6875rem; border-radius: 50%; background-size: contain; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); background-color: #abf5f5; background-image: url("/assets/shared/logo.png"); } @media (max-width: 600px) { .auth-card { max-width: 20.625rem; } } .auth-card--wide { width: 100%; max-width: 50rem; } @media (max-width: 768px) { .auth-card--wide { width: 100%; max-width: 100%; margin: 0 auto; padding-inline: 1rem; } }

Question

image.png
image.png

Так. смотри. Когда у меня отображается email, то он уже помещается. но если они слишком короткие, то карточка слева получается слишком маленькой как на картинке, хотелось бы, чтобы минимальный размер был чуть побольше. также ты не все стили перенес на бутстрап, которые можно было. Сначала точно также полность скинь код для решения этих проблем. А дальше есть еще одна вещь. Дело в том, что когда пользователь регистриурется первым у него появляется экран с паролем и почтой. Дальше, если он правильно их ввел, тогда он переносится на создаия профиля, но если при создании профиля он введет что-то не так при создании профиля, тогда он переносится на обратно на страницу с паролями, а они сбрасываются и ему приходится их сначала вводить. как можно это решить?

Réflexion

Addressing UI tweaks and registration flow in Rails

User wants UI tweaks, including adjusting the account sidebar’s min-height and moving inline styles to Bootstrap/SCSS. I need to make sure the structure and variable names are consistent with their preferences.

For the registration flow issue, I'll suggest handling multi-step registration and persisting form data in Rails to prevent resets.

Handling registration flow and validation in Devise

It sounds like the user is implementing a multi-step registration flow with Devise. I'll suggest overriding the Devise registration controller and using render instead of redirect to avoid resetting fields. Storing partial user data in the session could also help maintain state across steps, preventing data loss on validation failure.

Fixing issue with registration flow and field persistence

The issue seems to be that when validation fails on the profile, the user isn’t saved, and redirect_to instead of render causes the fields to reset. I'll suggest changing the controller to use render for the new view after validation failure so that the email and password fields persist.

Fixing profile flow and validation handling

To fix the issue, I can suggest either using render :new instead of a redirect_to when validation fails or restructuring the flow so the sign-up page includes both user and profile fields. Another option is to ensure form fields retain values using f.object or a preserve attribute. If they still use a two-step flow, handling profile creation as an update and avoiding unnecessary redirects will help.

Proposing multi-step registration solutions

To solve this, I can propose 2–3 approaches:

  1. Use a single-step form with both user and profile fields together; though they intentionally separated these steps.
  2. For two-step registration without clearing data: after the user signs up, stay on the profile page if there's an error, preventing a reset of fields. We need to ensure the profile form uses @profile validations and handle failure with render :edit.

Adjusting UI styling preferences with Bootstrap and SCSS

First, we need to send the full code to address the UI issues: setting the minimum height for the sidebar, replacing SCSS with more Bootstrap classes, etc. For the sign-up form, we need to strip styles to rely on Bootstrap's utility classes, such as replacing custom box-shadow with Bootstrap's shadow-sm. We'll also revise the use of custom SCSS like for the account sidebar.

Aligning SCSS with Bootstrap classes

They’d like us to retain structure and variable names while integrating Bootstrap. We can add additional classes but need to minimize changes. For example, styles like .account-avatar-placeholder can't be fully replaced with Bootstrap, but many others like .account-user-header and .account-tabs can be simplified using Bootstrap utilities. I’ll update HTML to replace specific SCSS rules with Bootstrap classes and adjust the CSS accordingly. The goal is maintaining structure while optimizing with Bootstrap.

Adjusting layout for responsive and consistent height

The .account-layout rule may no longer be needed since Bootstrap grid handles structure now. However, the user may be using it elsewhere, so we'll keep it simple without overcomplicating things. For the sidebar, we need to ensure a minimum height for consistency in card sizes and bottom-alignment. The align-items-stretch property should solve the issue with uneven heights, but we might need some tweaks in the layout for complete alignment.

Fixing misaligned cards with flexbox adjustments

The issue with misaligned cards may be due to the outer align-items-start overriding the inner flex container’s align-items-stretch. To fix this, we could ensure that the .account-sidebar and .account-main both have h-100 set. This will allow the flex children to stretch and match height within the container.

Fixing the card size discrepancy

I suspect the issue might be that we didn't apply h-100 or equal height to .account-sidebar and .account-main. Since the user mentioned they want the sidebar and the main card to be the same height at the bottom, I could apply a min-height to .account-sidebar-card. This may help balance their size more evenly.

Updating for Bootstrap integration

The user wants to optimize the account layout using Bootstrap classes for consistency. For example, adding min-height to .account-sidebar-card, switching from custom padding/radius/shadow to Bootstrap’s classes, and updating SCSS styles. We'll keep modifications minimal to align with Bootstrap utilities while retaining the user’s previous requests for customization in hover/active states.

Updating account styles and registration flow

I’m updating the code but keeping the structure intact as requested, using Bootstrap for consistency and keeping some customizations. For avatars and cards, I'll adjust SCSS and classes, maybe reducing unnecessary styles. For registration flow, I'll suggest handling it with a two-step process, maintaining user details through session data on failed validation.

Improving registration flow handling

For registration, it's best to separate the sign-up and profile creation steps. I’d suggest letting Devise handle the user creation at the first step, then redirecting to the profile form with after_sign_up_path_for. On profile validation failure, re-render the profile form, avoiding a redirect to the sign-up page. Detailed code will be provided.

Updating view structure and classes

The main issue is preventing a redirect back to the sign-up page and ensuring the user stays on the profile edit page after validation errors. We'll make sure that the profile page correctly re-renders on errors instead of going back to the sign-up page. Regarding the updated view files, I'll ensure no inline styles, minimal changes as per request, and clean but effective use of Bootstrap classes for consistency across mobile and desktop views.

Let's finalize with the revised code.

Thought for 5m 46s

Réponse

Вот обновлённые файлы с учётом двух пожеланий:

  1. Минимальная высота левой карточки (и в целом более аккуратные карточки на десктопе, без влияния на мобильный).
  2. Максимально возможный перенос стилей на Bootstrap-классы, а в SCSS оставлено только то, чего нет в Bootstrap.

app/views/account/_tabs.html+desktop.erb

erb
<div class="account-sidebar-card bg-white rounded-3 shadow-sm p-4 h-100 d-flex flex-column"> <div class="account-user-header text-center mb-4"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar" %> <% else %> <div class="account-user-avatar d-flex align-items-center justify-content-center bg-light"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %> <h5 class="mb-0 text-break"> <%= current_user.profile&.nickname || current_user.email %> </h5> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small> </div> <div class="list-group account-tabs"> <%= link_to t('account.tabs.my_profile'), account_path, class: "list-group-item list-group-item-action border-0 rounded-3 mb-1 fw-semibold #{'active' if local_assigns[:active] == :profile}" %> <%= link_to t('account.tabs.edit_user'), edit_user_account_path, class: "list-group-item list-group-item-action border-0 rounded-3 mb-1 fw-semibold #{'active' if local_assigns[:active] == :edit_user}" %> <%= link_to t('account.tabs.edit_profile'), edit_profile_account_path, class: "list-group-item list-group-item-action border-0 rounded-3 mb-1 fw-semibold #{'active' if local_assigns[:active] == :edit_profile}" %> <%= link_to t('account.tabs.addresses'), addresses_account_path, class: "list-group-item list-group-item-action border-0 rounded-3 mb-1 fw-semibold #{'active' if local_assigns[:active] == :addresses}" %> </div> </div>

app/views/account/_tabs.html+mobile.erb

erb
<div class="mb-3 text-center"> <% if current_user.profile&.avatar&.attached? %> <%= image_tag current_user.profile.avatar.variant(:thumb), class: "account-user-avatar rounded-circle mb-2" %> <% else %> <div class="account-user-avatar d-inline-flex align-items-center justify-content-center bg-light rounded-circle mb-2"> <span class="fw-bold"> <%= (current_user.profile&.nickname || current_user.email).first.upcase %> </span> </div> <% end %> <div class="fw-semibold text-break"> <%= current_user.profile&.nickname || current_user.email %> </div> <small class="text-muted"> <%= t('account.sidebar.subtitle') %> </small> </div> <div class="nav nav-pills justify-content-between flex-wrap gap-2 mb-3"> <%= link_to t('account.tabs.my_profile'), account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :profile}" %> <%= link_to t('account.tabs.edit_user'), edit_user_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_user}" %> <%= link_to t('account.tabs.edit_profile'), edit_profile_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :edit_profile}" %> <%= link_to t('account.tabs.addresses'), addresses_account_path, class: "btn btn-outline-secondary flex-fill #{'active' if local_assigns[:active] == :addresses}" %> </div>

app/views/account/addresses.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :addresses %> </div> <div class="account-main flex-fill"> <div class="account-main-card bg-white rounded-3 shadow-sm p-4 h-100"> <h3 class="mb-4"><%= t('account.addresses.title') %></h3> <% if @addresses.present? %> <div class="row g-3 mb-4"> <%= render partial: 'account/address_card', collection: @addresses, as: :address %> </div> <% else %> <p class="text-muted mb-4"> <%= t('account.addresses.empty') %> </p> <% end %> <hr class="my-3"> <h5 class="mb-3"> <%= t('account.addresses.new_title') %> </h5> <%= render 'devise/shared/error_messages', resource: @address %> <%= form_for(@address, url: create_address_account_path, html: { method: :post, novalidate: true, data: { turbo: false } }) do |f| %> <%= render 'devise/registrations/address_fields', f: f, context: :edit %> <div class="d-grid"> <%= f.submit t('account.addresses.save_new'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

app/views/account/edit_profile.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :edit_profile %> </div> <div class="account-main flex-fill"> <div class="account-main-card bg-white rounded-3 shadow-sm p-4 h-100"> <h3 class="mb-4"><%= t('account.edit_profile.title') %></h3> <%= render 'devise/shared/error_messages', resource: @profile %> <%= form_for(current_user, url: update_profile_account_path, html: { method: :patch, novalidate: true, multipart: true, data: { turbo: false } }) do |f| %> <%= f.fields_for :profile, @profile do |pf| %> <%= render 'devise/registrations/profile_fields', f: pf, context: :edit %> <% end %> <div class='d-grid mb-2'> <%= f.submit t('account.edit_profile.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

app/views/account/edit_user.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :edit_user %> </div> <div class="account-main flex-fill"> <div class="account-main-card bg-white rounded-3 shadow-sm p-4 h-100"> <h3 class="mb-4"><%= t('account.edit_user.title') %></h3> <%= render 'devise/shared/error_messages', resource: current_user %> <%= form_for(current_user, url: update_user_account_path, html: { method: :patch, novalidate: true, data: { turbo: false } }) do |f| %> <div class="mb-3"> <%= f.email_field :email, autocomplete: 'email', placeholder: t('devise.registrations.edit.email_placeholder'), class: 'form-control' %> </div> <hr class="my-3"> <h5 class="mb-3"><%= t('account.edit_user.security_title') %></h5> <div class='mb-3'> <%= f.password_field :password, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.new_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :password_confirmation, autocomplete: 'new-password', placeholder: t('devise.registrations.edit.confirm_password_placeholder'), class: 'form-control' %> </div> <div class='mb-3'> <%= f.password_field :current_password, autocomplete: 'current-password', placeholder: t('devise.registrations.edit.current_password_placeholder'), class: 'form-control' %> </div> <div class='d-grid mb-2'> <%= f.submit t('devise.registrations.edit.submit'), class: 'btn btn-success' %> </div> <% end %> </div> </div> </div> </div>

app/views/account/show.html.erb

erb
<div class="d-flex flex-grow-1 justify-content-center align-items-start mt-4"> <div class="account-layout container d-flex flex-column flex-md-row align-items-stretch gap-4"> <div class="account-sidebar mb-4 mb-md-0"> <%= render 'account/tabs', active: :profile %> </div> <div class="account-main flex-fill"> <div class="account-main-card bg-white rounded-3 shadow-sm p-4 h-100"> <h3 class="mb-4"><%= t('account.my_profile.title') %></h3> <div class="row gy-4"> <div class="col-md-4 text-center"> <% if @profile&.avatar&.attached? %> <%= image_tag @profile.avatar.variant(:preview), class: "img-fluid rounded-3 mb-3" %> <% else %> <div class="bg-light rounded-3 d-flex align-items-center justify-content-center account-avatar-placeholder"> <span class="text-muted"> <%= t('account.my_profile.no_avatar') %> </span> </div> <% end %> <p class="mt-2 mb-0 fw-semibold text-break"> <%= @profile&.nickname || current_user.email %> </p> <small class="text-muted text-break"><%= current_user.email %></small> </div> <div class="col-md-8"> <h5 class="mb-3"><%= t('account.my_profile.basic_info') %></h5> <dl class="row mb-4"> <dt class="col-sm-4"><%= t('account.labels.full_name') %></dt> <dd class="col-sm-8"> <%= [@profile&.first_name, @profile&.last_name].compact.join(' ').presence || '—' %> </dd> <dt class="col-sm-4">Email</dt> <dd class="col-sm-8 text-break"><%= current_user.email %></dd> <dt class="col-sm-4"><%= t('account.labels.birthday') %></dt> <dd class="col-sm-8"><%= @profile&.birthday&.strftime('%d.%m.%Y') || '—' %></dd> <dt class="col-sm-4"><%= t('account.labels.metrics') %></dt> <dd class="col-sm-8"> <% if @profile&.weight || @profile&.height %> <%= [@profile&.weight && "#{@profile.weight} kg", @profile&.height && "#{@profile.height} cm"].compact.join(' / ') %> <% else %> <% end %> </dd> </dl> <h5 class="mb-3"><%= t('account.my_profile.about') %></h5> <p class="mb-0"> <%= @profile&.description.presence || t('account.my_profile.no_description') %> </p> </div> </div> </div> </div> </div> </div>

app/assets/stylesheets/account.scss

scss
.account-layout { width: 100%; } .account-user-avatar { width: 6rem; height: 6rem; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 4px #ffffff, 0 4px 10px rgba(0, 0, 0, 0.15); margin: 0 auto 1rem; display: flex; align-items: center; justify-content: center; font-size: 2rem; } .account-tabs .list-group-item.active { background-color: #198754; color: #ffffff; } .account-tabs .list-group-item:hover { background-color: #e9f5ef; } .account-avatar-placeholder { min-height: 12rem; } @media (min-width: 768px) { .account-sidebar-card, .account-main-card { min-height: 20rem; } } @media (max-width: 768px) { .account-sidebar-card { margin-bottom: 1rem; } .account-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; } .account-tabs .list-group-item { margin-bottom: 0; flex: 1 1 calc(50% - 0.5rem); text-align: center; } }

app/assets/stylesheets/devise/form_card.scss

scss
.auth-card { width: 100%; max-width: 25rem; z-index: 1; overflow: visible; margin: 0 auto; } .auth-card::before { content: ""; position: absolute; top: -3.125rem; left: 50%; transform: translateX(-50%); width: 6.25rem; height: 3.75rem; background: #f7edb6; border-radius: 50% 50% 0 0; box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.1); } .auth-card::after { content: ""; position: absolute; top: -4.375rem; left: 50%; transform: translateX(-50%); width: 4.6875rem; height: 4.6875rem; border-radius: 50%; background-size: contain; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); background-color: #abf5f5; background-image: url("/assets/shared/logo.png"); } @media (max-width: 600px) { .auth-card { max-width: 20.625rem; } } .auth-card--wide { width: 100%; max-width: 50rem; } @media (max-width: 768px) { .auth-card--wide { width: 100%; max-width: 100%; margin: 0 auto; padding-inline: 1rem; } }

Теперь про проблему с двухшаговой регистрацией

Сценарий:

  1. Шаг 1 — форма Devise с email/паролем.
  2. Шаг 2 — создание профиля.
  3. Если на шаге 2 есть ошибка, тебя снова кидает на форму с паролем, и поля там пустые.

По сути, есть две нормальные стратегии.

Вариант 1. Создаём пользователя на шаге 1, профиль — отдельно

Это самый простой и «девизовский» путь.

  1. Оставляешь стандартную регистрацию Devise: на форме только email + password.
  2. После успешного sign_up переопределяешь редирект:
ruby
# app/controllers/users/registrations_controller.rb class Users::RegistrationsController < Devise::RegistrationsController protected def after_sign_up_path_for(resource) edit_profile_account_path end end
  1. В AccountsController#update_profile при ошибках делай не redirect_to, а именно render той же вьюхи:
ruby
def update_profile @profile = current_user.profile || current_user.build_profile if @profile.update(profile_params) redirect_to account_path else render :edit_profile, status: :unprocessable_entity end end

Тогда:

  • пользователь уже создан и залогинен после шага 1;
  • на шаге 2 он редактирует только Profile;
  • при ошибках он остаётся на странице профиля, к форме с паролем вообще не возвращается.

Это обычно решает проблему полностью и логически красиво выглядит.

Вариант 2. Хранить данные шага 1 в сессии

Если очень хочется, чтобы формально пользователь создавался только после обоих шагов:

  1. На шаге 1 (email + password) не сохраняешь пользователя, а записываешь параметры в сессию:
ruby
session[:registration_user] = { email: params[:user][:email], password: params[:user][:password], password_confirmation: params[:user][:password_confirmation] } redirect_to new_profile_step_path
  1. На шаге 2 собираешь объект:
ruby
def create user_attrs = session[:registration_user] || {} @user = User.new(user_attrs) @user.build_profile(profile_params) if @user.save session.delete(:registration_user) sign_in(@user) redirect_to account_path else render :new_profile, status: :unprocessable_entity end end

Тут при ошибках профиля форма new_profile просто рендерится снова, а email/пароль берутся из @user, который собран из данных в сессии — вводить их заново не нужно.


Если хочешь, можешь скинуть свой RegistrationsController/AccountsController, я прямо на нём покажу, какой именно render/redirect_to поменять и где лучше сделать редирект после sign_up.

Partager cette Q&R