0

I have a rails 4.1 app with a work_tasks table and a work_task_statuses table.

They are joined together on work_task_statuses.id = work_tasks.id.

In my controller, I want to pull up only the work_tasks that do not have any records in the work_task_statuses table.

Here is models/work_tasks.rb:

require 'rails'
require 'filterrific'



class WorkTask < ActiveRecord::Base

  has_many :work_task_statuses

  scope :without_work_task_statuses, includes(:work_task_statuses).where(:work_task_statuses => { :id => nil })    

end

Here is work_tasks_controller.rb:

require 'builder'
require 'will_paginate'
include ActionView::Helpers::NumberHelper

class WorkTasksController < ApplicationController
  before_action :authenticate_user!

  def list
  end

  def index
    @filterrific = Filterrific.new(WorkTask, params[:filterrific])

    @filterrific.select_options = {
      sorted_by: WorkTask.options_for_sorted_by,
      with_work: WorkTask.options_for_select
    }

    @work_tasks WorkTask.filterrific_find(@filterrific).page(params[:page]).without_work_task_statuses(@work_tasks)

    respond_to do |format|
      format.html
      format.js
    end
  end

  def reset_filterrific
    # Clear session persistence
    session[:filterrific_work_tasks] = nil
    # Redirect back to the index action for default filter settings.
    redirect_to action: :index
  end
end

I am getting this error:

undefined method `call' for #<WorkTask::ActiveRecord_Relation:0x007fa0eeab4870>

How do I make the controller exclude work tasks that have records in work_task_statuses?

user2437742
  • 93
  • 2
  • 6
  • In Rails 4 you should use scopes with a callable block: `scope :without_work_task_statuses, -> { includes(:work_task_statuses).where(:work_task_statuses => { :id => nil }) }`. Also, in your controller, you miss the `=` after `@work_tasks`? – markets Aug 01 '14 at 19:20

2 Answers2

2

With the help of @jkeuhlen (who helped me to realize that the scope syntax had changed in rails 4) and via some further research I solved my problem.

For the benefit of future searchers, here is the final working code:

Model:

scope :with_work_task_statuses, -> {where.not(:id => WorkTaskStatus.select(:work_task_id).uniq)
  }

Controller:

@work_tasks = WorkTask.filterrific_find(@filterrific).page(params[:page]).with_work_task_statuses

Here is a blog post that explains it in more detail: http://www.lauradhamilton.com/how-to-filter-by-multiple-options-filterrific-rails

user2437742
  • 93
  • 2
  • 6
0

This question is related to this other SO question.

Using the information on the highest voted answer from that post and applying it to your question:

WorkTask.includes(:work_task_statuses).where( :work_task_statuses => { :work_task_id => nil } )
Community
  • 1
  • 1
jkeuhlen
  • 4,401
  • 23
  • 36
  • Thanks for the feedback. I did see that SO answer, but I am having problems defining the scope. That answer is from 2011, but rails 4 requires each scope to have a callable object. I think that's what is tripping me up. – user2437742 Aug 01 '14 at 20:43