7

ネストされたカスタム属性Profile (Mongoid ドキュメント) をデバイスのUserクラスに追加しようとしています。Devise 登録フォームが送信されると、 Userオブジェクトと対応するProfileオブジェクトの両方が作成されます。

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 登録コントローラー。

モデル/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

モデル/プロファイル.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"
              }

私はすでにこれらの関連記事を見てきましたが、役に立たなかったようです:


編集:

Devise は実際には「rails4」ブランチで強力なパラメーターをサポートしているようです (これは数日で master にマージされる予定です)。コードを調べると、devise コントローラーの各アクションに対して params 関数をオーバーライドできるようです。新しいユーザーを作成する場合、私の例sign_up_paramsの代わりに。resource_params

この名前を適切な名前に変更したにもかかわらず、まだ機能しませんでした...この強打を使用してすべてのパラメーターをホワイトリストに登録することだけが機能しているように見えました:

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

明らかに、この種の強力なパラメーターの目的は無効になります...だから、問題は、ネストされた属性をどのように許可するかですprofile_attributes(元の質問に見られるように)?

4

4 に答える 4

11

まったく同じ問題があり、sign_up_paramsをオーバーライドするとうまくいきました

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

もちろん、違いは、リレーションを大量に割り当てようとしている間、私のものは単なるスカラー値であるということです...それがあなたが探すべき場所だと思います。

ところで、このトピックにはまだドキュメントが存在せず (新しすぎます)、コード コメントではdevise_parameter_sanitizerをオーバーライドするよう提案されていますが、これは必要ありません。

于 2013-04-24T15:57:20.027 に答える
2

ログイン時に同じ問題が発生しましたUnpermitted parameters: password, remember_meDevise::SessionsControllerを継承するコントローラーがあるため、独自のパラメーターサニタイザーを使用します。

これが私がすることです:

'#{Rails.root}/lib' フォルダーにファイルを作成します。my はconfig/application.rbhzsapa_parameter_sanitizer.rbで必須であり、application_controller.rbでメソッドをオーバーライドします。devise_parameter_sanitizer

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

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

編集:私はdevise READMEで解決策を見つけました。ここでそれに従うことができます

于 2013-06-15T01:36:52.030 に答える
1

私はあなたのコードを使用しましたが、うまくいきました!

これが私がしたことです

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
于 2013-04-24T21:00:46.913 に答える