Örneğin elimizde Customer
, Address
, Invoice
modelleri olan bir proje olsun.
Şu şekilde birbileri ile bağlantıları olsun.
# app/model/customer.rb
class Customer < ActiveRecord::Base
has_one :address
has_many :invoices
end
# app/model/address.rb
class Address < ActiveRecord::Base
belongs_to :customer
end
# app/model/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :customer
end
Invoice view’lerinden birinde faturanın sahibinin adını öğrenmek isteyelim, veya faturanın sahibine ait adres tablosundan cadde, şehir.. vs. görmek isteyelim. Yani lafı uzatmadan:
@invoice.customer.name
@invoice.customer.address.street
@invoice.customer.address.city
Okurken bile insan yoruldu değil mi :P
.
Law of demeter prensibine göre
- Her yapı kendisi ile ilgili yapılarla konuşmalı, yabancı yapılarla konuşmamalı
- Her birim diğer birimler hakkında sınırlı bilgiye sahip olmalı
Olabildiğince az nokta koymalıyız. Peki ama nasıl ?
# app/model/customer.rb
class Customer < ActiveRecord::Base
has_one :address
has_many :invoices
def street
address.street
end
def city
address.city
end
end
# app/model/address.rb
class Address < ActiveRecord::Base
belongs_to :customer
end
# app/model/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :customer
def customer_street
customer.street
end
def customer_city
customer.city
end
def customer_name
customer.name
end
end
Peki view’de nasıl kullanılıyor şimdi görelim.
@invoice.customer_name
@invoice.customer_street
@invoice.customer_city
Noktaları, alt tirelerle değiştirdik. Baya anlamlı, kolay okunan kod oldu işimizi görür. Fakat aklınıza malum soru geldi hemen. Modelde böyle elli tane fonksiyon mu yazacağım ben. Tabi ki hayır görelim, oynat uğuorcuumm.
# app/model/customer.rb
class Customer < ActiveRecord::Base
has_one :address
has_many :invoices
delegate :street,
:city,
to: :address
end
# app/model/address.rb
class Address < ActiveRecord::Base
belongs_to :customer
end
# app/model/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :customer
delegate :street,
:city,
:name,
to: :customer,
prefix: true
end
View’de tekrar görelim.
@invoice.customer_name
@invoice.customer_street
@invoice.customer_city
delegate
‘i çaktın mı işlem tamam :P