Мультиблог на 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>
Теперь, если щёлкнуть по имени пользователя, мы таким образом отфильтруем посты по автору, что нам и было нужно. Весь код данного урока, как и всегда, в коммите.
Статья получалась довольно объёмной, поэтому я разделил её на две части. Вскоре будет вторая, где мы сделаем возможность редактировать и удалять статью; а так же проставим все необходимые ссылки для этих действий.