DeviseとRails 4.)を使用してWebアプリに取り組んでいます。Userモデルがあり、次のような2つの追加のフォームフィールドで拡張しています。ユーザーがサインアップすると、姓名も送信できます( http://blog.12spokes.com/web-design-development/adding-custom-fields-to-your-deviseに基づく) -user-model-in-Rails-4 / )。Institutionモデルを追加します。このモデルhas_many:users、およびuserbelongs_to:institution。機関の名前を同じフォームに登録できるようにしたいユーザーを登録します。これは親であるため、Institutionモデルにnested_attributeが必要です。これについては後で説明します。ユーザーをサインアップしようとするとコンソールにアクセスします:許可されていないパラメーター:機関。
私のヒントは、子クラス(ユーザー)に基づいて親クラス(機関)を更新できないことです。これに対する解決策があるでしょうか?または誰かが似たようなことを経験したことがありますか?
class Institutions < ActiveRecord::Base
has_many :users,
accepts_nested_attributes_for :users
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :institution
end
registrations/new.html.erbここにネストされたフォームがあります
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
.
.
<%= f.fields_for :institutions do |i| %>
<p><%= i.label :name %><br />
<%= i.text_field :institutions_attr %></p>
<% end %>
以前にリンクしたチュートリアルに基づいて、Devise :: ParameterSanitizerから継承する新しいUser :: ParameterSanitizerを作成しましたsign_up
メソッドを次のようにオーバーライドします。
lib/user_sanitizer.rb
private
def sign_up
default_params.permit(:first_name, :last_name ,:email, :password, :password_confirmation, :current_password, institutions_attributes: [:id, :name])
end
最後に、私のapplication_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
protected
def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super
end
end
end
読んでくれてありがとう!
コンソールパラメータ出力:
{"utf8"=>"✓",
"authenticity_token"=>"JKuN6K5l0iwFsj/25B7GKDj7WEHR4DO3oaVyGxGJKvU=",
"user"=>{"email"=>"[email protected]",
"first_name"=>"abc",
"last_name"=>"xyz",
"institutions"=>{"name"=>"Government"},
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Sign up"}
[〜#〜]編集[〜#〜]
提案されたように、私は追加しました
params.require(resource_name).permit( :email, :first_name, :last_name, institution: [:name], :password, :password_confirmation ) and I get an *error syntax error, unexpected ',', expecting => ...nstitution: [:name], :password, :password_confirmation )*
しかし、私が再編集した場合
params.require(resource_name).permit( :email, :first_name, :last_name, :password, :password_confirmation, institution: [:name] )
構文エラーは発生しませんが、許可されていないパラメーターが表示されます:リクエスト内の機関。
私の信念は、これはユーザーが教育機関の子供であるために起こるということです。しかし、私はこれを回避する方法を見つけることができませんでした。
config/rules.rb
次のように独自の登録コントローラーを作成します...( コントローラーのオーバーライドの詳細についてはDeviseのドキュメントを参照してください... )...これはApplicationController
devise_for :users, controllers: {registrations: 'users/registrations'}
app/controllers/users/repositorys_controller.rb
新しいメソッドをオーバーライドして、以下のようにProfile
モデルに関連付けられたUser
を作成します...パラメータをサニタイズする前にconfigure_permitted_parameters
メソッドを実行します(注ネストされたパラメータを追加する方法)
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
# GET /users/sign_up
def new
# Override Devise default behaviour and create a profile as well
build_resource({})
resource.build_profile
respond_with self.resource
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u|
u.permit(:email, :password, :password_confirmation, :profile_attributes => :fullname)
}
end
end
db/mergerate/xxxxxxxxxxxxxx_create_profiles.rb
これは、Profile
モデルを生成する移行です(User
への参照に注意してください)...このサンプルプロファイルはfullname
User
の拡張として。ただし、必要に応じて自由に追加してください。
class CreateProfiles < ActiveRecord::Migration
def change
create_table :profiles do |t|
t.references :user
t.string :fullname
t.timestamps
end
end
end
app/models/user.rb
class User < ActiveRecord::Base
# Associations
has_one :profile, dependent: :destroy, autosave: true
# Allow saving of attributes on associated records through the parent,
# :autosave option is automatically enabled on every association
accepts_nested_attributes_for :profile
# Devise
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
app/models/profile.rb
class Profile < ActiveRecord::Base
# Associations
belongs_to :user
# Validations
validates :fullname, presence: true
end
app/views /装飾/registrations/new.html
<% resource.build_profile if resource.profile.nil? %>
<%= form_for(resource, :as => resource_name,
:url => registration_path(resource_name)) do |f| %>
<ul>
<%= devise_error_messages! %>
<li class="fullname">
<%= f.fields_for :profile do |profile_fields| %>
<%= profile_fields.label :fullname %>
<%= profile_fields.text_field :fullname %>
<% end %>
</li>
<li class="email">
<%= f.label :email %>
<%= f.email_field :email, :autofocus => true %>
</li>
<li class="password">
<%= f.label :password %>
<%= f.password_field :password %>
</li>
<li class="password">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</li>
<li>
<%= f.submit %>
</li>
<li>
<p><%= render "devise/shared/links" %></p>
</li>
</ul>
<% end %>
これを行うには、独自の登録コントローラーを作成する必要があります。方法は次のとおりです。
routes.rb
_devise_for :users, controllers: {registrations: 'registrations'}
_
コントローラー
_:your_fields
_を許可したいフィールドに置き換える必要があります(それをあなたに任せて申し訳ありませんが、それは私の答えをより一般的にするので、通りすがりの人なら誰でも使用できます)
_class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
allow = [:email, :your_fields, :password, :password_confirmation]
params.require(resource_name).permit(allow)
end
end
_
追加情報(ネストされた属性+いくつかのテスト)
また、アソシエーションと_accepts_nested_attributes_for
_を使用している場合は、params
が次のように構成されていることに注意してください。
_model: {field, field, field, associated_model: {field, field}}
_
もちろん、_sign_up_params
_メソッドでも同じ構造を使用する必要があります。これを理解する必要がある場合は、次のように_sign_up_params
_メソッドの内容を変更できます。
_ def sign_up_params
params.require(resource_name).permit!
end
_
これにより、任意のパラメーターが許可され、フォームを投稿して(今回は通過するはずです)、Railsコンソールを調べてparams
の構造を確認し、最後にセットアップできます。 _sign_up_params
_メソッドは正しく
詳細については、これを確認してください http://www.railsexperiments.com/using-strong-parameters-with-nested-forms/
あなたの場合、あなたは使うべきです:
params.require(resource_name).permit( :email, :first_name, :last_name, institutions: [:name], :password, :password_confirmation )
Rails 5.1とデバイス4.4.1を使用するのが最短で、かなりうまく機能します。
app/models/user.rb
after_initialize do
build_profile if new_record? && profile.blank?
end
app/controllers/application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [{ profile_attributes: :name }])
end
ここで重要なのは、個別のコントローラーを作成せずに次のことを実行できることです。