Существует ли способ переопределить один из методов, предоставленных ассоциацией 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.empty?, и т.д.
Как я иду о переопределении одного из этих методов? Конкретно теги <<метод. Довольно легко переопределить нормальные методы класса, но я, может казаться, не нахожу информации о том, как переопределить методы ассоциации. Выполнение чего-то как
def tags<< *new_tags
#do stuff
end
производит синтаксическую ошибку, когда это называют так, это, очевидно, не настолько просто.
Вы можете использовать блок с has_many
, чтобы расширить вашу связь с методами. См. Комментарий «Используйте блок для расширения ваших ассоциаций» здесь .
Переопределение существующих методов также работает, но не знаю, хорошая ли это идея.
has_many :tags, :through => :taggings, :order => :name do
def << (value)
"overriden" #your code here
super value
end
end
Вам нужно будет определить метод тегов для возврата объекта, который имеет метод <<
.
Вы могли бы сделать это так, но я бы не советовал это делать. Было бы намного лучше просто добавить в свою модель метод, который делает то, что вы хотите, чем пытаться заменить что-то, что использует ActiveRecord.
По сути, это запускает стандартный метод tags
, добавляет метод << к результирующему объекту и возвращает этот объект. Это может быть немного ресурсоемким, потому что он создает новый метод каждый раз, когда вы его запускаете
def tags_with_append
collection = tags_without_append
def collection.<< (*arguments)
...
end
collection
end
# defines the method 'tags' by aliasing 'tags_with_append'
alias_method_chain :tags, :append
Думаю, вам нужны теги def. << (* new_tags)
для подписи, которая должна работать, или следующее, что эквивалентно и немного чище, если вам нужно для переопределения нескольких методов.
class << tags
def <<(*new_tags)
# rawr!
end
end