2010-01-17 21 views
8

एक बात तुम मेरे rap lyric explanation site पर कर सकते हैं (आपके द्वारा लॉग इन कर रहे हैं) स्पष्टीकरण "की तरह" है लेता है के बाद एक उपयोगकर्ता से पूछें:लॉगइन करने के लिए वह एक निश्चित कार्रवाई

http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1645.png

मैं करना चाहते हैं लॉग इन नहीं किए गए उपयोगकर्ताओं के लिए "पसंद" लिंक दिखाएं, और फिर, जब कोई गैर-लॉग इन उपयोगकर्ता "पसंद" पर क्लिक करता है, तो उसे "लॉगिन या पंजीकरण" फ़ॉर्म (जैसे डिग/रेडडिट) के साथ एक लाइटबॉक्स दिखाएं (जैसे डिग/रेडडिट)

http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1650.png

टी को पूरा करने का सबसे अच्छा तरीका क्या है उनके?

वर्तमान में मैं इस दृष्टिकोण का उपयोग कर रहा:

  1. क्लिक करना /annotations/:id/vote करने के लिए पोस्ट "लाइक" (पोस्ट शरीर को इंगित उपयोगकर्ता या "लिंक समाप्त करने" को पसंद करने गया है या नहीं)।
  2. vote एनोटेशन नियंत्रक कार्रवाई एक require_userbefore_filter कि इस तरह दिखता है है:

    def require_user 
        unless current_user 
        store_desired_location 
        flash[:notice] = "You'll need to login or register to do that" 
        redirect_to login_path # map.login '/login', :controller => 'user_sessions', :action => 'new' 
        return false 
        end 
    end 
    
  3. user_sessions#new इस तरह दिखता है:

    def new 
        @user_session = UserSession.new 
        respond_to do |format| 
        format.html {} 
        format.js { 
         render :layout => false 
        } 
        end 
    end 
    

समस्या यह है कि रीडायरेक्ट नहीं करता है जावास्क्रिप्ट पर सही ढंग से काम करने लगते हैं:

http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1700.png

मैं इसे सही तरीके से पुनर्निर्देशित करने के लिए कैसे प्राप्त करूं?

इसके अलावा, क्या यह सही सामान्य दृष्टिकोण है? एक और विचार था कि जब मैं उपयोगकर्ता में लॉग इन नहीं करता था तब जावास्क्रिप्ट में "पसंद" लिंक में एक अलग हैंडलर संलग्न करना था (लेकिन मुझे नहीं लगता कि यह विधि अन्य कार्यों के लिए अच्छी तरह से स्केल करती है जिन्हें मैं उसी तरह से संभालना चाहता हूं)

उत्तर

3

यहां पर काबू पाने के लिए कुछ समस्याएं हैं।

  1. सामान्य रूप से ब्राउज़र पोस्ट अनुरोध पर रीडायरेक्ट करने की अनुमति नहीं देते हैं।

  2. redirect_to अतिरिक्त इनपुट के बिना प्रारूप को संरक्षित नहीं करता है।

  3. स्टोर स्थान फॉर्म डेटा को सुरक्षित नहीं करता है।

इन सभी समस्याओं को पुनर्निर्देशित करने के द्वारा हल किया जा सकता है।

यहाँ कैसे मैं अतीत में सौंप दिया गया है:

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

नया कार्य प्रवाह के उच्च स्तर दृश्य दिखाई देगा:

  1. अनुरोध एनोटेशन के लिए # वोट (बाद का)
  2. required_user फिल्टर विफल रहता है
  3. नया सत्र
  4. प्रस्तुत करना लॉगिन जानकारी और मूल प्रस्तुत पोस्ट डेटा एनोटेशन पर वापस # वोट (POST)
  5. मतदान में नया फ़िल्टर सत्र जानकारी और लॉग इन कैप्चर करता है। उम्मीद के अनुसार वोट प्राप्त होता है। लॉगिन 3.
  6. एनोटेशन # वोट करने के लिए वापस विफल रहता है/renders के रूप में यह

प्रारंभ require_user दोबारा काम से user_sessions # नया टेम्पलेट प्रस्तुत करना चाहिए पुनर्निर्देश।

def require_user 
    unless current_user 
    flash[:notice] = "You'll need to login or register to do that" 
    @user_session ||= UserSession.new 
    respond_to do |format| 
     format.html {render :template => 'user_sessions/new'} 
     format.js { 
     render :template => 'user_sessions/new', :layout => false 
     } 
    end 
    end 
end 

@user_session ||= UserSession.new सुनिश्चित करता है हम फार्म के लिए सत्यापन त्रुटियों लौट सकते हैं।

अब हमें आपके user_session # नए टेम्पलेट को गोमांस करना होगा ताकि यह कार्रवाई को याद रख सके। इसके अलावा यदि आप लाइटबॉक्स का उपयोग करने की योजना बनाते हैं, तो यह प्रासंगिक आरजेएस या new.html.erb द्वारा प्रस्तुत आंशिक रूप से प्रस्तुत किया जाना चाहिए।

:

<% if params[:controller] == "annotations" %> 
    <% content_for :old_form do %> 
    <%= hidden_field_tag "annotation[song_id]", params[:annotation][:song_id] %> 
    <%= hidden_field_tag "annotation[vote]", params[:annotation][:vote] %> 
    <% end %> 
<% end %> 

फिर लॉगिन आंशिक कि आपके लाइटबॉक्स को घेरता है में है कि आंशिक प्रस्तुत करना:

पहले हम पोस्ट डेटा होता है कि एक रीडायरेक्ट में खो गया है संरक्षण छिपा क्षेत्रों बनाने के लिए एक आंशिक बनाने

<%= render :partial => vote_form_replica %> 

<% url = params[:controller] == "user_sessions ? user_sessions_url : {} %> 
<% form_tag @user_session, :url => url do |f| %> 
    <%= yield :old_form %> 
    <%= f.label :user_name %> 
    <%= f.text_field :user_name %> 
    <%= f.label :password %> 
    <%= f.password_field :password %> 
    <%= submit_tag %> 
<%end%> 

form_tag में url के लिए खाली हैश एक त्रुटि की तरह दिखता है, लेकिन नहीं है। यह सुनिश्चित करता है कि फॉर्म डेटा यूआरएल पर पोस्ट किया गया है जो फॉर्म प्रस्तुत करता है। जो इस बिंदु पर एनोटेशन/होना चाहिए: आईडी/वोट

अब लॉगिन करने के लिए नए फ़िल्टर के लिए। अनिवार्य रूप से यह वही करेगा जो उपयोगकर्ता सत्र कंट्रोलर # बनाता है बिना रेंडर/रीडायरेक्ट के करता है। निम्नलिखित विश्वसनीय प्रमाणीकरण प्लगइन से कॉपी किया गया है।

def authenticate 
    self.current_user = User.authenticate(params[:login], params[:password]) 
    if logged_in? 
    if params[:remember_me] == "1" 
     current_user.remember_me unless current_user.remember_token? 
     cookies[:auth_token] = { :value => self.current_user.remember_token, 
     :expires => self.current_user.remember_token_expires_at } 
    end 
    end 
end 

यह सब सुनिश्चित है कि फ़िल्टर ऑर्डर सही है।

before_filter :authenticate, :require_user, :only => :vote 

N.B .: आप शायद नहीं प्रमाणित के इस संस्करण के बिना require_user के इस संस्करण का उपयोग करने के लिए जा रहे हैं तो यह समझ में आता है उन्हें एक ही फिल्टर में गठबंधन करने के लिए।

और यही वह है। जिस तरह से यह स्थापित किया गया है, मजबूत ड्रवाई आसानी से पुन: उपयोग करने योग्य कोड के लिए अनुमति देता है। नए फ़िल्टर को एप्लिकेशन कंट्रोलर में रखकर वे किसी भी नियंत्रक में उपलब्ध हैं।

  1. vote_form_replica आंशिक के बाद एक नया आंशिक मॉडलिंग बनाएँ: इस बिंदु से, किसी भी अन्य नियंत्रक/कार्रवाई करने के लिए इस कार्यक्षमता जोड़ने केवल 3 सरल चरणों लेता है।
  2. नए सत्र टेम्पलेट में संबंधित रेंडर स्टेटमेंट जोड़ें।
  3. फ़िल्टर को अपने कार्यों में लागू करें।
+0

मुझे लगता है कि आपको फ़िल्टर से पहले 'प्रमाणीकरण' और ': requ_user'' गठबंधन करना होगा। जैसा कि है, आप ': requ_user' को अलग से कॉल नहीं कर सकते क्योंकि उपयोगकर्ता कभी लॉग इन नहीं कर पाएगा। हालांकि, मुझे लगता है कि यह पूरी तरह से सही दृष्टिकोण है - विशेष रूप से' content_for' उपयोगकर्ता के "पुनः चलाने" के लिए चाल वांछित कार्रवाई करने के बाद वह लॉग इन करता है और उपयोगकर्ता को 'pre_filter' के माध्यम से लॉग इन करने का सामान्य विचार दोनों चालाक –

+0

धन्यवाद है। content_for वास्तव में जरूरी नहीं है, मैंने महसूस किया कि यह कोड को पढ़ने में आसान बना दिया गया है। यह आपके आंशिक रूप से बेहतर काम करता है, ताकि अन्य नियंत्रकों/कार्यों के लिए इसे अनुकूलित करने के लिए एक नया आंशिक और संबंधित प्रस्तुत करने की आवश्यकता हो: आंशिक कथन। मैंने इसे प्रतिबिंबित करने के लिए समाधान को अद्यतन किया है। प्रमाणीकरण और requ_user फ़िल्टर को एक फ़िल्टर में जोड़ना अधिक व्यावहारिक है। मुझे लगा कि समाधान की व्याख्या इस योजना में अपने वर्तमान कोड को अनुकूलित करने के लिए आप परमाणु कदमों को तोड़कर बेहतर हो सकती है। – EmFi

+0

ओह, भी - प्रस्तुत नहीं करना चाहिए: action => 'user_sessions/new'' प्रस्तुत करें: टेम्पलेट =>' user_sessions/new'' ('require_user' में)? –

0

मैं आपके प्रश्न के निचले हिस्से में वर्णन के तरीके से इस तरह से संपर्क करूंगा। शुरुआत में पृष्ठ को प्रदर्शित करने से पहले, जांचें कि उपयोगकर्ता लॉग इन है या नहीं। अगर वे हैं, तो "पसंद" लिंक को उनके सामान्य व्यवहार का उपयोग करना चाहिए। यदि नहीं, रजिस्टर/लॉगिन पैनल दिखाने के लिए एक क्लिक ईवेंट बांधें। इसके बारे में कुछ भी नहीं है जिसे पुन: उपयोग नहीं किया जा सकता है। वास्तव में, हम अपने काम पर इस सटीक विधि का उपयोग करते हैं। प्रमाणीकरण की आवश्यकता वाले किसी भी उपयोगकर्ता कार्रवाई या तो अपने सामान्य व्यवहार का पालन करती है या पेज लोड होने पर लॉगिन स्थिति के आधार पर एक सामान्य लॉगिन पैनल पॉप अप करती है।

+0

"यदि नहीं, रजिस्टर/लॉगिन पैनल दिखाने के लिए एक क्लिक ईवेंट बांधें" - मैं बस उन सभी कार्यों के लिए ऐसा नहीं करना चाहता हूं जिनके लिए उपयोगकर्ताओं को लॉग इन करने की आवश्यकता है (साथ ही, जब उपयोगकर्ता लॉग इन करता है, मैं कैसे सुनिश्चित कर सकता हूं कि मूल रूप से जो भी कार्रवाई की गई वह जगह लेती है?) –

संबंधित मुद्दे