Оформление дополнительных strong_parameters в RoR4
Я использую драгоценный камень оформления, который является в основном аутентификацией по электронной почте.
Теперь я хочу сохранить вход по электронной почте, но хочу добавить поле "имя" в регистрационную форму для пользователя.
User.rb
class User < ActiveRecord::Base
include Clearance::User
validates_presence_of :name
validates_uniqueness_of :name
end
users_controller.rb
class UsersController < Clearance::UsersController
def create
@user = user_from_params
if @user.save(permit_params)
sign_in @user
render :json => {:success => true}
else
render :json => {:success => false}
end
end
private
def user_from_params
user_params = params[:user] || Hash.new
email = user_params.delete(:email)
password = user_params.delete(:password)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.email = email
user.password = password
end
end
def permit_params
params.require(:user).permit(:name, :email, :encrypted_password, :password, :confirmation_token, :remember_token)
end
end
Как видите, я добавил разрешение на .save
и все же приложение выдает мне следующую ошибку по запросу:
ActiveModel::ForbiddenAttributesError in Clearance::UsersController#create
Если я удалю :name
Текстовое поле из моей формы все работает, но я хочу дополнительные поля для моей формы.
4 ответа
Вы должны поместить свой users_controller в такие папки:
приложение / контроллеры / оформление /users_controller.rb
Затем в users_controller.rb вместо:
class UsersController < Clearance::UsersController
вам нужно поставить:
class Clearance::UsersController < ApplicationController
Это не отменяет пользовательский контроллер Clearance. Вместо этого, теперь вы пишете это. Это контроллер, на который будет отправлена ваша регистрационная форма. Таким образом, вам все равно нужно включить базовый код из гема Clearance и отредактировать Clearance::UsersController#user_from_params
def user_from_params
user_params = params[:user] || Hash.new
email = user_params.delete(:email)
password = user_params.delete(:password)
name = user_params.delete(:name)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.email = email
user.password = password
user.name = name
end
end
и обновить оформление:: UsersController # allow_params
def permit_params
params.require(:user).permit(:name, :email, :password)
end
ОБНОВЛЕНИЕ: я изменил свой предыдущий ответ, так как он упускал суть.
Код, который вы предоставили, в порядке. Причина, по которой вы получаете ActiveModel::ForbiddenAttributesError
потому что вы не переопределяете контроллер пользователей Clearance.
Вы должны указать своему приложению использовать переопределяющий контроллер вместо контроллера в движке Clearance, добавив следующее в ваш config/rout.rb.
resources :users,
controller: 'users',
only: 'create'
ИМО это лучше, чем писать новый Clearance::UsersController
в коде вашего приложения выше.
Вам на самом деле не нужно переопределять create
метод, на всякий случай, если вы создаете API (как выглядит).
Шаги:
конфиг /routes.rb
Rails.application.routes.draw do resources :users, controller: 'users', only: Clearance.configuration.user_actions end
приложение / контроллеры /users_controller.rb
class UsersController < Clearance::UsersController private def user_from_params email = user_params.delete(:email) password = user_params.delete(:password) name = user_params.delete(:name) Clearance.configuration.user_model.new(user_params).tap do |user| user.email = email user.password = password user.name = name end end end
После этого добавьте поле имени в форму, и все готово.
Я испробовал оба пути и пришел к выводу, что вам не нужны разрешительные параметры. Вам нужно всего лишь сделать 4 вещи:
- Добавить столбец имени в миграции
- Создайте app/controllers/users_contoller.rb для переопределения контроллера gem
- Создайте новую форму, чтобы принять имя app/views/users/new.html.erb
- Изменить ваши маршруты
Начиная с сгенерированной миграции rails generate clearance:install
(перед запуском rake db:migrate
)
добавить
name:string
столбец с таким индексом, чтобы ваша миграция выглядела так: добавив этот столбец, он включается в создание пользовательских параметров.def change change_table :users do |t| t.timestamps null: false t.string :email, null: false t.string :name, null: false, limit: 50 t.string :encrypted_password, limit: 128, null: false t.string :confirmation_token, limit: 128 t.string :remember_token, limit: 128, null: false end add_index :users, :name add_index :users, :email add_index :users, :remember_token end
Тогда вам нужно всего лишь создать 2 файла:
приложение / контроллеры / users_controller.rb
class UsersController < Clearance::UsersController
def create
@user = user_from_params
if @user.save
sign_in @user
redirect_to '/'
else
render template: 'users/new'
end
end
private
def user_from_params
user_params = params[:user] || Hash.new
name = user_params.delete(:name)
email = user_params.delete(:email)
password = user_params.delete(:password)
Clearance.configuration.user_model.new(user_params).tap do |user|
user.name = name
user.email = email
user.password = password
end
end
end
а также
приложение / просмотров / пользователей / new.html.erb
<div id='clearance' class='sign-up'>
<h2><%= t('.title') %></h2>
<%= form_for @user do |form| %>
<div class='text-field'>
<%= form.label :name %>
<%= form.text_field :name, :type => 'name' %>
</div>
<div class='text-field'>
<%= form.label :email %>
<%= form.text_field :email, :type => 'email' %>
</div>
<div class='password-field'>
<%= form.label :password %>
<%= form.password_field :password %>
</div>
<div class='submit-field'>
<%= form.submit %>
</div>
<div class='other-links'>
<%= link_to t('.sign_in'), sign_in_path %>
</div>
<% end %>
</div>
Тогда ваши маршруты должны включать это
resources :users,
controller: 'users',
only: 'create'