flyingarmadillo
flyingarmadillo

Reputation: 2139

Undefined method on class method

I am have an app where users post. I have a filter that will order and retrieve different posts based on a value passed through the params[] hash. I keep getting a no method error on a class method that clearly exists. Here is the query I am trying to run (posts_controller.rb):

def room
    select_filter = params[:post_filter]
    course_id = params[:id].to_i

    @posts = Post.where_filter(select_filter, course_id).order_filter(select_filter).page(params[:page])    
end 

I am getting this error whenever 'select_filter' has a value of 3 :

undefined method `order_filter' for #<Array:0x007fa012d6eef8>

Here is my model (post.rb, remember whenever 'select_filter' is 3 I get an error):

  def self.where_filter(select_filter, course_id_params)
      case select_filter.to_i
      when 1
        where('course_id = ?', course_id_params)
      when 2
        where('course_id = ?', course_id_params)
      when 3
        where('course_id = ? AND created_at > ?', course_id_params.to_i, 48.hours.ago.utc.to_s(:db))
        .reject! {|i| i.net_reputation <= 0 }
      else
        where('course_id = ?', course_id_params)
      end
    end

  def self.order_filter(select_filter)
      case select_filter.to_i
      when 1
        order('created_at DESC')
      when 2
        sort_by {|i| i.net_reputation}
      when 3
        sort_by {|i| i.net_reputation}
      else
        order('created_at DESC')
      end
  end

The strange thing is if I run this in the console, everything is fine. Like this:

Post.where('course_id = ? AND created_at > ?', 10, 48.hours.ago.utc.to_s(:db)).reject {|i| i.net_reputation <= 0 }.sort_by {|i| i.net_reputation}

Any and all input is appreciated.

Upvotes: 0

Views: 761

Answers (2)

flyingarmadillo
flyingarmadillo

Reputation: 2139

For some reason, when I collapsed the queries & sorts into one Class method, it worked. However, since Kiminari (which I am using for pagination) cannot pagniate arrays by default, I have to use the Kaminari.pageinate_array() method.

My posts_controller.rb:

def room
    @course = Course.find(params[:id])
    select_filter = params[:post_filter]
    course_id = params[:id].to_i

    query_posts = Post.select_input_filter(select_filter, course_id)
    @posts = Kaminari.paginate_array(query_posts).page(params[:page])
end

My post.rb:

def self.select_input_filter(select_filter, course_id_params)
    case select_filter.to_i
    when 1
      where('course_id = ?', course_id_params)
      .order('created_at DESC')
    when 2
      where('course_id = ?', course_id_params)
      .sort_by {|i| i.net_reputation}
      .reverse
    when 3
      where('course_id = ? AND created_at > ?', course_id_params.to_i, 48.hours.ago.utc.to_s(:db))
      .reject! {|i| i.net_reputation <= 0 }
      .sort_by {|i| i.net_reputation}
      .reverse
    else
      where('course_id = ?', course_id_params)
      .order('created_at DESC')
    end
end

Upvotes: 0

Peter Brown
Peter Brown

Reputation: 51697

It's because your "where_filter" method is changing it from an active record relation object to an array when it gets to:

.reject! {|i| i.net_reputation <= 0 }

Once this happens, you can no longer chain other query methods onto it. Why not just make the "i.net_reputation <= 0" part of the where query?

Upvotes: 2

Related Questions