ruby-on-rails - 干燥开始-救援-结束

标签 ruby-on-rails ruby design-patterns

我有这个创建方法:

def create
    ...
    grid = Tag.find_by_id(story[:tag_id]) or raise GridNotFoundError
    ...
    event = Event.find_by_id(story[:event_id]) or raise EventNotFoundError
    ...
  rescue GridNotFoundError
    flash.now[:error] = "Please select a category"
    @item = item
    @years = story[:years]
    @event_name = race[:name]
    @country = race[:country]
    @classification = race[:class]
    @events = Event.all
    @countries = Tag.countries
    @classifications = Classification.all
    @grids = Tag.grids.find(:all, :conditions => ["value != ?", "Channel Creation Grid"])
    render "home/race_updates"
  rescue EventNotFoundError
    flash.now[:error] = "Please select an event or create a new one if you don't find your event"
    @item = item
    @event = story[:event_id]
    @years = story[:years]
    @events = Event.all
    @countries = Tag.countries
    @classifications = Classification.all
    @grids = Tag.grids.find(:all, :conditions => ["value != ?", "Channel Creation Grid"])
    render "home/race_updates"
  rescue CreateEventError
    flash.now[:error] = "There has been a problem creating your event."
    params[:expand] = true
    @item = item
    @years = story[:years]
    @event_name = race[:name]
    @country = race[:country]
    @classification = race[:class]
    @events = Event.all
    @countries = Tag.countries
    @classifications = Classification.all
    @grids = Tag.grids.find(:all, :conditions => ["value != ?", "Channel Creation Grid"])
    render "home/race_updates"
  rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid, ActiveRecord::RecordNotFound
    flash.now[:error] = item.errors.full_messages.join(" ,")
    @item = item
    @event = story[:event_id]
    @years = story[:years]
    @events = Event.all
    @countries = Tag.countries
    @classifications = Classification.all
    @grids = Tag.grids.find(:all, :conditions => ["value != ?", "Channel Creation Grid"])
    render "home/race_updates"
  end

如您所见,救援几乎是一样的。救援也是 home#race_updates 方法的文字复制粘贴。

我有两个问题:

  1. 有什么办法让我把它擦干吗?
  2. 对于一般的 Controller 来说,这是一个好的模式吗?

我曾考虑过将其作为一个函数分离出来,但我需要传入闪现消息、元素、故事和种族变量。我觉得这不是一个优雅的解决方案,但它肯定会更干净。

我发现以这种方式编码(即引发错误并挽救它们)使我更容易按应有的方式分离实际的业务逻辑,并处理业务逻辑中出现的不同错误/案例。到目前为止,它有效,但我想就这是最佳做法还是我没有按预期使用开始/救援收集意见?

最佳答案

如果可以的话,干掉它是一个好主意,也是 rails 设计(和测试驱动开发/TDD)的一个很好的教训。

理想情况下,你会做这样的事情:

def create
    ...
    grid = Tag.find_by_id(story[:tag_id]) or raise GridNotFoundError
    ...
    event = Event.find_by_id(story[:event_id]) or raise EventNotFoundError
    ...
  rescue GridNotFoundError
    flash.now[:error] = "Please select a category"
    process_grid_not_found(item, story, race, etc...)
  rescue EventNotFoundError
    flash.now[:error] = "Please select an event or create a new one if you don't find your event"
    process_event_not_found(item, story, race, etc...)
  rescue CreateEventError
    flash.now[:error] = "There has been a problem creating your event."
    process_event_create_error(item, story, race, etc...)
  rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid, ActiveRecord::RecordNotFound
    flash.now[:error] = item.errors.full_messages.join(" ,")
    process_other_error(item, story, race, etc...)
  end
  render 'home/race_updates'

然后您应该在模型中创建相关的新方法(process_event_not_found 等)作为单独的(可能是 private)方法。

这两者都使代码更具可读性,但最大的优势是更容易为其编写测试代码。

那么您应该编写测试代码(使用 Test::Unitrspec 或其他)来测试每个单独的异常方法所需的独立功能。您会发现这会产生更好的代码,而且它还可能将异常方法本身分解为更小、更模块化的方法。

当您听到 Ruby 和 Rails 开发人员谈论测试驱动开发的好处时,该方法的主要好处之一是它不太可能导致像您在此处获得的那样冗长、复杂的方法。更有可能的是,您的代码更简洁,方法更小、更简单。

我还建议您在完成此操作后再看一下并尝试进一步简化它。将有更多的简化空间,但我建议迭代重构它,并按照我所描述的那样将其分解并开始进行测试。

关于ruby-on-rails - 干燥开始-救援-结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11293347/

相关文章:

ruby-on-rails - 如何使用 Google-Maps-for-Rails 使信息窗口自动显示为打开状态

ruby-on-rails - 如何在还包含其他字段的表单中立即仅上传图像?

java - 几个类之间的通信

ruby-on-rails - 大型下拉列表

ruby-on-rails - 在 rails 3 中形成带有 mustache 的助手

ruby-on-rails - 嵌套模型上的自定义验证错误

c# - 什么是 C# 中好的线程安全单例通用模板模式

design-patterns - MVVM Light DI 在虚拟机之间共享数据?

ruby-on-rails - 如何检查 Rails 更新操作中属性是否发生变化?

ruby-on-rails - Has_one 关联应该是一个 has "only"一个关联