2013-03-27 27 views
9

Denetleyicide örnek bir eylem var.RAILS 3 - Denetleyicilerindeki işlemler

def some_action 
product = Product.new 
product.name = "namepro" 
    if product.save 
    client.update_attribute(:product_id,product.id) 
    end 
end 

Bu kod için işlemler nasıl eklenir? Bu örnek kodu ile deneyin:

def some_action 
**transaction do** 
    product = Product.new 
    product.name = "namepro" 
    if product.save 
    client.update_attribute(:product_create,Time.now) 
    end 
**end** 
end 

Ama bu hatayı üretir:

undefined method `transaction' 

Ben Kontrolörleri içinde işlemlerini kullanma hakkında okumak kötü bir uygulamadır ancak nedenidir neden (http://markdaggett.com/blog/2011/12/01/transactions-in-rails/ bilmiyorum

Örnekte, ürün oluşturuldu ve kaydedildiyse ve istemci güncellemesi başarısız olursa ... Raylar hiçbir şey yapmamalıdır.

Teşekkürler.

cevap

25

Gerçekten istiyorsanız, bir denetleyicideki bir işlemi kullanabilirsiniz. Belirttiğiniz gibi, bu kötü bir uygulamadır, ancak bunu yapmak istiyorsanız, transaction do yerine Product.transaction do'u arayın. transaction, ActiveRecord::Base üzerinde bir sınıf yöntemidir, bu nedenle ActiveRecord türetilmiş bir sınıfta çağırmanız gerekir. Uygulamanızdaki herhangi bir model sınıfı (nit-picking caveat: farklı modeller için farklı veritabanlarına bağlanıyorsanız, bu doğru olmayabilir ... ama muhtemelen bunu yapmıyorsanız) yapacağız. Bu kötü bir uygulama olmasının sebebi, kaygıları MVC paradigmasına göre doğru şekilde ayırmamasıdır. Denetleyiciniz, veri kalıcılığı uygulamanızla o kadar ilgilenmemelidir. Daha iyi bir yaklaşım, Product'a bir yöntem eklemek olacaktır. Böyle Belki bir şey: yerine denetleyici içinde product.save çağıran

def save_and_update_create_time 
    transaction do 
    if save 
     client.update_attribute(:product_create, Time.now) 
    end 
    end 
end 

Sonra product.save_and_update_client_create_time diyoruz. Bu yönteme de client kodunu iletmeniz gerekebilir; client'un nereden geldiği kodunuzdan net değil. product'daki bir özellikse, yukarıdaki yöntem çalışmalıdır.

Ayrıca, bir productclient herhangi bir denetleyici verisine gerek kalmadan bilirse, bunu yapmak için daha iyi, daha Railsy yolları vardır.

after_save :update_client 

private 

def update_client(product) 
    product.client.update_attribute(:product_create, Time.now) 
end 

Sonra Product kaydedilir her zaman, ilgili istemcide alan güncellenecektir: O zaman sadece bu gibi ( Product sınıfa ekleyin), bir after_save geri arama kullanabilirsiniz. İlk önce bir client varlığını kontrol etmek için bir kod eklemeniz gerekecek.

Temiz kodun yanı sıra geri çağrıları kullanmanın yararı, geri dönüşüm zincirinin tamamının kaydetme ile birlikte tek bir işlemde çalıştığıdır; işlemi manuel olarak oluşturmanız gerekmez. Rails documentation numaralı telefondan geri arama hakkında daha fazla bilgi edinebilirsiniz.

+0

Çok teşekkürler Jim, bana açıklamalarınızda yardımcı oluyorsunuz! – user1364684

+3

Eğer işlem mantığı bir Modele sokulursa, işlemler ayrı bir model kuralını ihlal etmemek için bir Model ile sınırlı olmaz mı? Genellikle, işlemlerin, DB düzeyinde birbiriyle ilintili olmayan birden fazla Model arasında geniş bir şansı vardır. – xSNRG

+1

Evet, yorumumun bu özel yönü üzerinde bir kalp değişikliği yaşadım. Denetleyiciden uzak tutmayı sevdim ama çok modelli etkileşimler bir yere sarılmalıdır.Belki başka bir sınıf, ancak bazı durumlarda kontrolör her şeyden sonra doğru yer olabilir. –