Подклассный Activerecord с Permalink_fu в двигателе Rails
-
01-10-2019 - |
Вопрос
Этот вопрос связан с расширением методов классов в Ruby, возможно, более конкретно так, как Permalink_FU делает это.
Кажется, что has_permalink
На модели не будут доступны в полученной модели. Конечно, я ожидаю, что все определено в классе, который будет унаследован своими полученными классами.
class MyScope::MyClass < ActiveRecord::Base
unloadable
self.abstract_class = true
has_permalink :name
end
class MyClass < MyScope::MyClass
unloadable
#has_permalink :name # This seems to be required
end
Есть ли что-то в пути Permalink_fu смешивает себя в том, что вызывает этот вопрос?
Я использую GEM Permalink-V.1.0.0 http://github.com/goncalossilva/permalink_fu.
Решение
После расследования этого я могу видеть, что проблема связана с тем, как Permalink_FU проверяет его, он должен создать постоянную ссылку или нет. Он проверяет это, проверяя, если Permalink_Field из класса пустой или нет.
Что такое permalink_field? Когда вы делаете
class Parent < ActiveRecord::Base
has_permalink :name
end
class Child < Parent
end
Вы можете получить доступ к постоянным соке, написав Parent.new.permalink
или Child.new.permalink
. Отказ Это имя метода может быть изменено путем письма
class Parent < ActiveRecord::Base
has_permalink :name 'custom_permalink_name'
end
Если это так, постоянная ссылка будет доступна путем письма Parent.new.custom_permalink_name
(или Child.new.custom_permalink_name
).
В чем проблема с этим? Методы AccessoR Permalink_field определены на Parent
Метакласс:
class << self
attr_accessor :permalink_field
end
Когда вы запускаете метод HAS_PERMALINK, он называет Parent.permalink_field = 'permalink'
.
Проблема в том, что хотя permalink_field
метод доступен на всех подклассах, его стоимость хранится на классе, который его называли. Это означает, что значение не распространяется на подклассы.
Итак, как permalink_field
хранится на Parent
Класс, ребенок не наследует значение, хотя он наследует методы доступа. Так как Child.permalink_field
пусто, should_create_permalink?
возвращается false
, а также Child.create :name => 'something'
не создает постоянную ссылку.
Возможное решение будет заменить Attr_aceSsors на метаклассе с CATTR_ACCESSORS в классе (линии от 57 до 61 на файле Permalink_fu.rb).
Заменять
class << base
attr_accessor :permalink_options
attr_accessor :permalink_attributes
attr_accessor :permalink_field
end
с участием
base.cattr_accessor :permalink_options
base.cattr_accessor :permalink_attributes
base.cattr_accessor :permalink_field
Обратите внимание, что это будет аннулировать любую возможную настройку на подклассе. Вы больше не сможете указать различные параметры для подклассов, поскольку эти три атрибута совместно используются Parent
и все его подклассы (и подсказки).