You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Rails 5中使用responders gem的控制器代码问题咨询

Refactoring OfficehoursController with Responders Gem (DRY Approach)

Hey there! Let's take your OfficehoursController and trim it down to be even more DRY using the Responders gem. Your current code is already on the right track, but we can leverage the gem's built-in tools to make it cleaner and add useful functionality without extra lines.

Your Current Code

class OfficehoursController < ApplicationController
  def new
    @officehour = Officehour.new
  end

  def create
    @officehour = Officehour.create(officehour_params)
    respond_with(@officehour, location: officehours_path)
  end

  def officehour_params
    params.require(:officehour).permit(:end, :start, :status)
  end
end

First Pass: Basic DRY Refactor

First, make sure the responders gem is installed in your project. Then we can start by adding common responder behaviors and cleaning up the respond_with call:

class OfficehoursController < ApplicationController
  # Include flash messages and HTTP caching helpers out of the box
  responders :flash, :http_cache

  def new
    @officehour = Officehour.new
  end

  def create
    @officehour = Officehour.create(officehour_params)
    # No need to explicitly pass location if we set a default below
    respond_with(@officehour)
  end

  # Mark params method as private (Rails best practice)
  private

  def officehour_params
    params.require(:officehour).permit(:end, :start, :status)
  end
end

Even Cleaner: Set Default Redirect Location

You mentioned the create action correctly redirects to officehours_path when params are valid. To avoid passing location: every time, we can set this as the default for successful creates:

Option 1: Override Location in the Controller

This is the simplest approach for one-off controller needs:

class OfficehoursController < ApplicationController
  responders :flash, :http_cache

  def new
    @officehour = Officehour.new
  end

  def create
    @officehour = Officehour.create(officehour_params)
    respond_with(@officehour)
  end

  private

  def officehour_params
    params.require(:officehour).permit(:end, :start, :status)
  end

  # Customize location for successful create actions
  def location_for(resource)
    officehours_path if action_name == 'create'
  end
end

Option 2: Custom Responder (For Reusable Logic)

If you want this redirect behavior across multiple controllers, create a custom responder:

  1. Create app/responders/resource_collection_responder.rb:
class ResourceCollectionResponder < ActionController::Responder
  def location
    # Redirect to index on successful create, use default otherwise
    if resource.persisted? && action_name == 'create'
      send("#{controller_name}_path")
    else
      super
    end
  end
end
  1. Update your controller to use this responder:
class OfficehoursController < ApplicationController
  # Use our custom responder plus flash/http cache helpers
  responders ResourceCollectionResponder, :flash, :http_cache

  def new
    @officehour = Officehour.new
  end

  def create
    @officehour = Officehour.create(officehour_params)
    respond_with(@officehour)
  end

  private

  def officehour_params
    params.require(:officehour).permit(:end, :start, :status)
  end
end

What We Gained:

  • Less boilerplate: No more repeating the redirect location in respond_with
  • Free functionality: The :flash responder automatically adds success/error flash messages when the resource is saved or fails validation (no need for manual if @officehour.save blocks!)
  • Best practices: Marked officehour_params as private, keeping internal controller logic encapsulated
  • Maintainability: Custom responders let you share redirect logic across controllers without duplication

Your create action will still behave exactly as before (redirecting to the officehours index on valid params) but with cleaner, more DRY code.

内容的提问来源于stack exchange,提问作者dev_054

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:37:22