ओवरराइड डेविस रजिस्ट्रेशन कंट्रोलर


236

मैंने साइन-अप फ़ॉर्म में एक फ़ील्ड जोड़ा है जो एक अलग मॉडल पर आधारित है, देखें कि मैं कैसे gor विवरण के लिए devise मॉडल के साथ नेस्टेड विशेषताओं का उपयोग करता हूं । यह हिस्सा ठीक काम कर रहा है।

अब समस्या यह है कि जब मैं बचत करता हूं, तो यह Activerecord::UnknownAttributeErrorइस क्षेत्र (कंपनी) के साथ वसीयत द्वारा आपूर्ति किए गए पंजीकरण नियंत्रक की कार्रवाई में विफल हो रहा है ।

मैं यह मान रहा हूं कि मुझे पंजीकरण नियंत्रक को ओवरराइड करने की आवश्यकता है, या क्या मुझे इस दृष्टिकोण से बेहतर / आसान तरीका होना चाहिए?


1
मैं वास्तव में इस पर एक पूरा ब्लॉग पोस्ट लिखा था jacopretorius.net/2014/03/…
जाको प्रिटोरियस

जवाबों:


354

अपने फॉर्म में आप किसी भी अन्य विशेषताओं में बड़े पैमाने पर काम कर रहे हैं, जो आपके उपयोगकर्ता मॉडल या किसी भी नेस्टेड मॉडल से संबंधित नहीं हैं?

यदि ऐसा है, तो मुझे विश्वास है कि ActiveRecord :: UnknownAttributeError इस उदाहरण में चालू है।

अन्यथा, मुझे लगता है कि आप केवल अपना नियंत्रक बना सकते हैं, कुछ इस तरह से उत्पन्न करके:

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  def new
    super
  end

  def create
    # add custom create logic here
  end

  def update
    super
  end
end 

और फिर उस नियंत्रक को डिफ़ॉल्ट के बजाय उस नियंत्रक का उपयोग करने के लिए कहें:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}

3
लेकिन आप यह कैसे सुनिश्चित करते हैं कि विचारों के लिए डेविस डेरी में डेविस दिखता है? मैं यह कोशिश कर रहा हूँ, लेकिन "sign_in_and_redirect (रिसोर्स_नाम, संसाधन)" जैसे भ्रामक तरीके टेम्पलेट के लिए विचारों में दिख रहे हैं।
अपरेंटिस

7
यदि आप अपने डेविस व्यू को कस्टमाइज़ करना चाहते हैं, तो आपको बस उन्हें सबसे पहले जेनरेट करना होगा और जेम से व्यूज को लोड करने से पहले अपने व्यू फोल्डर को चेक करना होगा। रेल 3 में यह है: rails generate devise:viewsऔर रेल में 2 (मुझे लगता है) यह है:script/generate devise:views
12

2
उपरोक्त हैक 1.0.8 के साथ काम नहीं करता है जो संस्करण 2 रेल के लिए काम करता है।
विलियम यंग

18
यदि आप इस तरह एक डेविस कंट्रोलर को ओवरराइड करते हैं, तो सुनिश्चित करें कि आप ऐप / व्यूज़ / डेविस / रजिस्ट्रेशन से लेकर ऐप / व्यूज़ / रजिस्ट्रेशन / (जो भी आपके द्वारा ओवरराइडिंग करने वाले कंट्रोलर के लिए बदलाव) से सभी व्यूज़ कॉपी कर लें।
जेमी कॉबेट

31
वैकल्पिक रूप से आप अपने विचारों को छोड़ सकते हैं जहां वे हैं और paths.app.views << "app/views/devise"आपके में जोड़ सकते हैं config/application.rb
TheTRON

66

नामस्थानों के उपयोग से डेविस नियंत्रकों और विचारों को देखने का एक बेहतर और व्यवस्थित तरीका:

निम्नलिखित फ़ोल्डर बनाएँ:

app/controllers/my_devise
app/views/my_devise

सभी नियंत्रकों को रखें जिन्हें आप एप्लिकेशन / नियंत्रकों / my_devise में ओवरराइड करना चाहते हैं और MyDeviseनियंत्रक वर्ग के नामों में नामस्थान जोड़ें । Registrationsउदाहरण:

# app/controllers/my_devise/registrations_controller.rb
class MyDevise::RegistrationsController < Devise::RegistrationsController

  ...

  def create
    # add custom create logic here
  end

  ...    

end 

तदनुसार अपने मार्गों को बदलें:

devise_for :users,
           :controllers  => {
             :registrations => 'my_devise/registrations',
             # ...
           }

app/views/my_deviseडेविस मणि फ़ोल्डर से सभी आवश्यक विचारों को कॉपी करें या उपयोग करें rails generate devise:views, उन विचारों को हटा दें जिन्हें आप ओवरराइड नहीं कर रहे हैं और deviseफ़ोल्डर का नाम बदलें my_devise

इस तरह आपके पास सब कुछ बड़े करीने से दो फ़ोल्डरों में व्यवस्थित होगा।


1
यह उस दृष्टिकोण के समान है जो मैं ले रहा हूं, लेकिन मुझे नहीं पता कि createडेविस आई की विधि में कौन सा कस्टम तर्क डाला गया है । मेरा मचान-निर्मित नियंत्रक जिसे मैंने संशोधित किया है, महान काम करता है, लेकिन आप इसे डेविस के resourceव्यवसाय के साथ कैसे काम करते हैं?
काइल कार्लसन

@Vincent आपको धन्यवाद - अगर मैं सिर्फ एक विधि को ओवरराइड करना चाहता हूं, तो क्या मैं सिर्फ उस विधि को लिख सकता हूं जिसे मैं ओवरराइड करना चाहता हूं - और क्या बाकी सब सामान्य रूप से काम करेंगे? आपकी सहायता की बहुत सराहना की
BKSpurgeon

MyDevise::RegistrationsController < Devise::RegistrationsControllerएक परिपत्र निर्भरता त्रुटि बनाता है। क्या मुझसे कुछ गलत हो रही है?
ianrandmckenzie

34

मेरा मानना ​​है कि रजिस्ट्रेशंसकंट्रोलर को फिर से लिखने से बेहतर उपाय है। मैंने बिल्कुल वही काम किया (कंपनी के बजाय मेरे पास संगठन है)।

यदि आप मॉडल और दृश्य स्तर पर अपना नेस्टेड रूप ठीक से सेट करते हैं, तो सब कुछ एक आकर्षण की तरह काम करता है।

मेरा उपयोगकर्ता मॉडल:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable, :lockable and :timeoutable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  has_many :owned_organizations, :class_name => 'Organization', :foreign_key => :owner_id

  has_many :organization_memberships
  has_many :organizations, :through => :organization_memberships

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :username, :owned_organizations_attributes

  accepts_nested_attributes_for :owned_organizations
  ...
end

मेरा संगठन मॉडल:

class Organization < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User'
  has_many :organization_memberships
  has_many :users, :through => :organization_memberships
  has_many :contracts

  attr_accessor :plan_name

  after_create :set_owner_membership, :set_contract
  ...
end

मेरा विचार: 'वसीयत / पंजीकरण / new.html.erb'

<h2>Sign up</h2>

<% resource.owned_organizations.build if resource.owned_organizations.empty? %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <p><%= f.label :name %><br />
    <%= f.text_field :name %></p>

  <p><%= f.label :email %><br />
    <%= f.text_field :email %></p>

  <p><%= f.label :username %><br />
    <%= f.text_field :username %></p>

  <p><%= f.label :password %><br />
    <%= f.password_field :password %></p>

  <p><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %></p>

  <%= f.fields_for :owned_organizations do |organization_form| %>

    <p><%= organization_form.label :name %><br />
      <%= organization_form.text_field :name %></p>

    <p><%= organization_form.label :subdomain %><br />
      <%= organization_form.text_field :subdomain %></p>

    <%= organization_form.hidden_field :plan_name, :value => params[:plan] %>

  <% end %>

  <p><%= f.submit "Sign up" %></p>
<% end %>

<%= render :partial => "devise/shared/links" %>

3
मॉडल के लिए देखने से निर्माण तर्क चलती क्लीनर होगा, देखना stackoverflow.com/questions/3544265#3764837
meleyal

मैंने डेविस कंट्रोलर्स जेनरेट किए हैं और अब जब यूजर क्लिक साइन अप करते हैं तो कंट्रोलर एक्शन ट्रिगर हो जाता है। क्या कोई तरीका है (जैसे ओवरराइडिंग / कुछ उदाहरण कोड) मैं पासवर्ड को एन्क्रिप्ट करने के लिए डेविस का उपयोग कर सकता हूं और पासवर्ड और अन्य क्षेत्रों के बैकएंड चेक कर सकता हूं? और इसे बचाने के लिए मॉडल डेटाबेस?
एचपी

आप resourceवर्ग आवृत्ति चर के बजाय दृश्य में स्थानीय चर का उपयोग कैसे कर सकते हैं @resource?
च्लोए

12

आप वसीयत अनुकूलन के लिए विचार और नियंत्रक उत्पन्न कर सकते हैं।

उपयोग

rails g devise:controllers users -c=registrations

तथा

rails g devise:views 

यह मणि से आपके अनुप्रयोग के लिए विशेष नियंत्रकों और विचारों को कॉपी करेगा।

अगला, इस नियंत्रक का उपयोग करने के लिए राउटर को बताएं:

devise_for :users, :controllers => {:registrations => "users/registrations"}

11

बहुत सरल तरीके बस टर्मिनल और निम्नलिखित प्रकार पर जाएं

rails g devise:controllers users //This will create devise controllers in controllers/users folder

कस्टम दृश्यों का उपयोग करने के लिए अगला

rails g devise:views users //This will create devise views in views/users folder

अब आपके path.rb फ़ाइल में

devise_for :users, controllers: {
           :sessions => "users/sessions",
           :registrations => "users/registrations" }

आप अन्य नियंत्रक भी जोड़ सकते हैं। यह उपयोगकर्ताओं के फ़ोल्डर में नियंत्रक का उपयोग करने के लिए और उपयोगकर्ताओं के फ़ोल्डर में विचारों को समर्पित करेगा।

अब आप अपनी इच्छा के अनुसार अपने विचारों को अनुकूलित कर सकते हैं और अपने तर्क को नियंत्रकों / उपयोगकर्ता फ़ोल्डर में जोड़ सकते हैं। का आनंद लें !

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.