2013-05-20 4 views
8

मैं दो मॉडल User और Submission बचाने:first_or_create ईमेल द्वारा और फिर इस रूप में नेस्टेड मॉडल

class User < ActiveRecord::Base 
    # Associations 
    has_many :submissions 
    accepts_nested_attributes_for :submissions 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :email, :name, :role, :submission_ids, :quotation_ids, :submissions_attributes 

    validates :email, :presence => {:message => "Please enter a valid email address" } 
    validates :email, :uniqueness => { :case_sensitive => false } 
end 

class Submission < ActiveRecord::Base 
    belongs_to :user 
    attr_accessible :due_date, :text, :title, :word_count, :work_type, :rush, :user, :notes 

    validates :work_type, :title, :text,:presence => true 
    validates :text, :length => { :minimum => 250 } 
    validates :word_count, :numericality => { :only_integer => true } 
end 

मैं एक रूप है जो इन दो मॉडलों के लिए आवश्यक डेटा एकत्र करता है। उपयोगकर्ता नियंत्रक:

def index 
    @user = User.new 
    @user.submissions.build 
end 

def create 
    @user = User.where(:email => params[:user][:email]).first_or_create(params[:user]) 

    if @user 
    redirect_to :root 
    else 
    render 'pages/index' 
    end 
end 

मैं क्या करना चाहता हूं सबसे पहले यह जांचें कि उपयोगकर्ता द्वारा सबमिट किए गए ईमेल द्वारा सिस्टम में पहले से मौजूद है या नहीं। यदि ऐसा है तो मैं उस उपयोगकर्ता के लिए एक सबमिशन बनाना चाहता हूं। अन्यथा एक ही समय में उपयोगकर्ता और सबमिशन बनाएं।

मैं first_or_create विधि के साथ ऐसा करने के तरीके पर उलझन में हूं।

किसी भी मदद की सराहना की।

उत्तर

13

first_or_createaccepts a block। इस प्रकार तो तुम यह कर सकता है:

@user = User.where(:email => params[:user][:email]).first_or_create do |user| 
    # This block is called with a new user object with only :email set 
    # Customize this object to your will 
    user.attributes = params[:user] 
    # After this, first_or_create will call user.create, so you don't have to 
end 
+0

मुझे इसे निर्दिष्ट करने के बजाय 'विलय' करना चाहिए, लेकिन यह मेरी व्यक्तिगत वरीयता है। थोड़ा सा क्लीनर। –

+0

धन्यवाद जो कि सबसे साफ उत्तर लगता है – chell

+0

निर्माण केवल तभी कहा जाता है जब उपयोगकर्ता डेटाबेस में पहले से मौजूद नहीं है। मैंने पाया कि इससे कोई समस्या उत्पन्न हुई है क्योंकि जब उपयोगकर्ता पहले से मौजूद है तो यह सबमिशन ऑब्जेक्ट नहीं बनायेगा – chell

-3

अरे मुझे लगता है कि यह तो उपयोगकर्ता मॉडल

def first_or_create(params) 
    unless user = User.where(:email => params[:email]).first # try to find user 
    user = User.create(email: params[:user]) 
    # it should create also submission because of accepts_nested_attributes_for 
    else #user exsists so we need to create submission for him 
    user.submissions.create(params[:submissions]) 
    end 
end 
+1

[ 'first_or_create'] (http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-first_or_create) ActiveRecord में पहले से मौजूद है। आपको अपना खुद का लेखन नहीं करना चाहिए। – Mischa

+0

यदि उपयोगकर्ता मौजूद नहीं है, तो यह कोड सबमिशन नहीं बनाता है। – davogones

1

में है कि

@user = User.first_or_create(params[:user]) 

की तरह कुछ किया जाना चाहिए के बाद से आपके उपयोग के मामले में एक छोटे से अधिक जटिल है, यह इस अप में विभाजित करने के लिए चोट नहीं कर सकते दो अलग-अलग क्रियाएं यदि आप इसे परमाणु रूप से करना चाहते हैं, तो आप इसे transaction में फेंक सकते हैं।

User.transaction do 
    # Create the user if they don't already exist 
    @user = User.where(:email => params[:user][:email]).first_or_create 

    # Update with more attributes, and create nested submissions 
    @user.update_attributes(params[:user]) 
end 
+0

मैं लेनदेन के रूप में ऐसा क्यों करूं? क्या यह सबमिशन ऑब्जेक्ट भी बनायेगा? – chell

+0

मुझे लगता है कि आपके पैराम '{user: ..., submissions_attributes: {...}} 'जैसा दिखते हैं, क्योंकि आपके मॉडल में' accepts_nested_attributes_for: submissions_attributes' था। यदि आप सबमिशन विशेषताओं को घोंसला करते हैं तो संबंधित मॉडल स्वचालित रूप से बनाया जाएगा। लेनदेन यह सुनिश्चित करेगा कि सब कुछ परमाणु रूप से बनाया/अपडेट हो जाता है (यानी यह सब सफल होता है या सभी रोल वापस आते हैं)। – davogones

+0

मुझे यह जवाब भी पसंद है। मैं एक एनओयूबी हूं और यह सुनिश्चित नहीं करता कि सबसे अच्छा जवाब कौन सा है। मैं आरडीएक्स से एक के साथ गया क्योंकि यह सिर्फ एक विधि का इस्तेमाल किया। – chell

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