Ellen W
Ellen W

Reputation: 227

using will_paginate with scope, undefined method error

I'm using the will_paginate gem in a ruby app, and for the most part it works fine. But when I don't have a user signed in, I run into trouble.

The app is a reddit-type thing, with topics and related posts and comments.

In my Topic model, I have the following:

class Topic < ActiveRecord::Base
  has_many :posts, dependent: :destroy

  scope :visible_to, -> (user) {user ? all : :publicly_viewable}

  scope :publicly_viewable, -> {where(public: true)}

  scope :privately_viewable, -> {where(public: false)}

end

In my TopicsController:

class TopicsController < ApplicationController
  require 'will_paginate/array'

  def index
    @topics = Topic.visible_to(current_user).paginate(page: params[:page], per_page: 10)
    authorize @topics
  end

When I click on the link to Topics without a current_user, as I understand it, "user" in the model should return nil, which should be a functional record. Only publicly_viewable Topics should be returned. But I'm getting the following error message:

undefined method `paginate' for :publicly_viewable:Symbol

I thought perhaps I was dealing with an array, so I added in "require 'will_paginate/array'", but this isn't helping.

Does anyone have any ideas?

Thank you.

Upvotes: 0

Views: 184

Answers (1)

pdobb
pdobb

Reputation: 18037

Don't use a symbol. Just call the scope publicly_viewable directly.

scope :visible_to, -> (user) {user ? all : publicly_viewable}

That said, it's generally better to scope your queries from a root object. Like this:

def index
  @topics = (current_user.try(:topics) || Topic.privately_viewable).paginate(page: params[:page], per_page: 10)
end

This way your topics come from the model that owns them. This lends itself especially well to finding resources later like this:

def show
  @topic = current_user.topics.find_by_id(params[:id])
end

This approach ensures you're finding a topic scoped by the current user, ensuring he/she actually has "permissions" to view the topic.

Upvotes: 1

Related Questions