2013-03-25 29 views
1

使用Rails。如何最好地重写country_photoif-else中的链接条件过多

# country.rb 
class Country < ActiveRecord::Base 
    has_many :zones 

    def country_photo 
    if !zones.blank? && !zones.first.shops.blank? && !zones.first.shops.first.photos.blank? 
     zones.first.shops.first.photos.first.url(:picture_preview) 
    end 
    end 
end 

# zones.rb 
class Zone < ActiveRecord::Base 
    belongs_to :country 
    has_many :zone_shops 
    has_many :shops, :through => :zone_shops 
end 

# zone_shop.rb 
class ZoneShop < ActiveRecord::Base 
    belongs_to :zone 
    belongs_to :shop 
end 

# shop.rb 
class Shop < ActiveRecord::Base 

end 
+0

当你有那些有多深的关联,你不能做任何事情。但避免深层关联的一种方法是在'country'模型中存储'photo_id',其中'belongs_to:photo'。还有一种方法可以做到没有if-else的情况,即zone.try(:first).try(:shops).try(:first).try(:photos).try(:first).try(:url ).try(:picture_preview)' – codeit 2013-03-25 16:27:14

回答

1

请注意,!x.blank?x.present?。无论如何,如果你都OK在if在做幽会(他们是很常见的红宝石),你可以这样写:

def country_photo 
    if (zone = zones.first) && 
    (shop = zone.shops.first) && 
    (photo = shop.photos.first) 
    photo.url(:picture_preview) 
    end 
end 

如果你喜欢花哨的抽象,与Ick你可以写:

def country_photo 
    zones.first.maybe { |zone| zone.shops.first.photos.first.url(:picture_preview) } 
end 
+0

我得安装Ick吧?不愿意为此安装一个新的宝石。 – Victor 2013-03-25 16:35:21

+0

@维克多:增加了一个更正统的方法。在任何情况下请注意,这些都是简单的抽象,你可以自己写在你的扩展模块上('Object#maybe'可以在4/5行中实现)。 – tokland 2013-03-25 16:36:49

1

假设你要显示在视图中的图像,我会做这样的事情:

# show.html.haml 
- if @country.photo 
    image_tag @country.photo.url(:picture_preview) 

# country.rb 
class Country < ActiveRecord::Base 
    def photo 
    zones.first.photo unless zones.blank? 
    end 
end 

# zone.rb 
class Zone < ActiveRecord::Base 
    def photo 
    shops.first.photo unless shops.blank? 
    end 
end 

# shop.rb 
class Shop < ActiveRecord::Base 
    def photo 
    photos.first unless photos.blank? 
    end 
end