Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

ActiveRecord::StatementInvalid: PG::Error: ERROR: relation "pg_search_documents" does not exist #95

Open
uberllama opened this Issue · 7 comments

3 participants

@uberllama

Its been a long day, so I may be missing something completely obvious, but I ran into this very strange error today.

I have two models named User and Document that both have search scopes.
A user has many documents.

I wanted to add a method to user to get all documents available in his network. It looked something like this:

user.rb

include PgSearch

has_many :documents

  pg_search_scope :search,
    :against => [:name],
    :using => {
      :tsearch => {
        :dictionary => "english",
        :prefix => true,
        :any_word => true
      }
    }

def network_documents
  Document.where(:user_id => followings.collect(&:followed_user_id))
end

So that I can call something like:

current_user.network_documents

Normal enough right? However, any time I try to add a method to the User or Document model that refers to Document, I get the error listed in the issue subject along with a stack trace that looks like this:


LINE 5:              WHERE a.attrelid = '"pg_search_documents"'::reg...
                                        ^
:             SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                     pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
              FROM pg_attribute a LEFT JOIN pg_attrdef d
                ON a.attrelid = d.adrelid AND a.attnum = d.adnum
             WHERE a.attrelid = '"pg_search_documents"'::regclass
               AND a.attnum > 0 AND NOT a.attisdropped
             ORDER BY a.attnum

    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:1153:in `async_exec'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:1153:in `exec_no_cache'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:662:in `block in exec_query'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activesupport-3.2.12/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:661:in `exec_query'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:1278:in `column_definitions'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:857:in `columns'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/connection_adapters/schema_cache.rb:12:in `block in initialize'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/model_schema.rb:228:in `yield'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/model_schema.rb:228:in `default'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/model_schema.rb:228:in `columns'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/model_schema.rb:237:in `columns_hash'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/locking/optimistic.rb:129:in `locking_enabled?'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/relation.rb:170:in `exec_queries'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/relation.rb:160:in `block in to_a'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/explain.rb:33:in `logging_query_plan'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/relation.rb:159:in `to_a'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/relation/finder_methods.rb:159:in `all'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/activerecord-3.2.12/lib/active_record/querying.rb:5:in `all'
    from /Users/uberllama/Documents/webdev/littleblimp/taughtit/app/models/user.rb:71:in `foo'
    from (irb):21
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
    from /Users/uberllama/.rvm/gems/ruby-1.9.3-p385/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

If I remove the include and search scope, everything runs fine as expected. I tried adding the method as a class method to the Document class with the same result.

What the hell am I missing? Cheers.

@uberllama

I tried doing the same thing with my Comment model and didn't encounter any issues, which leads me to believe there's a reserved term issue with models named "Document" and pg_search.

@uberllama

Finally had time to open up the lib and there it is, Document as an un-namespaced class. Would there be any chance of either namespacing this under PgSearch or renaming it to something like SearchDocument?

@inertialbit

I am pretty sure that the included AR document class is already name spaced as PgSearch::Document.

Do you get the same error if you try to access your own Document class from the top-level? e.g.

class User < ActiveRecord::Base
  include PgSearch

  def network_documents
    ::Document.where(...) # note the 2 colons in front
  end
end
@uberllama

It is name spaced, but as soon as you include PgSearch the name spacing is rendered moot. I've submitted pull request 96 that renames the class to something less generic, to avoid any possibility of conflict.

@inertialbit

Ok. But renaming PgSearch::Document to PgSearch::SearchDocument will work until someone has a model named SearchDocument in a similar scenario to your Document. In other words there is still possibility for conflict unless one uses an absolute reference to the constant. So prefixing :: to Document should give you the behavior you're after unless there is something else going on.

@uberllama

You're right, but that is a more specific, less likely scenario, especially in an environment where pg_search is being used. We could go as far as naming it PGSearchDocument to be sure. I've been involved in a lot of projects involving file uploading/management and there's almost always an AR model named Document. This is actually the first time I've run into a class name conflict from a gem, so not sure if there's a different solution to including PgSearch and exposing its own Document class.

@nertzy
Owner

Copying over comment from #96 that is also relevant here:

I'd rather work towards removing the need for an Active Record model to live in PgSearch at all. I don't want to break existing code that might assume the PgSearch::Document class is there.

Let's move toward a generator that generates models that the developer chooses the name for, and remove the idea of a single "Document" class once and for all.

There's a discussion going on over at #92 towards this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.