Rails控制器重构DRY代码

时间:2014-03-25 17:01:15

标签: ruby-on-rails refactoring 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

我想摆脱重复,特别是我的group_by方法

我尝试进入模型并创建方法

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

我已尝试确定范围,但似乎没有任何工作

我没有专家,并且真的想学习如何重构代码并保持干燥

2 个答案:

答案 0 :(得分: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

任何进一步的建议都会受到欢迎!谢谢!

答案 1 :(得分:1)

您可以使用groupupdate gem 它将在数据库级别为您提供此功能

这是一种简单的方法

如果您想以某种方式了解有关rails

的更多信息

你有一个明显的阻止你一遍又一遍地使用

{ 
     |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)

您可能希望将此块保存在您可以轻松访问的某个位置