13

मैं डेविस और रेल 4 का उपयोग कर एक वेब ऐप पर काम कर रहा हूं। मेरे पास उपयोगकर्ता मॉडल है जिसे मैंने 2 अतिरिक्त फॉर्म फ़ील्ड्स के साथ बढ़ाया है, जैसे कि जब कोई उपयोगकर्ता साइन अप करता है तो वह अपना पहला/उपनाम। (http://blog.12spokes.com/web-design-development/adding-custom-fields-to-your-devise-user-model-in-rails-4/ पर आधारित)। अब मैं संस्थान मॉडल जोड़ना चाहता हूं। यह मॉडल has_many: उपयोगकर्ता, और उपयोगकर्ता संबंधित है: संस्था। मैं उसी उपयोगकर्ता पर संस्था का नाम पंजीकृत करने में सक्षम होना चाहता हूं, जिसे मैं उपयोगकर्ता पंजीकृत करता हूं। मुझे पता है कि मुझे अपने संस्थान मॉडल में nested_attribute की आवश्यकता है, क्योंकि यह अभिभावक है, जिसे मैं थोड़ा सा दिखाऊंगा। जब मैं उपयोगकर्ता को साइन अप करने का प्रयास करता हूं तो मुझे कंसोल में मिलता है: अप्रत्याशित पैरामीटर: संस्थानडेविस के साथ रेल 4.0। नेस्टेड विशेषताओं अनपेक्षित पैरामीटर

मेरा संकेत यह है कि मैं अपने बच्चे वर्ग (उपयोगकर्ता) के आधार पर अपने मूल वर्ग (संस्थान) को अपडेट नहीं कर सकता। क्या इसका समाधान हो सकता है? या किसी ने कुछ ऐसा अनुभव किया है?

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 

पंजीकरण/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 %> 

ट्यूटोरियल मैं लिंक कर लिया है पहले, मैं एक नया उपयोगकर्ता :: 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, :password, :password_confirmation, institution: [:name]) 
को

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)* 

लेकिन, अगर मैं फिर से संपादित जोड़ लिया है

मुझे कोई वाक्यविन्यास त्रुटि नहीं मिलती है लेकिन मुझे अनिर्धारित पैरामीटर मिलते हैं: अनुरोध में संस्थान।

मेरा विश्वास यह है कि ऐसा इसलिए होता है क्योंकि उपयोगकर्ता संस्थान का बच्चा है। हालांकि, मैं इसके आसपास एक काम खोजने में असमर्थ रहा हूं।

उत्तर

33

config/routes.rb

इसलिए की तरह अपने खुद के पंजीकरण नियंत्रक ... (see Devise documentation for the details of overriding controllers here ...) ... जो अधिक सुरुचिपूर्ण तरीके के रूप में ApplicationController

devise_for :users, controllers: {registrations: 'users/registrations'} 
के माध्यम से यह कर करने का विरोध किया है बनाएं

एप्लिकेशन/नियंत्रक/उपयोगकर्ताओं/registrations_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/विस्थापित/xxxxxxxxxxxxxx_create_profiles.rb

चलाने

इस माइग्रेशन कि Profile मॉडल (टिप्पणी User के संदर्भ में) उत्पन्न करता है ... इस उदाहरण प्रोफ़ाइल केवल एक ई के रूप में fullname रहता है User का xtension लेकिन अपनी इच्छानुसार जोड़ने के लिए स्वतंत्र महसूस करें!

class CreateProfiles < ActiveRecord::Migration 
    def change 
    create_table :profiles do |t| 
     t.references :user 
     t.string :fullname 
     t.timestamps 
    end 
    end 
end 

एप्लिकेशन/मॉडल/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 

एप्लिकेशन/मॉडल/profile.rb

class Profile < ActiveRecord::Base 

    # Associations 
    belongs_to :user 

    # Validations 
    validates :fullname, presence: true 
end 

एप्लिकेशन/विचारों/वसीयत/पंजीकरण/नई। एचटीएमएल

<% 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 %> 
+5

उत्कृष्ट उत्तर –

+1

धन्यवाद बहुत राजाओरी, यह वही है जो मैं ढूंढ रहा था!मुझे निराशा के कुछ अतिरिक्त घंटे बचाया। – DerProgrammer

+0

@ राजाओरी मेना मैं devise_auth_token मणि का उपयोग कर रहा हूं और उसी मणि के लिए उपरोक्त विधियों के बाद मुझे अभी भी अप्रत्याशित पैरामीटर मिल रहा है: मेरे सर्वर लॉग में खाता त्रुटि – Anjan

13

आप ऐसा करने के लिए अपने स्वयं के पंजीकरण नियंत्रक, यहाँ बनाना होगा कि कैसे:

मार्गों।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 

कि किसी भी परम की अनुमति देगा, तो अपने प्रपत्र पोस्ट (यह इस समय पास करना चाहिए) और अपने रेल कंसोल पर गौर को देखने के लिए 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)

+0

Thx। मैंने कोशिश की। मैं काम नहीं करता क्योंकि यह अभी भी इंस्टीट्यूशन मॉडल के पैरामीटर की अनुमति नहीं देता है। –

+0

ठीक है मेरे उत्तर – Benj

+0

संपादित किया मैंने देखा^_ ^। मैंने इसे निम्न तरीके से लिखा था: अनुमति = [: ईमेल,: first_name,: last_name,: पासवर्ड,: password_confirmation,: name], जहां: नाम दूसरे मॉडल में एक फ़ील्ड है। –

2

रेल 5.1 का उपयोग करना और 4.4.1 वसीयत निम्नलिखित कम से कम है और बहुत अच्छी काम करता है:

एप्लिकेशन/मॉडल/user.rb

after_initialize do 
    build_profile if new_record? && profile.blank? 
end 

एप्लिकेशन/नियंत्रक/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 

यहां कुंजी यह है कि आप अलग-अलग con ट्रोलर: प्रपत्र बिल्डर के लिए

  • परमिट नेस्ट विशेषताओं
  • निर्माण संबंध उत्तर के लिए
संबंधित मुद्दे