有没有办法覆盖ActiveRecord关联提供的方法之一?
比方说,我有以下典型的多态has_many:通过关联:
class Story < ActiveRecord::Base
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings, :order => :name
end
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :stories, :through => :taggings, :source => :taggable, :source_type => "Story"
end
您可能知道这会为Story模型添加一大堆相关方法,如标签,标签<<,tags =,tags.empty?等 .
我如何重写这些方法之一?特别是标签<<方法 . 覆盖普通的类方法很容易,但我似乎无法找到有关如何覆盖关联方法的任何信息 . 做点什么
def tags<< *new_tags
#do stuff
end
调用它时会产生语法错误,所以显然不那么简单 .
7 回答
您可以使用
has_many
块来扩展与方法的关联 . 见评论"Use a block to extend your associations" here .覆盖现有方法也有效,但不知道这是否是一个好主意 .
如果要在Rails 3.2中访问模型本身,则应使用
proxy_association.owner
例:
见documentation
我认为您需要
def tags.<<(*new_tags)
用于签名,这应该可以使用,或者以下是等效的,如果您需要覆盖多个方法则更清洁一点 .您必须定义tags方法以返回具有
<<
方法的对象 .你可以这样做,但我真的不推荐它 . 除了尝试替换ActiveRecord使用的东西之外,只需向模型添加一个方法就可以做得更好 .
这基本上运行默认的
tags
方法将<<方法添加到结果对象并返回该对象 . 这可能有点资源,因为每次运行它都会创建一个新方法我使用的方法是扩展关联 . 你可以在这里看到我处理'quantity'属性的方式:https://gist.github.com/1399762
它基本上允许你这样做
如果不能确切地知道你希望通过覆盖方法实现什么,那么很难知道你是否可以做同样的事情 .
这可能对您的情况没有帮助,但可能对其他人有用 .
协会回调:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
来自文档的示例:
另请参阅Association Extensions:
Rails guides有关直接覆盖添加方法的文档 .
OP覆盖
<<
的问题可能是唯一的例外,因为the top answer . 但它不适用于has_one
的=
赋值方法或getter方法 .