如何在控制器轨道中制作干净的代码

时间:2014-05-10 01:15:41

标签: ruby-on-rails controller dry

如何在rails中清除此代码?

profiles_controller.rb:

class ProfilesController < ApplicationController
  before_action :find_profile, only: [:edit, :update]

  def index
   @profiles = Profile.all
  end

  def new
    @profile = Profile.new
  end

  def create
    profile, message = Profile.create_object(params["profile"], current_user)
    flash[:notice] = message
    redirect_to profile_url
  end

  def edit
  end

  def update
    profile, message = @profile.update_object(params["profile"])
    flash[:notice] = message
    redirect_to profile_url
  end

  private
    def find_profile
      @profile = Profile.friendly.find(params["id"])
    end

end

我看起来flash [:notice]和redirct_to profile_url在我的代码中是重复的,如何使代码清理干燥?

2 个答案:

答案 0 :(得分:0)

如何将重复代码移动到单独的方法并在操作中调用该方法。

def flash_redirect # you can come up with a better name
   flash[:notice] = message
   redirect_to profile_url
end

然后在update动作:

def update
   profile, message = @profile.update_object(params["profile"])
   flash_redirect
end

create操作

做同样的事情

更新:

如果您想知道如何使用after_action,则无法使用它来重定向,因为在操作完成后会追加回调。请参阅此answer

答案 1 :(得分:0)

看看Inherited Resources。它基于以下事实:Rails中的许多CRUD控制器具有完全相同的通用结构。它可以为您完成大部分工作,并且可以完全自定义,以防您的控制器中的内容略有不同。

使用此gem,您的代码将如下所示:

class ProfilesController < InheritedResources::Base
  def create
    redirect_to_profile(*Profile.create_object(params[:profile], current_user))
  end

  def update
    redirect_to_profile(*@profile.update_object(params[:profile]))
  end

  private
  def redirect_to_profile(profile, message)
    redirect_to(profile_url, notice: message)
  end

  def resource
    @profile ||= Profile.friendly.find(params[:id])
  end
end

create和update方法返回多个值,因此我使用splat operator来干掉它。

create_objectupdate_object不遵循Rails默认值,因此我们需要为继承资源实现这些操作。目前他们似乎没有处理验证错误。如果可以的话,重构它们以使用ActiveRecord saveupdate,它会让一切变得更加轻松和干燥。