2010-11-08 34 views
1

我已经干燥一些代码,这refactors之一是如下:
我有3个控制器(ConstructionCompanies,RealEstateCompanies,人)所有这些具有下列模式:这太干了,我会过度?


class ConstructionCompaniesController < ApplicationController 
before_filter :correct_user, :only => [:edit, :update] 

private 
    def correct_user 
     @company = ConstructionCompany.find(params[:id]) 
     if(current_user.owner != @company.user) 
     redirect_to(root_path) 
     end 
    end 

class RealEstateCompaniesController < ApplicationController 
    before_filter :correct_user, :only => [:edit, :update] 
... 

private 
    def correct_user 
     @company = RealEstateCompany.find(params[:id]) 
     if(current_user.owner != @company.user) 
     redirect_to(root_path) 
     end 
    end 

作为您可以看到每个控制器中都重复了correct_user。
所以我做了什么里面我帮手包括为所有这些我创建了一个方法:


def correct_user_for_seller_of_controller(controller) 
    #"User".classify will return the class User etc. 
    @seller = controller.controller_name.classify.constantize.find(params[:id])  
    redirect_to(root_path) unless (current_user == @seller.user) 
    end        

知道每个控制器里面,我有:


class ConstructionCompaniesController < ApplicationController 

    before_filter :only => [:edit, :update] do |controller| correct_user_for_seller_of_controller(controller) end   


class RealEstateCompaniesController < ApplicationController 

before_filter :only => [:edit, :update] do |controller| correct_user_for_seller_of_controller(controller) end   

我喜欢的事实,现在是干的,但问题是这对我来说似乎有点复杂,很难理解。我走得太远了吗?

+0

@KandadaBoggu:我甚至没有看到这一点。哇,很好抓xD – Matchu 2010-11-08 03:50:41

+0

这是一个很大的A **,很难错过... :-) – 2010-11-08 03:54:16

回答

4

correct_user方法添加到ApplicationController类。

class ApplicationController 
    def correct_user_for_seller_of_controller 
    #"User".classify will return the class User etc. 
    @seller = controller_name.classify.constantize.find(params[:id])  
    redirect_to(root_path) unless (current_user == @seller.user) 
    end 
end 

在你的控制器使用了新方法的过滤方法:

class RealEstateCompaniesController < ApplicationController 

before_filter :correct_user_for_seller_of_controller, :only => [:edit, :update] 

end 
+1

哦,代码示例! +1 – Matchu 2010-11-08 03:52:46

+0

好!从你们那里学习很多技巧真是太棒了..... – daniel 2010-11-08 05:13:28

1

这绝对是很好的清理。我认为你可能已经做出了比必要更复杂的事情,尽管如此,所有的Proc都是如此。

如果过滤器正在控制器的一个实例上运行,那么就不需要将控制器传递给它自己。只需在方法内拨打controller_name,您就可以轻松前往。

+0

是的,self.controller_name所以我可以摆脱这个参数,但我仍然必须做self.controller_name.classify。 constantize – daniel 2010-11-08 03:47:29

+0

@丹尼尔:块是非常混乱的一点。这个小小的方法链绝对没问题,特别是因为它只用了一次。 – Matchu 2010-11-08 03:49:06

1

我个人DRY它多一点,并将过滤器移到超类(或AppplicationController)。

该方法本身也可以绝对简化。例如使用一些内省。

+0

是的好主意,我会更多的代码,使用一些自省,并将编辑和更新的所有控制器的验证移动到ApplicationController,它应该像6或7行 – daniel 2010-11-08 03:50:40

+0

@daniel:只移动'before_filter如果你不打算在不久的将来再制造更多的控制器,那么它就应用程序控制器。只是提醒:) – Matchu 2010-11-08 03:52:24

+0

@Matchu究竟是什么意思;) – 2010-11-08 03:54:31