Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора? |
Обновление, демонстрация и удаление пользователей
Уничтожение пользователей
Теперь, когда список пользователей завершен, осталось лишь одно каноничное REST действие: destroy. В этом разделе мы добавим ссылки для удаления пользователей, как это показано на 12" type="image" />, и определим destroy действие необходимое для выполнения удаления. Но мы начнем с создания класса уполномоченных на это административных пользователей.
Административные пользователи
Мы будем идентифицировать привилегированных пользователей с правами администратора посредством булевого атрибута admin в модели User, что, как мы увидим, автоматически приведет нас к методу admin? для проверки административного статуса. Мы можем написать тесты для этого атрибута, как в Листинге 9.38.
require 'spec_helper' describe User do . . . it { should respond_to(:authenticate) } it { should respond_to(:admin) } it { should be_valid } it { should_not be_admin } describe "with admin attribute set to 'true'" do before do @user.save! @user.toggle!(:admin) end it { should be_admin } end . . . endЛистинг 9.38. Тесты для атрибута admin. spec/models/user_spec.rb
Здесь мы использовали метод toggle! для изменения атрибута admin от false к true. Отметим также, что строка
it { should be_admin }
подразумевает (через булеву конвенцию RSpec), что пользователь должен иметь булев метод admin?.
Мы добавим атрибут admin как обычно, посредством миграции, указав тип boolean в командной строке:
$ rails generate migration add_admin_to_users admin:boolean
Миграция просто добавляет столбец admin к таблице users (Листинг 9.39), приводя к модели данных показанной на рис. 9.13.
class AddAdminToUsers < ActiveRecord::Migration def change add_column :users, :admin, :boolean, default: false end endЛистинг 9.39. Миграция для добавления булевого атрибута admin к пользователям. db/migrate/[timestamp]_add_admin_to_users.rb
Обратите внимание на то, что мы добавили аргумент default: false к add_column в Листинге 9.39, что означает, что пользователи не будут администраторами по умолчанию. (Без аргумента default: false, admin был бы по умолчанию nil, что все же является false, так что этот шаг не является строго обязательным. Однако это более явно и четко сообщает о наших намерениях, и Rails, и читателям нашего кода.)
Наконец, мы мигрируем базу данных разработки и подготавливаем тестовую бд:
$ bundle exec rake db:migrate $ bundle exec rake test:prepare
Как и ожидалось, Rails догадывается о булевом характере атрибута admin и автоматически добавляет метод со знаком вопроса admin?:
$ rails console --sandbox >> user = User.first >> user.admin? => false >> user.toggle!(:admin) => true >> user.admin? => true
В результате, тесты для admin должны пройти:
$ bundle exec rspec spec/models/user_spec.rb
В качестве последнего шага, давайте обновим наш заполнитель образцов данных для того, чтобы сделать первого пользователя администратором (Листинг 9.40).
namespace :db do desc "Fill database with sample data" task populate: :environment do admin = User.create!(name: "Example User", email: "example@railstutorial.org", password: "foobar", password_confirmation: "foobar", admin: true) . . . end endЛистинг 9.40. Код заполнителя образцов данных для создания административного пользователя. lib/tasks/sample_data.rake
Наконец, перезапустим заполнитель для перезагрузки базы данных и последующей перестройки ее с нуля:
$ bundle exec rake db:reset $ bundle exec rake db:populate $ bundle exec rake test:prepare
Возвращение к строгим параметрам
Вы могли заметить, что Листинг 9.40 делает пользователя администратором с помощью добавления admin: true к хэшу инициализации. Это подчеркивает опасность демонстрации наших объектов в диком Вебе: если мы просто передадим инициализационный хэш с произвольного веб-запроса, вредоносный пользователь может в таком случае отправить PATCH запрос следующим образом:8Инструменты командной строки, такие как curl могут выдавать PATCH запросы такой формы.
patch /users/17?admin=1
Этот запрос сделал бы администратором пользователя 17, что могло бы стать потенциально серьезной брешью в безопасности, если не сказать больше.
Из-за этой опасности очень важно передавать на дальнейшую обработку только параметры безопасных для редактирования атрибутов. Как отмечалось в Разделе 7.3.2, это может быть достигнуто с помощью строгих параметров вызывая require и permit на хэше params:
def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end
В частности, обратите внимание на то, что admin не включен в список разрешенных атрибутов. Именно это не позволяет произвольному пользователю предоставлять себе административный доступ к нашему приложению. Поскольку это очень важный нюанс, хорошей идеей будет написание теста на каждый нередактируемый атрибут и написание такого теста для атрибута admin оставлено в качестве упражнения (Раздел 9.6).