DRY - 执行相同更新功能的多行代码

时间:2011-10-06 03:44:13

标签: ruby-on-rails ruby dry

以下是我的代码的简短示例:

def update_records!

  # Teams.
  home_team_record = PoolRecord.for_recordable_and_user(event_home_team, user)
  home_team_record.update_for!(self)

  away_team_record = PoolRecord.for_recordable_and_user(event_away_team, user)
  away_team_record.update_for!(self)

  # Division(s).
  home_team_div_record = PoolRecord.for_recordable_and_user(event_home_team_division, user)
  home_team_div_record.update_for!(self)

  # Create/update PoolRecord for away_team division if they're in a different division.
  unless event_away_team_division == event_home_team_division
    away_team_div_record = PoolRecord.for_recordable_and_user(event_away_team_division, user)
    away_team_div_record.update_for!(self)
  end

  # User.
  user_record = PoolRecord.for_recordable_and_user(user, user)
  user_record.update_for!(self)

end

如果不是因为需要检查away_team分区的条件,那么干这个代码实际上会相当简单。我可以创建一个传入的第一个参数的字符串数组,你可以创建Object#send。但是,就像我说的,我需要在一个场景中检查一个条件。你会怎么推荐干这个?

1 个答案:

答案 0 :(得分:4)

一个简单的帮手会减少噪音:

def update_records!
    update_one(event_home_team)
    update_one(event_away_team)
    update_one(event_home_team_division)
    update_one(event_away_team_division) unless event_away_team_division == event_home_team_division
    update_one(user)
end

private

def update_one(team)
    PoolRecord.for_recordable_and_user(team, user).update_for!(self)
end

如果出于某种原因你想采取另一个步骤,你可以做这样的事情:

def update_records!
    [
        [ event_home_team,          true ],
        [ event_away_team,          true ],
        [ event_home_team_division, true ]
        [ event_away_team_division, event_away_team_division != event_home_team_division ],
        [ user,                     true ]
    ].each do |team, do_it|
        if(do_it)
            PoolRecord.for_recordable_and_user(team, user).update_for!(self)
        end
    end
end

或者,根据您的数据,这可能会有效:

def update_records!
    [
        event_home_team, 
        event_away_team,
        event_home_team_division, 
        event_away_team_division,  
        user
    ].uniq.each do |team|
        PoolRecord.for_recordable_and_user(team, user).update_for!(self)
    end
end

最后一个用简单的unless a == b过滤器替换原文中的单个uniq条件。

我不知道您的数据的确切属性,或者您想知道多远,所以我提供了一些想法。我认为最后一个最接近“说出你的意思”但也许不是。