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
精彩评论