2010-09-28 9 views
11

Kullanıcılarımın bir takım tercihlere sahip olabileceği bir uygulama var.Raylar: Hatalı hataları önlemek için hiçbiri bulunamazsa ilişki oluşturun

class User < AR::Base 
    has_one :preference_set 
end 

class PreferenceSet < AR::Base 
    belongs_to :user 
end 

Şimdi bir kullanıcının tercihlerine erişebilir: şu şekildedir: Her iki ActiveRecord-modelleri olarak depolanır

@u = User.first 
@u.preference_set => #<PreferenceSet...> 
@u.preference_set.play_sounds => true 

Ama bir tercih kümesi zaten oluşturulmuş değilse bu @u beri başarısız olur. preference_set sıfır geri dönecek ve nil numaralı telefondan play_sounds numaralı telefonu arayacağım.

Arşivlemek istediğim, User.preference_set öğesinin her zaman bir PreferenceSet örneği döndürdüğüdür. Böyle tanımlamadan denedim: o yinelemeli kendisini aradığını, bu durum bir 'Stack level too deep' neden oluyor

class User < .. 
    has_one :preference_set 

    def preference_set 
    preference_set || build_preference_set 
    end 
end 

.

nasıl @user.preference_set döner gelen preference_set kayıt ya da, hiçbiri varsa, yeni bir tane oluşturur sağlayabilirsiniz:

Sorum şudur?

Derneğimi (örn. preference_set_real) yeniden adlandırabildiğimi ve bu şekilde yinelemeli çağrılardan kaçınabileceğimi biliyorum, ancak uygulamanızdaki basitlik uğruna, adlandırma işlemini sürdürmek istiyorum.

Teşekkürler!

class User < ActiveRecord::Base 
    has_one  :preference_set, :autosave => true 
    before_create :build_preference_set 
end 

bir User oluşturulduğunda böylece kurmak için başında PreferenceSet olduğunu: Eğer birincil birini oluştururken Eh

cevap

27

Bunu yapmanın en iyi yolu ilişkili kayıt yaratmaktır. İlişkili kaydı bağımsız değişkenlerle başlatmanız gerekirse, before_create'da build_preference_set(:my_options => "here") numaralı çağrıları farklı bir yöntemle arayın ve true döndürür.

PreferenceSet olmayan ve #create_preference_set numaralı telefonu arayarak bina üzerinde yineleme yaparak mevcut tüm kayıtları normalleştirebilirsiniz. alias_method_chain rastlamak olmasaydı

class User < ActiveRecord::Base 
    has_one :preference_set 

    def preference_set_with_initialize 
    preference_set_without_initialize || build_preference_set 
    end 

    alias_method_chain :preference_set, :initialize 
end 
+3

Vay,: Yalnızca kesinlikle gerekli olduğunda, o zaman böyle bir şey yapabilirsiniz PreferenceSet oluşturmak istiyorsanız

. Çok havalı. – Chowlett

+0

"alias_method_chain" modülünün "Module # prepend" lehine önerilmemesi önerilir. Daha fazla bilgi burada: https://github.com/rails/rails/pull/19434 –

38

veya basitçe

class User < ApplicationRecord 
    has_one :preference_set 

    def preference_set 
    super || build_preference_set 
    end 
end