Мультиблог на Ruby on Rails. Создание личного кабинета. Урок 9. Часть 1.
Теперь, когда у каждого пользователя есть возможность создавать записи в блоге, приступим к созданию личного кабинета, в котором будет отображаться сайдбар и записи, которые принадлежат текущему авторизованному пользователю.
В первую очередь нам понадобится контролер, который будет отвечать за вывод личного кабинета. Сгенерировать его можно через консоль:
rails g controller Profiles
Сразу прописываем маршрут:
get 'profiles/index', to: 'profiles#index', as: 'cabinet'
В контролере мы будем получать записи текущего пользователя:
def index @user = User.find(current_user.id) @posts = @user.post end
Здесь мы сначала получаем объект текущего пользователя, а потом все посты, которые ему принадлежат. Работает это всё благодаря тому, что в модели User прописана связь:
has_many :post
Ну ещё добавим метод before_action, чтобы возможность создавать пост была только у авторизованного пользователя:
before_action :authenticate_user!, only: [:index]
Подробнее об этом методе было написано в предыдущем уроке.
Шаблон для личного кабинета
В личном кабинете мы будем выводить только те посты, которые принадлежат текущему авторизованному пользователю. Плюс слева у нас будет небольшой сайдбар, в котором будут ссылки на создание новой статьи и разлогинивание. Что касается вывода постов, то у нас уже всё готово, поскольку чуть ранее, когда мы выводили посты на главной, то использовали частичное представление из _post.html.erb Стало быть, можем точно так же использовать его для вывода постов в личном кабинете. Итоговый шаблон получился таким:
<% content_for :title do %>
Записи пользователя <%= @user.email %>
<% end %>
<main role="main" class="container">
<div class="row">
<% if params[:action] == 'index' %>
<div class="col-md-3 mb-3 mt-1">
<div class="card">
<div class="card-body">
<div class="h2">
<!-- Email автора -->
<%= @user.email %>
</div>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<a href="<%= url_for(new_post_path) %>" style="text-decoration:underline">Создать пост</a>
</li>
<li class="list-group-item">
<a href="<%= url_for(edit_user_registration_path) %>" style="text-decoration:underline">Смена пароля</a><br />
</li>
<li class="list-group-item">
<div class="h6 text-muted">
<!-- Количество записей -->
Записей: <%= @posts.count %>
</div>
</li>
</ul>
</div>
<div class="logout">
<%= button_to "logout", destroy_user_session_path, { method: :delete, class: 'btn btn-danger' } %>
</div>
</div>
<% end %>
<div class="col-md-9">
<!-- Начало блока с отдельным постом -->
<% @posts.each do |post| %>
<%= render 'posts/post', post: post %>
<% end %>
<!-- Остальные посты -->
<!-- Здесь будет постраничная навигация паджинатора -->
</div>
</div>
</main>
Особо комментировать тут нечего, кроме того, что у вас может возникнуть вопрос, зачем здесь дополнительное условие для отображения сайдбара. А всё дело в том, что данный шаблон будет одновременно использоваться как для личного кабинета, так и для отображения постов. И там и там, будут отображаться посты определённого пользователя, но только во втором случае сайдбар нам не будет нужен.
Ну и ещё я добавил стилей для кнопки разлогинивания, чтобы она отлипла от сайдбара и стала по центру:
.logout {
margin-top: 20px;
text-align: center;
}
Страница просмотров записей пользователя
Так же нам понадобится реализовать функционал просмотра постов определённого пользователя. Здесь всё проще, поскольку у нас уже есть похожий функционал и аналогичный шаблон; осталось только это всё грамотно внедрить. Создаём маршрут:
get 'profiles/show/:id', to: 'profiles#show', as: 'profile'
Соответствующий action для контролера Profiles:
def show @user = User.find(params[:id]) @posts = @user.post render :index end
Здесь я указал что рендерить будем именно шаблон index, потому что он у нас, помимо сайдбара, абсолютно такой же, как и для личного кабинета.
Контролер и view готовы, теперь осталось добавить ссылку на сам профиль пользователя. Для этого, в файле _post.html.erb вместо строчки:
<a href="#"><%= post.user.email %></a>
пропишем:
<a href="<%= url_for(profile_path(id: post.user.id)) %>"><%= post.user.email %></a>
Теперь, если щёлкнуть по имени пользователя, мы таким образом отфильтруем посты по автору, что нам и было нужно. Весь код данного урока, как и всегда, в коммите.
Статья получалась довольно объёмной, поэтому я разделил её на две части. Вскоре будет вторая, где мы сделаем возможность редактировать и удалять статью; а так же проставим все необходимые ссылки для этих действий.