在rails引擎中使用permalink_fu对ActiveRecord进行子类化

时间:2010-08-27 18:47:56

标签: ruby-on-rails activerecord rails-engines permalink-fu

这个问题与在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

1 个答案:

答案 0 :(得分:0)

在对此进行调查之后,我现在可以看到问题与permalink_fu如何验证它应该如何创建永久链接有关。它通过检查类的permalink_field是否为空来验证这一点。

permalink_field是什么?当你这样做

class Parent < ActiveRecord::Base
  has_permalink :name
end

class Child < Parent
end

您可以通过撰写Parent.new.permalinkChild.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?会返回falseChild.create :name => 'something'不会创建固定链接。

一种可能的解决方案是用类上的cattr_accessors替换元类上的attr_acessors(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及其所有子类(和子类)共享。