2014-03-25 49 views
1

林坚持试图找到一种方式来重构这个丑陋的控制器Rails的控制器重构DRY代码

def video_games 
    @video_games_released = Item.video_games.released.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @video_games_coming_soon = Item.video_games.coming_soon.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @video_games_unknown = Item.video_games.unknown.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
end 

def movies 
    @movies_coming_soon = Item.movies.coming_soon.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @movies_released = Item.movies.released.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @movies_unknown = Item.movies.unknown.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
end 

def tv 
    @tv_coming_soon = Item.tv.coming_soon.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @tv_released = Item.tv.released.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
    @tv_unknown = Item.tv.unknown.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
end 

我想摆脱重复的espcially我GROUP_BY方法

我试着去到模型和创建方法

def group_by_month 
    self.group_by { 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 
end 

香港专业教育学院试图划定范围,但似乎没有任何合作

我不是轨专家,真的想学习如何重构代码,并保持干燥的事情

回答

1

您可以使用groupupdate宝石 它会给你在数据库级别上

这是最简单的方式这个功能

如果你想这样做的方式更多地了解轨道

您有使用一遍又一遍

一个明显的块
{ 
    |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join() 
    } 

,你可以将它保存和调用它,当你需要它

date_group = lambda { |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join()} 

,当你需要使用它,你可以做

Item.tv.coming_soon.group_by(&date_group) 

您可能希望保存此块在一些地方你可以很容易地访问

+0

这是一个很好的建议......但有没有简单的方法来重构这个?感谢宝石上的头衔,尽管...我想知道是否有一种很好的方式来重构此代码而不使用宝石。只是为了学习目的...谢谢! – user1502223

+0

为更多的澄清添加更多的意见 –

+0

谢谢多数民众赞成在我正在寻找...什么与在date_group(&date_group)前面的& – user1502223

2

所以我做了什么重构这个代码与khaled_gomaa的建议帮助是

我创建了一个主持人在

app/presenters/items/index_presenter.rb 

module Items 
class IndexPresenters 
    def initialize(item) 
    @item = item 
    end 

    def released 
    @item.released.group_by(&date_group) 
    end 

    def coming_soon 
    @item.coming_soon.group_by(&date_group) 
    end 

    def unknown 
    @item.unknown.group_by(&date_group) 
    end 

    def date_group 
    lambda { |item| [item.release_date.try(:strftime, "%B %d, %Y"), item.time_diff_components].join()} 
    end 
end 
end 

然后在我的控制器

def video_games 
    @presenter = Items::IndexPresenters.new(Item.video_games) 
end 

def movies 
    @presenter = Items::IndexPresenters.new(Item.movies) 
end 

def tv 
    @presenter = Items::IndexPresenters.new(Item.tv) 
end 

和我的看法

%h2 Movies Released 
= render 'items', item: @presenter.released 
%h2 Movies Coming Soon 
= render 'items', item: @presenter.coming_soon 
%h2 Movies Unknown 
= render 'items', item: @presenter.unknown 

任何进一步的建议,将受到欢迎!谢谢!