I had a complex query in the controller like:
def outgoing_tasks
@tasks = current_user.
assigned_tasks.
uncompleted.
includes(executor: :profile).
order("deadline DESC").
paginate(page: params[:page], per_page: Task.pagination_per_page)
end
and since I have some other collections in that controller I refactored to this:
def outgoing_tasks
@tasks = current_user.assigned_tasks.assigned_default(page: params[:page])
end
with these new methods in the model:
def self.ordered
order("deadline DESC")
end
def self.paginated(page: 1)
paginate(page: page, per_page: self.pagination_per_page)
end
def self.assigned_default(page: 1)
uncompleted.includes(executor: :profile).ordered.paginated(page: page)
end
Should I do something differently or is this okay?
1 Answer 1
This is a good place to use scopes. http://edgeguides.rubyonrails.org/active_record_querying.html#scopes Scopes are just syntactic sugar for class methods that return relations. In this way they can always be chain-able.
scope :ordered -> { order(deadline: 'DESC') }
scope :paginated -> (page: 1) { paginate(page: page, per_page: pagination_per_page) }
scope :assigned_default -> (page: 1) { uncompleted.includes(executor: :profile).ordered.paginated(page: page) }
-
\$\begingroup\$ kjprice, I checked out a few repos (for instance the upcase.com by thoughtbot) and the guys using scopes only for where clauses. For some reason they use class methods for these. Can you guess why are they doing that way? \$\endgroup\$Szilard Magyar– Szilard Magyar2016年06月17日 18:43:03 +00:00Commented Jun 17, 2016 at 18:43
-
\$\begingroup\$ I could only speculate. Maybe they've decided on a style that they think is more readable? -- I for instance, see the pattern of
scope :for -> (task) { where(task: task) }
a lot. But I find that to be a unnecessary abstraction. \$\endgroup\$kjprice– kjprice2016年06月17日 21:13:29 +00:00Commented Jun 17, 2016 at 21:13
Explore related questions
See similar questions with these tags.