2012-02-21 37 views
7

Benim formumda 3 alanım var cadı veritabanımda değil: open_type, opening_hours, opening_minutes. Bu 3 alan ile "açılış" (veritabanı) ana özniteliğini güncellemek istiyorum.Raylar - Model niteliklerini ve model niteliklerini güncelleştirin

Çalışılmayan birçok şeyi denedim. Aslında

Ben: Ben böyle bir şey ekleyerek çalıştı

attr_accessor :opening_type, :opening_hours, :opening_minutes 

    def opening_type=(opening_type) 
    end 
    def opening_type 
    opening_type = opening.split("-")[0] if !opening.blank? 
    end 

    def opening_hours=(opening_hours) 
    end 
    def opening_hours 
    opening_hours = opening.split("-")[1] if !opening.blank? 
    end 

    def opening_minutes=(opening_minutes) 
    end 
    def opening_minutes 
    opening_minutes = opening.split("-")[2] if !opening.blank?  
    end 

:

def opening=(opening) 
    logger.info "WRITE" 

    if !opening_type.blank? and !opening_hours.blank? and opening_minutes.blank? 
     opening = "" 
     opening << opening_type if !opening_type.blank? 
     opening << "-" 
     opening << opening_hours if !opening_hours.blank? 
     opening << "-" 
     opening << opening_minutes if !opening_minutes.blank? 
    end 
    write_attribute(:opening, opening) 
    end 

    def opening 
    read_attribute(:opening) 
    end 

Ama erişimcileri yöntemler aradım ve opening_type, opening_hours, opening_minutes çok boş olduğunu düşünüyorum değildir erişimcilerine eğer denirdi ...

Sanırım bir before_save geri aramasına ihtiyacım yok ve bunu erişimcileri yeniden yazmalıyım.

Notlar: - Raylar 3.0.5, - opening_type: opening_hours: opening_minutes boş

DÜZENLEME olabilir: Benim kod

cevap

15

Not sadece kendi yöntemleri tanımlayan için makroları. Şu anda

# attr_reader(:foo) is the same as: 
def foo 
    @foo 
end 

# attr_writer(:foo) is the same as: 
def foo=(new_value) 
    @foo = new_value 
end 

# attr_accessor(:foo) is the same as: 
attr_reader(:foo) 
attr_writer(:foo) 

, senin ayarlayıcı yöntemleri özel bir şey yapmıyoruz, bu nedenle sadece attr_accessor geçerseniz kodunuzu temizleyici hale gelecektir.

Diğer sorununuz, opening= yönteminizin hiçbir zaman aranmadığı ve bu durumun mantıklı olduğu için kodunuzun hiçbir yerinde bulunmamasıdır. Gerçekten istediğiniz şey, tüm parçaların ayarlanmasından sonra açılışınızın ayarlanmasıdır. Şimdi orada bunu yapmak için hiçbir önemsiz yol, ama Raylar hangi değerlerin döşendikten sonra çalışır ancak doğrulama dolmadan kodu koyabilirsiniz bir before_validation geri arama var: Tamam

class Shop < ActiveRecord::Base 

    attr_accessor :opening_type, :opening_hours, :opening_minutes 

    before_validation :set_opening 

    private 
    def set_opening 
    return unless opening_type && opening_hours && opening_minutes 
    self.opening = opening_type + "-" + opening_hours + "-" + opening_minutes 
    end 
end 
+0

Not: Bu cevap sadece birleşik 'açılış 'alanını veritabanında saklamak istediğinizi varsayar. Başka bir yaklaşım, veritabanındaki her bir bileşenin depolanması ve birleştirilmiş dizinin dinamik olarak talep üzerine oluşturulması olacaktır. Gereksinimlerinize bağlı olarak sizin için daha iyi bir yaklaşım olabilir. – Gareth

+0

Bu veritabanını açılış alanı ile aldım. Bu veritabanı bir akıllı telefon uygulamasıyla senkronize ediliyor ve 3 farklı alanı saklamak için yapısını değiştiremiyorum. ;-) Before_validation geri çağırma ile ilgili sorun, formu düzenleyeceğimiz zamanki durumu ele almamanız ... ve açılış alanı için 3 çeşit ... ... biçimini kesmemiz gerektiğidir. Bunu el ile yapabildiğimi biliyorum ama bunu yapanlar için daha iyi bir yaklaşım olduğunu düşündüm ... –

+0

Hepsi doğru, ama 'açma =' seçeneğini geçersiz kılmanın önerisi pek çok şeyi kırıyor. Ayrıca, içinden geçen parametreyi tamamen iptal eden bir dizgi yöntemine sahip olmak çok kabataslak bir fikir. Yaptığını netleştiren ayrı bir yönteme (benim 'set_opening') sahip olmak daha iyidir. Bu yöntemi çağırmak için * before_validation kullanmanız * gerekmiyor ancak bunun ayrı bir yöntem olduğunu kesinlikle öneriyorum – Gareth

0

yerine

attr_reader :opening_type, :opening_hours, :opening_minutes 

ihtiyacınız güncellenmiş

attr_accessor :opening_type, :opening_hours, :opening_minutes 
attr_reader :opening_type, :opening_hours, :opening_minutes 

hf ...

// Bunlar: open_type,: open_hours,: open_minutes gerçek alanlar? Eğer evetse, buna ihtiyacınız var mı?

attr_accessor: açılış attr_reader: açılış attr_reader, attr_writer ve attr_accessor olan

+0

, ben attr_accessor için değişti. Ancak açılış erişenler çağırılmaz ... –

+0

bkz. Güncelleme, .... – davidb

+0

Hayır. Gerçek alan veritabanımda "açılış" dır. Formumdan gönderilen 3 alana katılmam gerekiyor: açılış_tipi, açılış_saati, ana "açılış" alanını doldurmak için açılış_adı. Bu 3 alan veritabanında değildir. İlk gönderiyi güncelledim. –