Piuttosto che includere la preoccupazione in ogni modello, io suggerirei di creare un ActiveRecord
modulo e estendo ActiveRecord::Base
con esso, e quindi aggiungere un metodo che modulo (diciamo include_importable
) che fa il compreso. È quindi possibile passare il nome del campo come argomento a tale metodo e nel metodo definire una variabile di istanza e un accessorio (ad esempio, ad esempio importable_field
) per salvare il nome del campo come riferimento nei metodi di classe e istanza Importable
.
Quindi qualcosa di simile:
module Importable
extend ActiveSupport::Concern
module ActiveRecord
def include_importable(field_name)
# create a reader on the class to access the field name
class << self; attr_reader :importable_field; end
@importable_field = field_name.to_s
include Importable
# do any other setup
end
end
module ClassMethods
# reference field name as self.importable_field
end
module InstanceMethods
# reference field name as self.class.importable_field
end
end
Sarai quindi necessario estendere ActiveRecord
con questo modulo, dicono mettendo questa linea in un inizializzatore (config/initializers/active_record.rb
):
ActiveRecord::Base.extend(Importable::ActiveRecord)
(Se il preoccupazione è nel tuo config.autoload_paths
quindi non dovrebbe essere necessario richiedere qui, vedere i commenti qui sotto.)
Quindi nei tuoi modelli, yo u dovrebbe includere Importable
come questo:
class MyModel
include_importable 'some_field'
end
E il lettore imported_field
restituirà il nome del campo:
MyModel.imported_field
#=> 'some_field'
Nella tua InstanceMethods
, è possibile impostare il valore del campo importato nel vostro caso metodi passando il nome del campo per write_attribute
, e di ottenere il valore utilizzando read_attribute
:
m = MyModel.new
m.write_attribute(m.class.imported_field, "some value")
m.some_field
#=> "some value"
m.read_attribute(m.class.importable_field)
#=> "some value"
Spero che questo aiuti. Questa è solo la mia opinione personale su questo, però, ci sono altri modi per farlo (e sarei interessato a sentir parlare anche di loro).
Grande risposta, grazie. Tutto ha un senso. Proverò ciò che hai suggerito domani e assegnerò la soluzione dopo. – Col
Funziona tutto ma ho un piccolo problema. Ottengo il seguente errore a meno che non richieda espressamente "preoccupazioni/importazione" nella parte superiore di ciascun file di modello. NameError: undefined variabile locale o metodo 'include_importable' per # Ho aggiunto la directory preoccupazioni al autoload_path in questo modo: config.autoload_paths + = Dir [" # {} config.root/app/models/**/"] Non è un grosso problema, ma preferirei non doverlo richiedere ovunque. Eventuali suggerimenti? –
Col
Il problema è la riga 'ActiveRecord :: Base.extend (Importabile :: ActiveRecord)', che deve essere chiamata * prima * i tuoi modelli sono caricati in modo che ActiveRecord abbia il metodo 'includes_importable'. L'autocaricamento non funziona perché il nome reale del modulo "Importabile" non è menzionato nel codice del modello. Ci sono alcuni modi per risolvere il problema, immagino che il modo più semplice sia creare un inizializzatore in 'config/initializers/active_record.rb' e spostare la riga' extend' in là, con un 'require 'preoccupazioni/importable'' a la cima. Quindi non dovrai richiederlo nei tuoi modelli. –