2010-11-08 3 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        

Know внутри каждого контроллера у меня есть:


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: Я даже не видел. Wow, nice catch xD – Matchu

+0

Это был большой A **, который сложно пропустить ... :-) –

ответ

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

+0

NICE! это потрясающе, чтобы узнать много трюков от вас, ребята ..... – daniel

1

Это определенно хорошо, чтобы очистить это. Я думаю, вы, возможно, сделали вещи немного более сложными, чем необходимо, хотя, что со всем Proc whatnot.

Если фильтр запускается на экземпляр контроллера, тогда нет необходимости передавать контроллер самому себе. Просто позвоните controller_name в пределах метода, и вы хорошо пойдете.

+0

yes, self.controller_name, чтобы я мог избавиться от аргумента, но мне все же нужно сделать self.controller_name.classify. constantize – daniel

+0

@ daniel: Блоки - это действительно грязный бит. Эта небольшая цепочка методов абсолютно прекрасна, тем более, что она используется только один раз. – Matchu

1

Я лично DRY это немного больше и переместить фильтр в суперкласс (или AppplicationController).

Сам метод также может быть определенно упрощен. Например, используйте некоторые интроспекции.

+0

yep хорошие идеи, я исправлю еще какой-нибудь код, воспользуюсь некоторой интроспекцией и переведу проверку на редактирование и обновление всех моих контроллеров на ApplicationController, это должно быть как 6 или 7 строк – daniel

+0

@ daniel: только переместите 'before_filter 'бит для контроллера приложения, если вы определенно не планируете создавать какие-либо контроллеры в ближайшем будущем. Просто напоминание :) – Matchu

+0

@Matchu, что я имел в виду;) –

Смежные вопросы