Направляющие: Переопределение метода ассоциации ActiveRecord

Существует ли способ переопределить один из методов, предоставленных ассоциацией 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

производит синтаксическую ошибку, когда это называют так, это, очевидно, не настолько просто.

34
задан seaneshbaugh 23 May 2010 в 05:36
поделиться

3 ответа

Вы можете использовать блок с has_many , чтобы расширить вашу связь с методами. См. Комментарий «Используйте блок для расширения ваших ассоциаций» здесь .
Переопределение существующих методов также работает, но не знаю, хорошая ли это идея.

  has_many :tags, :through => :taggings, :order => :name do
    def << (value)
      "overriden" #your code here
      super value
    end     
  end
55
ответ дан 27 November 2019 в 16:33
поделиться

Вам нужно будет определить метод тегов для возврата объекта, который имеет метод << .

Вы могли бы сделать это так, но я бы не советовал это делать. Было бы намного лучше просто добавить в свою модель метод, который делает то, что вы хотите, чем пытаться заменить что-то, что использует 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  
0
ответ дан 27 November 2019 в 16:33
поделиться

Думаю, вам нужны теги def. << (* new_tags) для подписи, которая должна работать, или следующее, что эквивалентно и немного чище, если вам нужно для переопределения нескольких методов.

class << tags
  def <<(*new_tags)
    # rawr!
  end
end
0
ответ дан 27 November 2019 в 16:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: