17

私はDeviseとRails 4を使用してWebアプリに取り組んでいます.2つの追加フォームフィールドで拡張したUserモデルがあり、ユーザーがサインアップするときに姓/名も送信できるようになっています。( http://blog.12spokes.com/web-design-development/adding-custom-fields-to-your-devise-user-model-in-rails-4/に基づく)。機関モデルを追加したいと思います。このモデルには多くのユーザーがいて、ユーザーは機関に所属しています。ユーザーを登録するのと同じフォームに機関の名前を登録できるようにしたいです。自分の機関にnested_attributeが必要なのはわかっていますこれは親であるため、後で少し説明します。ユーザーにサインアップしようとすると、コンソールにUnpermited parameters: Institutionsが表示されます。

私のヒントは、子クラス (ユーザー) に基づいて親クラス (機関) を更新できないことです。これに対する解決策はありますか?または、似たようなことを経験した人はいますか?

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"=>"abc@foo.com",
 "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] ) 

構文エラーは発生しませんが、許可されていないパラメーター: 機関がリクエストに含まれています。

これは、User が Institution の子であるために発生すると私は信じています。ただし、これを回避する方法を見つけることができませんでした。

4

3 に答える 3

12

そのためには、独自の登録コントローラーを作成する必要があります。方法は次のとおりです。

ルート.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 )

于 2013-07-20T23:03:20.690 に答える