2014-11-01 113 views
1

如何在轨道控制器中重构此类似的代码片段?Rails,重复代码重构

应用程序/控制器/ albums_controller.rb:58 ... 62 <>

def set_album 
    if current_user.admin? 
    @album = User.find(params[:user_id]).albums.find(params[:id]) 
    else 
    @album = current_user.albums.find(params[:id]) 
    end 
end 

应用程序/控制器/ articles_controller.rb:45 ... 49 <>

def set_article 
    if current_user.admin? 
    @article = User.find(params[:user_id]).articles.find(params[:id]) 
    else 
    @article = current_user.articles.find(params[:id]) 
    end 
end 

应用程序/控制器/ photos_controller。 rb:55 ... 59 <>

def set_photo 
    if current_user.admin? 
    @photo = User.find(params[:user_id]).photos.find(params[:id]) 
    else 
    @photo = current_user.photos.find(params[:id]) 
    end 
end 

回答

2

控制器/关切/ user_resource.rb

module UserResource 
    extend ActiveSupport::Concern 

    included do 
    before_action :set_resource , only: [:edit, :update, :destroy] 
    before_action :signed_in_user, only: [:new, :edit, :update, :destroy] 
    before_action :correct_user, only: [:edit, :update, :destroy] 
    end 

    def set_resource 
    association = controller_name.classify.downcase 
    resource = current_user.admin? ? User.find(params[:user_id]) : current_user 
    resource = resource.send(association.to_s.pluralize).find(params[:id]) 
    instance_variable_set("@#{association}", resource) 
    end 

    def correct_user 
    association = controller_name.classify.downcase 
    redirect_to root_path unless admin_or_current?(instance_variable_get("@#{association}").user) 
    end 
end 

然后,在{照片,相册,文章} _controller .rb

include UserResource 
0

这样很好思想在这里使用元编程,我的意思是这样的:在控制器内

def set_resource(association_singular) # e.g. :photo 
    resource = current_user.admin? ? User.find(params[:user_id]) : current_user 
    resource = resource.send(association.to_s.pluralize).find(params[:id])) 
    instance_variable_set("@#{association}", resource) 
end 

然后,要么before_filter only: [:action]

def action 
    # ... 
    set_resource(:photo) 
    # ... 
end 
1

的一种方式做,这是创建一个新的控制器:

class ResourceController < ApplicationController 
    before_filter :set_resource, only: [:show, :edit, :update, :destroy] 

    private 

    def set_resource 
    user = current_user.admin? ? User.find(params[:user_id]) : current_user 
    resource = user.send(controller_name.to_sym).find(params[:id]) 
    instance_variable_set("@#{controller_name.singularize}", resource) 
    end 
end 

then your albums_controller.rb:

class AlbumsController < ResourceController 
    # use @album in show, edit, update, and destroy 
end 

articles_controller.rb:

class ArticlesController < ResourceController 
    # use @article in show, edit, update, and destroy  
end 

photos_controller.rb:

class PhotosController < ResourceController 
    # use @photo in show, edit, update, and destroy 
end 
+0

是的,很好!但是我已经创建了控制器问题并将其包含在所有“资源”控制器中。它类似的方法。谢谢! – davydes 2014-11-01 20:27:13