Raylar Model, Görünüm, Kontrolör ve Yardımcı: nereye gidiyor?


155

Ruby on Rails Development'da (veya genel olarak MVC'de), mantığın nereye konulacağı konusunda hangi hızlı kuralı izlemeliyim.

Lütfen olumlu cevap verin - İle bunu buraya koymak yerine Bunu buraya koyun .

Yanıtlar:


173

MVC

Kontrolör : Buraya, kullanıcının ne istediğini öğrenmek ve onlara ne vereceğine karar vermek, giriş yapıp yapmadığını, belirli verileri görüp görmemesi gerekip gerekmediği vb. İle ilgili olan kodu buraya koyun. hangi verilerin (Modeller) gösterileceğini ve hangi Görünümlerin görüntüleneceğini belirler. Kodun denetleyiciye girip girmeyeceğinden şüphe ediyorsanız, muhtemelen gitmemelidir. Denetleyicilerinizi sıska tutun .

Görünüm : Görünüm yalnızca verilerinizi görüntülemek için minimum kodu içermelidir (Model), çok fazla işlem veya hesaplama yapmamalı, Model tarafından hesaplanan (veya özetlenen) verileri göstermeli veya Denetleyiciden oluşturmalıdır. Görünümünüzün gerçekten Model veya Kontrolör tarafından yapılamayan işlemler yapması gerekiyorsa, kodu bir Yardımcıya yerleştirin. Bir Görünümdeki Ruby kodunun birçoğu sayfa işaretlemesini okumayı zorlaştırır.

Model : Modeliniz , verilerinizle ilgili tüm kodunuzun (Sitenizi oluşturan varlıklar, ör. Kullanıcılar, Posta, Hesaplar, Arkadaşlar vb.) Bulunduğu yerde olmalıdır . Kodun varlıklarınızla ilgili verileri kaydetmesi, güncellemesi veya özetlemesi gerekiyorsa buraya yerleştirin. Görünümleriniz ve Denetçileriniz arasında yeniden kullanılabilir.


2
İnsanlar şişman modelden uzaklaşmaya başlıyor. Modelimi bir veri yapısı olarak düşünmeyi seviyorum. Sonra davranışı uygulayan bazı Ruby nesnesini yazıyorum, modelle başlatalım (modeli veri olarak ele alır, dizeleri ve dizileri Rails dışındaki nesnelere veri gibi davranır). İşte bu tekniğin bir örneğiyle iyi bir video.
Joshua Cheek

@AdamDonahue Şişman bir şeyin iyi bir şey olarak görülebileceğinden emin değilim. Tonlarca sorumluluk hizmetlere ait olmaktan daha iyidir.
fatuhoku

35

Pauliephonic'in cevabına eklemek için:

Yardımcı : görünümü oluşturmayı kolaylaştıran işlevler. Örneğin, fiyatlarını görüntülemek için her zaman bir widget listesi üzerinde yineleniyorsanız, bir yardımcıya koyun (gerçek ekran için kısmi ile birlikte). Ya da görüntüyü karıştırmak istemediğiniz bir RJS parçanız varsa, bir yardımcıya koyun.


Aslında Helper'a sign_in yöntemini de koymadık mı? RoR Tutorial'ın burada önerdiği gibi >>> ruby.railstutorial.org/book/…
Ivan Wang

14

MVC modeli gerçekten sadece kullanıcı arayüzü ile ilgilidir ve başka bir şey değildir. Görünümü kontrol ettiği için mantığa değil kontrolöre karmaşık bir iş mantığı koymamalısınız. Denetleyici, uygun görünümü seçmeyle ilgilenmeli ve etki alanı modeline (Model) veya iş katmanına daha karmaşık şeyler aktarmalıdır.

Etki Alanına Dayalı Tasarım, genel olarak bir Model sınıfına ait olmayan mantık anlamına gelen çeşitli nesne türlerini düzenlemek için mantığı taktığınız bir hizmet kavramına sahiptir.

Genelde Hizmet katmanını uygulamalarımın API'si olarak düşünüyorum. Hizmetlerim katmanları genellikle oluşturduğum uygulamanın gereksinimleriyle oldukça yakından eşleşir, bu nedenle Servis katmanı, uygulamamın alt düzeylerinde bulunan daha karmaşık etkileşimlerin basitleştirilmesi işlevini görür; yani Hizmet katmanlarını atlayarak aynı hedefi gerçekleştirebilirsiniz ancak çalışması için çok daha fazla kol çekmeniz gerekir.

Burada Rails'den bahsetmiyorum, özel sorununuzu ele alan genel bir mimari tarzdan bahsediyorum.


Bu harika bir cevap :)
Carlos Martinez



7

Denetleyiciye yetkilendirme / erişim kontrolü ile ilgili şeyler koyun.

Modeller tamamen verilerinizle ilgilidir. Doğrulama, İlişkiler, CRUD, İş Mantığı

Görüntülemeler verilerinizi göstermekle ilgilidir. Sadece görüntüleme ve giriş alma.

Kontrolörler, modelinizden görünümünüze (ve hangi görünüm) ve görünümünüzden modelinize hangi verilerin gittiğini kontrol etmekle ilgilidir. Kontrolörler modelsiz de bulunabilir.

Denetleyiciyi, müşteriyi (talebi) bir veznedara bir soru sorduğunuzda (görüntüleme) uygun sayaca yönlendiren bir güvenlik görevlisi / resepsiyonist olarak düşünmeyi seviyorum. Vezne (görünüm) daha sonra gider ve hiç görmediğiniz bir yöneticiden (model) cevap alır. Siz daha sonra güvenlik görevlisi / resepsiyonistine (denetleyici) geri dönün ve yöneticinin (modelin) diğer teller (görüş) sorusuna yanıt olarak size söylediği yanıtı söyleyen başka bir veznedar (görüş) gitmek için yönlendirilene kadar bekleyin. .

Aynı şekilde, veznedara (görünüm) bir şey söylemek istiyorsanız, ikinci kez gelen yöneticinin bilgilerinizi kabul edip etmediğini size bildirmesi dışında, büyük ölçüde aynı şey olur. Güvenlik görevlisi / resepsiyon görevlisi (denetleyici), yöneticiye bu bilgileri bildirme yetkiniz olmadığı için size bir yürüyüş yapmanızı söylemiş olabilir.

Bu nedenle, basmakalıp ve gerçekçi olmayan dünyamdaki metaforu genişletmek için, anlatıcılar (görüşler) güzel ama boş kafalı ve onlara söylediğiniz her şeye inanıyorlar, güvenlik görevlisi / resepsiyonistleri çok kibar ama çok bilgili değiller ama insanların nerede olması gerektiğini biliyorlar ve gitmemelisiniz ve yöneticiler gerçekten çirkin ve kaba ama her şeyi biliyorlar ve neyin doğru neyin yanlış olduğunu söyleyebilirler.


4

Düzgün ayrılmaya yardımcı olan bir şey, "yerel değişkenleri denetleyiciden görüntülemeye" önleme yönteminden kaçınmaktır. Bunun yerine:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  def show
    @foo = Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...

Yardımcı yöntem olarak kullanılabilen bir alıcıya taşımayı deneyin:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  helper_method :foo

  def show
  end

  protected

  def foo
    @foo ||= Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...

Bu, "@foo" ya konanları ve nasıl kullanıldığını değiştirmeyi kolaylaştırır. Daha karmaşık hale getirmeden kontrolör ve görünüm arasındaki mesafeyi arttırır.


uhmmm ... Yuk. Lütfen bunu ne zaman yapacağınıza ilişkin bazı iyi nedenler / senaryolar ekleyebilir misiniz? Bu KISS ve YAGNI'yi kırıyor ve çok kötü kokulu (sadece bir klişe daha
fırlatmak için

2
1) Rails, denetleyicinin örnek değişkenlerini görünüm örneğinize kopyalamak için çok fazla sihir yapar. 2) Önerilen uygulama aynı zamanda yalnızca erişilirse foo yükler, bu da zaman zaman bazı işleri kurtarabilir. Önemli cevap gerçekten 1).
webmat

11
İç çek Bu korkunç. Rails örneği değişken paylaşımı, anti-desen olmayan bir özelliktir. Gerçek dünya sorunlarına nadiren neden olan, her yerde bulunan, düşük zihinsel tepegöz bir sözdizimsel şekerdir. Eğer hoşlanmıyorsanız, iyi, ama etrafı barok standart dışı bir yapı ile kodlamak işleri sonsuz derecede kötüleştirir. Bu durumda, foo'yu etkili bir şekilde genel olarak (her kontrolör için) bir değişken haline getirirsiniz. Kapsamı önemli ölçüde artırarak değişken kapsamın algılanan kötüye kullanımını düzeltmeye çalışmak son derece ironiktir.
gtd

1
Satın almıyorum dasil003. Kapsamı foove @fooaynıdır - her ikisi de <ControllerClass, istek> çiftine kapsamına eklenir. Ayrıca, getter sürümünü kullanarak Foo, görünümün ona nasıl eriştiğini değiştirmeden bu nesnenin nasıl bulunduğunu / depolandığını / önbelleğe alındığını değiştirebilirim.
James A. Rosen

1
Sanırım "geçiş örneği değişkenleri" anti-modelini kastediyorsunuz. Bir örnek değişkeni, derin yuvalanmış bölümlerde bile tüm oluşturma için sızıntı durumu oluşturur. Çözümünüz de durumu sızdırıyor, ancak yeniden atamaya izin vermediği için bir örnek vardan biraz daha iyi. Yerel bir geçiş yapmak aslında en iyisidir çünkü bir yöntemi çağırmak gibidir; yerel kısmi kişiler tarafından görülemez. Bu cevaba bakınız .
Kelvin

2

Şey, mantığın neyle uğraştığına bağlı ...

Çoğu zaman, kontrol cihazlarınızı küçük bırakarak modellerinize daha fazla şey itmek mantıklıdır. Bu, bu mantığın, modelinizin temsil ettiği verilere erişmek için ihtiyacınız olan her yerden kolayca kullanılabilmesini sağlar. Görünümler neredeyse hiç mantık içermemelidir. Yani gerçekten, genel olarak, Kendinizi Tekrarlamamak için bunu yapmaya çalışmalısınız.

Ayrıca, Google'ın hızlı bir kısmı, nereye gittiğine dair birkaç somut örnek daha ortaya koyuyor.

Model: doğrulama gereksinimleri, veri ilişkileri, yöntem oluşturma, güncelleme yöntemleri, yok etme yöntemleri, yöntemleri bulma (yalnızca bu yöntemlerin genel sürümlerine sahip olmanız gerektiğini değil, aynı zamanda çok fazla yaptığınız bir şey varsa, kırmızı olan insanları bulmak gibi) saç soyadına göre, o zaman bu mantığı ayıklamak gerekir böylece tek yapmanız gereken find_redH_by_name ("smith") veya bunun gibi bir şey çağırmak)

Görünüm: Bu, verilerin işlenmesi değil, verilerin biçimlendirilmesi ile ilgili olmalıdır.

Denetleyici: Veri işleme burada gider. İnternetten: "Kontrolörün amacı, kullanıcı tarafından talep edilen eyleme cevap vermek, kullanıcının ayarladığı tüm parametreleri almak, verileri işlemek, modelle etkileşime girmek ve daha sonra istenen verileri nihai formda görünüm."

Umarım yardımcı olur.


0

Basit bir ifadeyle, genel olarak, Modeller tablolarla ilgili tüm kodlara, basit veya karmaşık ilişkilerine (birden çok tablo içeren sql sorguları olarak düşünün), iş mantığını kullanarak bir sonuca varmak için verilerin / değişkenlerin manipülasyonuna sahip olacaktır. .

Kontrolörler , istenen iş için ilgili modellere yönelik kod / göstergelere sahip olacaktır.

Görünümler kullanıcı girişini / etkileşimini kabul eder ve elde edilen yanıtı görüntüler.

Bunlardan herhangi bir büyük sapma, o parça üzerinde istenmeyen bir yük oluşturacak ve genel uygulama performansı etkilenebilir.


-1

Test Etme, Test Etme ... Modele mümkün olduğunca çok mantık koyun ve daha sonra düzgün bir şekilde test edebileceksiniz. Birim testleri, verileri ve modeli test ederek oluşturulma şeklini test eder ve fonksiyonel testler, denetleyicileri test ederek yönlendirilme veya kontrol etme şeklini test eder, böylece verilerin içinde olmadığı sürece bütünlüğünü test edemezsiniz. model.

j

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.