1

这个问题与在 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 混合自身的方式是否会导致此问题?

我正在使用 permalink-v.1.0.0 gem http://github.com/goncalossilva/permalink_fu

4

1 回答 1

0

经过调查,我现在可以看到问题与 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所有子类(和子子类)共享。

于 2010-09-01T06:14:00.340 回答