在rails 3中制作一个胖控制器

时间:2011-08-12 16:26:35

标签: ruby-on-rails ruby ruby-on-rails-3

我的应用程序中有这个非常大的控制器。我真的很想让它尽可能瘦。下面是一些代码,显示了我目前正在做的事情的类型......我想知道我可以摆脱的是什么?

注意 - 这不是我的确切代码,很多相似之处。基本上每个实例变量都在视图中使用 - 这就是为什么我不理解如何将逻辑放在模型中?模型可以返回实例变量的值吗?

  def mine

    #For Pusher
    @push_ch = "#{current_user.company.id}"+"#{current_user.id}"+"#{current_user.profile.id}"

    #Creating a limit for how many items to show on the page
    @limit = 10
    if params[:limit].to_i >= 10
      @limit = @limit + params[:limit].to_i     
    end

    #Setting page location
    @ploc="mine"

    @yourTeam = User.where(:company_id => current_user.company.id)
    #Set the user from the param
    if params[:user]
      @selectedUser = @yourTeam.find_by_id(params[:user])
    end

    #Get all of the user tags
    @tags = Tag.where(:user_id => current_user.id)    

    #Load the user's views
    @views = View.where(:user_id => current_user.id)

    if !params[:inbox]

         #Hitting the DB just once for all the posts
         @main_posts = Post.where(:company_id => current_user.company.id).includes(:status).includes(:views)
         @main_posts.group_by(&:status).each do |status, posts|
           if status.id == @status.id
             if @posts_count == nil
               @posts_count = posts
             else
               @posts_count = @posts_count + posts
             end
           elsif status.id == @status_act.id
             if @posts_count == nil
               @posts_count = posts
             else
               @posts_count = @posts_count + posts
             end
           end
         end

         if params[:status] == "All" || params[:status] == nil
           @posts = Post.search(params[:search]).status_filter(params[:status]).user_filter(params[:user]).order(sort_column + " " + sort_direction).where(:company_id => current_user.company.id, :status_id => [@status.id, @status_act.id, @status_def.id, @status_dep.id, @status_up.id]).limit(@limit).includes(:views)
         else
           @posts = Post.search(params[:search]).status_filter(params[:status]).user_filter(params[:user]).order(sort_column + " " + sort_direction).where(:company_id => current_user.company.id).limit(@limit).includes(:views)
         end

    elsif params[:inbox] == "sent"

         @yourcompanylist = User.where(:company_id => current_user.company.id).select(:id).map(&:id)
          @yourcompany = []
          @yourcompanylist.each do |user|
            if user != current_user.id
            @yourcompany=@yourcompany.concat([user])  
            end
          end

          if params[:t]=="all"
            @posts = Post.search(params[:search]).status_filter(params[:status]).user_filter(params[:user]).tag_filter(params[:tag], current_user).order(sort_column + " " + sort_direction).where(:user_id => current_user.id).includes(:views, :tags).limit(@limit)
          elsif params[:status]!="complete"
            @posts = Post.search(params[:search]).status_filter(params[:status]).user_filter(params[:user]).tag_filter(params[:tag], current_user).order(sort_column + " " + sort_direction).where(:user_id => current_user.id).includes(:views, :tags).limit(@limit)
          elsif params[:status]!=nil
            @posts = Post.search(params[:search]).status_filter(params[:status]).user_filter(params[:user]).tag_filter(params[:tag], current_user).order(sort_column + " " + sort_direction).where(:user_id => current_user.id).includes(:views, :tags).limit(@limit)
          end

    end

    respond_to do |format|
      format.html # index.html.erb
      format.js # index.html.erb
      format.xml  { render :xml => @posts }
    end
  end

3 个答案:

答案 0 :(得分:4)

您可以先将逻辑移入模型......

像这样的一条线让人羡慕:

@push_ch = "#{current_user.company.id}"+"#{current_user.id}"+"#{current_user.profile.id}"

我建议将其移入模型中:

#user.rb
def to_pusher_identity
  "#{self.company_id}#{self.id}#{self.profile_id}"
end

然后在你的控制器中

@push_ch = current_user.to_pusher_identity

此时您甚至可以将其移至before_filter

before_filter :supports_pusher, :only => :mine

您可以做的另一件事是创建更丰富的关联,因此您可以表达:

@tags = Tag.where(:user_id => current_user.id)    

作为

@tags = current_user.tags

另一个例子是主要帖子,而不是

Post.where(:company_id => current_user.company.id).includes(:status).includes(:views)

你会经历这些协会:

current_user.company.posts.includes(:status).includes(:views)

答案 1 :(得分:2)

当我干掉一个控制器/动作时,我会尝试识别哪些代码(应该是?)卸载到模型甚至新模块中。我对你的应用程序知之甚少,无法真正指出这些机会可能存在的地方,但这就是我开始的地方。

答案 2 :(得分:2)

几点简短的想法:

考虑使用respond_to/respond_with。此控制器操作最多可分为两个 - 一个用于显示 @main_posts ,另一个用于 params [:inbox] ==“sent”。可以使用 before_filters 删除重复的代码。

另外,有几个宝石建议: