Question

I'm currently using the has_scope gem in conjunction with scopes/class methods on models to filter result sets returned to my UI.

I have a model Task which I'd like to be able to filter by status -- a virtual attribute on the model.

The Task model has a few attributes which you might need to know about

uuid: Generated by SecureRandom
running: A boolean
success: A boolean
started_at: DateTime

The status is calculated as such:

def status
    if running?
        'Running'
    elsif started_at.nil?
        'Queued'
    elsif success?
        'Finished'
    else
        'Failed'
    end
end

Ignoring the fact that this is probably not an ideal way of doing this, I have currently implemented the status filtering method like so:

def self.by_status(status)
  records = all.select {|s| s.status == status}
  where(uuid: records.map(&:uuid))
end

I cannot return just the results from select as it's of type Array as opposed to an ActiveRecord::Relation, hence my where hackery. For context the reason I cannot/do not want to return an array is the result-set is passed to kaminari for pagination.

Please note: The method I currently use meets my requirements, but I don't like the way it's done. I feel like there should be a better way.

Can anyone suggest a better by_status method for returning an ActiveRecord::Relation?

tl;dr: Need a class method to return an ActiveRecord::Relation filtering on a virtual attribute.

Thanks in advance.

Was it helpful?

Solution

Here is how I would do it

def self.by_status(status)
  case status
  when 'Running'  then where(running: true)
  when 'Finished' then where(success: true)
  when 'Queued'   then where(started_at: nil)
  else scoped #change this to all in Rails 4 since Model.all returns an AR Relation
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top