Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 Concern Modules for Models

First off, I'm following the practice found here for Rails concerns (great idea!): https://gist.github.com/1014971

I'm getting an error though:

undefined method `search' for #<Class:0x5c25ea0>
app/controllers/accessories_controller.rb:6:in `index'

I DO have my /app/models/concerns/ directory loaded in /config/application.rb. So the "concern" modules ARE being loaded. Just wanted to point that out.

Here is my code:

/app/models/concerns/searchable.rb

module Searchable
  extend ActiveSupport::Concern

  # Add a "search" scope to the models
  def self.search (search)
    if search
      where('name LIKE ?', "%#{search}%")
    else
      scoped
    end
  end
end

/app/models/accessory.rb

class Accessory < ActiveRecord::Base
  include Searchable

  ...
end

/app/controllers/accessories_controller.rb

class AccessoriesController < ApplicationController

  def index
    @accessories  = Accessory.search(params[:search])

    ...
  end

end
like image 676
Wes Foster Avatar asked Jul 17 '12 01:07

Wes Foster


People also ask

What are Rails model concerns?

A Rails Concern is a module that extends the ActiveSupport::Concern module. Concerns allow us to include modules with methods (both instance and class) and constants into a class so that the including class can use them.

Where should Rails concerns be placed?

Usually, you want model related concerns inside /app/models/concerns and controller related concerns inside /app/controllers/concerns, but that's just for organization purposes, rails will autoload them even if you use /app/whatever/concerns, so be carefull about name collisions.

What is the reason for using concerns in Rails?

People use Rails concern for mainly for two things: First, to reduce the size of a model that could be separated into several models, and therefore reducing the size. Second, to avoid declaring the same class over and over again.

What does ActiveSupport :: concern do?

Using extend ActiveSupport::Concern tells Rails that we are creating a concern. The code within the included block will be executed wherever the module is included. This is best for including third party functionality. In this case, we will get an error if the before_action is written outside of the included block.


1 Answers

Well, with a little more toying around I figured out what is wrong!

When you're wanting to directly modify the Model from within the Module (concern), you need to wrap the functionality inside an included block.

I've changed my concern module to the following:

    module Searchable
        extend ActiveSupport::Concern

        included do
            # Add a "search" scope to the models
            def self.search (search)
                if search
                    where('name LIKE ?', "%#{search}%")
                else
                    scoped
                end
            end
        end

    end

That is it! Hopefully this will help someone else with the same quesion!

like image 187
Wes Foster Avatar answered Sep 28 '22 19:09

Wes Foster