Rails 4 / Devise / MongoDB: "Unpermitted parameters" с использованием пользовательских свойств и сильных параметров
попытка добавить вложенный пользовательский атрибут,профиль (монгольский документ), к моему изобретению пользователей класса. Когда форма регистрации Devise будет отправлена, она должна создать как пользователей и тегом профиль а также объект.
Я хотел бы, чтобы конечный результат выглядел примерно так в моем В MongoDB:
пользователь:
{
# Devise fields:
"email": "my@email.com",
...
# Custom field
"profile" : "<object_id>"
}
профиль:
{
"first_name": "Dave",
....
}
к сожалению, я получаю это в моей консоли всякий раз, когда я отправляю свою регистрацию. Он успешно создает пользователя, но не удается создать связанный профиль.
Started POST "/" for 127.0.0.1 at 2013-04-20 23:37:10 -0400
Processing by Users::RegistrationsController#create as HTML
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"awN2GU8EYEfisU0",
"user"=>
{"profile_attributes"=>
{"first_name"=>"Dave",
"birthday(2i)"=>"4",
"birthday(3i)"=>"21",
"birthday(1i)"=>"1933",
"occupation_title"=>"Software Developer"},
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"email"=>"my@email.com"}}
Unpermitted parameters: profile_attributes
у меня есть установка:
- Rails 4.0.0beta1, Ruby 2.0.0-p0
- Devise (ветка' rails4'), Mongoid (от git)
- пользовательский контроллер регистрации Devise для добавления определения сильных параметров.
модели/пользователя.rb:
class User
include Mongoid::Document
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable, :confirmable, :lockable, :timeoutable
field :email, type: String, default: ''
...
has_one :profile
accepts_nested_attributes_for :profile
end
моделей/профиль.rb:
class Profile
include Mongoid::Document
include Mongoid::Timestamps
# Attributes
# ----------
field :slug, type: String, default: '' # Acts as user-'friendlier' slug
field :birthday, type: DateTime, default: DateTime.now
field :first_name, type: String, default: ''
field :occupation_title, type: String, default: ''
belongs_to :user
embeds_many :photos
has_one :occupation_industry, :as => :industry
end
контроллеры/пользователи/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def resource_params
params.require(:user).permit(:email, :password, :password_confirmation, :profile_attributes)
end
private :resource_params
end
маршруты.rb
devise_for :users,
:path => '',
:path_names => {
:sign_in => 'login',
:sign_out => 'logout',
:sign_up => 'register'
},
:controllers => {
:registrations => "users/registrations",
:passwords => "users/passwords"
}
Я уже смотрел на эти связанные сообщения, они, похоже, не помогите!--20-->
EDIT:
похоже, Devise действительно поддерживает сильные параметры в своей ветви "rails4" (которая должна быть объединена в master через несколько дней.) Просматривая код, похоже, вы можете переопределить функцию params для каждого действия на devise контроллеры. Для создания новых пользователей, его sign_up_params
вместо resource_params
в моем примере.
несмотря на изменение этого имени на правильное, он все еще не работал... только белый список всех параметров, использующих этот взрыв, казалось, работал:
def sign_up_params
params.require(:user).permit!
end
очевидно, что этот вид поражений цель сильных параметров... Итак, теперь вопрос в том, как разрешить мои вложенные атрибуты profile_attributes
(как видно из моего первоначального вопроса)?
4 ответов
У меня была точно такая же проблема и переопределение sign_up_params работал на меня
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation, :other, :etc)
end
конечно, разница в том, что мои-это просто скалярные значения, в то время как вы пытаетесь массово назначить отношение... Думаю, это то место, где ты должен искать.
кстати, документация по-прежнему не существует в этой теме (слишком новая), и Code commnents предлагают переопределить devise_parameter_sanitizer, что не обязательно.
Я нашел другой способ, который позволяет вся логика и код переопределения devise, чтобы находиться в контроллере приложения. Это позволяет передавать любые пользовательские параметры для каждого действия devise (вход, регистрация, обновление). Я также добавляю дезинфицирующее средство параметров для devise_invitable и обрабатываю эту логику здесь (invite, accept_invitation). У меня есть пользовательские параметры, такие как avatar, avatar_cache и т. д.:
#application_controller.rb
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
# There are just three actions in Devise that allows any set of parameters to be passed down to the model,
# therefore requiring sanitization. Their names and the permited parameters by default are:
# sign_in (Devise::SessionsController#new) - Permits only the authentication keys (like email)
# sign_up (Devise::RegistrationsController#create) - Permits authentication keys plus password and password_confirmation
# account_update (Devise::RegistrationsController#update) - Permits authentication keys plus password, password_confirmation
# and current_password. More at https://github.com/plataformatec/devise#strong-parameters
def configure_permitted_parameters
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:username,:validate_username, :password,:password_confirmation, :invitation_token)
end
devise_parameter_sanitizer.for(:invite) do |u|
u.permit(:name,:comments)
end
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:username,:password,:password_confirmation)
end
devise_parameter_sanitizer.for(:sign_in) do |u|
u.permit(:username,:email,:password,:password_confirmation,:phone, :validate_username, :avatar_cache, :remove_avatar, :current_password,:remember_me)
end
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:username,:email,:password,:password_confirmation,:phone, :validate_username,:avatar, :avatar_cache, :remove_avatar, :current_password)
end
end
найти и прочитать больше на https://github.com/plataformatec/devise#strong-parameters
у меня была такая же проблема при входе в систему, он говорит:Unpermitted parameters: password, remember_me
.
и потому что у меня есть любой контроллер, который наследует Devise:: SessionsController, поэтому я использую свой собственный дезинфицирующее средство параметров.
вот что я делаю:
создайте файл в ' #{Rails.root} / lib' fold, my is hzsapa_parameter_sanitizer.rb
а в конфиг/приложения.rb, затем переопределить devise_parameter_sanitizer
метод application_controller.rb
lib / hzsapa_parameter_sanitizer.rb
class HzsapaParameterSanitizer < Devise::ParameterSanitizer
def sign_in
default_params.permit(auth_keys + [:password, :remember_me])
end
end
вы можете переопределить этот метод в зависимости от вашей проблемы:
def sign_in
default_params.permit(auth_keys)
end
def sign_up
default_params.permit(auth_keys + [:password, :password_confirmation])
end
def account_update
default_params.permit(auth_keys + [:password, :password_confirmation, :current_password])
end
конфиг/приложения.rb
require "hzsapa_parameter_sanitizer"
app / application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
def devise_parameter_sanitizer
@devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
HzsapaParameterSanitizer.new(resource_class, resource_name, params)
else
Devise::BaseSanitizer.new(resource_class, resource_name, params)
end
end
end
Edit: Я только что нашел решение в devise README, вы можете следовать ему здесь
я использовал ваш код и он работал для меня!
вот что я сделал
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :verify_authenticity_token, :only => :create #, :if => Proc.new { |c| c.request.format == 'application/json' }
respond_to :json, :html, :xml
def create
user = User.new(devise_registrations_permitted_parameters)
if user.save
render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email,:name => user.name), :status=>201
return
else
warden.custom_failure!
render :json=> user.errors, :status=>422
end
end
protected
def devise_registrations_permitted_parameters
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end