filtering_service.rb 2.94 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# FilteringService class
#
# Used to filter Issues and MergeRequests collections by set of params
#
# Arguments:
#   klass - actual class like Issue or MergeRequest
#   current_user - which user use
#   params:
#     scope: 'created-by-me' or 'assigned-to-me' or 'all'
#     state: 'open' or 'closed' or 'all'
#     group_id: integer
#     project_id: integer
#     milestone_id: integer
#     assignee_id: integer
#     search: string
#     label_name: string
#     sort: string
#
class FilteringService
  attr_accessor :klass, :current_user, :params

  def execute(klass, current_user, params)
    @klass = klass
    @current_user = current_user
    @params = params

27
28
    items = init_collection
    items = by_scope(items)
29
30
    items = by_state(items)
    items = by_group(items)
Marin Jankovski's avatar
Marin Jankovski committed
31
    items = by_project(items)
32
33
34
35
36
37
38
39
40
    items = by_search(items)
    items = by_milestone(items)
    items = by_assignee(items)
    items = by_label(items)
    items = sort(items)
  end

  private

41
  def init_collection
42
43
    table_name = klass.table_name

44
    if project
45
      if project.public? || (current_user && current_user.can?(:read_project, project))
46
47
48
49
        project.send(table_name)
      else
        []
      end
50
    elsif current_user && params[:authorized_only].presence
51
      klass.of_projects(current_user.authorized_projects)
52
53
    else
      klass.of_projects(Project.accessible_to(current_user))
54
55
56
57
    end
  end

  def by_scope(items)
58
59
    case params[:scope]
    when 'created-by-me', 'authored' then
60
      items.where(author_id: current_user.id)
61
    when 'all' then
62
      items
63
    when 'assigned-to-me' then
64
      items.where(assignee_id: current_user.id)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    else
      raise 'You must specify default scope'
    end
  end

  def by_state(items)
    case params[:state]
    when 'closed'
      items.closed
    when 'all'
      items
    when 'opened'
      items.opened
    else
      raise 'You must specify default state'
    end
  end

  def by_group(items)
    if params[:group_id].present?
      items = items.of_group(Group.find(params[:group_id]))
    end

    items
  end

  def by_project(items)
    if params[:project_id].present?
      items = items.of_projects(params[:project_id])
    end

    items
  end

  def by_search(items)
    if params[:search].present?
      items = items.search(params[:search])
    end

    items
  end

  def sort(items)
    items.sort(params[:sort])
  end

  def by_milestone(items)
    if params[:milestone_id].present?
      items = items.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
    end

    items
  end

  def by_assignee(items)
    if params[:assignee_id].present?
      items = items.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
    end

    items
  end

  def by_label(items)
    if params[:label_name].present?
      items = items.tagged_with(params[:label_name])
    end

    items
  end
134
135
136
137

  def project
    Project.where(id: params[:project_id]).first if params[:project_id].present?
  end
138
end