开发者

Rails: How do I define an association extension in a module that gets included in my AR model?

I have a Blockable module that contains associations and methods to be included in a few other ActiveRecord classes.

Relevant code:

module Blockable
  def self.included(base)
    base.has_many :blocks
  end
end

I want to add an association extension. The usual syntax (ie when I'm not defining the association in a module) is like this:

# definition in Model < ActiveRecord::Base
has_many :blocks do
  def method_name
    ... code ...
  end
end

# usage
Model.first.blocks.method_name

This syntax doesn't work when used in the module which is included in the AR model. I get an undefined method 'method_name' for #<ActiveRecord::Relation:0xa16b714>.

Any idea how I should go about defining an association extension开发者_如何学运维 in a module for inclusion in other AR classes?


Rails 3 has some helper methods for this. This example is from The Rails 3 Way, 2nd Edition:

module Commentable
  extend ActiveSupport::Concern
  included do
    has_many :comments, :as => :commentable
  end
end


I have something similar working in my Rails code (2.3.8) at the moment. I used base.class_eval rather than base.has_many:

module Blockable
    self.included(base)
        base.class_eval do
            has_many :blocks do
                def method_name
                    # ...stuff...
                end
            end
        end
    end
end

Whew - that was a lot of spacebarring...

Anyway, that works for me - hopefully it'll work for you, too!


Argh, I suck.

I had an unrelated bug that was causing the association extension to break.

I have verified that both my original method and Xavier Holt's method work under Rails 3.0.3:

self.included(base)
  base.has_many :blocks do 
    def method
      ...
    end
  end
end

# OR

self.included(base)
  base.class_eval do 
    has_many :blocks do
      def method
        ...
      end
    end
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜