एक अलग नियंत्रक के भीतर फार्म का गठन करें


128

मैं sign_in / sign_out प्रक्रियाओं के लिए डेविस रत्न का उपयोग कर रहा हूं।

मैं उपयोग से विचार फ़ाइलें उत्पन्न की, का उपयोग कर rails g devise views

मैंने देखा कि एक devise / session / new.html.erb फाइल थी जिसमें साइन_इन के लिए एक फॉर्म था।

मैंने एक और फ़ाइल डेविस / सत्र / _form.html.erb बनाया और एक नई.html.erb <%= render 'form' %>फ़ाइल के भीतर किया, और इसने बहुत अच्छा काम किया।

अब, मैं इस फॉर्म को अलग-अलग कंट्रोलर से शामिल करना चाहता था। इसलिए 'मुख्य' नामक एक नियंत्रक में, (विशेषकर, दृश्य पृष्ठ के भीतर) 'मुख्य / index.html.erb' में मैंने <%= render 'devise/sessions/form' %>फ़ाइल शामिल की । ऐसा लगता है कि समावेश ने ठीक काम किया है, लेकिन मुझे निम्नलिखित त्रुटि मिल रही है।

NameError in Mains#index

Showing /home/administrator/Ruby/site_v4_ruby/app/views/devise/sessions/_form.html.erb where line #1 raised:

undefined local variable or method `resource' for #<#<Class:0x007f1aa042d530>:0x007f1aa042b870>
Extracted source (around line #1):

1: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
2:   <p><%= f.label :email %><br />
3:   <%= f.text_field :email %></p>
4: 

ऐसा लगता है कि form_for (संसाधन, ...) भाग समस्या का कारण बन रहा है (जो कि ठीक काम करता है अगर मैं मूल डेविस sign_in पृष्ठ पर हूं ... मैं रेल मार्ग में इस समस्या को कैसे हल कर सकता हूं?

मैं व्यक्तिगत रूप से HTML कोड इनलाइन लिखने के बजाय फ़ॉर्म को शामिल करने के लिए 'रेंडर' फ़ंक्शन का उपयोग करना पसंद करता हूं।

क्या मुझे 'मुख्य' नियंत्रक के भीतर कुछ (संसाधन) निर्दिष्ट करना है?

मै आपकी मदद की सरहना करता हूँ। धन्यवाद।


क्या कोई हल है ...? Nov / 16 के रूप में मुझे वास्तव में रेंडर का उपयोग करके समाधान नहीं मिला है .. हालांकि अगर मैं सिर्फ इनलाइन कोड टाइप करता हूं, तो यह ठीक काम करता है लगता है ..
user482594

क्या आपको इसके लिए कोई समाधान मिला?
नेबज

हां, मैंने जवाब चुना जो मेरी समस्या का समाधान करता है। जितना मैंने सोचा था, यह उससे कहीं ज्यादा सरल था।
user482594

जवाबों:


240

जैसा कि एंड्रेस कहते हैं, फॉर्म उन सहायकों को बुलाता है जो डेविस द्वारा निर्दिष्ट किए जाते हैं और इसलिए जब आप गैर-डेविस नियंत्रक से डेविस फॉर्म तक पहुंचते हैं तो मौजूद नहीं होते हैं।

इसके आस-पास जाने के लिए, आपको निम्न विधियों को उस नियंत्रक के सहायक वर्ग में जोड़ना होगा जिसे आप प्रपत्र के तहत प्रदर्शित करना चाहते हैं। वैकल्पिक रूप से, आप उन्हें कहीं भी उपलब्ध कराने के लिए बस उन्हें अपने आवेदन सहायक में जोड़ सकते हैं।

  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end

स्रोत: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/


6
अति उत्कृष्ट। सुनिश्चित करें कि यह सहायक में नहीं, सहायक में जाता है। यदि आपके पास अन्य संसाधन हैं (जैसे कि कंपनियां भी लॉग इन कर सकती हैं) और आप उनके फ़ॉर्म को लोड करना चाहते हैं, तो इससे भारी समस्या हो सकती है। नामों को फिर से परिभाषित करना सुनिश्चित करें, और रूटिंग एक समस्या भी बन सकती है।
माइकल श्मिट

1
इस समाधान के बारे में बुरी बात यह है कि यह टूट जाता है inherited_resources
jrhorn424 22

6
इन विधियों के दायरे को सीमित करने के लिए (और उदाहरण के लिए अन्य रत्नों के साथ नाम स्थान के टकराव से बचें), उपरोक्त विधियों को नियंत्रक के साथ जोड़ने की कोशिश करें, साथ ही helper_method :resource_name, :resource_class, :resource, :devise_mapping( :resource_classनए डेवी संस्करण में एक आवश्यकता प्रतीत होती है)।
झाग

1
यदि हमारे पास कुछ कम आदर्श हैं, तो क्या समाधान होना चाहिए?
yozzz

मेरे पास दो डेविस मॉडल हैं और मुखपृष्ठ पर दोनों के लिए लॉगिन की आवश्यकता है। किसी भी विचार कैसे अपने जवाब के समान कुछ करने के लिए?
DR_

8

यह भी कोशिश कर सकते हैं ... इस सवाल की जाँच करें ।

स्रोत

<%= form_for("user", :url => user_session_path) do |f| %>
  <%= f.text_field :email %>
  <%= f.password_field :password %>
  <%= f.check_box :remember_me %>
  <%= f.label :remember_me %>
  <%= f.submit 'Sign in' %>
  <%= link_to "Forgot your password?", new_password_path('user') %>
<% end %> 

क्या यह सभी उत्तरों का सबसे अच्छा अभ्यास नहीं है?
अलिगुट्टा

4

डेविस कंट्रोलर से रेंडर होने पर आपके द्वारा बनाया गया फॉर्म काम करता है क्योंकि "संसाधन" डेविस के माध्यम से परिभाषित किया गया है। डेविस सेशंसकंट्रोलर के कार्यान्वयन पर एक नज़र डालें - मैं जो समझता हूं, आप "नई" कार्रवाई को दोहराने का प्रयास कर रहे हैं। विधि "build_resource" शायद वही है जो आप देख रहे हैं।

वार्डन मणि जहां "संसाधन" वस्तुओं से आ रहे है। यदि आप गहरी खुदाई करना चाहते हैं, तो यह देखने की जगह होगी।


मुझे अभी mains_controller में 'build_resource' कहा जाता है, लेकिन यह [अपरिभाषित स्थानीय चर या विधि `build_resource '] त्रुटि कहता है। मैंने 'डेविस :: कंट्रोलर्स :: इंटरनल हेल्पर्स' को 'मेनस_कंट्रोलर' में शामिल करके डेविस इंटरनल हेल्पर को शामिल करने की कोशिश की, लेकिन यह 'एब्सट्रैक्ट
कंट्रोलर

3

स्वीकृत उत्तर को परिष्कृत करने के लिए, हम विभिन्न प्रकार के संसाधनों की अनुमति देने के लिए इस सहायक का उपयोग करते हैं:

def resource_name
  @resource_name ||= if admin_controller?
    :admin_user
  else
    :user
  end
end

def resource
  @resource ||= resource_name.to_s.classify.constantize.new
end

def devise_mapping
  @devise_mapping ||= Devise.mappings[resource_name]
end

लॉगिन रीडायरेक्ट को हैंडल करने admin_controller?के ApplicationControllerलिए हमारे पास पहले से कुछ कहां है :

def admin_controller?
  !devise_controller? and request.path =~ /^\/admin/
end
helper_method :admin_controller?

2

मुझे वही त्रुटि मिल रही थी undefined local variable or method "resource"जिसका वर्णन आप मेरे एक कंट्रोलर से कर रहे हैं, क्योंकि मेरे कंट्रोलर बेस क्लास को मिसिंग था (रेल्स-एपीआई एक्शनकंट्रोलर :: एपीआई गलती पर था):

include ActionController::Helpers

इस प्रकार डेविस से सहायक विधियों को दृश्य में हल नहीं किया जा सकता था।

रेल-एपीआई के साथ काम करने के लिए मुझे शामिल करने की आवश्यकता है:

class ApplicationController < ActionController::API

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