经过调查,我现在可以看到问题与 permalink_fu 如何验证它是否应该创建永久链接有关。它通过检查类的 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)访问永久链接。
这有什么问题? permalink_field 访问器方法在Parent 的元类上定义:
class << self
attr_accessor :permalink_field
end
当你运行 has_permalink 方法时,它会调用Parent.permalink_field = 'permalink'。
问题在于,虽然permalink_field 方法 在所有子类中都可用,但它的值 存储在它被调用的类中。这意味着该值不会传播到子类。
因此,由于 permalink_field 存储在 Parent 类中,因此 Child 不会继承该值,尽管它继承了访问器方法。由于Child.permalink_field 为空白,should_create_permalink? 返回false,而Child.create :name => 'something' 不会创建永久链接。
一种可能的解决方案是将元类上的 attr_accessors 替换为类上的 cattr_accessors(permalink_fu.rb 文件的第 57 到 61 行)。
替换
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 及其所有子类(和子子类)共享。