ruby-on-railsacts-as-taggable-onpg-search

Rails controller not loading extended class


I am using rails (5.0.7.2) for a small project. For tags I choose the acts-as-taggable-on and for search pg_search gems. As I want the tags to be searchable, I first created a folder in the app directory called "utilities". Then I crated a file called "search_tags.rb" in that folder.

The content:

ActsAsTaggableOn::Tag.class_eval do
  # includes
  include PgSearch

  # search scope
  pg_search_scope :search, against: {
    name: 'A',
  },
  using: {
    tsearch: {
      dictionary: 'english',
      prefix: true
    }
  }

  class SearchTags; end

end

However if I want to use that search function on the tags in my tags controller I get a "method undefined" error. If I include the code from the file above right in the controller action it works properly. Thus I guess it may be not loaded at all from that new folder.

What would be the proper way of making the content from the extension available to my controller?

Update:

I created:

# app/models/concerns/searchable.rb
module Searchable
  extend ActiveSupport::Concern

  included do
    include PgSearch

    # search scope
    pg_search_scope :search, against: {
      name: 'A',
    },
    using: {
      tsearch: {
        dictionary: 'english',
        prefix: true
      } 
    }
  end
end

I removed utilities folder and the file. In the tags controller now I do

class ActsAsTaggableOn::Tag
  include Searchable
end

This works and looks a bit better. However not optimal. At least it does not feel to good to have the class call and that include in the controller.


Solution

  • I think a better approach might be to move this into a concern and include the concern in your model (concerns should get autoloaded by default). Something like this might work.

    # app/models/concerns/searchable.rb
    module Searchable
      extend ActiveSupport::Concern
    
      included do
        include PgSearch
    
        # search scope
        pg_search_scope :search, against: {
          name: 'A',
        },
        using: {
          tsearch: {
            dictionary: 'english',
            prefix: true
          } 
        }
      end
    end
    
    # app/models/act_as_taggable_on/tag.rb
    class ActsAsTaggableOn::Tag
      include Searchable
    end