7

Cố gắng thêm một thuộc tính tùy chỉnh lồng nhau, Hồ sơ (một tài liệu Mongoid), để đưa ra tôi tài lớp. Khi biểu mẫu đăng ký Devise được gửi, nó sẽ tạo cả một đối tượng Người dùng và tương ứng Tiểu sử.Rails 4/lập mưu/MongoDB: "thông số Unpermitted" sử dụng thuộc tính tùy chỉnh và các thông số mạnh mẽ

Tôi muốn kết quả cuối cùng để trông giống như thế này trong MongoDB tôi:

User:

{ 
    # Devise fields: 
    "email": "[email protected]", 
    ... 
    # Custom field 
    "profile" : "<object_id>" 
} 

hồ sơ:

{ 
    "first_name": "Dave", 
    .... 
} 

Thật không may, tôi là người nhận ving điều này trong bảng điều khiển của tôi bất cứ khi nào tôi gửi đăng ký của tôi. Nó tạo thành công một User nhưng không tạo được Profile được liên kết.

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"=>"[email protected]"}} 
Unpermitted parameters: profile_attributes 

tôi đã thiết lập:

  • Rails 4.0.0beta1, Ruby 2.0.0-p0
  • lập mưu (chi nhánh 'rails4'), Mongoid (từ git)
  • Bộ điều khiển đăng ký Devise tùy chỉnh để thêm định nghĩa cho thông số mạnh.

mô hình/user.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 

mô hình/profile.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 

controllers/người dùng/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 

routes.rb

devise_for :users, 
       :path => '', 
       :path_names => { 
       :sign_in => 'login', 
       :sign_out => 'logout', 
       :sign_up => 'register' 
       }, 
       :controllers => { 
       :registrations => "users/registrations", 
       :passwords => "users/passwords" 
       } 

tôi đã xem xét những bài viết liên quan, họ không có vẻ để giúp:


CHỈNH SỬA:

Có vẻ như Devise thực sự hỗ trợ các thông số mạnh trong nhánh 'rails4' của nó (được cho là hợp nhất thành chính trong vài ngày tới.) Nhìn qua mã, nó xuất hiện bạn có thể ghi đè lên một hàm params cho mỗi hành động trên bộ điều khiển phát sinh. Để tạo người dùng mới, số sign_up_params thay vì resource_params trong ví dụ của tôi.

Mặc dù thay đổi tên này để người thích hợp, nó vẫn không làm việc ... chỉ danh sách trắng tất cả các thông số sử dụng tiếng nổ này dường như làm việc:

def sign_up_params 
    params.require(:user).permit! 
end 

Rõ ràng, loại đánh bại mục đích của mạnh các tham số ... vì vậy bây giờ câu hỏi là làm thế nào để tôi cho phép các thuộc tính lồng nhau của tôi profile_attributes (như đã thấy trong câu hỏi ban đầu của tôi)?

Trả lời

11

tôi đã có cùng một vấn đề chính xác và trọng sign_up_params đã làm việc cho tôi

def sign_up_params 
    params.require(:user).permit(:email, :password, :password_confirmation, :other, :etc) 
end 

tất nhiên, sự khác biệt là ở tôi mà chỉ là những giá trị vô hướng, trong khi bạn đang cố gắng để khối lượng gán một mối quan hệ ... Tôi đoán đó là nơi bạn nên tìm kiếm.

Nhân tiện, các tài liệu vẫn không tồn tại trong chủ đề này (quá mới), và mã số commnents đề nghị ghi đè devise_parameter_sanitizer, điều này không cần thiết.

+2

Nơi nào bạn đặt mã này để ghi đè sign_up_params? –

+0

Trong lớp kế thừa từ ** Devise :: RegistrationsController **, đây là cách bạn ghi đè/mở rộng nó –

+3

Vâng, đây là cách để làm điều đó ... cho băm (như 'profile_attributes') của tôi, bạn cần phải xác định mọi thuộc tính được nhúng một cách rõ ràng bởi thiết kế. nghĩa là nó trông giống như: 'params.require (: user) .permit (: email,: password,: password_confirmation, profile_attributes: [: first_name,: Occupation_title])' –

1

Tôi đã sử dụng mã của bạn và mã này hoạt động cho tôi!

Đây là những gì tôi đã làm

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 
2

tôi đã cùng một vấn đề khi đăng nhập, nó nói: Unpermitted parameters: password, remember_me. và vì tôi có bất kỳ bộ điều khiển nào kế thừa Devise :: SessionsController, vì vậy tôi sử dụng riêng parameter sanitizer của mình.

đây là những gì tôi làm:

Tạo một tập tin trong '# {Rails.root}/lib' lần, tôi là hzsapa_parameter_sanitizer.rb và yêu cầu trong config/application.rb, sau đó ghi đè devise_parameter_sanitizer phương pháp trong 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 

Bạn có thể ghi đè lên những phương pháp phụ thuộc vào vấn đề của bạn:

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 

config/application.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: tôi chỉ tìm thấy giải pháp trong việc đưa ra README, bạn c hãy theo dõi nó here

4

Tôi đã tìm thấy một phương pháp khác cho phép tất cả logic và mã ghi đè dự kiến ​​sẽ nằm trong bộ điều khiển ứng dụng.Điều này cho phép bất kỳ và tất cả các thông số tùy chỉnh được chuyển qua cho mỗi hành động đưa ra (đăng nhập, đăng ký, cập nhật). Tôi cũng thêm một tham số sanitizer cho devise_invitable và xử lý logic ở đây (mời, accept_invitation). Tôi đã có params tùy chỉnh như avatar, avatar_cache, vv:

#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 

Tìm và đọc thêm tại https://github.com/plataformatec/devise#strong-parameters

Các vấn đề liên quan