के लिए एक जटिल मॉडल पर प्रमाणीकरण मैं devise और सक्रिय व्यापारी का उपयोग करके पंजीकरण लिखने की कोशिश कर रहा हूं। प्रपत्र जटिल है कि मेरे उपयोगकर्ता वस्तु इस तरह दिखता है:एक बहु-पृष्ठ फ़ॉर्म
class User < ActiveRecord::Base
include ActiveMerchant::Utils
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
# Setup accessible (or protected) attributes
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :first_name,
:subscription_attributes, :last_name, :zipcode,
:payment_profile_attributes, :customer_cim_id, :payment_profile_id
...
# Track multi-page registration
attr_writer :current_step
...
# Setup Payment Profile element (authorize.net billing profile)
has_one :payment_profile, :dependent => :delete
accepts_nested_attributes_for :payment_profile
अब PaymentProfile वर्ग का अपना बच्चों, सक्रिय व्यापारी से दो आइटम नहीं है:
require 'active_merchant'
class PaymentProfile < ActiveRecord::Base
include ActiveMerchant::Billing
include ActiveMerchant::Utils
validate_on_create :validate_card, :validate_address
attr_accessor :credit_card, :address
belongs_to :user
validates_presence_of :address, :credit_card
def validate_address
unless address.valid?
address.errors.each do |error|
errors.add(:base, error)
end
end
end
def address
@address ||= ActiveMerchant::Billing::Address.new(
:name => last_name,
:address1 => address1,
:city => city,
:state => state,
:zip => zipcode,
:country => country,
:phone => phone
)
end
def validate_card
unless credit_card.valid?
credit_card.errors.full_messages.each do |message|
errors.add(:base, message)
end
end
end
def credit_card
@credit_card ||= ActiveMerchant::Billing::CreditCard.new(
:type => card_type,
:number => card_number,
:verification_value => verification_code,
:first_name => first_name,
:last_name => last_name
)
@credit_card.month ||= card_expire_on.month unless card_expire_on.nil?
@credit_card.year ||= card_expire_on.year unless card_expire_on.nil?
return @credit_card
end
अब मैं से RegistrationsController overrided गए रयान बेट्स मल्टी-पेज फॉर्म स्क्रीनकास्ट (http://railscasts.com/episodes/217-multistep-forms) से समाधान का उपयोग करके मल्टी-पेज फॉर्म को संभालने के लिए तैयार करें। मुझे इसे डेविस के साथ काम करने के लिए थोड़ा सा ट्विक करना पड़ा, लेकिन मैं सफल रहा। अब क्योंकि रयान की बहु-पृष्ठ प्रपत्र बस विभिन्न पृष्ठों पर एक ही मॉडल से विभिन्न क्षेत्रों के लिए कहा है, वह एक जोड़कर अपने valid?
विधि ओवरराइड करने में सक्षम था: अगर उसकी सत्यापित करें विधि एक ला करने के लिए ब्लॉक:
validates_presence_of :username, :if => lambda { |o| o.current_step == "account" }
लेकिन में मेरा मामला, मैं अपने मूल मॉडल (उपयोगकर्ता) से पहले फॉर्म पर सभी फ़ील्ड मांग रहा हूं, और फिर अपने दो पोते मॉडल (उपयोगकर्ता: भुगतान प्रोफाइल: पता, उपयोगकर्ता: भुगतान प्रोफाइल: क्रेडिट_Card) से सभी फ़ील्ड मांग रहा हूं तेह दूसरा पृष्ठ।
मुझे जिस समस्या का सामना करना पड़ रहा है वह यह है कि हालांकि PayProfile.valid? ActiveMerchant के तर्क के आधार पर त्रुटियां लौटाता है, फ़ॉर्म स्वयं ही उन त्रुटियों को प्रस्तुत या प्रदर्शित नहीं करता है। बिलिंग पृष्ठ के लिए दृश्य कोड इस तरह दिखता है:
<h2>Payment Details</h2>
<%= semantic_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= f.semantic_fields_for :payment_profile do |p| %>
<%= p.semantic_fields_for :address do |a| %>
<%= a.inputs "Billing Information", :id => "billing" do %>
<%= a.input :type, :label => "Credit Card", :as => :select, :collection => get_creditcards %>
<%= a.input :number, :label => "Card Number", :as => :numeric %>
<%= a.input :card_expire_on, :as => :date, :discard_day => true, :start_year => Date.today.year, :end_year => (Date.today.year+10), :add_month_numbers => true %>
<%= a.input :first_name %>
<%= a.input :last_name %>
<%= a.input :verification_code, :label => "CVV Code" %>
<% end %>
<% end %>
<%= f.semantic_fields_for :credit_card do |c| %>
<%= c.inputs "Billing Address", :id => "address" do %>
<%= c.input :address1, :label => "Address" %>
<%= c.input :city %>
<%= c.input :state, :as => :select, :collection => Carmen::states %>
<%= c.input :country, :as => :select, :collection => Carmen::countries, :selected => 'US' %>
<%= c.input :zipcode, :label => "Postal Code" %>
<%= c.input :phone, :as => :phone %>
<% end %>
<% end %>
<% end %>
<%= f.commit_button :label => "Continue" %>
<% unless @user.first_step? %>
<%= f.commit_button :label => "Back", :button_html => { :name => "back_button" } %>
<% end %>
<% end %>
मैं सही वैध करने के बाद अपने कोड में एक puts errors
संदेश जोड़ा?
{:username=>["can't be blank"]}
तो:
{:base=>[["first_name", ["cannot be empty"]], ["last_name", ["cannot be empty"]], ["year", ["expired", "is not a valid year"]], ["type", ["is required", "is invalid"]], ["number", ["is not a valid credit card number"]], ["verification_value", ["is required"]], ["address1", ["is required"]], ["city", ["is required"]], ["state", ["is required"]], ["zip", ["is required", "must be a five digit number"]], ["phone", ["is required", "must be in the format of 333-333-3333"]]]}
{:base=>[["first_name", ["cannot be empty"]], ["last_name", ["cannot be empty"]], ["year", ["expired", "is not a valid year"]], ["type", ["is required", "is invalid"]], ["number", ["is not a valid credit card number"]], ["verification_value", ["is required"]], ["address1", ["is required"]], ["city", ["is required"]], ["state", ["is required"]], ["zip", ["is required", "must be a five digit number"]], ["phone", ["is required", "must be in the format of 333-333-3333"]]]}
अब इस उत्पादन की संरचना एक मानक त्रुटि उत्पादन है जो इस तरह के रूप में एक परत हैश बंद बनाया गया है के उत्पादन से मेल नहीं खाता: आदेश और इसे इस प्रकार से पता चलता आपको यह सब दिखाने के बाद, मेरे प्रश्न ये हैं: ए) मैं त्रुटि आउटपुट को सही तरीके से दिखाने के लिए कैसे प्राप्त करूं ताकि फ़ॉर्म वास्तव में उन्हें थूक सके? बी) मैं माता-पिता को कैसे रोकूं? वैध? पोते को वैध करने से भी। वैध? जब मैं उस पृष्ठ पर नहीं हूं? मैं इसका उपयोग नहीं कर सकता: if => lambda ... बाल मॉडल पर समाधान क्योंकि वे नहीं जानते कि current_step क्या है।
इतनी लंबी पोस्ट के लिए मेरी माफ़ी, मैं बस जितना संभव हो उतना जानकारी शामिल करना चाहता था। मैं इसके साथ एक हफ्ते तक कुश्ती कर रहा हूं और मुझे इससे पहले प्रतीत नहीं होता है। कोई सलाह बेहद सहायक होगी। अग्रिम में धन्यवाद।
क्लाइंट-साइड सत्यापन एक अच्छा अतिरिक्त है, लेकिन सर्वर-साइड सत्यापन के लिए बिल्कुल कोई प्रतिस्थापन नहीं है। क्लाइंट-साइड सत्यापन आसानी से दुर्भावनापूर्ण स्क्रिप्ट द्वारा अवरुद्ध किया जाता है जो जेएस-सक्षम ब्राउज़र का उपयोग नहीं करते हैं। यह सुनिश्चित करने के लिए कि आपका डेटा उच्च अखंडता का है, सर्वर-साइड सत्यापन केवल विश्वसनीय तंत्र है। –