Domanda

Questa domanda è legata ad estendere i metodi della classe in Ruby, forse più precisamente nel modo in cui lo fa permalink_fu.

Sembra che has_permalink su un modello non sarà disponibile in un modello derivato. Certo mi sarei aspettato qualcosa di definito in una classe per essere ereditata dai suoi classi derivate.

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

C'è qualcosa nel modo permalink_fu si mescola in che causa questo problema?

Sto usando la gemma permalink-v.1.0.0 http://github.com/goncalossilva/ permalink_fu

È stato utile?

Soluzione

Dopo aver esaminato questo, posso ora vedere che il problema è legato al modo in cui la verifica permalink_fu si dovrebbe creare un permalink o meno. Si verifica questo controllando se il permalink_field della classe è vuota o meno.

Qual è il permalink_field? Quando si esegue

class Parent < ActiveRecord::Base
  has_permalink :name
end

class Child < Parent
end

è possibile accedere alla permalink scrivendo Parent.new.permalink o Child.new.permalink. Questo nome del metodo può essere modificato per iscritto

class Parent < ActiveRecord::Base
  has_permalink :name 'custom_permalink_name'
end

Se è così, il permalink sarà accessibile scrivendo Parent.new.custom_permalink_name (o Child.new.custom_permalink_name).

Qual è il problema con questo? Il permalink_field metodi di accesso sono definiti sulla metaclasse di Parent:

class << self
  attr_accessor :permalink_field
end

Quando si esegue il metodo has_permalink, chiama Parent.permalink_field = 'permalink'.

Il problema è che, sebbene la permalink_field metodo è disponibile su tutte le sottoclassi, il suo Valore è memorizzato sulla classe è stato chiamato. Ciò significa che il valore non viene propagata al sottoclassi.

Quindi, come il permalink_field è memorizzato sulla classe Parent, il bambino non eredita il valore, anche se eredita i metodi di accesso. Come Child.permalink_field è vuoto, il rendimento should_create_permalink? false, e Child.create :name => 'something' non crea un permalink.

Una possibile soluzione sarebbe quella di sostituire i attr_acessors sul metaclasse con cattr_accessors sulla classe (linee da 57 a 61 sul file permalink_fu.rb).

Sostituire

class << base
  attr_accessor :permalink_options
  attr_accessor :permalink_attributes
  attr_accessor :permalink_field
end

con

base.cattr_accessor :permalink_options
base.cattr_accessor :permalink_attributes
base.cattr_accessor :permalink_field

Si noti che ciò annulla ogni possibile personalizzazione della sottoclasse. Non sarà più in grado di specificare le opzioni diverse per le sottoclassi, come questi tre attributi sono condivisi da Parent e tutte le sue sottoclassi (e subsubclasses).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top